Error #1 when modifying orders - page 4

 
hoz:

Boris, let's assume that's the case... Assuming. But, if the function re-sends an order to modify the order, the significantton should be modified. And with me it doesn't modify at all. Even if we look at the log in the log, what we see is this:

Why is the order being sent? If it didn't have the right parameters, the function would've blown up... It's like OK... ...it was sent. Then it turned out that there was an error... What is the logic behind it?

Just turned on! Victor, if "ok", it means that some parameter has changed, but error 1 means that some parameter was declared to change, but turned out to be unchanged. That's why we need to correct your logic to avoid such cases, and all these inaccuracies will result in requotes and a lot of errors on the real market!

You know that I don't use that kind of programming style, where everything is scattered all over the place. I write the program as a logical script, all events develop sequentially, and everything is always close at hand with all the conditions without having to scour around looking for something. And I use external functions to perform final action and check for errors.

But in your case, it's unclear to the uninitiated what you have and where it's checked, everything is hidden, and you have to guess if you checked the prerequisite or not! That's a lot of words, like mine now, but your program doesn't get the point across. It should be clear and concise!

 

Boris, I realise of course that I don't have everything in one place. But the input parameters right before the modification function are docked. I've just thrown a screenshot of it. There are current and new PLOs, SL and TP. And they are all different. Why should I get into details when everything is nearby? If it's unprinted, and you can see that the parameters are different, it means they are indeed different. Or maybe you shouldn't trust the print either?

2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: Тикет № 2; New_OOP = 1.34048; New_SL = 1.34125; New_TP = 1.33362
2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify:  Тикет № 2; OrderOpenPrice() = 1.34048; OrderStopLoss() = 0.0; OrderTakeProfit() = 0.0
2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: Тикет № 2; New_OOP = 1.34048; New_SL = 1.34125; New_TP = 1.33362
2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: PositionsManipulations::fOrderModify: _LastError = 0
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
2013.08.26 00:00  Kevin Martens_Moi_Myrei EURUSD,M15: OrderModify error 1

And before that, as I've shown above, there is a test:

 if ((ND (OrderOpenPrice()) != fd_OpenPrice) || ND ((OrderStopLoss()) != fd_NewSL) || (ND (OrderTakeProfit()) != fd_NewTP))
{
 ... Если какой-то из параметров отличается от нового, значит выполняется это условие...
}

How can you be more specific? There are a couple of clowns on top started making up stories. Apparently they couldn't or wouldn't understand what I was asking. So they're laughing for no reason. But the question is an interesting one.

If we insert for example a parameter of another type or a wrong quantity into OrderModify(), it will cause an error. And here it is executed, says like OK, but then it turns out that no parameter was changed.

The question is how do we know what is wrong there? I have laid out my function. Everything should be clear there. Here it is:

// 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, "; New_OOP = ", fd_OpenPrice, "; New_SL = ", fd_NewSL, "; New_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, "; New_OOP = ", fd_OpenPrice, "; New_SL = ", fd_NewSL, "; New_TP = ", fd_NewTP);
   
   ResetLastError();
   
//---- Определяем цвет значков модификации ордеров
   if (fc_Arrow == CLR_NONE)
       fc_Arrow = ColorByModify [OrderType() % 2];
   
//---- Выполняем модификацию в тестере
   if (!CBase.GetRealTrade())
   {
      if ((ND (OrderOpenPrice()) != fd_OpenPrice) || ND ((OrderStopLoss()) != fd_NewSL) || (ND (OrderTakeProfit()) != fd_NewTP))
      {
      ResetLastError();
      
      Print (__FUNCTION__, ": ", " Тикет № ", OrderTicket(), "; OrderOpenPrice() = ", OrderOpenPrice(),
             "; OrderStopLoss() = ", OrderStopLoss(), "; OrderTakeProfit() = ", OrderTakeProfit());
      Print (__FUNCTION__, ": ", "Тикет № ", fi_Ticket, "; New_OOP = ", fd_OpenPrice, "; New_SL = ", fd_NewSL, "; New_TP = ", fd_NewTP);
      Print (__FUNCTION__, ": ", "_LastError = ", _LastError);
      
      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, "; New_OOP = ", fd_OpenPrice, "; New_SL = ", fd_NewSL, "; New_TP = ", fd_NewTP);
         return (false);
      }
      }
   }
   

I purposely commented out all the lines. You may just spoil the code. If you have any comments, please help.

 
hoz:

Boris, I realise of course that I don't have everything in one place. But the input parameters right before the modification function are docked. I've just thrown a screenshot of it. There are current and new PLOs, SL and TP. And they are all different. Why should I get into details when everything is nearby? If it's unprinted, and you can see that the parameters are different, it means they are indeed different. Or maybe you shouldn't trust the print either?

And before that, as I've shown above, there's a test:


Everything

Sorry, I'm not able to make sense of this as I don't see any conditions in the loop that ensures that the order parameters are not confused with each other!

The presence of an error tells you that you are making a logical error somewhere. But it also says that the program works, but we are interested in the quality of the program!

 
borilunad:

