Laços e Encerramento ou Eliminação de Pedidos - página 5

 
Eleni Anna Branou:

Favor usar o botão </> para inserir seu código.


Minhas desculpas... Aqui está no formato adequado...

OrdensTotal() não correto...

Fiquei surpreso com a seqüência de códigos de looping que usa OrdersTotal() não dando resultados corretos (observados com dois corretores diferentes).

Estou usando o MT4 versão 1090 em um desktop Linux Ubuntu-MATE 16.04, rodando o WINE 3.0

Aqui está o que venho usando...

Aqui está:

for(int cc = 0; cc < OrdersTotal(); cc++)
{
      if (!OrderSelect(cc, SELECT_BY_POS, MODE_TRADES) ) continue;
      if (OrderSymbol() != Symbol() ) continue;
      if (OrderType() > 1) continue;    //--ignore pending trades

      OpenTradecnt++;    //--counts up for every live position of that symbol that exists
      Print("count of the open trades of this symbol is: ", OpenTradecnt);

Notei com dois corretores diferentes que o valor OrdersTotal() nem sempre concorda com o que é mostrado na aba 'Trade' do corretor MT4. Inicialmente, pensei que era o corretor fazendo com que OrderTotal() não funcionasse corretamente. Quando notei no segundo corretor, comecei a me perguntar se o MT4 tinha um 'problema' interno, ou se meu código estava errado OU se este era um problema com o MT4 sincronizando corretamente com o servidor....?

Depois de ler este tópico do fórum, me pergunto se eu teria melhores resultados alterando o for...loop para ler:

for(int cc = OrdersTotal() - 1; cc >= 0; cc--)
{
      if (!OrderSelect(cc, SELECT_BY_POS, MODE_TRADES) ) continue;
      if (OrderSymbol() != Symbol() ) continue;
      if (OrderType() > 1) continue;    //--ignore pending trades

      OpenTradecnt++;    //--counts up for every live position of that symbol that exists
      Print("count of the open trades of this symbol is: ", OpenTradecnt);
OU, existe uma bandeira ou linha de código que irá garantir que o OrderTotal() esteja devidamente sincronizado durante um evento OnTick()?

Qualquer esclarecimento a respeito disso seria muito útil e seria muito apreciado!

 
Simon Gniadkowski:

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:

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

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

muito obrigado! é uma explicação muito clara
 
Olá codificadores,
Eu já passei por esta leitura sobre seleção de pedidos s. De fato, eu tenho um código onde acredito ter feito as coisas direito, mas a seleção não funciona para mim, pois não consigo ler o Preço Aberto dopedido selecionado. Tudo o resto funciona bem, apenas aquela parte do código fornecido. Não tenho certeza do motivo.
O código inteiro tem 4 seções onde eu preciso ligar para o OrderOpenPrice logo após o envio do pedido... OrderSend funciona bem, OrderSelect não me dará os resultados que eu preciso. Consulte 1 seção do código, se você puder ajudar.
Obrigado.
 if(Protection_Step_One==1)
        {
        while(Protective_Order<0)
          {
          RefreshRates();
          Protective_Order=OrderSend(Symbol(),OP_SELL,Protective_Lots,NormalizeDouble(MarketInfo(Symbol(),MODE_BID),MarketInfo(Symbol(),MODE_DIGITS)),3,0,0,"Intermediary",MN_Sell_Intermediary_Protection,0,Cyan);
          }
  //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Addition for Clamp       
          for (int i=OrdersTotal()-1; i>=0; i--)
            {if(OrderSelect(i,SELECT_BY_POS, MODE_TRADES)==true)
               {if (OrderMagicNumber()==MN_Sell_Intermediary_Protection)
                  { RefreshRates();
                  Intermediary_OpenPrice_Sell= OrderOpenPrice();
                  }
                }
             }   
               //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>..
        if(Protective_Order!=-1)
          { 
          Protection_Step_One=0;
          RealTime_Drawing=2;
          Protective_Mode_Activated=1;
          Protective_Order=-2;
          Defcon=2;

 

Obrigado, caroSimon Gniadkowski,

Seu cargo realmente economizou meu tempo.

 
Gelson Kasonia:
void OnStart()
{
     int Protective_Order=OrderSend(_Symbol,ORDER_TYPE_BUY,0.01,Ask,3,0,0,"Intermediary");
     if(Protective_Order<0)
          return;
     if(!OrderSelect(Protective_Order,SELECT_BY_TICKET, MODE_TRADES))
          return;
     Print(Protective_Order, " OrderOpenPrice: ", OrderOpenPrice());
}
 

Este é o código que sugiro para fechar ordens de mercado

int MagicNo=1234;
int Slippage=10;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseOrdersBackward()
  {
   for(int i=OrdersTotal()-1; i>=0 && !IsStopped(); i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         Print("Order Select failed, order index: ",i," Error: ",GetLastError());
         continue;
        }

      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNo && OrderType()<=OP_SELL)
        {
         if(!OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage))

            Print("Order Close failed, order ticket: ",OrderTicket()," Error: ",GetLastError());
        }
     }
  }

E eu sugiro que esta é a maneira correta se for utilizado um forward for loop (para cumprir as regras FIFO dos corretores dos EUA)

int MagicNo=1234;
int Slippage=10;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseOrdersForward()
  {
   for(int i=0; i<OrdersTotal() && !IsStopped(); i++)
     {
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         Print("Order Select failed, order index: ",i," Error: ",GetLastError());
         continue;
        }

      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNo && OrderType()<=OP_SELL)
        {
         if(OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage))
           {
            i--;
           }
         else
           {
            Print("Order Close failed, order ticket: ",OrderTicket()," Error: ",GetLastError());
           }
        }
     }
  }

No laço frontal,

  1. A função OrderTotal() é usada dentro do loop para atualizar o número restante de pedidos abertos com cada iteração do loop, para evitar índice fora da faixa de array.
  2. O índice i é decrescido com cada ordem fechada, para evitar saltar algumas ordens.
 
amrali: O índice i é decretado a cada pedido fechado, para evitar saltar alguns pedidos.
Na presença de múltiplas ordens (um gráfico EAmultiple, múltiplos EAs, comércio manual,) enquanto se espera que a operação atual (fechamento, exclusão, modificação) seja concluída, qualquer número de outras operações em outras ordens poderia ter acontecido simultaneamente e mudado a indexação de posição:
  1. Para os não FIFO ( USbrokers,)(ou a EA só abre uma ordem por símbolo,) você pode simplesmente contar para baixo em um positionloop, e você não perderá ordens. Tenha o hábito de sempre fazer a contagem regressiva.
    Loops e Ordens de Fechamento ou de Eliminação - Fórum de programação MQL4
    Para FIFO ( USbrokers,)e você (potencialmente) processa várias ordens por símbolo, você deve Encontrar a ordem mais antiga, fechá-la e, em uma operação bem sucedida, reprocessar todas as posições restantes.
    FecharOrdens porFIFO Rules - Strategy Tester - Fórum de programação MQL4 -Página 2 #16

  2. e verifique OrderSelect no caso de posições anteriores terem sido eliminadas.
    O que são valores de retorno de função ? Como utilizá-los ? - Fórum de programação MQL4
    Erros comuns em programas MQL4 e como evitá-los - Artigos MQL4
  3. e se você (potencialmente) processar vários pedidos, deve chamarRefreshRates() após as chamadas do servidor se você quiser usar, no texto order / server, as Variáveis Pré-definidas(Bid/Ask) ou (ser independente da direção e uso) OrderClosePrice().
 

Você saberá o quanto isso me ajudou. Não apenas com o código em que eu estava trabalhando, mas com a minha total compreensão. Ele funciona perfeitamente agora e eu tenho o entendimento para implementá-lo de diferentes maneiras.

Realmente aprecio muito esta informação.