Automatisches Initialisieren und Reinitialisieren des EA aus einer Datei

 
Aufgabe: Wiederherstellung der EA-Umgebung (Positionsdaten, Zähler usw.) nach einer Neuinitialisierung, einem Neustart im Falle eines Systemabsturzes usw.

Lösung: Wir speichern jede Änderung in den dynamischen Variablen des EA in einer Datei. Während OnInit() werden all diese Daten wieder in die Datei geladen.

Der frühere Zustand der Variablen kann jedoch nicht aus der Datei geladen werden, wenn:
  • Die Dateistruktur hat sich geändert (andere Version, neues Build des Expert Advisors). Es ist elementar, das zu überprüfen, kein Problem.
  • Beim letzten Mal hat der Bot versagt. Angenommen, das Programm stürzt bei einer Unterbrechung ab oder bleibt hängen oder überschreitet die Fehlergrenze, dann könnte es Variablen in der Datei geben, die sofort einen Fehler verursachen. Dies ist zum Teil sehr einfach zu überprüfen (zu berücksichtigende Fehlergrenze, kritischer Fehlersatz...), aber keine vollständige Lösung.
  • Die Datei ist einfach zu "verstaubt". Angenommen, der letzte EA wurde vor X Tagen oder sogar heute hochgeladen, aber die darin enthaltenen Informationen sind bereits veraltet. Wie man das überprüft - weiß Fudge.

Jetzt habe ich das getan: Analysieren Sie die Ursache von OnDeinit(), wenn das Programm geschlossen ist, dann lösche ich das globale Terminal (wie ein Flag der Neuinitialisierung).

Wenn dieses Flag bei OnInit() nicht gesetzt ist, muss ich den Benutzer jedes Mal mit einer stummen Meldung fragen: "restore variables from file?

Das ist ein wahnsinnig dummer und unbequemer Weg!


Frage: Wie lässt sich eine solche Lösung vollständig automatisieren?

Woran erkennt man, dass eine Datei nicht hochgeladen werden kann und wann sie heruntergeladen werden kann?

Reduzieren Sie zumindest den Aufruf dieser Nachrichtenbox auf ein Minimum.

 

MQL4 oder MQL5?

WennMQL5, dann:

In OnInit() prüfen:

1. Position

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

2) Bestellungen:

(Wenn etwas schief geht, lösche ich einfach alle Aufträge, ohne zu prüfen, woher sie kommen. )

//+------------------------------------------------------------------+
//| 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. Globale Variablen des Terminals:

  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. Zu speichernde Variablen

a) Laden:

//+------------------------------------------------------------------+
//| 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) Speichern ( 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_Антон:
Die Aufgabe: Wiederherstellung der Umgebung des EA (Positionsdaten, Zähler usw.) nach einer Neuinitialisierung, einem Neustart bei einem Systemausfall usw.

Die Gegenfrage lautet: Warum?

Imho ist die Wiederherstellung der Umgebung aus einer Datei auf lange Sicht immer selbstmörderisch. Beim Neustart sollten Sie Ihre Daten immer auf der Grundlage der MetaTrader-Handelsumgebung neu berechnen.

 
Fry_Антон:
Aufgabe: Wiederherstellung der EA-Umgebung (Positionsdaten, Zähler, etc.) nach Neuinitialisierung, Neustart bei Systemausfall, etc.
Neuberechnen
 
Vasiliy Sokolov:

Die Gegenfrage lautet: Warum?

Imho ist die Wiederherstellung der Umgebung aus einer Datei auf lange Sicht immer selbstmörderisch. Sie sollten Ihre Daten beim Neustart immer auf der Grundlage der MetaTrader-Handelsumgebung neu berechnen.

Merkmale des Terminmarktes.

Nicht alles kann neu berechnet werden. Natürlich aktualisiere ich, was ich aus der Umgebung entnehmen kann, aber... Nun, hier ein Beispiel:

Beim Clearing einer Position werden die Aufträge geschlossen/geöffnet. Das Terminal sperrt den Handel und löscht die Aufträge für den Tag (und die Aufträge werden vom Broker bis zur Stornierung gesperrt). Ich muss neue Aufträge anlegen.

Und ich benötige den Anfangskurs für die Eröffnung einer Position, die Anfangszeit für das Setzen einer Position und die Aufträge.

Ich muss also meine eigene Buchführung über solche Parameter führen.

Es gibt auch Zähler für Anfragen pro Sekunde/Minute/Stunde/Tag, Zähler für nicht fatale fehlerhafte Aktionen, usw. usw.

Ich würde die Datei gerne aufgeben! Wenn es echt wäre. =(

Es gibt eine Situation wie diese: Terminal abgestürzt (die heutigen Builds sind stabil, und bevor es war immer so, und nicht die Tatsache, dass es immer nur stabile Versionen).

Nach Absturz Terminal: schneller Neustart und Autorun - Wiederherstellung aus Datei und alles funktioniert.

Funktioniert sehr stabil, da ich die Initialisierungsdatei immer im OnTrade()-Ereignis speichere (mit Timer für ein oder zwei Sekunden, um die Festplatte nicht zu quälen).


Für mich ist die Frage also sehr relevant: Wie kann man Variablen nicht aus einer Datei laden, die veraltet oder gefährlich zu laden ist?

 
Михаил:

MQL4 oder MQL5?

Wenn esMQL5 ist, dann:

In OnInit() prüfen:

1. Position

2) Bestellungen:

(Wenn etwas schief geht, lösche ich einfach alle Aufträge, ohne zu prüfen, woher sie kommen. )

3. Globale Variablen des Terminals:

4. Zu speichernde Variablen

a) Laden:

b) Speichern ( OnDeInit() )

Ich habe es fast so gemacht. Aber ich speichere die Datei in OnTrade() mit einem Timer.

Ich habe auch einen Haufen verschiedener Eigenschaften und anderer Variablen, und der Code entwickelt sich ständig weiter, so dass es sehr unbequem war, sie einzeln zu speichern.

Ich habe eine Grundstruktur erstellt, die alles enthält, was ich für die Datei benötige (mit Ausnahme einiger String-Werte).

Ich habe ihn mit einem Buchstaben benannt, so dass der Code recht kurz ist (b.volume ist fast wie volume). Und es ist bequem, die gesamte Struktur auf einmal mit dem Operator = zu speichern.

 
Fry_Антон:

...

Frage: Wie lässt sich eine solche Lösung vollständig automatisieren?

...

Ein grundlegend anderer Ansatz für die EA-Programmierung.

 
Dmitry Fedoseev:

Ein grundlegend anderer Ansatz für die EA-Programmierung.

Erweitern Sie die Antwort auf einen vernünftigen, nützlichen Gedanken und ich wäre Ihnen dankbar.

Was sind die grundlegenden Prinzipien, die EA-Code "besser" machen?

 
Fry_Антон:

Erweitern Sie die Antwort auf einen vernünftigen, nützlichen Gedanken, und ich wäre Ihnen dankbar dafür.

Was sind die Grundprinzipien, die den EA-Code "besser" machen?

Es wurde hier schon geschrieben - rechnen Sie alles neu. D.h. die Situation mit Aufträgen zu analysieren. Es ist nicht von grundlegender Bedeutung, ob einige Daten in Dateien oder auf andere Weise (vielleicht in globalen Variablen) gespeichert werden. Der wichtigste Punkt ist, dass, wenn einige Daten benötigt werden, sie in der Bindung an Bestellscheine gespeichert werden, und in diesem Fall gibt es kein Problem mit veralteten Daten - wir haben Ordnung - wir haben Daten, keine Ordnung - wir haben keine Daten. Es mag Daten geben, die nicht an eine bestimmte Reihenfolge gebunden sind, aber wir müssen über jeden einzelnen Fall nachdenken, und es ist ein lösbares Problem.

Das Clearing ist wirklich das komplizierteste Problem. Aber es ist kein Problem der langfristigen Datenspeicherung (oder ihrer Veralterung), wir können Daten in einfachen Variablen im Expert Advisor speichern (ein bisschen riskant, aber nur für 5 Minuten). Die Schwierigkeit dabei ist, wie man später damit umgehen kann. Wir können eine Gruppe globaler Terminalvariablen für jeden Auftrag erstellen und den Eröffnungskurs darin speichern. Wenn dann die nicht markierten Aufträge erscheinen (oder zu Beginn eines neuen Tages), sehen wir uns die letzten geschlossenen Aufträge in der Historie an, gleichen sie nach den verwendbaren Merkmalen ab (z. B. Los) und setzen alle globalen Variablen des geschlossenen Auftrags auf den neuen Auftrag zurück.

 

Anton!

Sie machen sich zu viele Gedanken über dieses Problem.

Es ist klar, dass Sie die Arbeit des Experten nach dem Notfall ordnungsgemäß wiederherstellen wollen

Situation. Auch ich habe mir anfangs den Kopf zerbrochen.

Dann aber beschlossen, dass solche Situationen extrem selten sind

(aus meiner eigenen Erfahrung mit dem halbjährlichen MT5-Realhandel), also habe ich beschlossen, dass es sich nicht lohnt

sich mit den erteilten Aufträgen zu "beschäftigen" und alles, was nach dem Herbst existiert, einfach "festzunageln".

Die Aufträge wurden vor dem Sturz erteilt, wenn sie ausgeführt wurden, kann nichts unternommen werden, und wenn

Wenn sie immer noch "herumhängen", dann töten Sie sie und setzen Sie sie entsprechend der Handelssituation neu, dann verlieren Sie nichts!

Dann bleibt nur noch die Position - ob sie da ist oder nicht.

Was das Schreiben/Lesen von Variablen aus einer Datei betrifft.

Ich habe "heiße" (während der Arbeit) Änderung der Variablen in meinen EAs, so dass ich

Ich schreibe sie und lese sie aus einer Datei, damit der Expert Advisor bei einem Neustart die "heißen" Einstellungen übernimmt.

Das Problem, das SIE sich selbst schaffen!

Denken Sie darüber nach!

P/S MT5 ist nicht MT4, wo Aufträge sehr wichtig sind!

Im MT5 müssen Sie sich an der POSITION orientieren, nicht an den Aufträgen.

 
Fry_Антон:

Erweitern Sie die Antwort auf einen vernünftigen, nützlichen Gedanken, und ich wäre Ihnen dankbar dafür.

Was sind die Grundprinzipien, die den EA-Code "besser" machen?

Unter vier Augen geantwortet.

Z.I. Ihre Beispiele sind nicht gültig. Bei Forts gibt es solche Probleme nicht. Natürlich kann man sich jedes beliebige Problem ausdenken und dann lange Zeit versuchen, es zu lösen. Aber warum dieses Problem lösen, wenn es einfacher ist, es nicht zu erfinden?