Errore #1 quando si modificano gli ordini - pagina 2

 
borilunad:
Victor, tu, Renat, in generale giustamente sottolineato, Alexey ha mostrato l'ultimo controllo necessario, e prima controllare tutti i controlli necessari per ogni parametro con tutte le sfumature per evitare ambiguità di significato e senza perdere alcuna condizione!
A cosa servirebbe? Perché sto resettando il valore _LastError in ogni funzione. Non è che sia costantemente appeso nella memoria...
 
hoz:
A cosa serve? Perché ho resettato _LastError in ogni funzione. Non è che sia costantemente appeso nella memoria...
Mi dispiace, sei vittima delle tue funzioni e dei tuoi controlli! Emettere le informazioni sul grafico per interesse, e stampare i controlli degli errori solo dopo le funzioni di trading!
 
evillive:
ancora bisogno di controllare che se nessuno dei 3 parametri è cambiato, allora anche OrderModify non ha bisogno di essere toccato.

Ho capito. Non ha aiutato. Ecco un pezzo di codice del mio metodo di modifica:

   ResetLastError();
   
//---- Определяем цвет значков модификации ордеров
   if (fc_Arrow == CLR_NONE)
       fc_Arrow = ColorByModify [OrderType() % 2];
   
//---- Выполняем модификацию в тестере
   if (!CBase.GetRealTrade())         \\ Если работаем в тестере...
   {
      if ((OrderOpenPrice() != fd_OpenPrice) || (OrderStopLoss() != fd_NewSL) || (OrderTakeProfit() != fd_NewTP))
      
      if (!OrderModify (fi_Ticket, fd_OpenPrice, fd_NewSL, fd_NewTP, fdt_Expiration, fc_Arrow))
      {
         CLogs.WriteLog (StringConcatenate ("fOrderModify(): ", CErrs.ErrorToString (_LastError)));
         Print (__FUNCTION__, ": ", "После модификации тикета № ", fi_Ticket);
         Print (__FUNCTION__, ": ", "Тикет № ", fi_Ticket, "; OOP = ", fd_OpenPrice, "; SL = ", fd_NewSL, "; TP = ", fd_NewTP);
         return (false);
      }
   }
Possiamo vedere chiaramente che il valore di errore viene azzerato.

Poi riceve le informazioni sul mercato. Se la modifica è nel tester... allora... Faccio il test proposto da Alexei, e... se la modifica non ha successo, allora... scrive un registro e stampa nel registro...

In generale, possiamo vedere che non ci sono errori tra ResetLastError()... Non c'è niente di sbagliato lì.

Diario:

0       20:24:08        2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: Вошли в функцию 
0       20:24:08        2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: До проверки на FREEZELEVEL и STOPLEVEL  тикета № 2
0       20:24:08        2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: Тикет № 2; OOP = 1.34048; SL = 1.34125; TP = 1.33362
0       20:24:08        2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::CheckLevelsBLOCK: Вошли в функцию
0       20:24:08        2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::CheckLevelsBLOCK: Тикет № 2; fd_NewOpenPrice = 1.34048; fd_NewSL = 1.34125; fd_NewTP = 1.33362
0       20:24:08        2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::CheckLevelsBLOCK: fi_Type > 2 = true
0       20:24:08        2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::CheckLevelsBLOCK: Тикет № 2; fd_NewOpenPrice = 1.34048; fd_NewSL = 1.34125; fd_NewTP = 1.33362
0       20:24:08        2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::CheckLevelsBLOCK: Вышли из функции
0       20:24:08        2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: После проверки на FREEZELEVEL и STOPLEVEL  тикета № 2
0       20:24:08        2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: Тикет № 2; OOP = 1.34048; SL = 1.34125; TP = 1.33362
2       20:24:08        2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: modify #2  sell limit 0.10 EURUSD at 1.34048 sl: 1.34125 tp: 1.33362 ok
3       20:24:08        2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: OrderModify error 1
 
hoz:

Ho capito. Non ha aiutato. Ecco un pezzo di codice del mio metodo di modifica:

Potete vedere chiaramente che il valore dell'errore viene resettato lì.

Poi riceve le informazioni sul mercato. Se la modifica è nel tester... allora... Faccio il test proposto da Alexei, e... se la modifica non ha successo, allora... scrive un registro e stampa nel registro...

In generale, possiamo vedere che non ci sono errori tra ResetLastError()... Non c'è niente di sbagliato lì.

Diario:

È necessario registrare i valori precedenti di OOP, SL e TP prima del cambiamento per vedere se sono gli stessi di quelli nuovi, allora anche la causa dell'errore #1 sarà più chiara.
 

