Quaisquer perguntas de recém-chegados sobre MQL4 e MQL5, ajuda e discussão sobre algoritmos e códigos - página 493

 
Roman Sharanov:
Você poderia informar se a função de fechar todas as ordens abertas pela EA pelo símbolo é implementada corretamente?

A arquitetura em si é correta. Os erros estão na falta de verificações e no uso de algumas funções:

bool OrderCloseAll()
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
         if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)
            continue;

         if(OrderSymbol() !=Symbol() || OrderMagicNumber() != Magic)
            continue;
         
         if (!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), slippage, clrWhite))
            return false;
   }

   return true;
}

  1. A primeira iteração em seu caso falhará - a ordem com índice OrdensTotal() não existe.
  2. Não há verificação para o resultado da função OrderSelect.
  3. Não há verificação para o resultado da função OrderClose. Se o fechamento do pedido falhar, não podemos permanecer na mesma função, já que temos que descobrir por que o fechamento não foi bem sucedido. Para fazer isso, temos que deixar a função com o resultado falso, e depois decidir o que fazer a seguir.
  4. Não podemos usar o mesmo preço de fechamento para todos os pedidos. Primeiro, as ordens podem ser de tipos diferentes e, segundo, é provável que o preço tenha mudado ao longo do tempo de execução de ordens anteriores (no fechamento). Podemos usar um recurso MT4 para evitar adivinhar qual preço usar: o valor OrderClosePrice() de uma ordem de mercado antes de seu fechamento é o preço Bid or Ask, dependendo do tipo de ordem.
 
Ihor Herasko:

A arquitetura em si é correta. Os erros estão na falta de verificações e no uso de algumas funções:

  1. A primeira iteração em seu caso falhará - a ordem com o índice OrdensTotal() não existe.
  2. Não há verificação para o resultado da função OrderSelect.
  3. Não há verificação para o resultado da função OrderClose. Se o fechamento do pedido falhar, não podemos permanecer na mesma função, já que temos que descobrir por que o fechamento não foi bem sucedido. Para fazer isso, temos que deixar a função com o resultado falso, e depois decidir o que fazer a seguir.
  4. Não podemos usar o mesmo preço de fechamento para todos os pedidos. Primeiro, as ordens podem ser de tipos diferentes e, segundo, é provável que o preço tenha mudado durante a execução de ordens anteriores (no fechamento). Para evitar adivinhar qual preço usar, podemos usar um recurso MT4: o valor OrderClosePrice() de uma ordem de mercado antes de seu fechamento é o preço Bid or Ask, dependendo do tipo de ordem.

Obrigado, o principal problema provavelmente era apenas usar o mesmo preço

 

Da ajuda OrderSelect " Quando as ordens são selecionadas sequencialmente usando o parâmetro SELECT_BY_POS, a informação é dada na ordem em que veio do servidor comercial. Não é garantida a ordenação da lista de pedidos obtida".

Se pensamos que esta frase foi inserida na ajuda por nada, estamos bem. Se pensarmos que ela estava lá por alguma razão, não devemos alterar esta lista durante a execução do loop através da lista de pedidos. Como as ordens serão encomendadas após a exclusão de uma delas no servidor e a chegada de uma nova lista atual com uma ordem menorTotal, é desconhecida. É mais confiável, sem excluir, passar pela mesma cópia inalterada da lista e coletar (em uma matriz) todos os números de bilhetes das negociações a serem excluídos. Em seguida, esqueça essa lista e apague os negócios, selecionando-os por bilhete.

Gostaríamos de acreditar, é claro, que a ordenação na lista modificável é preservada, nem que seja apenas para este caso de remoção de várias ordens do final de uma lista não ordenada, mas os desenvolvedores estão contra... Agora funciona, e se surgir uma nova construção - "nós avisamos".

 
Vladimir:

Da ajuda OrderSelect " Quando as ordens são selecionadas sequencialmente usando o parâmetro SELECT_BY_POS, a informação é dada na ordem em que veio do servidor comercial. Não é garantida a ordenação da lista de pedidos obtida".

Se pensamos que esta frase foi inserida na ajuda por nada, estamos bem. Se pensarmos que ela estava lá por alguma razão, não devemos alterar esta lista durante a execução do loop através da lista de pedidos. Como as ordens serão encomendadas após a exclusão de uma delas no servidor e a chegada de uma nova lista atual com uma ordem menorTotal, é desconhecida. É mais confiável, sem excluir, passar pela mesma cópia inalterada da lista e coletar (em uma matriz) todos os números de bilhetes das negociações a serem excluídos. Em seguida, esqueça essa lista e apague os negócios, selecionando-os por bilhete.

Gostaríamos de acreditar, é claro, que a ordenação na lista modificável é preservada, nem que seja apenas para este caso de remoção de várias ordens do final de uma lista não ordenada, mas os desenvolvedores estão contra... Agora funciona, e se surgir uma nova construção - "nós avisamos".

Essa "América" está aberta há cerca de trezentos anos :)

 
Artyom Trishkin:

Este tipo de "América" está aberto há trezentos anos :)

Não creio que as pessoas que aqui fazem perguntas em nome dos recém-chegados já tenham descoberto isso por conta própria. É por isso que estou escrevendo. Não para os moderadores, mas para os questionadores. Veja o nome do fio.

P.S. Eu investiguei de onde veio este interesse. Acontece que é da filial https://www.mql5.com/ru/forum/215783/page8"Organising the Order Cycle" (Organização do Ciclo de Pedidos). Acontece que, em outubro de 2017, esses trezentos anos ainda não terminaram, ainda há novidades.

Организация цикла перебора ордеров
Организация цикла перебора ордеров
  • 2017.09.16
  • www.mql5.com
MQL4 и MetaTrader 4: Организация цикла перебора ордеров
 
Vladimir:

Não creio que as pessoas que aqui fazem perguntas em nome dos recém-chegados já tenham descoberto isso por conta própria. É por isso que estou escrevendo. Não para os moderadores, mas para os questionadores. Veja o nome do fio.

P.S. Eu olhei de onde vem este interesse. Acontece que é da filial https://www.mql5.com/ru/forum/215783/page8"Organising the order cycle" (Organizando o ciclo do pedido). Acontece que, em outubro de 2017, esses trezentos anos ainda não terminaram, ainda há novidades.

Errado novamente :) Trezentos anos começaram em mql4.com - houve uma época em que se discutia ativamente sobre o assunto. E houve até mesmo aqueles momentos que são descritos por você em "Agora funciona, e uma nova construção sairá - "nós avisamos". Somente sem avisos, e assim várias vezes - depende, não depende de classificação...

E, sim, há um fio especial para tais respostas:

Особенности языка mql4, тонкости и приёмы работы
Особенности языка mql4, тонкости и приёмы работы
  • 2017.02.24
  • www.mql5.com
В данной теме будут обсуждаться недокументированные приёмы работы с языком mql4, примеры решения тех, или иных задач...
 
Vladimir:

Da ajuda OrderSelect " Quando as ordens são selecionadas sequencialmente usando o parâmetro SELECT_BY_POS, a informação é dada na ordem em que veio do servidor comercial. Não é garantida a ordenação da lista de pedidos obtida".

Se pensamos que esta frase foi inserida na ajuda por nada, estamos bem. Se pensarmos que ela estava lá por alguma razão, não devemos alterar esta lista durante a execução do loop através da lista de pedidos. Como as ordens serão encomendadas após a exclusão de uma delas no servidor e a chegada de uma nova lista atual com uma ordem menorTotal, é desconhecida. É mais confiável, sem excluir, passar pela mesma cópia inalterada da lista e coletar (em uma matriz) todos os números de bilhetes das negociações a serem excluídos. Em seguida, esqueça essa lista e apague os negócios, selecionando-os por bilhete.

Eu gostaria, é claro, de acreditar que o pedido na lista modificada é preservado pelo menos para este caso de exclusão de vários pedidos do final de uma lista não ordenada, mas os desenvolvedores estão contra... Agora funciona, e se surgir uma nova construção, "nós avisamos".

Como uma boa idéia (considerando que pode haver vários Expert Advisors + trader trabalhando na conta em paralelo), você não pode realizar negócios em loop de forma alguma. A ordem necessária é recebida, a operação é executada, o OnTick() inteiro é executado novamente (não necessariamente com a chegada de um novo tick). E assim por diante, até que todas as operações necessárias sejam executadas.

Assim, formar uma matriz para eliminar ordens é equivalente a eliminar ordens no laço.

 

Há um botão "Parar", como posso mudar seu texto para "Começar" uma vez pressionado?

bool stop;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//Closed at Profit
   ObjectCreate(0,"Stop",OBJ_BUTTON,0,0,0);
   ObjectSetInteger(0,"Stop",OBJPROP_XDISTANCE,10);
   ObjectSetInteger(0,"Stop",OBJPROP_YDISTANCE,105);
   ObjectSetInteger(0,"Stop",OBJPROP_XSIZE,100);
   ObjectSetInteger(0,"Stop",OBJPROP_YSIZE,25);

   ObjectSetString(0,"Stop",OBJPROP_TEXT,"Stop");

   ObjectSetInteger(0,"Stop",OBJPROP_COLOR,White);
   ObjectSetInteger(0,"Stop",OBJPROP_BGCOLOR,Green);
   ObjectSetInteger(0,"Stop",OBJPROP_BORDER_COLOR,Green);
   ObjectSetInteger(0,"Stop",OBJPROP_BORDER_TYPE,BORDER_FLAT);
   ObjectSetInteger(0,"Stop",OBJPROP_HIDDEN,true);
   ObjectSetInteger(0,"Stop",OBJPROP_STATE,false);
   ObjectSetInteger(0,"Stop",OBJPROP_FONTSIZE,12);
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
if(sparam=="Stop")
     {
      ObjectSetInteger(0,"Stop",OBJPROP_STATE,false);
      CloseAtProfit();
      stop=true;
     }
     }
 
lil_lil: Há um botão "Parar", como posso mudar seu texto para "Começar" uma vez pressionado?

Veja meu exemplo de especialista

Arquivos anexados:
ToFile.mq4  11 kb
 
STARIJ:

Veja meu exemplo de Conselheiro Especialista

Obrigado, exatamente o que eu precisava.

Talvez seja útil saber que há um erro nas posições em falta--- ToFile EURUSD,H1: divisão zero em 'ToFile.mq4' (62,39)

/*62*/  Строка=DoubleToStr(AccountEquity()/AccountMargin()*100,2)+"%"; // Уровень=Средства/Залог
O texto não muda no testador, não existe tal opção?