Minha EA faz uma entrada dupla - página 4

 
doshur:

posso perguntar se PositionSelect() verifica o lado do cliente ou o lado da corte?

Tenho a forte sensação de que o problema é causado pelo atraso onde o servidor (lado do corretor) está processando a solicitação e não atualizou o lado do cliente, por isso PositionSelect() é executado novamente.

Eu sinto fortemente que não há diferença quando usamos o modo cTrade vs MqlTradeRequest e a função Sleep deve ajudar a atrasar tudo para que nosso lado cliente seja "atualizado" antes que o PositionSelect() seja executado novamente, causando uma entrada dupla. Verificando na minha ficha de diário, >2013.12.20 08:35:00 Negociações '800****': compra de câmbio 0.01 EURUSD no mercado colocado para execução em 313 ms <

colocar o sono mais de 400 deve ser seguro????

O que você acha?


"Tenho a forte sensação de que o problema é causado pelo atraso onde o servidor (lado do corretor) está processando a solicitação e não atualizou o lado do cliente, por isso PositionSelect() funciona novamente".

Também acho que esta é a causa para a entrada dupla. Em meu código é teoricamente impossível enviar uma nova ordem se o tamanho da posição atual for igual ou maior que o tamanho máximo permitido da posição, portanto, quando a PositionSelect() não receber a tempo o status da posição atual, minha EA enviará uma nova ordem novamente.


"colocar o sono mais de 400 deve ser seguro???".

Quanto maior o intervalo de tempo, melhor, mas há um problema. Se você virar sua posição, em duas etapas (LONG to SHORT ou SHORT to LONG), este atraso de tempo extra pode ser a causa de um preço de execução ruim, especialmente durante um evento macroeconômico.

 
snelle_moda:


"Tenho a forte sensação de que o problema é causado pelo atraso onde o servidor (lado do corretor) está processando a solicitação e não atualizou o lado do cliente, por isso PositionSelect() funciona novamente".

Também acho que esta é a causa para a entrada dupla. Em meu código é teoricamente impossível enviar uma nova ordem se o tamanho da posição atual for igual ou maior que o tamanho máximo permitido da posição, portanto, quando a PositionSelect() não receber a tempo o status da posição atual, minha EA enviará uma nova ordem novamente.


"colocar o sono mais de 400 deve ser seguro???".

Quanto maior o intervalo de tempo, melhor, mas há um problema. Se você virar sua posição, em duas etapas (LONG to SHORT ou SHORT to LONG), este atraso de tempo extra pode ser a causa de um preço de execução ruim, especialmente durante um evento macroeconômico.

Acho que não deve ser um problema. Minha EA não reverte imediatamente quando acabo de enviar um pedido de compra/venda. Estou colocando meu sono em 800ms para que minha EA tenha tempo suficiente para esperar pelas atualizações do corretor. Espero que o sono possa resolver este problema aqui.
 
doshur:
Não sei se o corretor joga à parte aqui, mas parece que nosso corretor é o mesmo. Alpari.

Se necessário, remova o nome do corretor.
sim corretor é o mesmo.
 
snelle_moda:


Tive mais 1 entrada dupla desde 03-10-2013. Eu utilizo os dois métodos para enviar meu pedido. Veja meu post anterior.

ah huh... tal como eu esperava...
 

isto é o que acabei de implementar. espero que possa adorar o problema

if(m_Trade.PositionOpen(Symbol(), ORDER_TYPE_BUY, LotSize, Price, 0, 0))
            {
               Sleep(800);

               if(m_Trade.ResultRetcode() == 10009)
               {
                  Print("Position opened in ", Symbol());

                  return;
               }
               else
               {
                  Print("Error opening position in ", Symbol(), " - ", m_Trade.ResultComment(), "\n", "Return Code Desc - ", m_Trade.ResultRetcodeDescription());
               }
            }
            else
            {
               Print("Error with PositionOpen in ", Symbol(), " - ", m_Trade.ResultComment(), "\n", "Return Code Desc - ", m_Trade.ResultRetcodeDescription());
            }
 
doshur:

isto é o que acabei de implementar. espero que possa adorar o problema

Tanto quanto sei, um código de resultado = 10008 também está indicando que um comércio está bem posicionado.
 

Acho que é muito importante encontrar a razão por trás desta questão, é claro que também é importante ter uma solução (Dormir ?) até que possamos entender completamente o que está acontecendo. Por isso, tento retomar a situação:

  • Ao utilizar o método PositionOpen da classe CTrade, pelo menos 3 usuários conseguiram em algum momento, 2 negócios na mesma direção em vez de 1, resultando em uma posição com um volume dobrado em relação ao que é esperado.
  • O código postado inicialmente por doshur, pode explicar porque ele pode ver em seu registro "Posição aberta em..." enquanto nenhuma troca foi aberta. Isto é porque, mesmo que PositionOpen() retorne verdadeiro, não significa que uma troca foi colocada. Veja a documentação. Mas não pode explicar por que uma "dupla" troca foi colocada.
  • Só vejo 2 explicações para este comércio "duplo":
  1. PositionSelect() nem sempre retorna a verdadeira situação da posição. Uma posição é aberta mas a PositionSelect retorna falsa. Bug in PositionSelect então.
  2. Uma negociação é colocada, mas, quando a PositionSelect() é chamada no próximo tick, a posição ainda não existe. Para entender se é possível, temos que conhecer o fluxo de operação quando uma troca é colocada.
  • Este problema parece ocorrer no mesmo corretor, com um símbolo onde a Profundidade de Mercado é ativada (as pessoas envolvidas podem confirmar isto, por favor).
  • Este problema ocorre com ordem síncrona, ordem assíncrona não foi utilizada (favor confirmar).
  • O problema ocorre de forma aleatória.
  • Os relatórios de Klammeraffe não têmmais o problema, mas não consigo ver como o código que ele postou pode explicar isso. Este código é executado em cada tick? Este código é executado após o uso do PositionSelect() ? Então talvez ele tenha removido a causa do erro ou é apenas aleatório.
  • Após verificar o código, não consigo ver nenhuma diferença entre usar a classe CTrade ou MqlTradeRequest com OrderSend diretamente.

Concordo com a snella_moda que a melhor explicação é:

I think the problem is the (to slow) execution of the PositionSelect(Symbol()) function. Maybe, the new ticks come in so fast, the EA sends in a new order before it receives a response of the PositionSelect(Symbol()). So the current position size is not calculated properly. In my code, its theoretically impossible to send in a new/double order if the current position size is equal or greater than the max allowed position size, see code. 

Mas é difícil de verificar.

Acho que o melhor a fazer é pedir conselhos à Metaquotes. Vou tentar isso.

 
angevoyageur:
  • Os relatórios do Klammeraffe não têmmais o problema, mas não consigo ver como o código que ele postou pode explicar isso. Este código é executado em cada tick? Este código é executado após o uso do PositionSelect() ? Então talvez ele tenha removido a causa do erro ou é apenas aleatório.

A linha referente a "cada tick" pode ser o motivo pelo qual isso não acontece mais.

A função só é executada, quando uma nova barra aparece. Portanto, muito provavelmente, apenas o primeiro tick de uma barra pode executar uma troca. Após a primeira barra, o código recebe um "retorno" até que uma nova barra apareça. Talvez isso tenha sido resolvido para mim.

Acho que este pedaço de código é dos artigos:

//-------------------------------------------------- Check for new bar     
         static datetime OldTime;
         datetime NewTime[1];
         bool newBar=false;
         
         int copied=CopyTime(Symbol(),Period(),0,1,NewTime);
         if (copied>0)
           {
             if (OldTime != NewTime[0])
               {  
                 newBar=true;
                 OldTime=NewTime[0];
               }
           }
         else
           {
            Print("Error in copying historical times data, error =",GetLastError());
            ResetLastError();
            return;
           }  
         if(newBar==false) return;      
//-------------------------------------------------- Check for new bar
 
Klammeraffe:

A linha referente a "cada carrapato" pode ser a razão pela qual isso não acontece mais.

A função só é executada, quando aparece uma nova barra. Portanto, muito provavelmente, apenas o primeiro tique de uma barra pode executar uma negociação. Após a primeira barra, o código recebe um "retorno" até que uma nova barra apareça. Talvez isso tenha sido resolvido para mim.

Acho que este pedaço de código é dos artigos:

Sim, eu acho que sim. Obrigado.
 
  • O código afixado inicialmente pelo doshur, pode explicar porque ele pode ver em seu diário de bordo "Posição aberta em..." enquanto nenhuma troca foi aberta. Isto porque, mesmo que a PositionOpen() retorne verdadeiro, não significa que uma troca foi colocada.Veja a documentação. Mas não pode explicar por que uma "dupla" troca foi colocada.

correção. Há uma dupla"Posição aberta em..." e 2 trocas foram abertas.

  • Este problema parece ocorrer no mesmo corretor, com um símbolo onde a Profundidade de Mercado é ativada (as pessoas envolvidas podem confirmar isto, por favor).
Não tenho certeza sobre os outros, mas os meus têm DOM

  • Este problema ocorre com ordem síncrona, ordem assíncrona não foi utilizada (favor confirmar).
Estou usando as configurações padrão cTrade.

  • O problema ocorre de forma aleatória.
sim, aleatoriamente

Razão: