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

 
Roman Sharanov:
¿Podríais indicar si la función de cerrar todas las órdenes abiertas por el EA por el símbolo está implementada correctamente?

La arquitectura en sí es correcta. Los errores están en la falta de controles y en el uso de algunas funciones:

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. La primera iteración en su caso fallará - el pedido con índice OrdersTotal() no existe.
  2. No se comprueba el resultado de la función OrderSelect.
  3. No se comprueba el resultado de la función OrderClose. Si el cierre de la orden falla, no podemos quedarnos en la misma función, ya que tenemos que averiguar por qué el cierre no tuvo éxito. Para ello, tenemos que dejar la función con el resultado falso, y luego decidir qué hacer a continuación.
  4. No podemos utilizar un mismo precio de cierre para todas las órdenes. En primer lugar, las órdenes pueden ser de diferentes tipos y, en segundo lugar, es probable que el precio haya cambiado durante la ejecución de las órdenes anteriores (al cierre). Podemos utilizar una característica de MT4 para evitar adivinar qué precio utilizar: el valor de OrderClosePrice() de una orden de mercado antes de su cierre es el precio Bid o Ask dependiendo del tipo de orden.
 
Ihor Herasko:

La arquitectura en sí es correcta. Los errores están en la falta de controles y en el uso de algunas funciones:

  1. La primera iteración en su caso fallará - el pedido con el índice OrdersTotal() no existe.
  2. No se comprueba el resultado de la función OrderSelect.
  3. No se comprueba el resultado de la función OrderClose. Si el cierre de la orden falla, no podemos quedarnos en la misma función, ya que tenemos que averiguar por qué el cierre no tuvo éxito. Para ello, tenemos que dejar la función con el resultado falso, y luego decidir qué hacer a continuación.
  4. No podemos utilizar un mismo precio de cierre para todas las órdenes. En primer lugar, las órdenes pueden ser de diferentes tipos y, en segundo lugar, es probable que el precio haya cambiado durante la ejecución de las órdenes anteriores (al cierre). Para evitar adivinar qué precio utilizar, podemos utilizar una característica de MT4: el valor de OrderClosePrice() de una orden de mercado antes de su cierre es el precio Bid o Ask dependiendo del tipo de orden.

Gracias, el principal problema fue probablemente usar el mismo precio

 

De la ayuda de OrderSelect " Cuando las órdenes se seleccionan secuencialmente usando el parámetro SELECT_BY_POS, la información se da en el orden en que vino del servidor de comercio. No se garantiza la ordenación de la lista de pedidos obtenida".

Si pensamos que esta frase fue insertada en la ayuda para nada, estamos bien. Si pensamos que estaba ahí por alguna razón, no debemos cambiar esta lista durante el recorrido del bucle por la lista de pedidos. Se desconoce cómo se ordenarán los pedidos tras la eliminación de uno de ellos en el servidor y la llegada de una nueva lista actual con un OrdersTotal menor. Es más fiable, sin borrar, recorrer la misma copia inalterada de la lista y recoger (en un array) todos los números de ticket de las operaciones a borrar. Entonces, olvídate de esa lista y elimina las operaciones, seleccionándolas por ticket.

Uno querría creer, por supuesto, que la ordenación en la lista modificable se conserva, aunque sólo sea para este caso de eliminar varios órdenes del final de una lista desordenada, pero los desarrolladores están en contra... Ahora funciona, y si sale una nueva construcción - "avisamos".

 
Vladimir:

De la ayuda de OrderSelect " Cuando las órdenes se seleccionan secuencialmente usando el parámetro SELECT_BY_POS, la información se da en el orden en que vino del servidor de comercio. No se garantiza la ordenación de la lista de pedidos obtenida".

Si pensamos que esta frase fue insertada en la ayuda para nada, estamos bien. Si pensamos que estaba ahí por alguna razón, no deberíamos cambiar esta lista durante el recorrido del bucle por la lista de pedidos. Se desconoce cómo se ordenarán los pedidos tras la eliminación de uno de ellos en el servidor y la llegada de una nueva lista actual con un OrdersTotal menor. Es más fiable, sin borrar, recorrer la misma copia inalterada de la lista y recoger (en un array) todos los números de ticket de las operaciones a borrar. Entonces, olvídate de esa lista y elimina las operaciones, seleccionándolas por ticket.

Uno querría creer, por supuesto, que la ordenación en la lista modificable se conserva, aunque sólo sea para este caso de eliminar varios órdenes del final de una lista desordenada, pero los desarrolladores están en contra... Ahora funciona, y si sale una nueva construcción - "avisamos".

Esta "América" lleva abierta unos trescientos años :)

 
Artyom Trishkin:

Este tipo de "América" ha estado abierto como trescientos años :)

No creo que las personas que preguntan aquí en nombre de los recién llegados ya lo hayan descubierto ellos mismos. Por eso lo escribo. No para los moderadores, sino para los que preguntan. Mira el nombre del hilo.

P.D. He buscado el origen de este interés. Resulta que es de la rama https://www.mql5.com/ru/forum/215783/page8"Organizar el ciclo de pedidos". Resulta que, en octubre de 2017, esos trescientos años aún no han terminado, todavía hay novedad.

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

No creo que las personas que preguntan aquí en nombre de los recién llegados ya lo hayan descubierto ellos mismos. Por eso lo escribo. No para los moderadores, sino para los que preguntan. Mira el nombre del hilo.

P.D. He mirado de dónde viene este interés. Resulta que es de la rama https://www.mql5.com/ru/forum/215783/page8"Organizar el ciclo de pedidos". Resulta que en octubre de 2017 esos trescientos años aún no han terminado, aún hay novedad.

Otra vez te equivocas :) Trescientos años comenzó en mql4.com - hubo un tiempo en que se discutió activamente allí. E incluso hubo esos momentos que describes en "Ahora funciona, y saldrá una nueva construcción - "avisamos". Sólo sin avisar, y así varias veces - depende, no depende de la clasificación...

Y, sí, hay un hilo especial para estas respuestas:

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

De la ayuda de OrderSelect " Cuando las órdenes se seleccionan secuencialmente usando el parámetro SELECT_BY_POS, la información se da en el orden en que vino del servidor de comercio. No se garantiza la ordenación de la lista de pedidos obtenida".

Si pensamos que esta frase fue insertada en la ayuda para nada, estamos bien. Si pensamos que estaba ahí por alguna razón, no debemos cambiar esta lista durante el recorrido del bucle por la lista de pedidos. Se desconoce cómo se ordenarán los pedidos tras la eliminación de uno de ellos en el servidor y la llegada de una nueva lista actual con un OrdersTotal menor. Es más fiable, sin borrar, recorrer la misma copia inalterada de la lista y recoger (en un array) todos los números de ticket de las operaciones a borrar. Luego, olvídate de esa lista y elimina las operaciones, seleccionándolas por ticket.

Me gustaría, por supuesto, creer que el orden en la lista modificada se conserva al menos para este caso de borrar varios órdenes del final de una lista desordenada, pero los desarrolladores están en contra... Ahora funciona, y si sale una nueva compilación, "te avisamos".

Como buena idea (teniendo en cuenta que puede haber varios Asesores Expertos + trader trabajando en la cuenta en paralelo), no se pueden realizar operaciones en bucle en absoluto. Se recibe la orden necesaria, se ejecuta la operación, se vuelve a ejecutar todo OnTick() (no necesariamente con llegada de un nuevo tick). Y así sucesivamente, hasta que se ejecuten todas las operaciones necesarias.

Por lo tanto, formar un array para borrar órdenes es equivalente a borrar órdenes en el bucle.

 

Hay un botón "Stop", ¿cómo puedo cambiar su texto a "Start" una vez pulsado?

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: Hay un botón "Stop", ¿cómo puedo cambiar su texto a "Start" una vez pulsado?

Vea mi ejemplo de experto

Archivos adjuntos:
ToFile.mq4  11 kb
 
STARIJ:

Mira mi ejemplo de Asesor Experto

Gracias, justo lo que necesitaba.

Podría ser útil saber, que hay un error en las posiciones que faltan--- ToFile EURUSD,H1: cero dividir en 'ToFile.mq4' (62,39)

/*62*/  Строка=DoubleToStr(AccountEquity()/AccountMargin()*100,2)+"%"; // Уровень=Средства/Залог
El texto no cambia en el probador, no hay tal opción?
Razón de la queja: