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

 
Vitaly Gorbunov:

El hecho de que haya identificado en algún lugar el número de pedidos que necesita es bueno, pero en este bloque vuelve a repasar todos los pedidos y los comprueba.

Desglosa bien el código y verás enseguida.

Por supuesto, puedes volver a calcularlo. Pero no hace la diferencia. El operador if() no realiza "de otro modo". Éste es sólo un caso, y había otros.
 
for(int h = OrdersTotal()-1; h >= 0; h--)
    {
     if(OrderSelect(h, SELECT_BY_POS))
      {
       if((cnt_OO >= 2))
        {
       if((OrderMagicNumber() == Magic)&&(OrderLots() <= Lots/Prikup - Dplus))
        {
         Nextstep  = NextStep;
         BaseNext  = OrderOpenPrice();
         LotsNext  = NormalizeDouble(OrderLots()*K,lotDigit);
         if(NewPB > 0)
          PBcloseON = true;
         Alert ("Pospedny Order NEXT  ",OrderTicket());
         Alert ("Otkritih orderov  ",cnt_OO);
//         break;
        }
       break;
       }
         LotsNext    = NormalizeDouble(Lots*Prikup,lotDigit); 
         Alert ("Otkritih orderov NEXT net ");
        Alert ("Otkritih orderov  ",cnt_OO);
         break;
     
        }}

Pruébalo así.

No veo nada más en su código.

Tira otros casos, a ver qué pasa ahí :)

Después de un cuidadoso estudio de la lógica, hice ingeniería inversa de su código.

Resultó algo así

if(cnt_OO>0) //Если нет ордеров то и не надо ни чего делать
{
  for(int h = OrdersTotal()-1; h >= 0; h--)
   {
    if(OrderSelect(h, SELECT_BY_POS))
     {
      if(cnt_OO==1)
         {
          //Если ордер один проверяем тот ли ордер (майджик и прочее) и что то там делаем
         }
      else
         {
          //Если ордеров больше чем 1 проверяем те ли ордера (майджик и прочее) и что то там делаем
         }
     }
   }
   
}
 

Podemos hacerlo así. Pero el tutorial dice que si la condición no se cumple, se procesan los comandos después de la llave que cierra el bloque para procesar la condición del operador if(). Esto no sucede.

Hubo un fallo más:

     if((OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))&&(OrderMagicNumber() == Magic)&&(OrderLotsOld==zLots))
      {
       

Si añadía una condición más al primer operador if -el siguiente- no funcionaba

Tengo dos sugerencias

1. Estúpido probador de estrategias. Como estas situaciones se producen en la fase de depuración del programa, hay que ser un completo idiota para comprobarlo en una cuenta real. Y en una cuenta demo, también, porque es difícil reproducir la situación de reinicio. El hecho de que el probador sea un idiota nos dice que el orden de cierre de varias órdenes en la ventana de MT4 a menudo no se corresponde con el real si el cierre se produce a la vez. Esto puede verse claramente si se recalculan los últimos pedidos en el programa. Este error me hizo pasar una semana intentando averiguar quién estaba loco.

La propia lógica del funcionamiento del probador, incluso en el historial de ticks, está lejos de la vida real. Es muy crítico para mi algoritmo.

2. Como una suposición. Una pregunta a los gurús especialmente avanzados no sólo en MQL/MT4, sino también a los especialistas en sistemas.

- Tengo dos EAs idénticos en el mismo par en diferentes ventanas. Cuando ejecuto los EAs, por ejemplo, el lunes después de que el ordenador esté apagado durante el fin de semana, ambos empiezan a funcionar al mismo tiempo cuando aparece el primer tick. Esperaba que uno trabajara primero para restaurar el estado y luego el otro. Quien tenía suerte, trabajaba primero.

De hecho, los mensajes de recuperación de datos están mezclados. En otras palabras, la ejecución del programa se interrumpe por alguna condición, por ejemplo el temporizador del sistema y luego continúa. Se producen situaciones interesantes cuando, por ejemplo, se cambia a otra cuenta para comprobar cómo va. Las condiciones para comprobar la cuenta están al principio del programa y en el momento de volver a la cuenta inicial, el programa está en el medio y le importa una mierda la cuenta que haya ahora.

He encontrado una solución: al principio de cada bloque compruebo el número de cuenta. No estoy seguro de dónde se supone que está.

 

Amon1953 ¿miraste la primera versión que arreglé? ¿Funciona? Exactamente como está escrito en el manual de if() y funciona durante muchos años de uso. El problema es que en tu código has puesto un break en un bloque equivocado.

if((OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))&&(OrderMagicNumber() == Magic)&&(OrderLotsOld==zLots)) debe comprobar qué se asigna a las variables.

Sobre el segundo punto - ambos búhos se ejecutarán en paralelo, por lo que los mensajes de los mismos se mezclarán. Para hacer lo que describes necesitas organizar el semáforo entre las copias del búho. Y es muy interesante que ocurra algo raro cuando se cambia la cuenta. Me gustaría mucho ver OnInit y OnDeinit. Lo más probable es que el problema esté ahí.

 
Vitaly Gorbunov:

Amon1953 ¿miraste la primera versión que arreglé? ¿Funciona? Exactamente como está escrito en el manual de if() y funciona durante muchos años de uso. El problema es que en tu código has puesto un break en un bloque equivocado.

if((OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))&&(OrderMagicNumber() == Magic)&&(OrderLotsOld==zLots)) debe comprobar qué se asigna a las variables.

En cuanto al segundo punto, ambos búhos se ejecutarán en paralelo, por lo que los mensajes de los mismos se mezclarán. Para poder hacer lo que describes necesitas implementar el semáforo entre las copias del búho. Y es muy interesante que ocurra algo raro cuando cambio la cuenta. Me gustaría mucho ver OnInit y OnDeinit. Lo más probable es que el problema esté ahí.

No lo he comprobado porque necesitamos salir del bucle por la última orden (es la primera de la lista).

No soy un programador experimentado y no entiendo bien el funcionamiento de OnInit y OnDeinit. Por eso no se utilizan en mi código, pero parece que permiten que el programa se ejecute sin interrupción en el medio.

Yo también no entiendo el semáforo, los asesores se instalan en diferentes ventanas y tienen diferentes mayores

 
Mi consejo, si hace poco que has empezado a programar, es que vuelvas a estudiar los fundamentos básicos de la programación. No te ofendas, pero es muy difícil comunicarse contigo.
 
Vitaly Gorbunov:
Mi consejo, si hace poco que has empezado a programar, es que vuelvas a estudiar los fundamentos básicos de la programación. No te ofendas, pero es muy difícil comunicarse contigo.
Gracias. Esta sección es para principiantes. Incluso este tipo de comunicación me ha beneficiado. Es difícil hacer tanto el algoritmo EA como escribir el código del programa (además, el lenguaje de programación es bastante nuevo para mí)
 
Amon1953:
Gracias. Esta es una sección para principiantes. Incluso este tipo de comunicación me ha beneficiado. Es difícil hacer tanto el algoritmo de EA como el código del programa (especialmente porque el lenguaje de programación es bastante nuevo para mí)
¡Parece que tienes que mejorar lo básico! Como no entiendo muy bien por tu código qué tipo de lógica quieres implementar, intenta explicar con palabras lo que quieres hacer. Y voy a tratar de explicar dónde tienes un error.
 
Vitaly Gorbunov:
¡Parece que tienes que apretar la base! Como no entiendo muy bien por tu código qué lógica quieres implementar, intenta explicar con palabras lo que quieres hacer. Y voy a tratar de explicar dónde tienes un error.

Ya he explicado antes lo que necesito. Intentaré aclarar los detalles.

Cuando se reinicia el EA, es necesario restaurar el estado anterior, porque el algoritmo es una cadena de órdenes. El primer orden es el básico, y a partir de él podemos calcular los parámetros de los siguientes órdenes de la cadena. Por ejemplo, el volumen del segundo orden es el 50% de la base, el tercero el 75%, y así sucesivamente. Al reiniciar un EA, necesitamos conocer el volumen de la línea base y de la última orden, ya que el volumen de la siguiente orden se calculará a partir de la última. Por ejemplo, hay 3 órdenes abiertas. Para calcular la siguiente (cuarta) orden, necesitamos encontrar el volumen de la última orden abierta.

Si sólo hay una orden, significa que es la base y en este caso, no nos interesa, la maneja otra unidad.

El algoritmo es muy sencillo. Pero sólo funciona con dos operadores if().

 
Amon1953:

Ya he explicado antes lo que necesito. Intentaré aclarar los detalles.

Cuando se reinicia el EA, es necesario restaurar el estado anterior, porque el algoritmo es una cadena de órdenes. El primer orden es el básico, y a partir de él podemos calcular los parámetros de los siguientes órdenes de la cadena. Por ejemplo, el volumen del segundo orden es el 50% de la base, el tercero el 75%, y así sucesivamente. Al reiniciar un EA, necesitamos conocer el volumen de la línea base y de la última orden, ya que el volumen de la siguiente orden se calculará a partir de la última. Por ejemplo, hay 3 órdenes abiertas. Para calcular la siguiente (cuarta) orden, necesitamos encontrar el volumen de la última orden abierta.

Si sólo hay una orden, significa que es la base y en este caso, no nos interesa, la maneja otra unidad.

El algoritmo es muy sencillo. Pero sólo funciona con dos operadores if().

Amon1953:

No lo he comprobado porque necesitamos salir del bucle por la última orden (es la primera de la lista).

No soy un programador experimentado y no entiendo bien el funcionamiento de OnInit y OnDeinit. Por eso no se utilizan en mi código, pero parece que permiten que el programa se ejecute sin interrupción en el medio.

Sobre el semáforo, tampoco está claro. Los Asesores Expertos están instalados en diferentes ventanas y tienen diferentes mayores.

Por favor, lea la documentación:

OnInit

La función OnInit() es el manejador del evento Init . Puede ser de tipovoid o int, no tiene parámetros:

voidOnInit();

Los eventos Init se generan inmediatamente después de cargar un Asesor Experto o un indicador. La función OnInit() se utiliza para la inicialización. Si OnInit() tiene el valor de retorno int, el código de retorno distinto de cero significa que la inicialización no ha tenido éxito, y genera el evento Deinit con el código de razón de desinicializaciónREASON_INITFAILED.

También hay que resolver la visibilidad de las variables.

События клиентского терминала - Программы MQL4 - Справочник MQL4
События клиентского терминала - Программы MQL4 - Справочник MQL4
  • docs.mql4.com
Сразу же после того, как клиентский терминал загрузит программу (эксперт или пользовательский индикатор) и запустит процесс инициализации глобальных переменных, будет послано событие Init, которое обрабатывается функцией OnInit(), если она есть. Это событие также генерируется после смены финансового инструмента и/или периода графика, после...