Sorry, I'm not able to make sense of this as I don't see any conditions in the loop that ensures that order parameters are not confused with each other!

The presence of an error tells you that you are making a logical error somewhere. But it also says that the program works, but we are interested in the quality of the program!


All operations with orders take place in a loop! This is where that method fOrderModify() is called, the code of which I cited above:

//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                                                   Перенос лимитных ордеров по сигналу                                                 |
//+---------------------------------------------------------------------------------------------------------------------------------------+
void MovingLimitPositions (const double& fd_MurreyLevelsValue[])
{
   double New_OOP = 0.0,
          New_SL = 0.0,
          New_TP = 0.0;
   int    Ticket = -1;
   
   for (int i=0; i<13; i++)
   {
      Print (__FUNCTION__, ": ", "fd_MurreyLevelsValue["+IToS (i)+"] = ", DToS (fd_MurreyLevelsValue[i]));
   }

   for (int i=OrdersTotal()-1; i>=0; i--)
   {
      New_OOP = 0.0;
      New_SL = 0.0;
      New_TP = 0.0;
      
      ResetLastError();
      
      if (!CPosMan.CheckMyOrdersBased(i, 7)) continue;
      if (!OrderSelect (i, SELECT_BY_POS, MODE_TRADES)) continue;

      Ticket = OrderTicket();

      Print (__FUNCTION__, ": ", "Выбран тикет № ", OrderTicket());
      Print (__FUNCTION__, ": ", "Тикет № ", OrderTicket(), "; OrderOpenPrice() = ", OrderOpenPrice(),
             "; OrderStopLoss() = ", OrderStopLoss(), "; OrderTakeProfit() = ", OrderTakeProfit());
          
      if (OrderType() == OP_BUYLIMIT)
      {
         if (ND (OrderOpenPrice()) != ND (fd_MurreyLevelsValue[1]))
            New_OOP = ND (fd_MurreyLevelsValue[1]);
         else New_OOP = ND (OrderOpenPrice());
         if (ND (OrderStopLoss()) != ND (fd_MurreyLevelsValue[0]))
            New_SL = ND (fd_MurreyLevelsValue[0]);
         else New_SL = ND (OrderStopLoss());
         if (ND (OrderTakeProfit()) != ND (fd_MurreyLevelsValue[10]))
            New_TP = ND (fd_MurreyLevelsValue[10]);
         else New_TP = ND (OrderTakeProfit());
         
         Print (__FUNCTION__, ": ", "New_OOP = ", New_OOP, "; New_SL = ", New_SL, "; New_TP = ", New_TP);
         
         if (ND (OrderOpenPrice()) != fd_MurreyLevelsValue[1])
         {
            if (!CPosMan.fOrderModify (OrderTicket(), 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(), " успешно завершена!");}
         }
      }
      
      if (OrderType() == OP_SELLLIMIT)
      {
         if (ND (OrderOpenPrice()) != ND (fd_MurreyLevelsValue[11]))
            New_OOP = ND (fd_MurreyLevelsValue[11]);
         else New_OOP = ND (OrderOpenPrice());
         if (ND (OrderStopLoss()) != ND (fd_MurreyLevelsValue[12]))
            New_SL = ND (fd_MurreyLevelsValue[12]);
         else New_SL = ND (OrderStopLoss());
         if (ND (OrderTakeProfit()) != ND (fd_MurreyLevelsValue[2]))
            New_TP = ND (fd_MurreyLevelsValue[2]);
         else New_TP = ND (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 (!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());
            }
         }
      }
   }
   Print (__FUNCTION__, ": ", "OUT OF FUNCTION");
}

You can see everything there... You can also see that after each iteration of the loop the error is cleared. Thus, the fact is guaranteed that an error in previous order, if there was one, will not jump to the next one (I mean its value, of course).

How much easier can it be? It's so simple...

 

I found a message.

It's the same terminal bug. I've never had such a bug before. I never tried to change 3 parameters (OOP, SL and TP) of pending orders before. But I have had to. And I have stumbled upon a bug.

I see, if, for example, the open price and Stop Loss have not changed and instead of them we get the same values, but the Take Points have changed. Does it also cause the error? Then it turns out that the documentation is crooked. And this point is not supported or what?

 
hoz:

I found a message.

It's the same terminal bug. I've never had this kind of thing before. I never tried to change 3 parameters (OOP, SL and TP) of pending orders before. But I have had to. And I have stumbled upon a bug.

I see, if, for example, the open price and Stop Loss have not changed and instead of them we get the same values, but the Take Points have changed. Does it also cause the error? Then it turns out that the documentation is crooked. And this point is not supported or what?

Do you check the distance on every tick as well? I have long ago adopted the rule to open orders at the opening of the TF bar and to modify and close them only at opening of the bar on M1! The code above reminds me of a progress report, which seems to contain everything, but nothing concrete! I do not see a loop, in which you define all actions by specific conditions! I only see a loop that tells me nothing to modify, then just don't modify, and there will be no errors.

