глюк mql4 при работе с массивами, или я где ошибся ???

 

Пишу эксперта, который торгует по сетке. Ценовые уровни отсчитываются от некоторого базового уровня, и хранятся в массивах. Например: базовый уровень 1.3232, эксперт должен просчитать уровни вверх и вниз, кратные некоторому шагу например 10 пунктов, т.е. уровни вверх должны быть: первый 1.3240,  второй 1.3250, третий - 1.3260, и т.д. уровни вниз должны быть: первый 1.3230, второй 1.3220, третий 1.3210. Уровни вычисляются в этом цикле:

 

for (counter01=1; counter01<=size_of_step*(ArrayRange(level_up, 0)-1); counter01++) // в этом цикле вычисляем значения уровней
{
    if (NormalizeDouble(MathMod(base_level*MathPow(10, Digits)+counter01, size_of_step),0) == ostatok)
       { // при глюке управление сюда не попадает
         counter02++;
         level_up[counter02] = NormalizeDouble(base_level + counter01*Point, Digits);
         Print(level_up[counter02]);
       }
    if (NormalizeDouble(MathMod(base_level*MathPow(10, Digits)-counter01, size_of_step),0) == ostatok)
       { // при глюке управление сюда не попадает
        counter03++;
        level_down[counter03] = NormalizeDouble(base_level - counter01*Point, Digits);
        Print(level_down[counter03]);
       }
}

 

 

При работе эксперта заметил, что при некоторых значениях базового уровня (например 1.3114) массивы с ценами не обновляются, и начинают сыпаться ошибки. При других значения все вычисляется нормально. Для проверки вынес цикл в отдельный скрипт (см. приложение). Пробовал запускать на виртуальной машине, результат тот же. Подскажите, это я где то ошибся, или глюк языка ?

Файлы:
 
molotkovsm:

Пишу эксперта, который торгует по сетке. Ценовые уровни отсчитываются от некоторого базового уровня, и хранятся в массивах. Например: базовый уровень 1.3232, эксперт должен просчитать уровни вверх и вниз, кратные некоторому шагу например 10 пунктов, т.е. уровни вверх должны быть: первый 1.3240, второй 1.3250, третий - 1.3260, и т.д. уровни вниз должны быть: первый 1.3230, второй 1.3220, третий 1.3210. Уровни вычисляются в этом цикле:

При работе эксперта заметил, что при некоторых значениях базового уровня (например 1.3114) массивы с ценами не обновляются, и начинают сыпаться ошибки. При других значения все вычисляется нормально. Для проверки вынес цикл в отдельный скрипт (см. приложение). Пробовал запускать на виртуальной машине, результат тот же.


А зачем нужен массив? Нужно хранить базовый уровень. От него всегда в любое время можно сосчитать любой уровень

 

Даже не вникал в Ваш код (где косяк). Я просто по другому поступил в аналогичной задаче: никакого массива не надо. Открыл первый ордер, если после него должна строиться сетка - через OrderSelect найти цену открытия этого ордера, прибавить к ней требуемый шаг и, как только цена достигнет следующего уровня, советник открывает новый ордер. Конечно, шаг может отклоняться от желаемого значения из-за неточности открытия ордеров, но для меня это было некритично. Вот таким образом - очень простой код получается.

 
Vinin:


А зачем нужен массив? Нужно хранить базовый уровень. От него всегда в любое время можно сосчитать любой уровень



просто количество уровней может быть разным в зависимости от валютной пары, и торговой тактики
 
Vinin:


А зачем нужен массив? Нужно хранить базовый уровень. От него всегда в любое время можно сосчитать любой уровень


вот, или так - в общем тоже самое
 
molotkovsm:


просто количество уровней может быть разным в зависимости от валютной пары, и торговой тактики

ну и нет проблем - количество открытых ордеров вверх - вот Ваш набор уровней вверх ( и наоборот), также можете менять шаг в зависимости от количества открытых ордеров - базовый шаг умножаете на коэффициент, зависящий от них (то ли в сторону увеличения шага, то ли наоборот) и нет проблемм.
 
пожалуйста попробуйте скрипт скомпилировать и запустить с тремя значениями базового уровня, у меня при базовом уровне 1.3114 выдаются нули, а при других значениях 1.3115  , 1.3113 все просчитывается нормально, вот в чем собственно моя проблема, мне удобно, когда уровни вычисляются таким образом, и не хотелось бы все переписывать
 

Самый простой вариант расчета

//+------------------------------------------------------------------+
//|                                                   array_test.mq4 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""

#define UP  1
#define DN -1
#property show_inputs

extern double base_level = 1.3114;
extern int size_of_step = 10;
extern int count_level=6;

int start()
  {
   double level;
    for (int i=1; i<=count_level; i++)    // в этом цикле вычисляем значения уровней 
      {
         level = CalculateLevel(base_level, size_of_step, i, UP);
         Print(DoubleToStr(level, Digits));

         level = CalculateLevel(base_level, size_of_step, i, DN);
         Print(DoubleToStr(level, Digits));
      }
   return(0);
  }
//+------------------------------------------------------------------+


double CalculateLevel(double base_level, int step, int pos, int dir){
   double level=base_level +dir*pos*step*Point;
   return(level);
}
 
Vinin:

Самый простой вариант расчета



Спасибо, но в вашем варианте последняя цифра верхних и нижних уровней зависит от базового уровня, а мне нужно, что бы базовый уровень мог "плавать" между первыми уровнями вверх и вниз, а сами уровни оставались на своих местах, и пересчитывались только тогда, когда базовый уровень уходит за первый уровень вверх или вниз .

 

molotkovsm:

if (NormalizeDouble(MathMod(base_level*MathPow(10, Digits)+counter01, size_of_step),0) == ostatok)
{ // при глюке управление сюда не попадает
counter02++;
level_up[counter02] = NormalizeDouble(base_level + counter01*Point, Digits);
Print(level_up[counter02]);
}

Некорректно проверять тождество двух чисел типа double. В Вашем случае, правильно будет так

if (MathAbs( MathMod(base_level*MathPow(10, Digits)+counter01, size_of_step) - ostatok ) < 0.1)

Во втором операторе аналогично.

 
Mislaid:

Некорректно проверять тождество двух чисел типа double. В Вашем случае, правильно будет так

Во втором операторе аналогично.



  Согласен, скопировал и вставил вашу строку, но проблема остается. Еще не понятно, почему с другими значениями базового уровня все прокатывает
Причина обращения: