OrderModify error 1

 

Какова истинная причина возникновения данной ошибки?

Тут  в описании её: " Нет ошибки, но результат неизвестен ". Порывшись на форуме, я понял, что иногда эта ошибка возникает в функциях модификации стопов, если новый стоплосс равен текущему стоплоссу. Это так?

Данную проверку я включил в функцию, но ошибки всё же проскакивают. Хотя принтуя я вижу, что никаких непредвиденных значений функции нет. Как понять что в моём случае нужно изменить? В принципе, модификации выполняются успешно, но предупреждения то тоже не особо радуют, особенно если ошибок в коде нет. Так что хочется понять причину возникновения предупреждения. Вот код траала по машке, в котором возникает предупреждение: 

void PositionsTrailings::TrailingByMA (int fi_Ticket,         // Тикет открытой позиции
                                       int fi_MATF,           // Период графика, на котором строится МА (1, 5, 15, 30, 60, 240, 1440, 10080, 43200)
                                       int fi_MAPeriod,       // Период МА (не меньше 2)
                                       int fi_MAShift,        // Свиг индикатора относительно ценового графика
                                       int fi_MAMethod,       // Метод усреднения (0 - MODE_SMA, 1 - MODE_EMA, 2 - MODE_SMMA, 3 - MODE_LWMA);
                                       int fi_AppliedPrice,   // Используемая цена (0 - PRICE_CLOSE, 1 - PRICE_OPEN, 2 - PRICE_HIGH, 3 - PRICE_LOW, 4 - PRICE_MEDIAN, 5 - PRICE_TYPICAL, 6 - PRICE_WEIGHTED)
                                       int fi_Shift,          // Индекс получаемого значения из индикаторного буфера
                                       int fi_Indent)         // Отступ от тени бара, на котором размещается SL
{     
   // Проверяем переданные значения
   if ((fi_MAPeriod < 2) || (fi_MAMethod < 0) || (fi_MAMethod > 3) || (fi_AppliedPrice < 0) || (fi_AppliedPrice > 6) || (fi_Shift < 0) || (fi_Indent < 0))
   {
      Print ("Трейлинг функцией TrailingByMA() невозможен из-за некорректности значений переданных ей аргументов.");
      return;
   }

   double ld_MAValue,   // Значение скользящего среднего с переданными параметрами
          ld_NewSL;     // Новое значение SL
   
   // Определим значение МА с переданными функции параметрами
   ld_MAValue = iMA (Symbol(), fi_MATF, fi_MAPeriod, fi_MAShift, fi_MAMethod, fi_AppliedPrice, fi_Shift);
   
   ResetLastError();
   
   // Если длинная позиция, и её SL хуже значения среднего с отступом в iIndent пунктов, модифицируем его
   if (OrderType() == OP_BUY)
   {
      Print ("OP_BUY");
      ld_NewSL = ld_MAValue - fi_Indent * SSym.gd_Pt;
      Print ("ld_NewSL = ", DToS (ld_NewSL));
      Print ("SPos.gd_CurSL = ", DToS (SPos.gd_CurSL));
      Print ("ld_MAValue = ", DToS (ld_MAValue));
      
      if (ld_NewSL == SPos.gd_CurSL) return;
      if ((OrderStopLoss() < ld_NewSL))
      {
         if (!CPosMan.fOrderModify (fi_Ticket, OrderOpenPrice(), ND (ld_NewSL), OrderTakeProfit(), 0, Gold))
         CLogging.WriteLog (StringConcatenate ("TrailingByMA(): ", CErrs.ErrorToString (_LastError)));
      }
   }
   
   // Если позиция - короткая, и её SL хуже (выше верхней границы канала или не определён, ==0), модифицируем его
   if (OrderType() == OP_SELL)
   {
      Print ("OP_SELL");
      ld_NewSL = ld_MAValue + (SSym.gd_Spread + fi_Indent * SSym.gd_Pt);
      Print ("ld_NewSL = ", DToS (ld_NewSL));
      Print ("SPos.gd_CurSL = ", DToS (SPos.gd_CurSL));
      Print ("ld_MAValue = ", DToS (ld_MAValue));
      
      if (ld_NewSL == SPos.gd_CurSL) return;
      if (((OrderStopLoss() == 0) || (OrderStopLoss() > ld_NewSL)))
      {
         if (!CPosMan.fOrderModify (fi_Ticket, OrderOpenPrice(), ND (ld_NewSL), OrderTakeProfit(), 0, Gold))
         CLogging.WriteLog (StringConcatenate ("TrailingByMA(): ", CErrs.ErrorToString (_LastError)));
      }
   }
}

 

На функцию  CPosMan.fOrderModify (fi_Ticket, OrderOpenPrice(), ND (ld_NewSL), OrderTakeProfit(), 0, Gold) просьба внимания не обращать, т.к. она проверена и в ней точно всё в порядке. Тем более

я заменял её на стандартную OrderModify() и предупреждения сохраняются.

Вызывается данная функция через цикл в функции OnTick() т.е. на каждом тике:

for (int li_Ord = OrdersTotal() - 1; li_Ord >= 0; li_Ord--)
   {
         CPosMan.CheckMyOrdersBased(li_Ord);
         
         //---- Получаем актуальную информацию по символу и текущему ордеру
         CBase.GetMarkerInfo (OrderSymbol(), OrderTicket());

         CPosTrail.TrailingByMA (OrderTicket(), _Period, 21, 0, 1, 0, 1, 30);
   }

 Вот в журнале я вижу как-раз таки ситуацию, когда предыдущий стоплосс равен текущему установленному у ордера возникает предупреждение:

 

12:30:00 2013.08.23 04:15  TempR EURUSD,M5: modify #2 sell 0.01 EURUSD at 1.33460 sl: 1.33516 tp: 1.32660 ok
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: OP_SELL
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: ld_NewSL = 1.33516
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: SPos.gd_CurSL = 1.33516
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: ld_MAValue = 1.33484
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: OrderModify error 1
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: OP_SELL
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: ld_NewSL = 1.33516
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: SPos.gd_CurSL = 1.33516
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: ld_MAValue = 1.33484
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: OrderModify error 1
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: OP_SELL
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: ld_NewSL = 1.33516
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: SPos.gd_CurSL = 1.33516
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: ld_MAValue = 1.33484
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: OrderModify error 1
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: OP_SELL
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: ld_NewSL = 1.33516
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: SPos.gd_CurSL = 1.33516
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: ld_MAValue = 1.33484
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: OrderModify error 1

Зато когда текущий стоплосс(SPos.gd_CurSL) не равен новому (ld_NewSL), то ошибок нет: 

12:30:00 2013.08.23 04:14  TempR EURUSD,M5: OP_SELL
12:30:00 2013.08.23 04:14  TempR EURUSD,M5: ld_NewSL = 1.33519
12:30:00 2013.08.23 04:14  TempR EURUSD,M5: SPos.gd_CurSL = 1.33519
12:30:00 2013.08.23 04:14  TempR EURUSD,M5: ld_MAValue = 1.33487
12:30:00 2013.08.23 04:14  TempR EURUSD,M5: OP_SELL
12:30:00 2013.08.23 04:14  TempR EURUSD,M5: ld_NewSL = 1.33519
12:30:00 2013.08.23 04:14  TempR EURUSD,M5: SPos.gd_CurSL = 1.33519
12:30:00 2013.08.23 04:14  TempR EURUSD,M5: ld_MAValue = 1.33487
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: OP_SELL
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: ld_NewSL = 1.33516
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: SPos.gd_CurSL = 1.33519
12:30:00 2013.08.23 04:15  TempR EURUSD,M5: ld_MAValue = 1.33484

Как избавиться от этого предупреждения?  

 

Попробуй поставить проверку изменения СЛ перед вызовом ф-ции модификации.

for (int li_Ord = OrdersTotal() - 1; li_Ord >= 0; li_Ord--)
   {
         CPosMan.CheckMyOrdersBased(li_Ord);
         
         //---- Получаем актуальную информацию по символу и текущему ордеру
         CBase.GetMarkerInfo (OrderSymbol(), OrderTicket());
          if ((OrderStopLoss() < Bid))// Если я правильно понял твои ф-ции то вот эту проверку.
         CPosTrail.TrailingByMA (OrderTicket(), _Period, 21, 0, 1, 0, 1, 30);
   }
 

В общем, БИД тут не причём. Функция траалит как селы, там и баи. Потому если и сравнивать с рыночной ценой инструмента стоплосс, то с БИДом или с АСКом. А это можно только внутри метода траала.

 У меня вопрос решился когда я нормализовал значение  ld_NewSL:

ld_NewSL = ND (ld_MAValue - fi_Indent * SSym.gd_Pt);

И предупреждения прекратились. А раньше нормализацию я проводил непосредственно в функции модификации ордера. Я так понимаю косяк в том, что до модификации сравнивались значение текущего стопа, который уже нормализован и нового не нормализованного, у которого было после запятой, скажем так, 8 знаков. Есс-но они могли быть разными. А когда попадало новое значение в функцию модификации и нормализовывалось, то новое значение становилось например такое же как и прошое.. и возникала ошибка. Например,

CurSL = 1,32562

NewSL = 1.325626

Сравниваем их... они разные (по 6 знаку). А попадая в функцию модификации NewSL нормализуется и станет равным CurSL.

Я так понимаю, в этом причина того, что сыпались одна за другой предупреждения. Верно? 

 

Верно что надо обрабатывать значение до вставки его в ордер.


Но нормализованное до 5 знака 1.325626 = 1.32563 а не 1.32562

 
hoz:

В общем, БИД тут не причём.

Я заменил твою переменную на Bid только потому, что поленился разбираться где она определяется.
 
evillive:

Верно что надо обрабатывать значение до вставки его в ордер.


Но нормализованное до 5 знака 1.325626 = 1.32563 а не 1.32562

Согласен. Я не вникал особо, а описал ситуацию примерно. Главное что суть понятна была.
 

Документацию читали?

Примечание

Цену открытия и время истечения можно изменять только у отложенных ордеров. Если в качестве параметров функции передать неизмененные значения, то в этом случае будет сгенерирована ошибка 1 (ERR_NO_RESULT).

 
Вообще да. Я не изменяю ни цену открытия, ни время истечения... Так что в моём случает это не имеет ни какого отношения. Причину я описал выше. И решилась ситуация именно так, а не иначе.