Laços e Encerramento ou Eliminação de Pedidos

 

Este é um dos erros mais comuns que eu vejo, provavelmente devido em parte a gostos de lixo como o Expert Advisor Builder. Por isso, achei que era hora de um tópico dedicado ao assunto para que ele possa ser ligado para referência futura.

O problema

Vamos dar um exemplo simples; queremos uma função para fechar todas as ordens abertas para nossa EA, há muitos exemplos, mas vamos criar um a partir do zero.

Precisamos de um loop porque queremos fechar todas as nossas ordens para uma EA específica, dentro deste loop teremos código para selecionar a ordem, código para verificá-la é o símbolo correto e número mágico e finalmente código para fechar a ordem:

int PositionIndex;    //  <-- this variable is the index used for the loop

int TotalNumberOfOrders;   //  <-- this variable will hold the number of orders currently in the Trade pool

TotalNumberOfOrders = OrdersTotal();    // <-- we store the number of Orders in the variable

for(PositionIndex = 0; PositionIndex < TotalNumberOfOrders; PositionIndex++)  //  <-- for loop to loop through all Orders
   {
   if( ! OrderSelect(PositionIndex, SELECT_BY_POS, MODE_TRADES) ) continue;   // <-- if the OrderSelect fails advance the loop to the next PositionIndex
   
   if( OrderMagicNumber() == MagicNo       // <-- does the Order's Magic Number match our EA's magic number ? 
      && OrderSymbol() == Symbol()         // <-- does the Order's Symbol match the Symbol our EA is working on ? 
      && ( OrderType() == OP_BUY           // <-- is the Order a Buy Order ? 
      ||   OrderType() == OP_SELL ) )      // <-- or is it a Sell Order ?

      if ( ! OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(), Slippage ) )               // <-- try to close the order
         Print("Order Close failed, order number: ", OrderTicket(), " Error: ", GetLastError() );  // <-- if the Order Close failed print some helpful information 
      
   } //  end of For loop

Este código é ruim . . . NÃO O UTILIZE. . . Explicarei por que na próxima seção . .

A explicação

Vamos trabalhar através do código acima . . . linha por linha, Ordem por Ordem . .

Vamos assumir que temos as seguintes Ordens que queremos fechar, todas elas têm o mesmo número mágico e Símbolo que nossa EA, então queremos que nosso código feche todas elas:

Posição Número do bilhete
0111
1222
2 333
3444
4555

1ª corrida através do loop:

o valor inicial do PositionIndex é 0, portanto a ordem na posição 0 é selecionada, o ticket número 111, esta ordem é eliminada com sucesso e as ordens restantes mudam de posição da seguinte forma:

Posição Número do bilhete
0222
1 333
2444
3555

2ª corrida através do loop:

agora o valor do PositionIndex é 1, portanto a ordem na posição 1 é selecionada, o ticket número 333, esta ordem é eliminada com sucesso e as ordens restantes mudam de posição da seguinte forma :

Posição Número do bilhete
0222
1 444
2555

3ª corrida através do loop:

agora o valor do PositionIndex é 2, portanto a ordem na posição 2 é selecionada, o ticket número 555, esta ordem é eliminada com sucesso e as ordens restantes mudam de posição da seguinte forma :

Posição Número do bilhete
0222
1 444

4ª corrida através do loop:

agora o valor do PositionIndex é 3 OrderSelect() tenta selecionar a ordem na posição 3 e falha, a continuação leva a execução do código para o próximo valor no laço .


5ª e última etapa do loop:

agora o valor do PositionIndex é 4 OrderSelect() tenta selecionar a ordem na posição 4 e falha, a continuação leva a execução do código para o próximo valor no laço . . o laço terminou .


Ficamos agora com 2 pedidos, bilhetes 222 e 444 que deveriam ter sido fechados mas não foram . . . a seguir, como resolver esta questão.

A solução

O seguinte código é a abordagem correta ao fechar ordens abertas ou apagar ordens pendentes. .

A diferença principal é que o loop decreta de ( TotalNumberOfOrders - 1 ) a 0

int PositionIndex;    //  <-- this variable is the index used for the loop

int TotalNumberOfOrders;   //  <-- this variable will hold the number of orders currently in the Trade pool

TotalNumberOfOrders = OrdersTotal();    // <-- we store the number of Orders in the variable

for(PositionIndex = TotalNumberOfOrders - 1; PositionIndex >= 0 ; PositionIndex --)  //  <-- for loop to loop through all Orders . .   COUNT DOWN TO ZERO !
   {
   if( ! OrderSelect(PositionIndex, SELECT_BY_POS, MODE_TRADES) ) continue;   // <-- if the OrderSelect fails advance the loop to the next PositionIndex
   
   if( OrderMagicNumber() == MagicNo       // <-- does the Order's Magic Number match our EA's magic number ? 
      && OrderSymbol() == Symbol()         // <-- does the Order's Symbol match the Symbol our EA is working on ? 
      && ( OrderType() == OP_BUY           // <-- is the Order a Buy Order ? 
      ||   OrderType() == OP_SELL ) )      // <-- or is it a Sell Order ?
   
      if ( ! OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(), Slippage ) )               // <-- try to close the order
         Print("Order Close failed, order number: ", OrderTicket(), " Error: ", GetLastError() );  // <-- if the Order Close failed print some helpful information 
      
   } //  end of For loop

Mais uma vez, vamos trabalhar através do código acima . . . linha por linha, Ordem por Ordem . . .

Temos as mesmas ordens que antes:

Posição Número do bilhete
0111
1222
2333
3444
4555

1ª corrida através do loop:

o valor inicial do PositionIndex é TotalNumberOfOrders - 1 que é igual a 5 - 1 = 4, portanto a ordem na posição 4 é selecionada, o ticket número 555, esta ordem é eliminada com sucesso e as ordens restantes mudam de posição da seguinte forma:

Posição Número do bilhete
0111
1222
2333
3444

2ª corrida através do loop:

agora o valor do PositionIndex é 3, portanto a ordem na posição 3 é selecionada, o ticket número 444, esta ordem é eliminada com sucesso e as ordens restantes mudam de posição da seguinte forma :

Posição Número do bilhete
0111
1222
2333

3ª corrida através do loop:

agora o valor do PositionIndex é 2, portanto a ordem na posição 2 é selecionada, o ticket número 333, esta ordem é eliminada com sucesso e as ordens restantes mudam de posição da seguinte forma :

Posição Número do bilhete
0111
1222

4ª corrida através do loop:

agora o valor do PositionIndex é 1 , portanto a ordem na posição 1 é selecionada, o ticket número 222, esta ordem é eliminada com sucesso e as ordens restantes mudam de posição da seguinte forma :

Posição Número do bilhete
0111

5ª e última etapa do loop:

agora o valor do PositionIndex é 0 então a ordem na posição 0 é selecionada, bilhete número 111, esta ordem é apagada com sucesso, valor 0 é o último valor válido para o laço . . o laço terminou .

Eliminamos com sucesso todas as nossas encomendas correspondentes . .

Link para esta linha: Loops e Encerramento ou Eliminação de Pedidos

 

Vamos dar um exemplo mais complexo . .

Vamos assumir que temos as seguintes ordens que queremos fechar, todas elas têm o mesmo número mágico, mas algumas têm um símbolo diferente de nossa EA, queremos que nosso código feche as ordens para o mesmo símbolo que nossa EA, EURUSD:

Posição Número do bilhete Símbolo
0111 EURUSD
1222 EURUSD
2333GBPUSD
3444 EURUSD
4555 EURUSD


1ª corrida através do loop:

o valor inicial do PositionIndex é TotalNumberOfOrders - 1 que é igual a 5 - 1 = 4, então a ordem na posição 4 é selecionada, o número do bilhete 555, esta ordem corresponde ao número mágico e o símbolo é apagado com sucesso e as demais ordens mudam de posição como a seguir:

Posição Número do bilhete Símbolo
0111EURUSD
1222EURUSD
2333GBPUSD
3444EURUSD

2ª corrida através do loop:

agora o valor do PositionIndex é 3, portanto a ordem na posição 3 é selecionada, o ticket número 444, esta ordem corresponde ao número mágico e o símbolo é apagado com sucesso e as ordens restantes mudam de posição como segue:

Posição Número do bilhete Símbolo
0111EURUSD
1222EURUSD
2333GBPUSD


3ª corrida através do loop:

agora o valor do PositionIndex é 2 para que a ordem na posição 2 seja selecionada, bilhete número 333, esta ordem corresponde ao número mágico mas NÃO aosímbolo, portanto não é apagado, as ordens restantes não mudam:

Posição Número do bilhete Símbolo
0111EURUSD
1222EURUSD
2333GBPUSD

4ª corrida através do loop:

agora o valor do PositionIndex é 1 , portanto o pedido na posição 1 é selecionado, o ticket número 222, este pedido corresponde ao número mágico e o símbolo, portanto é excluído com sucesso e os pedidos restantes mudam de posição da seguinte forma :

Posição Número do bilhete Símbolo
0111EURUSD
1333GBPUSD

5ª e última etapa do loop:

agora o valor do PositionIndex é 0 então a ordem na posição 0 é selecionada, bilhete número 111, esta ordem é apagada com sucesso, valor 0 é o último valor válido para o laço . . o laço terminou.

Eliminamos com sucesso todas as nossas ordens correspondentes, deixando a única ordem que não correspondia ao nosso símbolo, o ticket número 333 agora na posição 0 . .

Posição Número do bilhete Símbolo
0333GBPUSD


Link para esta linha: Loops e Encerramento ou Eliminação de Pedidos

 
Veja também porque você deve contar para baixo E testar o status OrderSelect
 

Obrigado Raptor por esta importante explicação.

Y.

 
Isto é extremamente útil para mim, rei do construtor especialista em lixo! Oh, como eu gosto de invadir o código resultante. Muito obrigado.
 

Uau. Todas essas informações para fechar um pedido.

Eu me pergunto quanta informação seria necessária para se obter mais de 50 pips líquidos por dia, consistentemente, todos os dias (em média) - sem falha, através das últimas 137 negociações.

Mostre-me como fazer algo assim, e eu consideraria isso informação extremamente útil e Guru, será seu título, para sempre e sempre, Amém.

 
CFx:

Uau. Todas essas informações para fechar um pedido.

Eu me pergunto quanta informação seria necessária para se obter mais de 50 pips líquidos por dia, consistentemente, todos os dias (em média) - sem falha, através das últimas 137 negociações.

Eu não tenho interesse em pips . . o que posso fazer com eles ? Não posso gastá-los, qual é a taxa GBPPIPS ? você mostra sua ignorância ao contar o sucesso em pips . .
 
CFx:

Eu me pergunto quanta informação seria necessária para se obter mais de 50 pips líquidos por dia, consistentemente, todos os dias (em média) - sem falha, através das últimas 137 negociações.

Mostre-me como fazer algo assim, e eu consideraria isso informação extremamente útil e Guru, será seu título, para sempre e sempre, Amém.

  1. Não se apropriar de informações fora do tópico
  2. NÃO vamos mostrar a você que, por não ter lido as regras, nenhuma discussão, exceto sobre MetaQuotes Idioma 4 e comércio de automóveis, é proibida
 

Raptor, eu sei que, ao primeiro olhar do seu posto, este tópico ajuda a esclarecer minhas dúvidas!

 

Apenas mais uma idéia:

for(PositionIndex = 0; PositionIndex < OrdersTotal() ; PositionIndex ++)  //  <-- for loop to loop through all Orders . .   COUNT DOWN TO ZERO !
   {
   if( ! OrderSelect(PositionIndex, SELECT_BY_POS, MODE_TRADES) ) continue;   // <-- if the OrderSelect fails advance the loop to the next PositionIndex
   
   if( OrderMagicNumber() == MagicNo       // <-- does the Order's Magic Number match our EA's magic number ? 
      && OrderSymbol() == Symbol()         // <-- does the Order's Symbol match the Symbol our EA is working on ? 
      && ( OrderType() == OP_BUY           // <-- is the Order a Buy Order ? 
      ||   OrderType() == OP_SELL ) )      // <-- or is it a Sell Order ?
   
         add_trade_to_close_queue( OrderTicket());  // <--  You need to model the queue mechanism ...
      
   } //  end of For loop


Cumprimentos.

 
abstract_mind:


Apenas mais uma idéia:


Cumprimentos.

sim, entenda a lógica por trás do MT4, cabe a você codificar o contador de aumento ou diminuição.