Note Renat's important point that your errors can come from confusion about what to do globally and what to do locally, and errors are always the latter, the earlier ones are reset without your involvement with function exit!

 
borilunad:

Do you check the distance at every tick too?!

No! I only allow modifications if a condition is met. In this case, the condition for modification is to change the calculated levels. Just like that:

void OnTick()
{
   static double FirstInd = 0.0;                    // Переменная, которая хранит значение 1-ого индекса массива
   double MurreyLevelsValue[13];                    // Массив значений уровней
   GetDataFromIndicator (MurreyLevelsValue);        // Функция, которая получает значения из индикатора уровней
   
   if (gdt_LastBarTime <= Time[0])
   {
      OTotal = CPosInf.FindPositions (AmountPosByType);   // Получаем количество позиций( по типам ).
      
      GetTradeSignal (MurreyLevelsValue);
      
      gdt_LastBarTime = Time[0];
   }

   if (FirstInd != ND (MurreyLevelsValue[1]))      // Если значений текущего состояния переменной FirstInd не равно новому рассчитанном, то.. 

   {
      MovingLimitPositions (MurreyLevelsValue);     // ..модифицируем ордер новым значением
      FirstInd = ND (MurreyLevelsValue[1]);
   }
}

Simple? Just....

Borilunad:


I made a rule long ago to open orders at opening of a bar in TF, and to modify and close only at opening of a bar on M1! The above code reminds me of a progress report, which seems to contain everything, but nothing specific! I do not see a loop, in which you define all actions by specific conditions! I only see a loop that tells me nothing to modify, then just don't modify and there will be no errors.

I had similar thoughts too, to modify only at the opening of M1, and, this is applicable if the modification is done by a predefined value. But there are situations when I don't need to check this data on M1. For example, I have a stop pulled at a level that has already been calculated. Then, as I have shown above, I have a check in the OnInit() function:

if (FirstInd != ND (MurreyLevelsValue[1]))
{
   MovingLimitPositions (MurreyLevelsValue);
   FirstInd = ND (MurreyLevelsValue[1]);
}
I.e. if the level has changed, it... modifies. This avoids unnecessary modification attempts. So to speak, modification by signal and not by timer. Understood here?


borilunad:


I don't see a loop where you define all the actions by specific conditions! I only see a loop that tells me nothing to modify, then just don't modify and there are no errors.

I've got it all undressed out there. What's not to understand... :(

borilunad:

Note Renat's important point that your errors can come from confusion about what to do globally and what to do locally, and errors are always the latter, the earlier ones are reset without your involvement with function exit!

This problem, as I found out, occurs not only with me. Here's an example...

And it seems that it was not solved and is not going to be. Maybe developers are lazy? If I'm not working correctly with errors, someone, including Renat could have poked into the code, and not just say that I have it wrong.

After all, if new and current values of parameters to be modified are printed before modification function, it's clear that these values are there. Why go higher up somewhere? There are values, you can see there are no errors (I printed there for errors). It means that all is well in logic. So the fault in the modification function.

 
hoz:

No! I only allow modifications if a condition is met. In this case, the condition for modification is to change the calculated levels. Just like that:

Simple? Just....

I had similar thoughts too, to modify only at the opening of M1, and, this is applicable if the modification is carried out by a predetermined value. But there are situations where I don't need to check this data at M1. For example, I have a stop pulled at a level that has already been calculated. Then, as I have shown above, there is a check in the OnInit() function:

I.e. if the level has changed, it... modifies. This avoids unnecessary modification attempts. So to speak, modification by signal and not by timer. Understood here?


I've unrung everything there. What's not to understand... :(

This problem, as I found out, occurs not only with me. Here's an example...

And it seems that it has not been solved and is not going to be. Maybe developers are lazy? If I'm not working correctly with errors, someone, including Renat could poke into code, and not just say that I have it wrong.

After all, if new and current values of parameters to be modified are printed before modification function, it's clear that these values are there. Why go higher up somewhere? There are values, it's clear that there are no errors (I printed there for errors). It means that all is well in logic. So the fault is in the modification function.

I already looked at this example. But we have to apply to any conditions, until there is nothing better. Your code doesn't convince me. I'm going to have lunch now, then I'll give you an example of a loop that works fine for setting SL, translation to B/S and trawling for just one call to modify function, where errors are handled, if they suddenly occur in work, they don't occur in the tester.

Do you want the Modify() function?

 
hoz:

After all, if the new and current values of the parameters to be modified are printed before the modification function, it is clear that these values are there. Why go higher up somewhere? There are values, it's clear that there are no errors (I printed there for errors). It means that all is well in logic. So the fault is in the modification function.

The code seems fine... and on the real (not demo) it works ?
 

Victor, why did you start modifying SL and TP in the pending positions? In general, it makes sense to set the SL only after opening a position, and the TP after the transfer of the SL to the B/S! So why bother the server so much for nothing and why do you have to go through all this trouble?!

We must minimize and simplify the code, to make it work fast and clear, and then it will be easier to tweak it because of the vagaries of the market! Think carefully about all the nuances related to market realities!