Robô abrindo muitas posições a cada tick

 

Olá pessoal!

Meu EA está abrindo muitas posições no mesmo sinal. Entendi que o problema é minha lógica/programação. Eu usei a condição "Se PositionsTotal() == 0 então ele envia uma posição" porém durante o delay até a posição ser aberta ele manda várias solicitações.


Existe no MQL5 um modo mais eficiente de escrever isso? De repente usando OnTradeTransaction para dar um tempo até a posição ser aberta...


double last=SymbolInfoDouble(Symbol(),SYMBOL_LAST);
      
if(Compra[1]!=0 && PositionsTotal()==0)
{
        if(!trade.Buy(Lote_fixo,NULL,last,last-stop*Point(),NULL,NULL))
        {Print("Erro ao abrir uma ordem de compra. ERRO: ",GetLastError());ResetLastError();}
}
      

if(Venda[1]!=0 && PositionsTotal()==0)
{
        if(!trade.Sell(Lote_fixo,NULL,last,last+stop*Point(),NULL,NULL))
        {Print("Erro ao abrir uma ordem de venda. ERRO: ",GetLastError());ResetLastError();}
}
 
Sidnei Da Silva Santos Junior:

...

Antes de abrir uma posição cheque se há alguma aberta, e esse loop se resolve....Eu tenho um exemplo que faz isso, da uma procurada...

 

Esse código verifica se tem posição aberta, use a flag "posicaoAberta" no condicional de abertura de posição:

   posicaoAberta = false;
   for(int i = PositionsTotal() - 1; i >= 0; i--)
   {
      string symbol = PositionGetSymbol(i);
      ulong id      = PositionGetInteger(POSITION_MAGIC);
         
      if(symbol == _Symbol && id == idRobo)
      {         
         posicaoAberta = true;
            
         break;
      }
   }
 
Hawllysson Gardel Queiroz Almeida:

...

A nivel de otimização....nunca é legal ficar criando variáveis dentro de um processo repetitivo, sempre que possível evite isso, pois há um custo alto para o compilador.

   posicaoAberta = false;
   for(int i = PositionsTotal() - 1; i >= 0; i--)
    {
      if(PositionGetSymbol(i) == Symbol() && PositionGetInteger(POSITION_MAGIC) == idRobo)
        {         
         posicaoAberta = true;
         break;
         }
    }
 
Jonathan Pereira:

A nivel de otimização....nunca é legal ficar criando variáveis dentro de um processo repetitivo, sempre que possível evite isso, pois há um custo alto para o compilador.

Obrigado pelo lembrete! Mas qual variável vc fala? Variável "i" do for ou a variável posicaoAberta?

 
Hawllysson Gardel Queiroz Almeida:

Obrigado pelo lembrete! Mas qual variável vc fala? Variável "i" do for ou a variável posicaoAberta?

Não...no seu exemplo a cada chamada vc cria um string symbol e um ulong id....e se vc analisar bem, não é necessário a criação dessas variáveis.

Em casos que é indispensável o uso delas, uma maneira, é cria-las no inicio do programa e ir atribuindo valor ao longo do programa...se vc fazer um code Profile vai notar que o custo de criação e atribuição é muito maior que simplesmente atribuição...Eu gosto de trabalhar sempre no paradigma de orientação a objetos, então essas variáveis que são "auxiliares" sempre são declaradas como membro do objeto, e no construtor, se houver a necessidade atribuo um valor default, e no decorrer do programa vai sobrepondo esses valores...
Mas pra quem não trabalha com objetos, basta criar essas variáveis no escopo global, se houver a necessidade de valor default faz na OnInit().

Isso que eu disse não quer dizer que seu código esteja errado, pelo contrário, está correto porem, há um pequeno custo computacional que pode ser evitado.

 

Então pessoal, no meu caso eu até faço a verificação com o uso do "PositionsTotal" porém é que existe um delay entre a execução da ordem e a recepção da informação de que temos 1 posição.

E nesse delay o EA acaba enviando mais uma ordem. @Jonathan Pereira preciso procurar direito no seu perfil aqui. Está naquele exemplo de EA com cruzamento de MA's? 

Adorei também sua dica para evitar a chamada de variáveis desnecessárias em laços. Obrigado!

 
Sidnei Da Silva Santos Junior:

Então pessoal, no meu caso eu até faço a verificação com o uso do "PositionsTotal" porém é que existe um delay entre a execução da ordem e a recepção da informação de que temos 1 posição.

E nesse delay o EA acaba enviando mais uma ordem. @Jonathan Pereira preciso procurar direito no seu perfil aqui. Está naquele exemplo de EA com cruzamento de MA's? 

Adorei também sua dica para evitar a chamada de variáveis desnecessárias em laços. Obrigado!

bom...não sei qual é a estratégia, mas, se há a necessidade de lançar ordem tick a tick, vc quer que seja uma ordem por vez, sem incremento...há duas alternativas...ou ate mais, enfim é o que veio a mente, rsrsrsrs..

1° faça um sleep logo apos lançar a ordem, sim eu sei que é meio porco mas...da uma segurada no seu código "the flash".

2° cheque o status da solicitação e se bem sucedida vc considera como uma Posição aberta e flaga alguma variável boleana como true ou false, dependendo da sua logica.

   if(trade.ResultDeal()!=0)
     {
      static string text = signal==BUY?"Buy":"Sell";
      if(trade.ResultRetcode()==10009) // trade order went to the exchange
        {
         Print(__FILE__," ",__FUNCTION__,", OK: "+text+" -> true. Result Retcode: ",trade.ResultRetcode(),
               ", description of result: ",trade.ResultRetcodeDescription());
        }
      else
        {
         Print(__FILE__," ",__FUNCTION__,", ERROR: "+text+" -> false. Result Retcode: ",trade.ResultRetcode(),
               ", description of result: ",trade.ResultRetcodeDescription());
        }


@Jonathan Pereira preciso procurar direito no seu perfil aqui. Está naquele exemplo de EA com cruzamento de MA's

Sim, porem nesse exemplo o sinal ocorre em aberturas de novas barras, e não tem esse problema, pois é uma verificação por barra.

 
Jonathan Pereira:

bom...não sei qual é a estratégia, mas, se há a necessidade de lançar ordem tick a tick, vc quer que seja uma ordem por vez, sem incremento...há duas alternativas...ou ate mais, enfim é o que veio a mente, rsrsrsrs..

1° faça um sleep logo apos lançar a ordem, sim eu sei que é meio porco mas...da uma segurada no seu código "the flash".

2° cheque o status da solicitação e se bem sucedida vc considera como uma Posição aberta e flaga alguma variável boleana como true ou false, dependendo da sua logica.


Sim, porem nesse exemplo o sinal ocorre em aberturas de novas barras, e não tem esse problema, pois é uma verificação por barra.

A estratégia focada em entrar nos pavios dos candles, o que faz necessário o uso do tick a tick no código. Vou tentar o caminho do flag, já que é mais desafiador, em caso de problemas eu reporto aqui. 
 
Sidnei Da Silva Santos Junior:

Olá pessoal!

Olá Sidnei,

por acaso o EA está operando modo ASync ?

 
Rogerio Giannetti Torres:

Olá Sidnei,

por acaso o EA está operando modo ASync ?

Nem sei o que é isso pra ser sincero.

Edit: Não especifiquei isso no Algoritmo, estou usando a classe Ctrade porém não especifiquei nada a respeito.
Razão: