Error nº 1 al modificar los pedidos - página 4

 
hoz:

Boris, supongamos que es así... Asumiendo. Pero, si la función reenvía una orden para modificarla, el significante debe ser modificado. Y conmigo no se modifica en absoluto. Incluso si miramos el registro en la bitácora, lo que vemos es esto:

¿Por qué se envía el pedido? Si no tuviera los parámetros correctos, la función habría explotado... Es como OK... ...fue enviado. Luego resultó que había un error... ¿Cuál es la lógica detrás de esto?

¡Acaba de encenderse! Victor, si "ok", significa que algún parámetro ha cambiado, pero el error 1 significa que algún parámetro fue declarado para cambiar, pero resultó ser sin cambios. Por eso hay que corregir su lógica para evitar estos casos, ¡y todas estas imprecisiones darán lugar a recotizaciones y a un montón de errores en el mercado real!

Ya sabes que yo no uso este estilo de programación, que todo está disperso. Escribo el programa como un guión lógico, todos los eventos se desarrollan secuencialmente, y todo está siempre a mano con todas las condiciones sin tener que rebuscar. Y utilizo funciones externas para realizar la acción final y comprobar los errores.

Pero en tu caso, no está claro para los no iniciados qué tienes y dónde está marcado, todo está oculto, ¡y tienes que adivinar si has marcado el requisito previo o no! Son muchas palabras, como las mías ahora, pero su programa no consigue que se entienda. Debe ser claro y conciso.

 

Boris, me doy cuenta, por supuesto, de que no tengo todo en el mismo sitio. Pero los parámetros de entrada justo antes de la función de modificación están acoplados. Acabo de lanzar una captura de pantalla de la misma. Hay PLO actuales y nuevos, SL y TP. Y todos son diferentes. ¿Por qué debería entrar en detalles si todo está cerca? Si no está impreso, y puedes ver que los parámetros son diferentes, significa que efectivamente son diferentes. ¿O tal vez tampoco deberías confiar en la impresión?

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

Y antes de eso, como he mostrado arriba, hay una prueba:

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

¿Cómo puede ser más específico? Hay un par de payasos encima que han empezado a inventarse historias. Al parecer, no pudieron o no quisieron entender lo que les pedía. Así que se ríen sin razón. Pero la cuestión es interesante.

Si insertamos, por ejemplo, un parámetro de otro tipo o una cantidad errónea en OrderModify(), los errores se producen de inmediato. Y aquí se ejecuta, dice como OK, pero luego resulta que ningún parámetro fue cambiado.

La pregunta es: ¿cómo sabemos qué es lo que está mal allí? He expuesto mi función. Todo debería estar claro ahí. Aquí está:

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

He comentado a propósito todas las líneas. Puedes estropear el código. Si tiene algún comentario, por favor ayude.

 
hoz:

Boris, me doy cuenta, por supuesto, de que no tengo todo en el mismo sitio. Pero los parámetros de entrada justo antes de la función de modificación están acoplados. Acabo de lanzar una captura de pantalla de la misma. Hay PLO actuales y nuevos, SL y TP. Y todos son diferentes. ¿Por qué debería entrar en detalles si todo está cerca? Si no está impreso, y puedes ver que los parámetros son diferentes, significa que efectivamente son diferentes. ¿O tal vez tampoco deberías confiar en la impresión?

Y antes de eso, como he mostrado arriba, hay una prueba:


Todo

Lo siento, no soy capaz de entender esto ya que no veo ninguna condición en el bucle que asegure que los parámetros de la orden no se confundan entre sí.

La presencia de un error le indica que está cometiendo un error lógico en alguna parte. Pero también dice que el programa funciona, ¡pero nos interesa la calidad del programa!

 
borilunad:

Lo siento, no soy capaz de entender esto ya que no veo ninguna condición en el bucle que garantice que los parámetros de la orden no se confundan entre sí.

La presencia de un error le indica que está cometiendo un error lógico en alguna parte. Pero también dice que el programa funciona, ¡pero nos interesa la calidad del programa!


Todas las operaciones con órdenes tienen lugar en un bucle. Aquí es donde se llama al método fOrderModify(), cuyo código he citado anteriormente:

//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                                                   Перенос лимитных ордеров по сигналу                                                 |
//+---------------------------------------------------------------------------------------------------------------------------------------+
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");
}

Puedes ver todo allí... También puedes ver que después de cada iteración del bucle se borra el error. Así, se garantiza que un error en el orden anterior, si lo hubiera, no saltará al siguiente (me refiero a su valor, claro).

¿Cuánto más fácil puede ser? Es tan simple...

 

He encontrado un mensaje.

Es el mismo error de la terminal. Nunca había tenido un bicho así. Nunca he intentado cambiar los 3 parámetros (OOP, SL y TP) de las órdenes pendientes. Pero he tenido que hacerlo. Y me he topado con un error.

Veo que, por ejemplo, el precio de apertura y el Stop Loss no han cambiado y en su lugar obtenemos los mismos valores, pero los Take Points han cambiado. ¿También provoca el error? Luego resulta que la documentación está torcida. ¿Y este punto no se sostiene o qué?

 
hoz:

Encontré un mensaje.

Es el mismo error de la terminal. Nunca había tenido este tipo de cosas. Nunca he intentado cambiar los 3 parámetros (OOP, SL y TP) de las órdenes pendientes. Pero he tenido que hacerlo. Y me he topado con un error.

Veo que, por ejemplo, el precio de apertura y el Stop Loss no han cambiado y en su lugar obtenemos los mismos valores, pero los Take Points han cambiado. ¿También provoca el error? Luego resulta que la documentación está torcida. ¿Y este punto no se sostiene o qué?

¿Compruebas también la distancia en cada tic? Hace tiempo que adopté la regla de abrir las órdenes en la apertura de la barra de TF y de modificarlas y cerrarlas sólo en la apertura de la barra de M1. El código anterior me recuerda a un informe de progreso, que parece contener todo, ¡pero nada concreto! ¡No veo un bucle, en el que se definen todas las acciones por condiciones específicas! Sólo veo un bucle que me dice que no hay que modificar nada, entonces no modifiques y no habrá errores.

Tenga en cuenta el importante punto de Renat de que sus errores pueden provenir de la confusión sobre lo que hay que hacer globalmente y lo que hay que hacer localmente, y los errores son siempre los segundos, ¡los anteriores se restablecen sin que usted intervenga con la salida de la función!

 
borilunad:

¡¿También compruebas la distancia en cada tictac?!

¡No! Sólo permito modificaciones si se cumple una condición. En este caso, la condición para la modificación es cambiar los niveles calculados. Así de fácil:

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? Sólo....

Borilunad:


Hace tiempo que establecí la regla de abrir órdenes en la apertura de una barra en TF, y de modificar y cerrar sólo en la apertura de una barra en M1. El código anterior me recuerda a un informe de progreso, que parece contener todo, ¡pero nada en concreto! ¡No veo un bucle, en el que se definen todas las acciones por condiciones específicas! Sólo veo un bucle que me dice que no hay que modificar nada, entonces no modifiques y no habrá errores.

Yo también tenía pensamientos similares, para modificar sólo en la apertura de M1, y, esto es aplicable si la modificación se hace por un valor predefinido. Pero hay situaciones en las que no necesito comprobar estos datos en M1. Por ejemplo, tengo un stop tirado a un nivel ya calculado. Entonces, como he mostrado arriba, tengo una comprobación en la función OnInit():

if (FirstInd != ND (MurreyLevelsValue[1]))
{
   MovingLimitPositions (MurreyLevelsValue);
   FirstInd = ND (MurreyLevelsValue[1]);
}
Es decir, si el nivel ha cambiado... modifica. Así se evitan intentos de modificación innecesarios. Por así decirlo, modificación por señal y no por temporizador. ¿Entendido aquí?


borilunad:


¡No veo un bucle donde se definan todas las acciones por condiciones específicas! Sólo veo un bucle que me dice que no hay que modificar, luego simplemente no se modifica y no hay errores.

Lo tengo todo desnudo ahí fuera. Qué es lo que no hay que entender... :(

borilunad:

Tenga en cuenta el importante punto de Renat de que sus errores pueden provenir de la confusión sobre lo que hay que hacer globalmente y lo que hay que hacer localmente, y los errores son siempre los segundos, ¡los anteriores se restablecen sin que usted intervenga con la salida de la función!

Este problema, como he descubierto, no sólo me ocurre a mí. He aquí un ejemplo...

Y parece que no se solucionó ni se va a solucionar. ¿Quizás los desarrolladores son perezosos? Si no estoy trabajando correctamente con errores, alguien, incluyendo Renat podría haber hurgado en el código, y no sólo decir que lo tengo mal.

Después de todo, si los valores nuevos y actuales de los parámetros a modificar se imprimen antes de la función de modificación, está claro que estos valores están ahí. ¿Por qué ir más arriba en algún lugar? Hay valores, está claro que no hay errores (imprimí allí para los errores). Significa que todo está bien en la lógica. Así que el fallo en la función de modificación.

 
hoz:

¡No! Sólo permito modificaciones si se cumple una condición. En este caso, la condición para la modificación es cambiar los niveles calculados. Así de fácil:

¿Simple? Sólo....

Yo también tenía pensamientos similares, para modificar sólo en la apertura de M1, y, esto es aplicable si la modificación se lleva a cabo por un valor predeterminado. Pero hay situaciones en las que no necesito comprobar estos datos en M1. Por ejemplo, tengo un stop tirado a un nivel ya calculado. Entonces, como he mostrado arriba, hay una comprobación en la función OnInit():

Es decir, si el nivel ha cambiado... modifica. Así se evitan intentos de modificación innecesarios. Por así decirlo, modificación por señal y no por temporizador. ¿Entendido aquí?


He descolgado todo allí. Qué es lo que no hay que entender... :(

Este problema, como he descubierto, no sólo me ocurre a mí. He aquí un ejemplo...

Y parece que no se ha resuelto ni se va a resolver. ¿Quizás los desarrolladores son perezosos? Si no estoy trabajando correctamente con errores, alguien, incluyendo Renat podría hurgar en el código, y no sólo decir que lo tengo mal.

Después de todo, si los valores nuevos y actuales de los parámetros a modificar se imprimen antes de la función de modificación, está claro que estos valores están ahí. ¿Por qué ir más arriba en algún sitio? Hay valores, está claro que no hay errores (imprimí allí para los errores). Significa que todo está bien en la lógica. Así que el fallo está en la función de modificación.

Ya he visto este ejemplo. Pero tenemos que aplicarnos a cualquier condición, hasta que no haya nada mejor. Su código no me convence. Voy a almorzar ahora, luego te daré un ejemplo de un bucle que funciona bien para la configuración de SL, la traducción a B/S y el rastreo de una sola llamada a la función de modificación, donde los errores se manejan, si de repente se producen en el trabajo, no se producen en el probador.

¿Quiere la función Modify()?

 
hoz:

Al fin y al cabo, si los valores nuevos y actuales de los parámetros a modificar se imprimen antes de la función de modificación, está claro que esos valores están ahí. ¿Por qué ir más arriba en algún lugar? Hay valores, está claro que no hay errores (imprimí allí para los errores). Significa que todo está bien en la lógica. Así que el fallo en la función de modificación.

El código parece estar bien... y en el real (no en la demo) funciona ?
 

Víctor, ¿por qué has modificado el SL y el TP en las posiciones pendientes? En general, tiene sentido fijar el SL sólo después de abrir una posición, y el TP después de la transferencia del SL al B/S. Entonces, ¿por qué molestar tanto al servidor para nada y por qué hay que pasar por todas estas molestias?

Hay que minimizar y simplificar el código, para que funcione de forma rápida y clara, ¡y luego será más fácil retocarlo por los caprichos del mercado! Piense cuidadosamente en todos los matices relacionados con las realidades del mercado.