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

 
Alexander_K2:

Há algo realmente errado, no entanto...

Quero dizer, faço OrderSelect uma e outra vez a partir da função Isso é uma coisa dos diabos...

  1. Você selecionou um pedido em um bilhete
  2. Você vai para a função que verifica o número de pedidos. Se houver mais de um pedido, todos os pedidos disponíveis são selecionados um a um no ciclo
  3. Quando você retornar da função, a ordem selecionada será a última da lista de ordens no terminal do cliente (não será necessariamente a ordem que você selecionou no ponto 1).
  4. Então você verifica o horário de fechamento de um novo pedido e está tentando fechar aquele que supostamente foi selecionado pelo bilhete, mas sua seleção já foi perdida.

Lógica simples...

Observe a seqüência de operações que você está fazendo.

Obviamente, você deve primeiro verificar a quantidade, depois selecionar a ordem requerida e, em seguida, realizar as operações necessárias sobre ela.

 
Maxim Kuznetsov:

em que direção você vê a matriz de pedidos?

se houver possíveis fechamentos/deleções durante a "revisão", é melhor olhar na direção oposta. De OrderTotal()-1 a 0 inclusive.

Caso contrário você pode se meter em problemas :-)


Eu quase descobri meu graal pessoal desta maneira uma vez :-)

E a remoção de ordens antigas das "profundezas do tempo" para o presente (de vez em quando, não todas) elevou a rentabilidade do testador para os céus :-)

 
Artyom Trishkin:
  1. Você selecionou um pedido por bilhete
  2. Você entrou na função para verificar o número de pedidos. Se houver mais de uma ordem, todas as ordens disponíveis serão selecionadas uma a uma para serem contadas no ciclo
  3. Quando você retornar da função, a ordem selecionada será a última da lista de ordens no terminal do cliente (não precisa necessariamente ser a ordem selecionada no ponto 1).
  4. Então você verifica o horário de fechamento de um novo pedido e está tentando fechar aquele que supostamente foi selecionado pelo bilhete, mas sua seleção já foi perdida.

Lógica simples...

Observe a seqüência de operações que você está fazendo.

É óbvio que você deve primeiro verificar a quantidade, depois selecionar a ordem correta e, em seguida, realizar as operações necessárias sobre ela

Eu o fiz desta maneira:

RefreshRates();
         total_orders_NZDUSD=TotalOrders("NZDUSD.I");
         if(OrderSelect(ticket_sell_NZDUSD, SELECT_BY_TICKET)==true)
         {
         ctm_ticket_sell_NZDUSD=OrderCloseTime();
         order_type_NZDUSD=OrderType();
            if(total_orders_NZDUSD>0)
            {
               if(ctm_ticket_sell_NZDUSD==0)
               {
                  if(order_type_NZDUSD==OP_SELL)
                  {
                  double AskNorm=NormalizeDouble(Ask,Digits);
                  OrderClose(ticket_sell_NZDUSD,0.01,AskNorm,0);
                  }
               }
            }
         }

Basta colocar a contagem de pedidos em primeiro lugar, e depois tudo mais.

Obrigado Artem. Eu lhe devo o graal. Esse é o erro que tem me matado...

 

Como calcular o número de casas decimais?

por exemplo, descobri que o lote mínimo é 0,01.

MarketInfo("EURUSD",MODE_MINLOT)

como posso deduzir que o número de casas decimais é 2?
para normalizar o volume de pedidos com duas casas decimais.

 
multiplicator:

Como calcular o número de casas decimais?

por exemplo, descobri que o lote mínimo é 0,01.

como posso deduzir que o número de casas decimais é 2?
para normalizar o volume de pedidos até duas casas decimais depois.

Experimente este aqui.

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 16.05.2008                                                     |
//|  Описание : Возвращает нормализованное значение торгуемого лота.           |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    lo - нормализуемое значение лота.                                       |
//|    ro - способ округления          (   False    - в меньшую,               |
//|                                        True     - в большую сторону)       |
//|    sy - наименование инструмента   ("" или NULL - текущий символ)          |
//+----------------------------------------------------------------------------+
double NormalizeLot(double lo, bool ro=False, string sy="") {
  double l, k;
  if (sy=="" || sy=="0") sy=Symbol();
  double ls=MarketInfo(sy, MODE_LOTSTEP);
  double ml=MarketInfo(sy, MODE_MINLOT);
  double mx=MarketInfo(sy, MODE_MAXLOT);

  if (ml==0) ml=0.1;
  if (mx==0) mx=100;

  if (ls>0) k=1/ls; else k=1/ml;
  if (ro) l=MathCeil(lo*k)/k; else l=MathFloor(lo*k)/k;

  if (l<ml) l=ml;
  if (l>mx) l=mx;

  return(l);
}
 
Alekseu Fedotov:

Experimente este aqui.

Por que oferecer coisas tão antigas?

multiplicador:

Como calcular o número de casas decimais?

Por exemplo, eu aprendi que o lote mínimo é 0,01.

Como posso descobrir que o número de casas decimais é 2?
Em seguida, normalizar o volume do pedido para duas casas decimais.

Aqui está uma função já feita no artigo.

//+------------------------------------------------------------------+
//|  Проверяет объем ордера на корректность                          |
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume,string &description)
  {
//--- минимально допустимый объем для торговых операций
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(volume<min_volume)
     {
      description=StringFormat("Объем меньше минимально допустимого SYMBOL_VOLUME_MIN=%.2f",min_volume);
      return(false);
     }

//--- максимально допустимый объем для торговых операций
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   if(volume>max_volume)
     {
      description=StringFormat("Объем больше максимально допустимого SYMBOL_VOLUME_MAX=%.2f",max_volume);
      return(false);
     }

//--- получим минимальную градацию объема
   double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
     {
      description=StringFormat("Объем не является кратным минимальной градации SYMBOL_VOLUME_STEP=%.2f, ближайший корректный объем %.2f",
                               volume_step,ratio*volume_step);
      return(false);
     }
   description="Корректное значение объема";
   return(true);
  }

Tudo o que resta é acrescentar uma ação, dependendo do resultado retornado por esta função.

Какие проверки должен пройти торговый робот перед публикацией в Маркете
Какие проверки должен пройти торговый робот перед публикацией в Маркете
  • www.mql5.com
Все продукты Маркета перед публикацией проходят обязательную предварительную проверку, так как небольшая ошибка в логике советника или индикатора может привести к убыткам на торговом счете. Именно поэтому нами разработана серия базовых проверок, призванных обеспечить необходимый уровень качества продуктов Маркета. Если в процессе проверки...
 
Vejo que quando o abro, o terminal normaliza o pedido para o número necessário de casas decimais.
Coloco muito parecido com isto
OrderSend(Symbol(),OP_BUY,1.11111111,Ask,3,0,0);
e o comércio abre com um volume de 1,11.

Então talvez você não precise normalizar nada?
 
multiplicator:
Vejo que o terminal normaliza o pedido para o número de casas decimais exigido quando o abro.
Talvez não haja necessidade de normalizar nada?

Se o editor fizer o mesmo - não há necessidade.

 
multiplicator:
Vejo que o terminal normaliza a ordem para o número de casas decimais necessário quando abre.
Talvez você não precise normalizar nada?

Se você quiser obter erro após erro, não se normalize.

 
Artyom Trishkin:

Se você quiser posteriormente obter erro após erro, não se normalize.

por alguma razão o terminal não apresenta erros)