Cualquier pregunta de los recién llegados sobre MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos - página 704

 
Alexander_K2:

Sin embargo, hay algo realmente malo...

Es decir, hago OrderSelect una vez y luego otra vez desde la función... Eso es un infierno...

  1. Ha seleccionado un pedido en un billete
  2. Se pasa a la función que comprueba el número de pedidos. Si hay más de un pedido, todos los pedidos disponibles se seleccionan uno a uno en el ciclo
  3. Cuando regrese de la función, la orden seleccionada será la última de la lista de órdenes en el terminal del cliente (no será necesariamente la orden que seleccionó en el punto 1).
  4. Entonces se comprueba la hora de cierre de una nueva orden, y se intenta cerrar la que supuestamente estaba seleccionada por el ticket, pero su selección ya se ha perdido.

Simple lógica...

Observa la secuencia de operaciones que estás realizando.

Evidentemente, primero hay que comprobar la cantidad, luego seleccionar el pedido deseado y, a continuación, realizar las operaciones necesarias en él.

 
Maxim Kuznetsov:

¿en qué dirección se ve el conjunto de órdenes?

si hay posibles cierres/supresiones durante la "revisión", es mejor mirar en dirección contraria. Desde OrdersTotal()-1 hasta 0 inclusive.

De lo contrario, podría tener problemas :-)


Una vez casi descubrí mi grial personal de esta manera :-)

Y la retirada de pedidos antiguos de las "profundidades del tiempo" hasta el presente (de vez en cuando, no todos) elevó la rentabilidad del probador a los cielos :-)

 
Artyom Trishkin:
  1. Ha seleccionado un pedido en un billete
  2. Ha entrado en la función para comprobar el número de pedidos. Si hay más de un pedido, todos los pedidos disponibles se seleccionarán uno a uno para ser contabilizados en el ciclo
  3. Al volver de la función, la orden seleccionada será la última de la lista de órdenes en el terminal del cliente (no tiene que ser necesariamente la orden que seleccionó en el punto 1).
  4. Entonces se comprueba la hora de cierre de una nueva orden, y se intenta cerrar la que supuestamente estaba seleccionada por el ticket, pero su selección ya se ha perdido.

Simple lógica...

Observa la secuencia de operaciones que estás realizando.

Es obvio que primero hay que comprobar la cantidad, luego seleccionar el pedido correcto y después realizar las operaciones necesarias sobre él

Yo lo he hecho así:

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);
                  }
               }
            }
         }

Sólo hay que poner primero el recuento del orden y luego todo lo demás.

Gracias Artem. Le debo el grial. Fue este error el que me estaba matando...

 

¿Cómo se calcula el número de decimales?

Por ejemplo, he descubierto que el lote mínimo es de 0,01.

MarketInfo("EURUSD",MODE_MINLOT)

¿cómo deduzco que el número de decimales es 2?
para normalizar el volumen de pedidos con dos decimales.

 
multiplicator:

¿Cómo se calcula el número de decimales?

Por ejemplo, he descubierto que el lote mínimo es de 0,01.

¿cómo deduzco que el número de decimales es 2?
para normalizar posteriormente el volumen de pedidos a dos decimales.

Prueba con este.

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. 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:

Prueba con este.

¿Por qué ofrecer cosas tan antiguas?

multiplicador:

¿Cómo calcular el número de decimales?

Por ejemplo, he aprendido que el lote mínimo es de 0,01.

¿Cómo puedo saber que el número de decimales es 2?
A continuación, normalice el volumen de pedidos con dos decimales.

Aquí hay una función preparada en el artículo.

//+------------------------------------------------------------------+
//|  Проверяет объем ордера на корректность                          |
//+------------------------------------------------------------------+
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);
  }

Sólo queda añadir una acción en función del resultado devuelto por esta función.

Какие проверки должен пройти торговый робот перед публикацией в Маркете
Какие проверки должен пройти торговый робот перед публикацией в Маркете
  • www.mql5.com
Все продукты Маркета перед публикацией проходят обязательную предварительную проверку, так как небольшая ошибка в логике советника или индикатора может привести к убыткам на торговом счете. Именно поэтому нами разработана серия базовых проверок, призванных обеспечить необходимый уровень качества продуктов Маркета. Если в процессе проверки...
 
Veo que cuando lo abro, el terminal normaliza la orden al número de decimales requerido.
Puse un montón así
OrderSend(Symbol(),OP_BUY,1.11111111,Ask,3,0,0);
y la operación se abre con un volumen de 1,11.

Entonces, ¿quizás no sea necesario normalizar nada?
 
multiplicator:
Veo que el terminal normaliza la orden al número de decimales requerido cuando lo abro.
¿Tal vez no sea necesario normalizar nada?

Si el editor hace lo mismo, no es necesario.

 
multiplicator:
Veo que el terminal normaliza la orden al número de decimales requerido cuando se abre.
¿Tal vez no sea necesario normalizar nada?

Si quieres obtener error tras error, no normalices.

 
Artyom Trishkin:

Si quieres obtener posteriormente un error tras otro, no normalices.

por alguna razón el terminal no muestra errores)
Razón de la queja: