修改订单时的错误#1 - 页 2

 
borilunad:
维克多,你,雷纳特,在一般情况下,正确地指出,阿列克谢显示了必要的最后检查,和更早,做所有必要的检查,为每个参数与所有的细微差别,以避免歧义的意思,并没有错过任何条件!。
这有什么好处呢?因为我在每个函数中重新设置_LastError 的值。它不像是一直挂在记忆中的...
 
hoz:
这有什么用呢?因为我在每个函数中都重置了_LastError。它不像是一直挂在记忆中的...
对不起,你是你的职能部门和支票的受害者!你是我的朋友。将信息输出到图表中,以获取利益,并在交易功能 后才打印错误检查!
 
evillive:
仍然需要检查,如果3个参数都没有改变,那么OrderModify也不需要被触动。

我听你的。这并没有什么帮助。下面是我修改方法中的一段代码。

   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);
      }
   }
我们可以清楚地看到,错误值被重置了。

然后它得到了市场信息。如果修改是在测试器中...那么......然后我运行Alexei 建议的测试,...如果修改不成功...我们记录日志和打印...

一般来说,我们可以看到,在ResetLastError() 之间没有错误...那里没有什么不对。

日志。

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:

我听你的。这并没有什么帮助。下面是我修改方法中的一段代码。

你可以清楚地看到,那里的错误值被重置了。

然后它得到了市场信息。如果修改是在测试器中...那么...我做了阿列克谢 建议的测试,并且......如果修改不成功,那么......。写日志并在日志中打印...

一般来说,我们可以看到,在ResetLastError()之间没有错误...那里没有什么不对。

日志。

你需要记录改变前的OOP、SL和TP值,看看它们是否与新的相同,那么错误#1的原因也会更清楚。
 

事情就是这样...

在专家顾问中,我像这样调用类方法

 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());
            }
         }
      }

这里是我们感兴趣的那块类。

// 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);
      }
   }

这里是我们想要的日志片。

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
 

让我解释一下。修改是在方法fOrderModify()中进行的。在这个方法fOrderModify()的输入端,订单参数的当前值和新的计划值被打印在正文的开头。你可以看到它。

   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);

这块是在日志中。

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
你可以看到,这些参数都是不同的。应该没有什么问题。
 
hoz:

事情就是这样...

在专家顾问中,我像这样调用类方法。

这里是我们感兴趣的那块类。

这里是我们想要的日志片。

我不明白,如果订单是待定的,与竞价有什么关系?

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());
            }
         }
      }


Bid总是低于SellLimit,所以if(New_OOP < Bid)一行永远不会为真。......分别,修改的实施没有阻碍。

 
hoz:

你为什么不也创建一个错误数组呢?文档中白纸黑字写着:_LastError变量存储的是最后一个错误的编号。并通过ResetLastError()函数将其重置。如果在调用_LastError之间没有更多的错误,_LastError存储最后一个错误的值。我的代码中不再有任何错误。嗯,这不是问题。

你是绝对错误的。最后一个错误在许多重要的功能中得到了很好的重置。在WinAPI中也是如此。

这就是为什么你应该在错误发生后立即将错误代码保存到一个本地变量 中,而不是在你的很多中间函数中清除这个系统变量十次后再尝试使用它。

 

对不起,SellLimit需要dist。

不是如果 (New_OOP < Bid) 继续;而是如果 (New_OOP-dist*Point < Bid) 继续

 
hoz:

我怎样才能摆脱这个该死的错误?我已经厌烦了。我正在检查函数的每个输入参数。对我来说,目前,它是这样的。

也就是说,如果参数没有被改变,就没有必要去改变它。我以前没有这样做过,但我决定...

然后参数被传递给订单修改方法,像这样。

日志中没有输出。

因此,期刊通知我们,如修改:好的,但随后...一个错误。所有的参数都没有改变。

该命令正在等待中。因此,我们可能会改变开盘价、停盘价和收盘价。而这一点,据我所知,并没有与文件相矛盾。

谁遇到过这样的事情?如何解决这个问题?

而且,如果没有一个参数被修改,你就不要试图修改挂单。