Erro nº 1 na modificação de ordens - página 4

 
hoz:

Boris, vamos supor que é esse o caso... Assumindo. Mas, se a função reenviar uma ordem para modificar a ordem, o significado deve ser modificado. E comigo não modifica em nada. Mesmo que olhemos para o tronco no toro, o que vemos é isto:

Por que a ordem está sendo enviada? Se não tivesse os parâmetros certos, a função teria explodido. É como se estivesse tudo bem... ...foi enviado. Aconteceu então que houve um erro... Qual é a lógica por trás disso?

Acabou de ser ligado! Victor, se "ok", significa que algum parâmetro mudou, mas o erro 1 significa que algum parâmetro foi declarado para mudar, mas acabou por ficar inalterado. É por isso que precisamos corrigir sua lógica para evitar tais casos, e todas essas imprecisões resultarão em solicitações e uma série de erros no mercado real!

Você sabe que eu não uso esse tipo de estilo de programação, onde tudo está espalhado por todo o lugar. Eu escrevo o programa como um roteiro lógico, todos os eventos se desenvolvem sequencialmente, e tudo está sempre à mão com todas as condições sem ter que vasculhar à procura de algo. E utilizo funções externas para realizar a ação final e verificar a existência de erros.

Mas no seu caso, não está claro para os não iniciados o que você tem e onde é verificado, tudo está escondido, e você tem que adivinhar se você verificou o pré-requisito ou não! Isso são muitas palavras, como a minha agora, mas seu programa não consegue passar o ponto de vista. Deve ser claro e conciso!

 

Boris, é claro que percebo que não tenho tudo em um só lugar. Mas os parâmetros de entrada logo antes da função de modificação são ancorados. Acabei de lançar uma foto de tela. Existem PLOs atuais e novos, SL e TP. E todas elas são diferentes. Por que eu deveria entrar em detalhes quando tudo está por perto? Se não estiver impresso, e você pode ver que os parâmetros são diferentes, isso significa que eles são de fato diferentes. Ou talvez você também não deva confiar na impressão?

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

E antes disso, como mostrei acima, há um teste:

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

Como você pode ser mais específico? Há um par de palhaços no topo que começaram a inventar histórias. Aparentemente, eles não podiam ou não queriam entender o que eu estava pedindo. Por isso, eles estão rindo sem motivo. Mas a questão é interessante.

Se inserirmos, por exemplo, um parâmetro de outro tipo ou uma quantidade errada na OrderModify(), os erros ocorrem imediatamente. E aqui ele é executado, diz como OK, mas depois se verifica que nenhum parâmetro foi alterado.

A questão é como saber o que está errado ali? Eu expus minha função. Tudo deve ficar claro aí. Aqui 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);
      }
      }
   }
   

Comentei de propósito todas as linhas. Você pode simplesmente estragar o código. Se você tiver algum comentário, por favor, ajude.

 
hoz:

Boris, é claro que percebo que não tenho tudo em um só lugar. Mas os parâmetros de entrada logo antes da função de modificação são ancorados. Acabei de lançar uma foto de tela. Existem PLOs atuais e novos, SL e TP. E todas elas são diferentes. Por que eu deveria entrar em detalhes quando tudo está por perto? Se não estiver impresso, e você pode ver que os parâmetros são diferentes, isso significa que eles são de fato diferentes. Ou talvez você também não deva confiar na impressão?

E antes disso, como mostrei acima, há um teste:


Tudo

Desculpe, não consigo entender isso porque não vejo nenhuma condição no laço que garanta que os parâmetros do pedido não sejam confundidos uns com os outros!

A presença de um erro lhe diz que você está cometendo um erro lógico em algum lugar. Mas também diz que o programa funciona, mas nós estamos interessados na qualidade do programa!

 
borilunad:

Desculpe, não consigo entender isso porque não vejo nenhuma condição no laço que garanta que os parâmetros do pedido não sejam confundidos uns com os outros!

