Inicializar y reinicializar automáticamente el EA desde un archivo

 
Tarea: restaurar el entorno del EA (datos de posición, contadores, etc.) después de la reinicialización, el reinicio en caso de caída del sistema, etc.

Solución: guardamos cada cambio en las variables dinámicas del EA en un archivo. Durante OnInit(), todo este material se carga de nuevo en el archivo.

Sin embargo, el estado anterior de las variables no se puede cargar desde el archivo si:
  • La estructura del archivo ha cambiado (versión diferente, nueva compilación del Asesor Experto). Es elemental comprobarlo, no hay problema.
  • El bot falló la última vez. Digamos que el bot se estrelló en una parada o se colgó o superó el límite de error, entonces podría haber variables en el archivo que causen un error inmediatamente. Esto es en parte muy fácil de comprobar (límite de error a considerar, registro de errores críticos...), pero no es una solución completa.
  • El archivo está demasiado "polvoriento". Supongamos que la última vez que se subió el EA fue hace X días o incluso hoy, pero la información que contiene ya está obsoleta. Cómo comprobarlo - fudge sabe.

Ahora lo he hecho: analizar la causa de OnDeinit(), si el programa se cierra, entonces borro el terminal global (como una bandera de reinicialización).

Cuando no hay esta bandera durante OnInit(), tengo que preguntar al usuario cada vez con la caja de mensajes tontos "¿restaurar variables desde el archivo?".

Esta es una manera increíblemente estúpida e inconveniente.


Pregunta: ¿cómo se puede automatizar totalmente una solución de este tipo?

¿Cómo se puede saber cuándo un archivo no se puede cargar y cuándo se puede descargar?

Al menos, reduzca al mínimo la llamada de este buzón de mensajería.

 

¿MQL4 o MQL5?

Si esMQL5, entonces:

En la comprobación de OnInit():

1. Posición

if ( PositionSelect(_Symbol) )
{
}
else
{
}

2) Pedidos:

(si algo va mal, simplemente borro todos los pedidos sin comprobar de dónde vienen. )

//+------------------------------------------------------------------+
//| Expert Remove orders function                                    |
//+------------------------------------------------------------------+
void RemoveOrders()
{
  int orders_total = OrdersTotal();
//---  
  if ( orders_total > 0 )
  {
    for ( int i = ( orders_total - 1 ); i >= 0; i-- )
    {
      ulong temp_order_ticket = OrderGetTicket( i );
      
      if ( OrderSelect( temp_order_ticket ) )
      {
        string temp_symbol = OrderGetString( ORDER_SYMBOL );
        
        if ( ( temp_symbol == sec_symbol ) || ( temp_symbol == _Symbol ) )
        {
          RemoveOldOrder( temp_order_ticket );
        }
      }
    }
  }
}

3. Variables globales del terminal:

  if ( !GlobalVariableCheck( "trans_count" ) )
  {
    datetime a_time = GlobalVariableSet( "trans_count", 0 );
    
    if ( ulong( a_time ) == 0 )
    {
      MessageBox( "Глобальная переменная терминала 'Счётчик транзакций' не создана!", "Ошибка", MB_OK | MB_ICONHAND );
      return( INIT_FAILED );
    }
  }

4. Variables a guardar

a) Carga:

//+------------------------------------------------------------------+
//| Expert Load setings function                                     |
//+------------------------------------------------------------------+
void LoadSettings()
{
  string file_name = _Symbol + ".dat";
  int file_handle;
//---  
  if ( FileIsExist( file_name, 0 ) )
  {
    file_handle = FileOpen( file_name, FILE_READ|FILE_BIN );
    
    if ( file_handle != INVALID_HANDLE )
    {
      e_high = FileReadLong( file_handle );
      a_profit = FileReadLong( file_handle );
      e_low = FileReadLong( file_handle );
      ord_delta_high = FileReadLong( file_handle );
      ord_delta_low = FileReadLong( file_handle );
      order_delta = FileReadLong( file_handle );
      exit_delta = FileReadLong( file_handle );
      FileClose( file_handle );
    }
  } 
}

b) Guardar ( OnDeInit() )

//+------------------------------------------------------------------+
//| Expert Save settings function                                    |
//+------------------------------------------------------------------+
void SaveSettings()
{
  string file_name = _Symbol + ".dat";
  int file_handle;
  bool file_found = true;
//---  
  if ( FileIsExist( file_name, 0 ) )
  {
    if ( FileDelete( file_name, 0 ) ) file_found = false;
  }
  else
  {
    file_found = false;
  }
//---
  if ( !file_found )
  {
    file_handle = FileOpen( file_name, FILE_WRITE|FILE_BIN );
    
    if ( file_handle != INVALID_HANDLE )
    {
      FileWriteLong( file_handle, e_high );
      FileWriteLong( file_handle, a_profit );
      FileWriteLong( file_handle, e_low );
      FileWriteLong( file_handle, ord_delta_high );
      FileWriteLong( file_handle, ord_delta_low );
      FileWriteLong( file_handle, order_delta );
      FileWriteLong( file_handle, exit_delta );
      FileClose( file_handle );
    }
  } 
}
 
Fry_Антон:
La tarea: restaurar el entorno del EA (datos de posición, contadores, etc.) después de la reinicialización, el reinicio en caso de fallo del sistema, etc.

La contrapregunta es ¿Por qué?

En mi opinión, restaurar el entorno desde un archivo es siempre suicida a largo plazo. Cuando se reinicie, siempre se deben recalcular los datos en base al entorno comercial de MetaTrader.

 
Fry_Антон:
Tarea: Restaurar el entorno del EA (datos de posición, contadores, etc.) después de la reinicialización, el reinicio en caso de fallo del sistema, etc.
Recalculando
 
Vasiliy Sokolov:

La contrapregunta es ¿Por qué?

En mi opinión, restaurar el entorno desde un archivo es siempre suicida a largo plazo. Siempre debe recalcular sus datos basados en el entorno de comercio de MetaTrader cuando se reinicie.

Características del mercado de futuros.

No todo se puede recalcular. Por supuesto que actualizo lo que puedo del entorno, pero... Pues bien, he aquí un ejemplo:

Al liquidar una posición y las órdenes se cierran/abren. El terminal bloquea la operación y borra las órdenes del día (y las órdenes son prohibidas por el corredor hasta que se cancelan). Tengo que crear nuevos pedidos.

Y necesito el precio inicial de apertura de una posición, el tiempo inicial de fijación de una posición y las órdenes.

Por lo tanto, tengo que llevar mi propia contabilidad de dichos parámetros.

También hay contadores de peticiones por segundo/minuto/hora/día, contadores de acciones erróneas no fatales, etc. etc.

¡Con gusto entregaría el archivo! Si fuera real. =(

Hay una situación como esta: el terminal se estrelló (las builds de hoy son estables, y antes era siempre así, y no el hecho de que siempre habrá sólo versiones estables).

Después de la caída del terminal: reinicio rápido y ejecución automática - restauración desde el archivo y todo funciona.

Funciona muy estable, porque siempre guardo el archivo de inicialización en el evento OnTrade() (con un temporizador de un segundo o dos, para no atormentar el disco).


Así que para mí la pregunta es muy relevante: ¿cómo no cargar variables de un archivo que es obsoleto o peligroso para cargar?

 
Михаил:

¿MQL4 o MQL5?

Si esMQL5, entonces:

En la comprobación de OnInit():

1. Posición

2) Pedidos:

(si algo va mal, simplemente borro todos los pedidos sin comprobar de dónde vienen. )

3. Variables globales del terminal:

4. Variables a guardar

a) Carga:

b) Guardar ( OnDeInit() )

Lo hice casi así. Pero guardo el archivo en OnTrade() con un temporizador.

También tengo un montón de signos diferentes y otras variables, y el código está en constante evolución, por lo que era muy incómodo almacenarlos uno por uno.

He creado una estructura básica que contiene todo lo que necesito para el archivo (excepto algunos valores de cadena).

He nombrado la estructura con una letra, por lo que el código es bastante corto (b.volumen es casi como volumen). Y es conveniente guardar toda la estructura de una vez con el operador =.

 
Fry_Антон:

...

Pregunta: ¿cómo se puede automatizar totalmente una solución de este tipo?

...

Un enfoque fundamentalmente diferente de la programación de EA.

 
Dmitry Fedoseev:

Un enfoque fundamentalmente diferente de la programación de EA.

Amplíe la respuesta a un pensamiento útil razonable y se lo agradeceré.

¿Cuáles son los principios básicos que hacen que el código de EA sea "mejor"?

 
Fry_Антон:

Amplíe la respuesta a un pensamiento útil razonable y se lo agradeceré.

¿Cuáles son los principios básicos que hacen que el código EA sea "mejor"?

Ya se ha escrito aquí - volver a calcular todo. Es decir, analizar la situación con órdenes. El hecho de que algunos datos se almacenen en archivos, o de alguna otra manera (tal vez en variables globales), no tiene una importancia fundamental. El punto principal es que si se necesitan algunos datos, se almacenan en entradas vinculantes para el orden, y en este caso no hay problema con los datos obsoletos - tenemos orden - tenemos datos, sin orden - no tenemos datos. Puede haber datos que no estén ligados a un orden concreto, pero hay que pensar en cada caso y es un problema solucionable.

El despeje es realmente el problema más complicado. Pero no es un problema de almacenamiento de datos a largo plazo (o de su obsolescencia), podemos almacenar los datos en simples variables en el Asesor Experto (un poco arriesgado, pero sólo durante 5 minutos). La dificultad estriba en cómo afrontarlo después. Podemos crear un grupo de variables terminales globales para cada orden y almacenar en ellas el precio de apertura. Luego, cuando aparecen las órdenes no marcadas (o en la apertura de un nuevo día) vemos las últimas órdenes cerradas en el historial, las emparejamos según las características que se pueden utilizar (por ejemplo, el lote), y reseteamos todas las variables globales de la orden cerrada a la nueva orden.

 

¡Anton!

Te estás poniendo demasiado "nervioso" con este problema.

Está claro que quieres restaurar adecuadamente el trabajo del experto después de la emergencia

situación. Yo también me devané los sesos al principio.

Pero luego decidió que tales situaciones son extremadamente raras

(por mi propia experiencia de comercio real semestral de MT5), así que decidí que no valdría la pena

para "molestar" con los pedidos realizados y simplemente "clavar" todo lo que existe después de la caída.

Las órdenes se han hecho antes de la caída, si se han ejecutado entonces no se puede hacer nada, y si

Si todavía están "colgados", entonces matarlos y reajustarlos de acuerdo con la situación comercial, ¡no perderás nada!

Entonces lo único que queda es la posición, si está o no está.

En cuanto a la escritura/lectura de variables desde un archivo.

Tengo cambio "en caliente" (durante el trabajo) de variables en mis EAs, por lo que

Los escribo y leo de un archivo para que el Asesor Experto tome la configuración "caliente" en un nuevo inicio.

El problema que te estás creando tú mismo.

Piénsalo.

¡P/S MT5 no es MT4 donde las órdenes son muy importantes!

En MT5 hay que guiarse por la POSICIÓN, no por las órdenes.

 
Fry_Антон:

Amplíe la respuesta a un pensamiento útil razonable y se lo agradeceré.

¿Cuáles son los principios básicos que hacen que el código EA sea "mejor"?

Contestado en privado.

Z.I. Sus ejemplos no son válidos. No existen esos problemas en Forts. Por supuesto, puedes inventarte cualquier problema y luego tratar de resolverlo durante mucho tiempo. Pero, ¿por qué resolverlo cuando es más fácil no inventarlo?