Initialiser et réinitialiser automatiquement l'EA à partir d'un fichier

 
Tâche : restaurer l'environnement de l'EA (données de position, compteurs, etc.) après une réinitialisation, un redémarrage en cas de panne du système, etc.

Solution : nous sauvegardons dans un fichier chaque modification des variables dynamiques de l'EA. Pendant OnInit(), tous ces éléments sont rechargés dans le fichier.

Cependant, l'état passé des variables ne peut pas être chargé à partir du fichier si :
  • La structure du fichier a changé (version différente, nouvelle construction du conseiller expert). C'est élémentaire à vérifier, pas de problème.
  • La dernière fois que le robot a eu un pépin. Disons qu'il s'est écrasé lors d'un arrêt, qu'il s'est bloqué ou qu'il a dépassé la limite d'erreur, alors il pourrait y avoir des variables dans le fichier qui provoquent immédiatement une erreur. Ceci est en partie très facile à vérifier (limite d'erreur à considérer, enregistrement d'erreur critique...), mais ce n'est pas une solution complète.
  • Le dossier est juste trop "poussiéreux". Supposons que la dernière évaluation environnementale a été téléchargée il y a X jours ou même aujourd'hui, mais que les informations qu'elle contient sont déjà périmées. Comment le vérifier - le caramel le sait.

Maintenant je l'ai fait : analyser la cause de OnDeinit(), si le programme se ferme, alors je supprime le terminal global (comme un drapeau de réinitialisation).

Lorsqu'il n'y a pas ce drapeau pendant OnInit(), je dois demander à l'utilisateur à chaque fois avec une boîte de messagerie muette "restaurer les variables à partir du fichier ?".

C'est un moyen incroyablement stupide et peu pratique !


Question : comment automatiser complètement une telle solution ?

Comment savoir quand un fichier ne peut pas être téléchargé et quand il peut l'être ?

Réduisez au moins l'appel de cette boîte de messagerie au minimum.

 

MQL4 ou MQL5 ?

SiMQL5, alors :

Dans le contrôle OnInit() :

1. Position

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

2) Les commandes :

(si quelque chose ne va pas, je supprime simplement toutes les commandes sans vérifier d'où elles proviennent. )

//+------------------------------------------------------------------+
//| 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 du 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 à sauvegarder

a) Chargement :

//+------------------------------------------------------------------+
//| 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) Sauvegarde ( 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 tâche : restaurer l'environnement de l'EA (données de position, compteurs, etc.) après une réinitialisation, un redémarrage en cas de panne du système, etc.

La contre question est "Pourquoi ?

A mon avis, restaurer l'environnement à partir d'un fichier est toujours suicidaire à long terme. Lors du redémarrage, vous devez toujours recalculer vos données en fonction de l'environnement de trading MetaTrader.

 
Fry_Антон:
Tâche : Restaurer l'environnement EA (données de position, compteurs, etc.) après une réinitialisation, un redémarrage en cas de panne du système, etc.
Recalculer
 
Vasiliy Sokolov:

La contre question est "Pourquoi ?

A mon avis, restaurer l'environnement à partir d'un fichier est toujours suicidaire à long terme. Vous devez toujours recalculer vos données sur la base de l'environnement de trading MetaTrader lors du redémarrage.

Caractéristiques du marché à terme.

Tout ne peut pas être recalculé. Bien sûr, je mets à jour ce que je peux de l'environnement, mais... Eh bien, voici un exemple :

Lors de la liquidation d'une position, les ordres sont fermés/ouverts. Le terminal verrouille la transaction et supprime les ordres pour la journée (et les ordres sont interdits par le courtier jusqu'à leur annulation). Je dois créer de nouvelles commandes.

Et j'ai besoin du prix initial d'ouverture d'une position, du temps initial d'établissement d'une position et des ordres.

Je dois donc tenir ma propre comptabilité de ces paramètres.

Il existe également des compteurs de demandes par seconde/minute/heure/jour, des compteurs d'actions erronées non fatales, etc. etc.

J'abandonnerais volontiers le dossier ! Si c'était réel. =(

Il y a une situation comme celle-ci : le terminal a planté (les builds d'aujourd'hui sont stables, et avant c'était toujours comme ça, et non le fait qu'il n'y aura toujours que des versions stables).

Après le crash du terminal : redémarrage rapide et autorun - restauration à partir du fichier et tout fonctionne.

Fonctionne de manière très stable, car je sauvegarde toujours le fichier d'initialisation dans l'événement OnTrade() (avec un timer d'une seconde ou deux, pour ne pas tourmenter le disque).


La question est donc pour moi très pertinente : comment ne pas charger les variables d'un fichier obsolète ou dangereux à charger ?

 
Михаил:

MQL4 ou MQL5 ?

Si c'estMQL5, alors :

Dans le contrôle OnInit() :

1. Position

2) Les commandes :

(si quelque chose ne va pas, je supprime simplement toutes les commandes sans vérifier d'où elles proviennent. )

3. Variables globales du terminal :

4. Variables à sauvegarder

a) Chargement :

b) Sauvegarde ( OnDeInit() )

Je l'ai fait presque comme ça. Mais j'enregistre le fichier à OnTrade() avec un timer.

J'ai aussi un tas de signes différents et d'autres variables, et le code est en constante évolution, il était donc très peu pratique de les stocker un par un.

J'ai créé une structure de base qui contient tout ce dont j'ai besoin pour le fichier (sauf quelques valeurs de chaîne).

Je l'ai nommé avec une seule lettre, donc le code est assez court (b.volume est presque comme volume). Et il est pratique de sauvegarder toute la structure en une seule fois avec l'opérateur =.

 
Fry_Антон:

...

Question : comment automatiser complètement une telle solution ?

...

Une approche fondamentalement différente de la programmation de l'EA.

 
Dmitry Fedoseev:

Une approche fondamentalement différente de la programmation de l'EA.

Développez la réponse à une pensée utile raisonnable et je vous en serai reconnaissant.

Quels sont les principes de base qui rendent le code de l'EA "meilleur" ?

 
Fry_Антон:

Développez la réponse à une pensée utile raisonnable et je l'apprécierais.

Quels sont les principes de base qui rendent le code de l'EA "meilleur" ?

Cela a déjà été écrit ici - recalculez tout à nouveau. C'est-à-dire analyser la situation avec des ordres. Le fait que certaines données soient stockées dans des fichiers, ou d'une autre manière (peut-être dans des variables globales), n'a pas d'importance fondamentale. L'essentiel est que si certaines données sont nécessaires, elles sont stockées dans des billets de commande contraignants, et dans ce cas il n'y a pas de problème de données périmées - nous avons la commande - nous avons les données, pas de commande - nous n'avons pas de données. Il peut y avoir des données qui ne sont pas liées à une commande spécifique, mais nous devons réfléchir à chaque cas et c'est un problème soluble.

Le défrichage est vraiment le problème le plus compliqué. Mais ce n'est pas un problème de stockage de données à long terme (ou de leur obsolescence), nous pouvons stocker des données dans des variables simples dans le conseiller expert (un peu risqué, mais seulement pour 5 minutes). La difficulté ici est de savoir comment y faire face plus tard. Nous pouvons créer un groupe de variables globales terminales pour chaque ordre et y stocker le prix d'ouverture. Ensuite, lorsque les ordres non marqués apparaissent (ou à l'ouverture d'une nouvelle journée), nous regardons les derniers ordres fermés dans l'historique, nous les faisons correspondre en fonction des caractéristiques qui peuvent être utilisées (par exemple, le lot), et nous réinitialisons toutes les variables globales de l'ordre fermé au nouvel ordre.

 

Anton !

Tu te prends trop la tête avec ce problème.

Il est clair que vous voulez restaurer correctement le travail de l'expert après l'urgence.

situation. Moi aussi, au début, je me suis creusé la tête.

Mais il a ensuite décidé que de telles situations sont extrêmement rares

(d'après ma propre expérience de transactions réelles MT5 semestrielles), j'ai donc décidé que cela ne valait pas la peine

de "s'embêter" avec les commandes passées et de "clouer" tout ce qui existe après l'automne.

Des ordres ont été passés avant la chute, s'ils ont été exécutés alors rien ne peut être fait, et si

S'ils " traînent " encore, il suffit de les tuer et de les réajuster en fonction de la situation commerciale pour ne rien perdre !

Il ne reste alors que la position - qu'elle soit là ou non.

Quant à l'écriture/lecture de variables à partir d'un fichier.

J'ai un changement de variables "à chaud" (pendant le travail) dans mes EA, donc je

Je les écris et les lis à partir d'un fichier afin que le conseiller expert prenne les paramètres "chauds" lors d'un nouveau départ.

Le problème que VOUS vous créez!

Pensez-y !

P/S MT5 n'est pas MT4 où les ordres sont très importants !

Dans MT5, vous devez être guidé par la POSITION, et non par les ordres.

 
Fry_Антон:

Développez la réponse à une pensée utile raisonnable et je l'apprécierais.

Quels sont les principes de base qui rendent le code de l'EA "meilleur" ?

Répondu en privé.

Z.I. Vos exemples ne sont pas valables. Il n'y a pas de tels problèmes sur les Forts. Bien sûr, vous pouvez inventer n'importe quel problème et essayer de le résoudre pendant longtemps. Mais pourquoi le résoudre quand il est plus facile de ne pas l'inventer ?

Raison: