Modify error 1

 

Продублирую здесь. А то в форум новичков, похоже, профи не заглядывают.

Помогите с тралом плиииз.

Выдает OrderModify error 1 . Две первые сделки модифицирует, третья остается без стопа и сливает депо. Сделки все Buy

Добавлю: вторую сделку тралит правильно, но в какой-то момент OrderModify error 1 очень много раз потом Stack overflow. Видимо поэтому 3 сделка остается без стопа.

void Trall()
{
     int total = OrdersTotal();
     for(int i=total-1;i>=0;i--)
     {
        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true)
           {
           if (Bid - OrderOpenPrice()>TralOneStep*Point && OrderStopLoss()<=OrderOpenPrice())
              {
              if (OrderStopLoss() != Bid-NormalizeDouble(TralOneStep*Point,Digits))
              {
              if   (OrderModify (OrderTicket(),OrderOpenPrice(),
              Bid-NormalizeDouble(TralOneStep*Point,Digits),
              OrderTakeProfit(),0,CLR_NONE)== false)
                 {
                 Trall();
                 }
              }
              }
            RefreshRates();
            if(Bid - OrderOpenPrice()>Tral*Point && Bid-OrderStopLoss()>=Tral*Point)
              {
              if (OrderStopLoss() != Bid-NormalizeDouble(Tral*Point,Digits))
              {
              if   (OrderModify (OrderTicket(),OrderOpenPrice(),
              Bid-NormalizeDouble(Tral*Point,Digits),
              OrderTakeProfit(),0,CLR_NONE)== false)
                 {
                 Trall();
                 }
              }
              }
           }
     }
}
 

Здесь видны две принципиальные ошибки. Одна связана с сравнением на тождество двух вещественных чиел, что неправильно. Это операторы

if (OrderStopLoss() != Bid-NormalizeDouble(TralOneStep*Point,Digits))

Правильно проверять так: два числа типа double не равны, если абсолютное значение их разности больше некоторого маленького числа. В вашем случае годится 0.5*Point.

Вторая ошибка связана с использованием ненормализованного числа в операторе OrderModify (). Правильно писать

NormalizeDouble(Bid-Tral*Point,Digits),

Если для вас критичны другие мелкие неточности, то стОит пересмотреть сравнения

if (Bid - OrderOpenPrice()>TralOneStep*Point && OrderStopLoss()<=OrderOpenPrice())
с учетом приведенного выше предложения по сравнению двух чисел типа double .
 
MarkTrade:

Продублирую здесь. А то в форум новичков, похоже, профи не заглядывают.

Помогите с тралом плиииз.

Выдает OrderModify error 1 . Две первые сделки модифицирует, третья остается без стопа и сливает депо. Сделки все Buy

Добавлю: вторую сделку тралит правильно, но в какой-то момент OrderModify error 1 очень много раз потом Stack overflow. Видимо поэтому 3 сделка остается без стопа.


А самое главное - не нужно осуществлять вызов функции из этой же самой функции. Возникает цикличность, которая и дает Stack overflow.
 
FxRoller:

А самое главное - не нужно осуществлять вызов функции из этой же самой функции. Возникает цикличность, которая и дает Stack overflow.


Если попытка модификации не удалась, не хотелось бы остаться без стопа.

вызов функции из этой же самой функции, по идее не должен переполнять стек, ведь там явная проверка, вызов только в том случае если модификация не удалась.

не может же быть такого большого количества реквотов и т.п.

Если не рекурсия, то как это сделать?

 
Mislaid:

Здесь видны две принципиальные ошибки. Одна связана с сравнением на тождество двух вещественных чиел, что неправильно. Это операторы

Правильно проверять так: два числа типа double не равны, если абсолютное значение их разности больше некоторого маленького числа. В вашем случае годится 0.5*Point.

Вторая ошибка связана с использованием ненормализованного числа в операторе OrderModify (). Правильно писать

Если для вас критичны другие мелкие неточности, то стОит пересмотреть сравнения

с учетом приведенного выше предложения по сравнению двух чисел типа double .


Спасибо! буду пробовать.
 
MarkTrade:


Если попытка модификации не удалась, не хотелось бы остаться без стопа.

Если не рекурсия, то как это сделать?

Циклом из нескольких попыток. Если модификация прошла успешно (т.е. после исполнения OrderModify() не было ошибки), выходим из цикла (break), если была ошибка, то Sleep(5000) и следующая итерация, до тех пор, пока ордер не будет модифицирован.
 
FxRoller:
Циклом из нескольких попыток. Если модификация прошла успешно (т.е. после исполнения OrderModify() не было ошибки), выходим из цикла (break), если была ошибка, то Sleep(5000) и следующая итерация, до тех пор, пока ордер не будет модифицирован.


Придется видимо так и сделать.

Просто рекурсией код получается проще.

 

Переписал с учетом вышеперечисленных ошибок.

Теперь на первом же ордере виснет в ошибкой modify error 1.

У меня уже голова кругом идет.

void Trall()
{
 double ossl;    
 double sl;    
 double tsl;    
     int total = OrdersTotal();
     for(int i=total-1;i>=0;i--)
     {
        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true)
           {
           sl=NormalizeDouble(OrderStopLoss(),Digits);
           ossl=NormalizeDouble(Bid-TralOneStep*Point,Digits);
           tsl=NormalizeDouble(Bid-Tral*Point,Digits);
           if (NormalizeDouble(Bid - OrderOpenPrice(),Digits)>
              ossl && 
              NormalizeDouble(OrderStopLoss(),Digits)<
              NormalizeDouble(OrderOpenPrice(),Digits))
              {
              if (ossl-sl>0.5*Point)
              {
              while(true)
              {
              ossl=NormalizeDouble(Bid-TralOneStep*Point,Digits);
              
              if (OrderModify (OrderTicket(),
                 OrderOpenPrice(),
                 ossl,
                 OrderTakeProfit(),0,CLR_NONE) ==true) 
                 break;
              Sleep(5000);
              }   
              }
              }
            RefreshRates();
            if (NormalizeDouble(Bid - OrderOpenPrice(),Digits)>
                tsl && 
                NormalizeDouble(Bid-sl,Digits)>
                tsl)
              {
              if (tsl-sl>0.5*Point)
              {
               while(true)
               {
               
               tsl=NormalizeDouble(Bid-Tral*Point,Digits);
               if   (OrderModify (OrderTicket(),OrderOpenPrice(),
                     tsl,
                     OrderTakeProfit(),0,CLR_NONE)== true) 
                     break;
               Sleep(5000);
               }
              }
              }
           }
     }
}
 

Вы не поняли особенности сравнения чисел типа double. Числа могут быть равны, "по жизни". А машина может выдать любой вариант сравнения: "меньше", "больше", "равно". Пассы с NormalizeDouble не катят.

Еще раз:

"Правильно проверять так: два числа типа double не равны, если абсолютное значение их разности больше некоторого маленького числа. В вашем случае годится 0.5*Point"

Определение того, что одно число меньше или больше другого, можно вывести из предыдущего предложения.

 
Mislaid:

Вы не поняли особенности сравнения чисел типа double. Числа могут быть равны, "по жизни". А машина может выдать любой вариант сравнения: "меньше", "больше", "равно". Пассы с NormalizeDouble не катят.

Еще раз:

"Правильно проверять так: два числа типа double не равны, если абсолютное значение их разности больше некоторого маленького числа. В вашем случае годится 0.5*Point"

Определение того, что одно число меньше или больше другого, можно вывести из предыдущего предложения.


Спасибо! Понял, переписал на сравнение разницы, ошибка пропала.

почему-то в строке if (NormalizeDouble(Bid - OrderOpenPrice(),Digits)> tsl при равных значениях условие все равно соблюдалось. Не всегда но все-же...

 
MarkTrade:


Спасибо! Понял, переписал на сравнение разницы, ошибка пропала.

почему-то в строке if (NormalizeDouble(Bid - OrderOpenPrice(),Digits)> tsl при равных значениях условие все равно соблюдалось. Не всегда но все-же...


Я думаю, если еще раз попробуете переписать, то ошибка пропадет навсегда. Наверно, глаз замылился.

Условие в строке все еще записано неправильно.

PS Если MQL поддерживает рекурсию, то, ребята скромняги, что так долго скрывали от мира возможности языка.

Причина обращения: