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.
[Excluído]  

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
[Excluído]  

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.