A presença de um erro lhe diz que você está cometendo um erro lógico em algum lugar. Mas também diz que o programa funciona, mas nós estamos interessados na qualidade do programa!


Todas as operações com pedidos acontecem em loop! É aqui que esse método fOrderModify() é chamado, o código do qual citei acima:

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

Você pode ver tudo lá... Você também pode ver que após cada iteração do loop o erro é eliminado. Assim, o fato é garantido que um erro na ordem anterior, se houvesse, não saltaria para a ordem seguinte (quero dizer seu valor, é claro).

Quão mais fácil pode ser? É tão simples...

 

Encontrei uma mensagem.

É o mesmo bug terminal. Eu nunca tive um bicho assim antes. Nunca tentei alterar 3 parâmetros (OOP, SL e TP) de ordens pendentes antes. Mas eu tive que fazê-lo. E eu tropecei em um bug.

Vejo, por exemplo, se o preço aberto e Stop Loss não mudaram e em vez deles recebemos os mesmos valores, mas os Take Points mudaram. Isso também causa o erro? Acontece então que a documentação está torta. E este ponto não é apoiado ou o quê?

 
hoz:

Encontrei uma mensagem.

É o mesmo bug terminal. Eu nunca tive esse tipo de coisa antes. Nunca tentei alterar 3 parâmetros (OOP, SL e TP) de ordens pendentes antes. Mas eu tive que fazê-lo. E eu tropecei em um bicho.

Vejo, por exemplo, se o preço aberto e Stop Loss não mudaram e em vez deles recebemos os mesmos valores, mas os Take Points mudaram. Isso também causa o erro? Acontece então que a documentação está torta. E este ponto não é apoiado ou o quê?

Você também verifica a distância em cada carrapato? Há muito tempo eu adotei a regra de abrir ordens na abertura do bar TF e de modificá-las e fechá-las somente na abertura do bar na M1! O código acima me lembra de um relatório de progresso, que parece conter tudo, mas nada de concreto! Eu não vejo um loop, no qual você define todas as ações por condições específicas! Eu só vejo um loop que não me diz nada para modificar, então simplesmente não modifique, e não haverá erros.

Observe o ponto importante de Renat de que seus erros podem vir da confusão sobre o que fazer globalmente e o que fazer localmente, e os erros são sempre os últimos, os primeiros são reiniciados sem seu envolvimento com a saída de função!

 
borilunad:

Você também verifica a distância a cada tique?!

Não! Eu só permito modificações se uma condição for cumprida. Neste caso, a condição para a modificação é alterar os níveis calculados. Sem mais delongas:

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

Simples? Just....

Borilunad:


Há muito tempo eu fiz uma regra para abrir pedidos na abertura de um bar na TF, e para modificar e fechar somente na abertura de um bar na M1! O código acima me lembra de um relatório de progresso, que parece conter tudo, mas nada específico! Eu não vejo um loop, no qual você define todas as ações por condições específicas! Só vejo um loop que não me diz nada para modificar, então simplesmente não modifique e não haverá erros.

Eu também tive pensamentos semelhantes, para modificar somente na abertura da M1, e, isto é aplicável se a modificação for feita por um valor pré-definido. Mas há situações em que não preciso verificar estes dados no M1. Por exemplo, tenho uma parada puxada em um nível que já foi calculado. Então, como mostrei acima, tenho um cheque na função OnInit():

if (FirstInd != ND (MurreyLevelsValue[1]))
{
   MovingLimitPositions (MurreyLevelsValue);
   FirstInd = ND (MurreyLevelsValue[1]);
}
Ou seja, se o nível mudou, ele... modifica. Isto evita tentativas desnecessárias de modificação. Por assim dizer, modificação por sinal e não por temporizador. Entendido aqui?


borilunad:


Não vejo um loop onde você define todas as ações por condições específicas! Eu só vejo um loop que não me diz nada para modificar, então simplesmente não modifique e não há erros.

Eu tenho tudo despido lá fora. O que não se deve entender... :(

borilunad:

Observe o ponto importante de Renat de que seus erros podem vir da confusão sobre o que fazer globalmente e o que fazer localmente, e os erros são sempre os últimos, os primeiros são reiniciados sem seu envolvimento com a saída de função!

Este problema, como eu descobri, não ocorre somente comigo. Aqui está um exemplo...

E parece que não foi resolvido e não vai ser. Talvez os desenvolvedores sejam preguiçosos? Se eu não estiver trabalhando corretamente com erros, alguém, incluindo Renat, poderia ter entrado no código, e não apenas dizer que eu o tenho errado.

Afinal, se novos e atuais valores de parâmetros a serem modificados forem impressos antes da função de modificação, é claro que esses valores estão lá. Por que subir mais alto em algum lugar? Há valores, é claro que não há erros (eu imprimi lá para erros). Isso significa que tudo está bem na lógica. Portanto, a falha na função de modificação.

 
hoz:

Não! Eu só permito modificações se uma condição for cumprida. Neste caso, a condição para a modificação é alterar os níveis calculados. Sem mais delongas:

Simples? Simples....

Eu também tive pensamentos semelhantes, para modificar somente na abertura da M1, e, isto é aplicável se a modificação for realizada por um valor pré-determinado. Mas há situações em que não preciso verificar estes dados na M1. Por exemplo, tenho uma parada puxada em um nível que já foi calculado. Então, como mostrei acima, há um cheque na função OnInit():

Ou seja, se o nível mudou, ele... modifica. Isto evita tentativas desnecessárias de modificação. Por assim dizer, modificação por sinal e não por temporizador. Entendido aqui?


Eu desatualizei tudo lá. O que não se deve entender... :(

Este problema, como eu descobri, não ocorre somente comigo. Aqui está um exemplo...

E parece que isso não foi resolvido e não vai ser. Talvez os desenvolvedores sejam preguiçosos? Se eu não estiver trabalhando corretamente com erros, alguém, incluindo Renat, poderia entrar em código, e não apenas dizer que eu estou errado.

Afinal, se novos e atuais valores de parâmetros a serem modificados forem impressos antes da função de modificação, é claro que esses valores estão lá. Por que subir mais alto em algum lugar? Há valores, é claro que não há erros (eu imprimi lá para erros). Isso significa que tudo está bem na lógica. Portanto, a falha está na função de modificação.

Já dei uma olhada neste exemplo. Mas temos que nos aplicar a qualquer condição, até que não haja nada melhor. Seu código não me convence. Vou almoçar agora, depois vou dar um exemplo de um loop que funciona bem para definir SL, tradução para B/S e arrasto para apenas uma chamada para modificar a função, onde os erros são tratados, se de repente eles ocorrem no trabalho, não ocorrem no testador.

Você quer a função Modificar()?

 
hoz:

Afinal, se os valores novos e atuais dos parâmetros a serem modificados forem impressos antes da função de modificação, fica claro que esses valores estão lá. Por que subir mais alto em algum lugar? Há valores, é claro que não há erros (eu imprimi lá para erros). Isso significa que tudo está bem na lógica. Portanto, a falha na função de modificação.

O código parece bom... e no real (não na demonstração) funciona ?
 

Victor, por que você começou a modificar o SL e TP nas posições pendentes? Em geral, faz sentido definir o SL somente após a abertura de uma posição, e o TP após a transferência do SL para o B/S! Então por que incomodar tanto o servidor por nada e por que você tem que passar por todo esse trabalho?!

Devemos minimizar e simplificar o código, para que ele funcione rápido e claro, e então será mais fácil ajustá-lo por causa dos caprichos do mercado! Pense cuidadosamente em todas as nuances relacionadas com as realidades do mercado!