È così...

Nell'Expert Advisor, chiamo il metodo della classe in questo modo:

 if (OrderType() == OP_SELLLIMIT)
      {
         if (OrderOpenPrice() != ND (fd_MurreyLevelsValue[11]))
            New_OOP = ND (fd_MurreyLevelsValue[11]);
         else New_OOP = OrderOpenPrice();
         if (OrderStopLoss() != ND (fd_MurreyLevelsValue[12]))
            New_SL = ND (fd_MurreyLevelsValue[12]);
         else New_SL = OrderStopLoss();
         if (OrderTakeProfit() != ND (fd_MurreyLevelsValue[2]))
            New_TP = ND (fd_MurreyLevelsValue[2]);
         else New_TP = OrderTakeProfit();
         
         Print (__FUNCTION__, ": ", "New_OOP = ", New_OOP, "; New_SL = ", New_SL, "; New_TP = ", New_TP);
         Print (__FUNCTION__, ": ", "Тикет № ", OrderTicket(), "; OrderOpenPrice() = ", OrderOpenPrice(),
             "; OrderStopLoss() = ", OrderStopLoss(), "; OrderTakeProfit() = ", OrderTakeProfit());
             
         if (ND (OrderOpenPrice()) != fd_MurreyLevelsValue[11])
         {
            if (New_OOP < Bid) continue;
            
            if (!CPosMan.fOrderModify (Ticket,  New_OOP, New_SL, New_TP))
            {
               if (_LastError != 0)
                  CLogs.WriteLog (StringConcatenate (__FUNCTION__, ". В строке ", __LINE__, " ", CErrs.ErrorToString (_LastError)),
                                  CLogs.GetNeedLogs(), CLogs.GetPrintUP(), CLogs.GetCommentUP());
            }
            else
            {
               Print (__FUNCTION__, ": ", "Модификация тикета №", OrderTicket(), " успешно завершена!");
               Print (__FUNCTION__, ": ", "Тикет № ", OrderTicket(), "; OrderOpenPrice() = ", OrderOpenPrice(),
             "; OrderStopLoss() = ", OrderStopLoss(), "; OrderTakeProfit() = ", OrderTakeProfit());
            }
         }
      }

Ecco il pezzo di classe che ci interessa:

// 1.2 Функция модифицирует выделенный ордер (установка TP и SL). =========================================================================
bool PositionsManipulations::fOrderModify (int       fi_Ticket,             // OrderTicket()
                                           double    fd_OpenPrice,          // OpenPrice
                                           double    fd_NewSL,              // Новый StopLoss (УРОВЕНЬ !!!)
                                           double    fd_NewTP,              // Новый TakeProfit (УРОВЕНЬ !!!)
                                           datetime  fdt_Expiration = 0,    // Время истечения отложенного ордера
                                           color     fc_Arrow = CLR_NONE)   // Цвет стрелок модификации StopLoss и/или TakeProfit на графике
{
   Print (__FUNCTION__, ": ", "Вошли в функцию ");

//---- Проверяем необходимость модификации
   if (fd_NewSL == OrderStopLoss() && fd_NewTP == OrderTakeProfit())
       return (false);
//----
   string ls_fName = "fOrderModify()";
   int    li_Cnt = 0;
   double ld_Price;
   bool   lb_InvalidSTOP = false,
          lb_FixInvalidPrice = false;    // Флаг первоначальной коррекции отложки

//---- Получаем актуальную информацию по символу и текущему ордеру
   CBase.GetMarkerInfo (OrderSymbol(), fi_Ticket);
   
   Print (__FUNCTION__, ": ", "До проверки на FREEZELEVEL и STOPLEVEL  тикета № ", fi_Ticket);
   Print (__FUNCTION__, ": ", "Тикет № ", OrderTicket(), "; OrderOpenPrice() = ", OrderOpenPrice(),
             "; OrderStopLoss() = ", OrderStopLoss(), "; OrderTakeProfit() = ", OrderTakeProfit());
   Print (__FUNCTION__, ": ", "Тикет № ", fi_Ticket, "; OOP = ", fd_OpenPrice, "; SL = ", fd_NewSL, "; TP = ", fd_NewTP);
//---- Проверяем на условия FREEZELEVEL и STOPLEVEL
   if (!CheckLevelsBLOCK (3, SPos.gs_Symbol, SPos.gi_Type, fd_OpenPrice, fd_NewSL, fd_NewTP, lb_FixInvalidPrice))
   {
      if (StringLen (CErrs.ErrInf) > 0)
      {
         CLogs.WriteLog (CErrs.ErrInf);
         return (false);
      }
   }
   Print (__FUNCTION__, ": ", "После проверки на FREEZELEVEL и STOPLEVEL  тикета № ", fi_Ticket);
   Print (__FUNCTION__, ": ", "Тикет № ", fi_Ticket, "; OOP = ", fd_OpenPrice, "; SL = ", fd_NewSL, "; TP = ", fd_NewTP);
   
   ResetLastError();
   
//---- Определяем цвет значков модификации ордеров
   if (fc_Arrow == CLR_NONE)
       fc_Arrow = ColorByModify [OrderType() % 2];
   
//---- Выполняем модификацию в тестере
   if (!CBase.GetRealTrade())
   {
      if ((OrderOpenPrice() != fd_OpenPrice) || (OrderStopLoss() != fd_NewSL) || (OrderTakeProfit() != fd_NewTP))
      
      if (!OrderModify (fi_Ticket, fd_OpenPrice, fd_NewSL, fd_NewTP, fdt_Expiration, fc_Arrow))
      {
         CLogs.WriteLog (StringConcatenate ("fOrderModify(): ", CErrs.ErrorToString (_LastError)));
         Print (__FUNCTION__, ": ", "После модификации тикета № ", fi_Ticket);
         Print (__FUNCTION__, ": ", "Тикет № ", fi_Ticket, "; OOP = ", fd_OpenPrice, "; SL = ", fd_NewSL, "; TP = ", fd_NewTP);
         return (false);
      }
   }

Ecco il pezzo di registro che vogliamo:

0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: MovingLimitPositions: Выбран тикет № 2
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: MovingLimitPositions: Тикет № 2; OrderOpenPrice() = 1.34048; OrderStopLoss() = 1.34125; OrderTakeProfit() = 1.33362
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: MovingLimitPositions: New_OOP = 1.3401; New_SL = 1.34048; New_TP = 1.33667
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: MovingLimitPositions: Тикет № 2; OrderOpenPrice() = 1.34048; OrderStopLoss() = 1.34125; OrderTakeProfit() = 1.33362
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: Вошли в функцию 
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: До проверки на FREEZELEVEL и STOPLEVEL  тикета № 2
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: Тикет № 2; OrderOpenPrice() = 1.34048; OrderStopLoss() = 1.34125; OrderTakeProfit() = 1.33362
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: Тикет № 2; OOP = 1.3401; SL = 1.34048; TP = 1.33667
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::CheckLevelsBLOCK: Вошли в функцию
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::CheckLevelsBLOCK: Тикет № 2; fd_NewOpenPrice = 1.3401; fd_NewSL = 1.34048; fd_NewTP = 1.33667
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::CheckLevelsBLOCK: fi_Type > 2 = true
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::CheckLevelsBLOCK: Ещё Чутка дальше
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::CheckLevelsBLOCK: Тикет № 2; fd_NewOpenPrice = 1.3401; fd_NewSL = 1.34048; fd_NewTP = 1.33667
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::CheckLevelsBLOCK: Вышли из функции
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: После проверки на FREEZELEVEL и STOPLEVEL  тикета № 2
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: Тикет № 2; OOP = 1.3401; SL = 1.34048; TP = 1.33667
2       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: modify #2  sell limit 0.10 EURUSD at 1.34010 sl: 1.34048 tp: 1.33667 ok
3       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: OrderModify error 1
 

Lasciatemi spiegare. La modifica avviene nel metodo fOrderModify(). All'ingresso di questo metodo fOrderModify(), i valori attuali dei parametri dell'ordine e i nuovi valori previsti sono stampati all'inizio del corpo. Si può vedere:

   Print (__FUNCTION__, ": ", "До проверки на FREEZELEVEL и STOPLEVEL  тикета № ", fi_Ticket);
   Print (__FUNCTION__, ": ", "Тикет № ", OrderTicket(), "; OrderOpenPrice() = ", OrderOpenPrice(),
             "; OrderStopLoss() = ", OrderStopLoss(), "; OrderTakeProfit() = ", OrderTakeProfit());
   Print (__FUNCTION__, ": ", "Тикет № ", fi_Ticket, "; OOP = ", fd_OpenPrice, "; SL = ", fd_NewSL, "; TP = ", fd_NewTP);

Questo pezzo è nel registro:

0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: Вошли в функцию 
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: До проверки на FREEZELEVEL и STOPLEVEL  тикета № 2
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: Тикет № 2; OrderOpenPrice() = 1.34048; OrderStopLoss() = 1.34125; OrderTakeProfit() = 1.33362
0       21:11:44        2013.08.26 09:45  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: Тикет № 2; OOP = 1.3401; SL = 1.34048; TP = 1.33667
Potete vedere che i parametri sono tutti diversi. Non dovrebbero esserci problemi.
 
hoz:

È così...

Nell'Expert Advisor, chiamo il metodo della classe in questo modo:

Ecco il pezzo di classe che ci interessa:

Ecco il pezzo di registro che vogliamo:

Non capisco cosa c'entra il Bid, se l'ordine è in sospeso?

if (OrderType() == OP_SELLLIMIT)
      {
         if (OrderOpenPrice() != ND (fd_MurreyLevelsValue[11]))
            New_OOP = ND (fd_MurreyLevelsValue[11]);
         else New_OOP = OrderOpenPrice();
         if (OrderStopLoss() != ND (fd_MurreyLevelsValue[12]))
            New_SL = ND (fd_MurreyLevelsValue[12]);
         else New_SL = OrderStopLoss();
         if (OrderTakeProfit() != ND (fd_MurreyLevelsValue[2]))
            New_TP = ND (fd_MurreyLevelsValue[2]);
         else New_TP = OrderTakeProfit();
         
         Print (__FUNCTION__, ": ", "New_OOP = ", New_OOP, "; New_SL = ", New_SL, "; New_TP = ", New_TP);
         Print (__FUNCTION__, ": ", "Тикет № ", OrderTicket(), "; OrderOpenPrice() = ", OrderOpenPrice(),
             "; OrderStopLoss() = ", OrderStopLoss(), "; OrderTakeProfit() = ", OrderTakeProfit());
             
         if (ND (OrderOpenPrice()) != fd_MurreyLevelsValue[11])
         {
            if (New_OOP < Bid) continue;
            
            if (!CPosMan.fOrderModify (Ticket,  New_OOP, New_SL, New_TP))
            {
               if (_LastError != 0)
                  CLogs.WriteLog (StringConcatenate (__FUNCTION__, ". В строке ", __LINE__, " ", CErrs.ErrorToString (_LastError)),
                                  CLogs.GetNeedLogs(), CLogs.GetPrintUP(), CLogs.GetCommentUP());
            }
            else
            {
               Print (__FUNCTION__, ": ", "Модификация тикета №", OrderTicket(), " успешно завершена!");
               Print (__FUNCTION__, ": ", "Тикет № ", OrderTicket(), "; OrderOpenPrice() = ", OrderOpenPrice(),
             "; OrderStopLoss() = ", OrderStopLoss(), "; OrderTakeProfit() = ", OrderTakeProfit());
            }
         }
      }


Il Bid è sempre inferiore al SellLimit, quindi la linea if(New_OOP < Bid) non sarà mai vera... ...rispettivamente, la modifica viene implementata senza impedimenti.

 
hoz:

Perché non create anche un array di errori? È scritto nero su bianco nella documentazione che la variabile _LastError memorizza il numero dell'ultimo errore. E viene resettato dalla funzione ResetLastError(). Se non ci sono più errori tra le chiamate di _LastError, _LastError memorizza il valore dell'ultimo errore. Non c'erano più errori nel mio codice. Beh, non è questa la domanda.

Si sbaglia di grosso. L'ultimo errore è ben resettato in molte funzioni importanti. Funziona così anche in WinAPI.

Questo è il motivo per cui dovreste salvare il codice di errore in una variabile locale subito dopo che si è verificato e non cercare di usarlo dopo aver cancellato questa variabile di sistema dieci volte in molte delle vostre funzioni intermedie.

 

Spiacente, SellLimit richiede un dist:

non se (New_OOP < Bid) continua; mase (New_OOP-dist*Point < Bid) continua;

 
hoz:

Come faccio a sbarazzarmi di questo cazzo di errore? Non ne posso più. Sto controllando ogni parametro di ingresso della funzione. Per me, al momento, è così:

Cioè, se il parametro non è stato cambiato, non c'è bisogno di cambiarlo. Non l'ho mai fatto prima, ma ho deciso di...

Poi i parametri vengono passati al metodo di modifica dell'ordine in questo modo:

Nw output nel log:

Allora, il giornale ci avvisa, come modifica: OK, ma poi... un errore. Nessuno dei parametri è cambiato.

L'ordine è in sospeso. Quindi possiamo cambiare open, stop e take price. E questo, a quanto ho capito, non contraddiceva la documentazione.

Chi ha incontrato qualcosa del genere? Come risolverlo?

E non si cerca di modificare gli ordini pendenti se nessuno dei parametri è stato modificato.
Motivazione: