Vom Neuling zum Experten: Reporting EA – Einrichten des Arbeitsablaufs
Inhalt:
- Einführung
- Verstehen der Handelsberichte in MQL5
- Umsetzung
- Tests
- Schlussfolgerung
- Wichtige Lektionen
- Anlagen
Einführung
Die Inspiration für dieses Konzept kam mir, als ich anfing, tägliche Handelsbestätigungen von meinem Broker per E-Mail zu erhalten. Diese Zusammenfassungen boten einen sauberen, professionellen Überblick über die Handelsaktivitäten und zeigten das Potenzial für statistische Leistungsanalysen auf. Bei der Erkundung des MetaTrader 5-Terminals habe ich festgestellt, dass es in der aktuellen Version ein umfassendes Reporting-Tool enthält, das detaillierte Berichte im HTML- und PDF-Format exportieren kann. Allerdings fehlt es an Funktionen für die automatische Bereitstellung von Berichten und die zentrale Verwaltung. In dieser Diskussion wollen wir die Rolle von Handelsberichten untersuchen, die wichtigsten Begriffe klären und ihre praktische Bedeutung für jeden Händler hervorheben, der fundierte Entscheidungen treffen möchte.
Letztendlich planen wir die Implementierung eines nutzerdefinierten Berichtssystems mit MQL5 in Zusammenarbeit mit Python und anderen externen Tools. Diese Lösung erstellt detaillierte Berichte, gewährleistet die Kompatibilität mit verschiedenen Dateiformaten und unterstützt die automatisierte Zustellung durch praktische und zuverlässige Methoden.
Nach der Untersuchung der aus MetaTrader 5 exportierten Dokumente wurde deutlich, dass sie wertvolle Erkenntnisse und vorberechnete Metriken enthalten, die Händlern eine mathematische Sicht auf ihre Performance bieten – Informationen, die Handelsentscheidungen und Verhaltensanpassungen direkt beeinflussen können.
Derzeit werden Berichte in MetaTrader 5 in der Regel durch manuelle Navigation erstellt. Wenn wir jedoch mit Expert Advisors (EAs) arbeiten, haben wir die Möglichkeit, die Erstellung und Bereitstellung dieser Berichte programmatisch zu steuern. Während einige Makler diese Berichte bereits automatisch versenden, besteht unser Ziel in dieser Diskussion darin, ein System zu entwickeln, mit dem wir die Zustellung von Berichten nach unseren eigenen Präferenzen planen und sowohl die Häufigkeit als auch den Inhalt anpassen können.
Um dieses Problem zu lösen, werden wir die praktische Bedeutung von Handelsberichten anhand eines Beispiels aus meiner eigenen Erfahrung untersuchen. Wir werden auch die in diesen Berichten häufig vorkommenden Begriffe untersuchen und erörtern, wie sie zur Verbesserung der manuellen Handelsstrategien und der Leistungsbewertung von Expert Advisors verwendet werden können.
In MetaTrader 5 können Sie auf Handelsberichte zugreifen, indem Sie im Menü Ansicht die Option Berichte auswählen oder die Tastenkombination Alt+E verwenden. Das Berichtsfenster zeigt verschiedene Aspekte Ihrer Handelsaktivitäten in einem übersichtlichen Format an. In diesem Fenster haben Sie auch die Möglichkeit, Ihre Berichte entweder im HTML- oder im PDF-Format zu speichern, wie in der folgenden Abbildung dargestellt:

Zugriff auf Berichte von MetaTrader 5
Die obige Abbildung verdeutlicht einige der wichtigsten Komponenten, die typischerweise in Handelsberichten zu finden sind. Obwohl diese Informationen sehr wertvoll sind, neigen viele Händler dazu, sich ausschließlich auf die Charts und die Handelsausführung zu konzentrieren – und vernachlässigen dabei oft, ihre Performance-Aufzeichnungen regelmäßig zu überprüfen. Ein klares Verständnis dieser Berichte ist von entscheidender Bedeutung, da es die Disziplin stärkt und eine gesündere Einstellung zum Handel fördert, indem es Erkenntnisse aus vergangenen Aktivitäten gewinnt.
Nach der Durchsicht meines Handelsberichts habe ich die Initiative ergriffen und die darin enthaltenen Schlüsselbegriffe recherchiert und mit praktischen Beispielen versehen, um sie besser zu verstehen. Im nächsten Abschnitt finden Sie fünf strukturierte Erkenntnisse, die jeweils eine kurze, aber aussagekräftige Erklärung bieten. Diese dienen als Grundlage für den Implementierungsplan, den wir im weiteren Verlauf des Artikels erkunden werden. Wenn wir in die technische Erstellungsphase übergehen, soll sichergestellt werden, dass diese Berichtskonzepte solide beherrscht werden. Wenn Sie bereits mit ihnen vertraut sind, können Sie mit der Umsetzungsphase weitermachen.
Verstehen der Handelsberichte in MQL5
1. Leistungsübersicht
ROI:
- Er misst, wie stark der Kontostand im Verhältnis zum Anfangskapital wächst.
- Nehmen wir an, Sie beginnen mit 5.000 $ und enden mit 12.000 $; das ergibt eine 140%ige Steigerung, d.h. aus jedem riskierten Dollar wurden 2,40 $.
Drawdown:
- Erfasst den stärksten prozentualen Rückgang von einer Hochwassermarke bis zum nächsten Tiefpunkt.
- Stellen Sie sich vor, der Aktienkurs erreicht einen Höchststand von 12 000 $ und fällt dann auf 9 600 $ – ein Rückgang von 20 %, der den tiefsten Rücksetzer vor der Erholung verdeutlicht.
Activity Metrics:
- Sie reflektieren das Handelstempo und die Konsistenz – Anzahl der Transaktionen pro Woche, Erfolgsquote und durchschnittliche Haltedauer.
- Zur Veranschaulichung: 80 Abschlüsse in acht Wochen entsprechen 10 pro Woche; 32 davon mit Gewinn. Das ergibt eine Erfolgsquote von 40 %. Bei insgesamt 160 Tagen im Markt ergibt sich eine durchschnittliche Haltedauer von 2 Tagen.
Sharpe Ratio:
- Gibt an, wie viel Überschussrendite pro Einheit der in Kauf genommenen Volatilität erzielt wird.
- Zur Veranschaulichung vergleichen wir zwei Systeme, die beide eine jährliche Rendite von 15 % erwirtschaften: Das System, das täglich um ±2 % schwankt, hat einen deutlich höheren Sharpe-Wert als ein System, das um ±6 % schwankt, was auf eine gleichmäßigere Aktienentwicklung zurückzuführen ist.
Profit Factor:
- Drückt den Bruttogewinn geteilt durch den Bruttoverlust aus, um die Effizienz von Gewinnern und Verlierern zu zeigen.
- Nehmen wir den Fall von 8.000 Dollar Gewinn aus erfolgreichen Handelsgeschäften gegenüber 5.000 Dollar Verlust, was ein Verhältnis von 1,6 ergibt – jeder verlorene Dollar wird also durch einen Gewinn von 1,60 Dollar ausgeglichen.
Erholungsfaktor:
- Er vergleicht den Nettogewinn mit dem größten wahrgenommenen Drawdown.
- Angenommen, eine Strategie erzielt einen Gewinn von 4 000 $ und verliert im schlimmsten Fall 1 000 $; der Erholungsfaktor von 4 zeigt an, dass der Gewinn viermal größer war als der größte Verlust.
2. Aufschlüsselung von Gewinn und Verlust
Bruttogewinn und Bruttoverlust:
- Die Summe aus gewonnenen und verlorenen Handelsgeschäften ergibt den Rohgewinn vor Kosten.
- Ein Beispiel: 15 000 $ an Gewinnern gegenüber 6 000 $ an Verlierern ergibt einen Bruttogewinn von 9 000 $.
Gebühren und Nettogewinn:
- Zieht man Provisionen, Swaps und andere Kosten von den Bruttoergebnissen ab, erhält man die tatsächlichen Erträge.
- Um das in die richtige Perspektive zu rücken, bleiben nach Abzug der Gebühren in Höhe von 1 200 Dollar von einem Vorsprung von 9 000 Dollar 7 800 Dollar als Nettogewinn übrig.
Monatliche Trends:
- Die Darstellung der Nettoergebnisse von Monat zu Monat offenbart Leistungsverschiebungen.
- Die Tatsache, dass im Januar +4 000 Dollar, im Februar +3 000 Dollar, im März +800 Dollar und im April –500 Dollar zu verzeichnen waren, verdeutlicht einen Abwärtstrend, der Aufmerksamkeit erfordert.
3. Risikoanalyse
Maximaler Drawdown:
- Definiert den größten prozentualen Rückgang von einem Höchststand bis zum nächsten Tiefpunkt.
- Stellen Sie sich ein Konto vor, das von 20 000 $ auf 14 000 $ abrutscht, bevor es sich wieder erholt – ein Rückgang von 30 % im schlimmsten Fall.
Gewinner und Verlierer in Folge:
- Die längste Reihe positiver oder negativer Ergebnisse stellt sowohl die Stabilität des Systems als auch die Psychologie des Händlers auf die Probe.
- Stellen Sie sich vor, Sie erleiden sieben Verlierer in Folge, während Sie fünfmal in Folge gewinnen; jede Pechsträhne prägt das Vertrauen, die Disziplin und die Positionsgröße.
Maximal vorteilhafte Entwicklung (Maximum Favorable Excursion, MFE):
- Verfolgt den höchsten nicht realisierten Gewinn, der während der Laufzeit eines Handelsgeschäfts erzielt wurde.
- Zur Veranschaulichung: Eine Position könnte in der Spitze auf 600 $ steigen, bevor ein Ausstiegsauftrag ausgelöst wird.
Maximal unerwünschte Entwicklung (Maximum Adverse Excursion, MAE):
- Erfasst den tiefsten nicht realisierten Verlust vor der Schließung.
- Bedenken Sie, dass derselbe Handel auf 200 $ fallen könnte, bevor er gewinnbringend geschlossen wird, was darauf hindeutet, dass Stop-Loss-Anpassungen hilfreich sein könnten.
4. Instrument/Symbol Leistung
Gewinnrate nach Vermögenswerten:
- Der prozentuale Erfolg pro Markt zeigt, wo der Vorsprung am größten ist.
- So kann beispielsweise EURUSD in 48 % der Fälle Gewinne erzielen, während USDJPY in 60 % der Fälle gewinnt, was auf stärkere Signale für letzteren schließen lässt.
Gewinnbeitrag:
- Die Nettoerträge nach Instrumenten zeigen, woher die Gewinne tatsächlich stammen.
- Nehmen wir das Beispiel EURUSD, das unter dem Strich 9.600 $ hinzufügt, während XAUUSD 1.100 $ abzieht, um die Ressourcenallokation zu steuern.
Konzentrationsrisiko:
- Hebt den Anteil des Kapitals oder die Anzahl der Geschäfte hervor, die an einen einzigen Markt gebunden sind.
- Angenommen, 40 % der Mittel sind in EURUSD angelegt; eine plötzliche Bewegung des Euro könnte die Gesamtperformance unverhältnismäßig stark beeinträchtigen.
Profit-Faktor pro Symbol:
- Vergleicht die Bruttogewinne mit den Verlusten für jeden Markt und verdeutlicht so die Effizienz.
- So kann der USDJPY ein Verhältnis von 1,8 aufweisen, während der AUDCAD bei 0,9 liegt – ein Hinweis darauf, welche Paare zu bevorzugen oder zu vermeiden sind.
5. Aktivität und Verhaltensmuster
Handelsverteilung:
- Das Gleichgewicht zwischen Kauf- und Verkaufspositionen zeigt eine Tendenz auf.
- Wenn man beispielsweise 70 % Kaufpositionen hält, deutet dies auf eine vorwiegend Kauforientierung hin, die in seitwärts tendierenden Märkten ins Wanken geraten kann.
Automatisierung vs. manueller Handel:
- Der Vergleich zwischen algorithmischen und von Menschen eingegebenen Handelsgeschäften zeigt, wo der wahre Vorteil liegt.
- Wenn man bedenkt, dass 65 % des Nettogewinns auf automatisierte Eingaben gegenüber 35 % auf manuelle Eingaben entfallen, unterstreicht dies die Stärke des Systems.
Zeitanalyse:
- Durch die Aufschlüsselung der Ergebnisse nach Stunden und Wochentagen lassen sich optimale und gefährdete Zeitfenster ermitteln.
- So können die meisten Verluste zwischen 11:00 und 12:00 Uhr GMT auftreten, was auf eine Mittagszeit hindeutet, die am besten vermieden wird.
Stil-Werte:
- Die durchschnittliche Haltedauer und das wöchentliche Handelsvolumen bestimmen den Ansatz.
- Zur Veranschaulichung: Eine durchschnittliche Haltezeit von vier Stunden in Kombination mit etwa 25 Transaktionen pro Woche kennzeichnet eine Intraday-Strategie mit moderatem Tempo.
Umsetzung
In diesem Stadium beginnen wir mit der Einrichtung unseres Arbeitsablaufs. Dank des vorangegangenen Abschnitts, in dem die Terminologie von Handelsberichten eingehend erläutert wurde, werden Sie diesem Teil leichter folgen können, da er weniger unbekannte Begriffe enthält.
Um das Ziel dieses Artikels zu erreichen, werden wir einen Expert Advisor (EA) entwickeln, der den Datenexport übernimmt und die notwendigen Protokolle erstellt. Dieser EA dient als Brücke zwischen MetaTrader 5 (MQL5) und den Python-Bibliotheken, die für die Verarbeitung historischer Handelsdaten und die Erstellung eines Abschlussberichts in einem portablen Format verantwortlich sind – ähnlich wie die in das MetaTrader 5-Terminal integrierten Reporting-Tools.
Wir beginnen mit einem Flussdiagramm, das den gesamten Prozess skizziert, gefolgt von einer Aufschlüsselung der erforderlichen Tools und der Einrichtung der Umgebung, damit alles funktioniert. Alle Komponenten dieses Projekts basieren auf Open-Source-Technologien, sodass die Zugänglichkeit für jedermann gewährleistet ist.

Prozessablauf
Um loszulegen, müssen Sie sicherstellen, dass MetaTrader 5 auf Ihrem System installiert ist. Richten Sie dann die Python-Umgebung ein, die ich später im Detail erläutern werde. In der folgenden Tabelle finden Sie eine vereinfachte Liste der Anforderungen und Werkzeuge, die in diesem Arbeitsablauf verwendet werden.
| Komponente | Open-Source-Tools | Kosten | Hinweise zur Umsetzung |
|---|---|---|---|
| Datenextraktion | MetaTrader 5 Expertenberater (ReporterEA.mq5) | Kostenlos | Nutzerdefinierter CSV-Export mit Datumsbereich-Filterung |
| Zeitplanungsmaschine | MetaTrader 5 Timer Ereignisse (OnTimer()) | Kostenlos | Interne Terminplanung im MetaTrader 5-Terminal |
| Verarbeitung | Python 3.10+ (Pandas, Matplotlib) | Kostenlos | Ausgelöst von EA über ShellExecute |
| Zustellung des Berichts | smtplib + Gmail SMTP | Kostenlos | Viele kostenlose E-Mails/Tag von Python-Skript |
| Wartung | EA Auto-Cleanup-Funktionen | Kostenlos | Dateidrehung und Fehlerbehandlung in MQL5/Python |
Entwicklung eines Reporting EA
In diesem Stadium beginnen wir wie geplant mit der Entwicklung des Expert Advisor (EA). Ich führe Sie durch jede Komponente des Codes und erkläre, wie sie zusammenarbeiten, um ein vollständiges und funktionierendes System zu bilden. Das Ziel ist es, einen robusten EA zu entwickeln, der seinen Zweck nahtlos erfüllt. Folgen Sie uns, wenn wir den Entwicklungsprozess in klare, überschaubare Schritte unterteilen, um sicherzustellen, dass jeder Teil leicht zu verstehen ist und einen sinnvollen Beitrag zum Endprodukt leistet.
Öffnen Sie in MetaEditor 5 eine neue Datei und wählen Sie die Vorlage „Expert Advisor“. Ich empfehle, alle Abschnitte des automatisch generierten Codes zu entfernen, die für unsere aktuellen Entwicklungsziele nicht relevant sind, damit wir uns nur auf das Wesentliche konzentrieren können. Folgen Sie den nummerierten Schritten unten, um den Expert Advisor Schritt für Schritt zu erstellen.
1. Datei-Metadaten und Kompilieranweisungen
Am Anfang der Datei deklarieren die #property-Anweisungen Metadaten für den Expert Advisor (EA). Zu diesen Eigenschaften gehören die Copyright- und Link-Informationen, die in der „Über“-Box des MetaTrader 5-Terminals erscheinen, sowie die Versionsnummer und der strenge Kompilierungsmodus. Der strenge Modus erzwingt eine strengere Typüberprüfung und Kompilierungsregeln und hilft, subtile Fehler zu vermeiden, indem er implizite Casts verbietet und explizite Konvertierungen verlangt.
#property copyright "Clemence Benjamin" #property link "https://www.mql5.com/go?link=https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" #property strict
2. Konstanten und Windows-API-Importe
Die #define-Anweisungen erzeugen symbolische Namen für häufig verwendete Konstantenwerte (SW_HIDE zum Ausblenden von Konsolenfenstern und INVALID_FILE_ATTRIBUTES zur Fehlerprüfung). Anschließend importiert der Code zwei Windows-Systembibliotheken über #import: kernel32.dll für Dateiattributfunktionen (GetFileAttributesW) und shell32.dll für die Ausführung externer Prozesse (ShellExecuteW). Durch den Aufruf dieser nativen DLL-Funktionen erweitert der EA die in MetaTrader 5 eingebauten Möglichkeiten, das Vorhandensein von Dateien zu überprüfen und den Python-Interpreter zu starten.
#define SW_HIDE 0 #define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF //--- Windows API imports #import "kernel32.dll" uint GetFileAttributesW(string lpFileName); #import #import "shell32.dll" int ShellExecuteW(int hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd); #import
3. Nutzereingaben für die Konfiguration
Die Eingangsdeklarationen stellen anpassbare Parameter im Einstellungsdialog des EA dar. Die Nutzer können den absoluten Pfad zur ausführbaren Python-Datei (PythonPath), das auszuführende Python-Skript (ScriptPath), die Stunde und Minute, zu der der tägliche Bericht ausgeführt werden soll (ReportHour, ReportMinute), angeben, ob Push-Benachrichtigungen gesendet werden (EnableEmail) und ob beim Start ein erster Testlauf erfolgt (TestOnInit). Wenn Sie diese als Eingaben freigeben, können auch Nicht-Programmierer das Verhalten ändern, ohne den Quellcode zu bearbeiten.
//--- User inputs input string PythonPath = "C:\\Users\\BTA24\\AppData\\Local\\Programs\\Python\\Python312\\python.exe"; input string ScriptPath = "C:\\Users\\BTA24\\Documents\\BENJC_TRADE_ADVISOR\\Scripts\\processor.py"; input int ReportHour = 15; // Hour (24h) to run report input int ReportMinute = 55; // Minute after the hour input bool EnableEmail = true; // Send push notification input bool TestOnInit = true; // Immediately run export+Python on init
4. Globale Zustandsverwaltung
Eine einzige globale Variable, lastRunTime, speichert den Zeitstempel der letzten erfolgreichen Berichtsausführung. Durch den Vergleich von TimeCurrent() mit lastRunTime stellt der EA sicher, dass der Bericht nur einmal alle 24 Stunden ausgeführt wird, auch wenn der Timer-Callback häufiger überprüft wird.
//--- Globals datetime lastRunTime = 0;
5. Initialisierungslogik (OnInit)
Die Funktion OnInit() führt alle Startup-Routinen durch. Zunächst werden Statusmeldungen in das Expertenprotokoll geschrieben. Es überprüft die Dateiattribute für die ausführbare Python-Datei und das Skript und gibt Warnungen aus, wenn sie fehlen. Anschließend werden die Schreibberechtigungen getestet, indem eine Dummy-Datei im Verzeichnis MQL5Files erstellt, geschrieben, geschlossen und gelöscht wird. Als Nächstes wird über EventSetTimer(30) ein alle 30 Sekunden wiederkehrendes Timer-Ereignis eingerichtet. Wenn TestOnInit wahr ist, wird sofort RunDailyExport() aufgerufen, um den gesamten Export- und Python-Workflow zu validieren, wobei die aktuelle Zeit in lastRunTime aufgezeichnet wird.
int OnInit() { Print(">> Reporting EA initializing…"); // Verify Python executable if(GetFileAttributesW(PythonPath) == INVALID_FILE_ATTRIBUTES) Print("!! Python executable not found at: ", PythonPath); else Print("✔ Found Python at: ", PythonPath); // Verify Python script if(GetFileAttributesW(ScriptPath) == INVALID_FILE_ATTRIBUTES) Print("!! Python script not found at: ", ScriptPath); else Print("✔ Found script at: ", ScriptPath); // Test write permission int h = FileOpen("test_perm.txt", FILE_WRITE|FILE_COMMON|FILE_ANSI); if(h==INVALID_HANDLE) Print("!! Cannot write to MQL5\\Files directory!"); else { FileWrite(h, "OK"); FileClose(h); FileDelete("test_perm.txt"); Print("✔ Write permission confirmed."); } // Set timer EventSetTimer(30); Print(">> Timer set to 30 seconds."); // Test run on init if(TestOnInit) { Print(">> Test mode: running initial export."); RunDailyExport(); lastRunTime = TimeCurrent(); } return(INIT_SUCCEEDED); }
6. Logik der Deinitialisierung (OnDeinit)
Wenn der EA entfernt wird oder die Plattform herunterfährt, wird OnDeinit() aufgerufen. Seine einzige Aufgabe besteht darin, den Timer zu löschen (EventKillTimer()) und eine Deinitialisierungsmeldung zu protokollieren. Die ordnungsgemäße Freigabe von Timer-Ressourcen verhindert verwaiste Rückrufe und mögliche Abstürze.
void OnDeinit(const int reason) { EventKillTimer(); Print(">> Reporting EA deinitialized."); }
7. Timer-Rückmeldung für die Zeitplanung (OnTimer)
Alle 30 Sekunden wird OnTimer() ausgeführt und ruft die aktuelle Stunde und Minute über die Struktur MqlDateTime ab. Es wird geprüft, ob die aktuelle Zeit mit der konfigurierten Berichtszeit (ReportHour, ReportMinute) übereinstimmt oder diese überschreitet und ob seit lastRunTime mindestens 86 400 Sekunden (24 Stunden) vergangen sind. Durch diese doppelte Überprüfung wird sichergestellt, dass der Bericht einmal täglich zur oder nach der geplanten Minute ausgeführt wird.
void OnTimer() { MqlDateTime dt; TimeToStruct(TimeCurrent(), dt); if(dt.hour==ReportHour && dt.min>=ReportMinute && (TimeCurrent()-lastRunTime)>86400) { RunDailyExport(); lastRunTime = TimeCurrent(); } }
8. Hauptarbeitsablauf: Export und Python-Aufruf (RunDailyExport)
- Diese Funktion kapselt die wichtigsten Schritte der EA-Berichtsfunktion.
- Berechne mit TerminalInfoString den absoluten Pfad zum Verzeichnis MQL5\Files von MetaTrader 5.
- Generiere Dateinamen mit Datumsstempel sowohl für den CSV-Export als auch für die Protokolldatei, indem das aktuelle Datum formatiert und die Punkte entfernt werden.
- Rufe ExportHistoryToCSV() auf, um die letzten 30 Tage des Handelsverlaufs in eine CSV-Datei zu schreiben. Wenn dies fehlschlägt, bricht die Funktion ab.
- Erstelle eine Befehlszeichenfolge, die den Python-Interpreter mit dem Skript und dem CSV-Dateinamen aufruft und sowohl die Standardausgabe als auch den Standardfehler in die Protokolldatei umleitet. Die Text-Formatierung und StringFormat sorgen für die richtige Quotierung von Pfaden, die Leerzeichen enthalten.
- Rufe ShellExecute()-Wrapper des EA auf, um cmd.exe /c <pythonCmd> zu starten, und erfasse den ganzzahligen Rückgabewert für die Diagnoseprotokollierung.
- Halte mit Sleep(3000) 3 Sekunden lang an, damit der externe Python-Prozess abgeschlossen werden kann.
- Prüfe, ob die Protokolldatei vorhanden ist, lesen Sie dann ihren Inhalt und geben Sie ihn zeilenweise im Expertenprotokoll aus.
- Erstelle schließlich eine Benachrichtigung, die den CSV-Pfad zusammenfasst, und sende sie – falls aktiviert – per SendNotification() an die mobilen Endgeräte des Nutzers.
void RunDailyExport() { string filesDir = TerminalInfoString(TERMINAL_DATA_PATH) + "\\MQL5\\Files\\"; string dateStr = TimeToString(TimeCurrent(), TIME_DATE); StringReplace(dateStr, ".", ""); string csvName = "History_" + dateStr + ".csv"; string logName = "ProcLog_" + dateStr + ".txt"; string csvFull = filesDir + csvName; string logFull = filesDir + logName; // 3) Export CSV if(!ExportHistoryToCSV(csvName)) { Print("!! CSV export failed: ", csvFull); return; } Print("✔ CSV exported: ", csvFull); // 4) Build Python command string pythonCmd = StringFormat( "\"%s\" \"%s\" \"%s\" >> \"%s\" 2>&1", PythonPath, ScriptPath, csvFull, logFull ); string fullCmd = "/c " + pythonCmd; PrintFormat("→ Launching: cmd.exe %s", fullCmd); // 5) Execute int result = ShellExecute(" " + fullCmd); PrintFormat("← ShellExecute returned: %d", result); // 6) Wait Sleep(3000); // 7) Read log if(GetFileAttributesW(logFull) == INVALID_FILE_ATTRIBUTES) Print("!! Log file not created: ", logFull); else { Print("=== Python Log Start ==="); int fh = FileOpen(logName, FILE_READ|FILE_COMMON|FILE_TXT); while(fh!=INVALID_HANDLE && !FileIsEnding(fh)) Print("PY: ", FileReadString(fh)); if(fh!=INVALID_HANDLE) FileClose(fh); Print("=== Python Log End ==="); } // 8) Notification string msg = "Report & log generated: " + csvFull; Print(msg); if(EnableEmail) SendNotification(msg); }
9. CSV-Erzeugung (ExportHistoryToCSV)
Diese Hilfsfunktion automatisiert die Extraktion der Geschäftshistorie in eine CSV-Datei. Es wählt die gesamte Historie der letzten 30 Tage aus (HistorySelect), iteriert durch jedes Deal-Ticket, ruft die Eigenschaften (Zeit, Typ, Symbol, Volumen, Preis, Gewinn, Provision, Swap) mit HistoryDealGet*-Funktionen ab und schreibt sie als kommagetrennte Werte mit FileWrite. Nach der Ausgabe einer Kopfzeile konstruiert die Schleife jede Zeile mit DoubleToString und TimeToString, um eine einheitliche numerische Präzision und Zeitstempelformatierung zu gewährleisten. Eine ordnungsgemäße Fehlerprüfung bei FileOpen verhindert stille Fehlschläge.
bool ExportHistoryToCSV(string filename) { datetime end = TimeCurrent(); datetime start = end - 2592000; // last 30 days HistorySelect(start, end); int total = HistoryDealsTotal(); int fh = FileOpen(filename, FILE_WRITE|FILE_CSV|FILE_COMMON|FILE_ANSI, ","); if(fh==INVALID_HANDLE) { Print("!! FileOpen failed for: ", filename); return(false); } FileWrite(fh, "Ticket,Time,Type,Symbol,Volume,Price,Profit,Commission,Swap"); for(int i=0; i<total; i++) { ulong deal = HistoryDealGetTicket(i); if(deal==0) continue; long tr = HistoryDealGetInteger(deal, DEAL_TIME); datetime t = (datetime)tr; int tp = (int)HistoryDealGetInteger(deal, DEAL_TYPE); string sym = HistoryDealGetString (deal, DEAL_SYMBOL); double vol = HistoryDealGetDouble (deal, DEAL_VOLUME); double prc = HistoryDealGetDouble (deal, DEAL_PRICE); double pf = HistoryDealGetDouble (deal, DEAL_PROFIT); double cm = HistoryDealGetDouble (deal, DEAL_COMMISSION); double sw = HistoryDealGetDouble (deal, DEAL_SWAP); FileWrite(fh, deal, TimeToString(t, TIME_DATE|TIME_SECONDS), tp, sym, DoubleToString(vol,2), DoubleToString(prc,5), DoubleToString(pf,2), DoubleToString(cm,2), DoubleToString(sw,2) ); } FileClose(fh); return(true); }
10. Shell Command Wrapper (ShellExecute)
Die Funktion ShellExecute dient als dünne Hülle um den importierten API-Aufruf ShellExecuteW. Durch die Standardisierung des Aufrufs von cmd.exe wird die Komplexität der nativen API verborgen und SW_HIDE zur Unterdrückung von Konsolenfenstern verwendet. Durch die Rückgabe des Integer-Ergebniscodes kann der EA mögliche Fehler beim Starten externer Befehle erkennen und protokollieren
int ShellExecute(string command) { return(ShellExecuteW(0, "open", "cmd.exe", command, NULL, SW_HIDE)); }
Entwicklung des Python-Prozessorskripts
Wir beginnen mit der Einrichtung von Python und der Installation der erforderlichen Bibliotheken. Öffnen Sie zunächst die Eingabeaufforderung und führen Sie die erforderlichen Installationsbefehle aus. Danach können Sie Ihr Python-Skript mit einem Texteditor vorbereiten. Ich persönlich bevorzuge Notepad++, ein Open-Source-Tool, aber es steht Ihnen frei, eine Python-IDE Ihrer Wahl zu verwenden.
Einrichten
1. Um die Python-Seite vorzubereiten, installieren Sie zunächst einen aktuellen Python 3.x Interpreter (z.B. 3.10 oder 3.12). Erstellen und aktivieren Sie eine virtuelle Umgebung in Ihrem Projektordner:
python -m venv venv source venv/Scripts/activate # Windows # or source venv/bin/activate # macOS/Linux
2. Nach der Aktivierung installieren Sie die erforderlichen Pakete mit:
pip install pandas fpdf
- pandas übernimmt das CSV-Parsing und die Datenanalyse,
- FPDF (oder eine andere PDF-Bibliothek Ihrer Wahl) erstellt den Bericht.
3. Wenn Sie E-Mail-Benachrichtigungen versenden wollen, installieren Sie auch eine SMTP-Bibliothek wie yagmail oder verwenden Sie die in Python integrierte smtplib.
Nun ist es an der Zeit, das Python-Skript zu entwickeln. Wir werden die folgenden Schritte durchführen, um jeden Teil zu implementieren.
1. Skript-Kopfzeile und Importe
Das Skript beginnt mit einem Shebang im Unix-Stil, um die Ausführung auf Systemen zu ermöglichen, die dies respektieren, gefolgt von den Importen der wichtigsten Bibliotheken:
- sys, os und traceback für die Interaktion mit dem Betriebssystem, die Behandlung von Argumenten und die Ausgabe von Fehlern;
- pandas zum Laden und Verarbeiten von Daten;
- datetime und timedelta für Datumsberechnungen;
- FPDF aus dem fpdf-Paket, um PDF-Berichte zu erstellen.
#!/usr/bin/env python import sys, os, traceback import pandas as pd from datetime import datetime, timedelta from fpdf import FPDF
2. Hauptarbeitsablauf: Validierung von Argumenten und Dateiprüfungen
Die Funktion main(csv_path) ist der Orchestrator. Es gibt die zu verarbeitende CSV-Datei aus und prüft sofort, ob die Datei vorhanden ist. Falls nicht, wird ein FileNotFoundError ausgegeben. Dies spiegelt die eigenen Preflight-Prüfungen des MQL5 EA für die ausführbaren Python-Dateien und Skriptpfade wider.
def main(csv_path): print(f"Processing CSV: {csv_path}") if not os.path.isfile(csv_path): raise FileNotFoundError(f"CSV not found: {csv_path}")
3. Laden und Parsen der CSV
Mit pandas.read_csv lädt das Skript die vom EA erstellte CSV-Datei mit der Handelshistorie. Anschließend wird die Spalte „Time“ mit pd.to_datetime in Datetime-Objekte umgewandelt, um sicherzustellen, dass die nachfolgenden zeitbasierten Berechnungen korrekt sind. Dies entspricht der Formatierung der Zeiten durch EA mit TimeToString.
# 1. Load & parse df = pd.read_csv(csv_path) df['Time'] = pd.to_datetime(df['Time'])
4. Berechnen der zusammenfassenden Analyse
Das Skript fasst die wichtigsten Leistungskennzahlen in einem Bericht zusammen:
- „date“: das heutige Datum als String;
- „net_profit“: die Summe der Spalte Profit;
- „trade_count“: Gesamtzahl der Zeilen im DataFrame;
- „top_symbol“: das Symbol mit dem höchsten kumulierten Gewinn, unter Verwendung von groupby und idxmax.
Diese Metriken stimmen mit dem CSV-Inhalt des EA überein und ermöglichen eine genaue Zusammenfassung der exportierten Daten in der PDF-Datei.
# 2. Analytics report = { 'date' : datetime.now().strftime("%Y-%m-%d"), 'net_profit' : df['Profit'].sum(), 'trade_count': len(df), 'top_symbol' : df.groupby('Symbol')['Profit'].sum().idxmax() }
5. Generierung des PDF-Berichts
Das Skript erstellt den Ausgabepfad im gleichen MQL5-Dateiverzeichnis wie die CSV-Datei und benennt die PDF-Datei nach Datum. Dann ruft es generate_pdf(report, pdf_file) auf. Dies steht im Einklang mit der EA-Protokollierung der Python-Ausgabe und der Erwartung, dass alle Artefakte (sowohl CSV als auch PDF) im gemeinsamen Dateiordner landen.
# 3. Generate PDF dirpath = os.path.dirname(csv_path) pdf_file = os.path.join(dirpath, f"Report_{report['date']}.pdf") generate_pdf(report, pdf_file) print(f"PDF written: {pdf_file}") return 0
6. PDF-Erstellung mit FPDF
Die Funktion generate_pdf verwendet die einfache API von FPDF: Erstellen eines Dokuments, Hinzufügen einer Seite, Einstellen der Schriftart und Schreiben von Zeilen für jede Metrik. Der Parameter ln=True springt automatisch in die nächste Zeile. Dieses modulare Hilfsmittel trennt die PDF-Formatierung von der Datenlogik.
def generate_pdf(report, output_path): pdf = FPDF() pdf.add_page() pdf.set_font("Arial", size=12) pdf.cell(0, 10, f"Report Date: {report['date']}", ln=True) pdf.cell(0, 10, f"Total Trades: {report['trade_count']}", ln=True) pdf.cell(0, 10, f"Net Profit: ${report['net_profit']:.2f}", ln=True) pdf.cell(0, 10, f"Top Symbol: {report['top_symbol']}", ln=True) pdf.output(output_path)
7. Maintenance: Alte Berichte bereinigen
Um das Aufblähen der Festplatte zu verhindern, löscht clean_old_reports alle PDF-Dateien, die älter als eine konfigurierbare Anzahl von Tagen sind (Standardwert 30). Es wird nur ausgeführt, wenn der EA das Skript sonntags aufruft (Wochentag() == 6) und den CSV-Pfad in sys.argv[1] erhält, um sicherzustellen, dass es das richtige Verzeichnis ansteuert. Diese Wartung entspricht der EA-eigenen Logik der datumsbasierten Benennung und der 24-Stunden-Sperre.
def clean_old_reports(days=30): now = datetime.now() cutoff = now - timedelta(days=days) dirpath = os.path.dirname(sys.argv[1]) for fname in os.listdir(dirpath): if fname.startswith("Report_") and fname.endswith(".pdf"): full = os.path.join(dirpath, fname) if datetime.fromtimestamp(os.path.getmtime(full)) < cutoff: os.remove(full) print(f"Deleted old report: {full}")
8. Skripteinstiegspunkt und Fehlerbehandlung
Der Block if __name__ == "__main__": erzwingt die Verwendung von genau einem Argument (dem vollständigen Pfad zur CSV-Datei). Es verpackt den Aufruf von main in ein try/except, um jede Ausnahme abzufangen, einen Traceback auszugeben und mit einem Code ungleich Null zu beenden – so wie der EA Pythons stdout/stderr erfasst und alle Fehler in seinen eigenen Protokollen ausgibt. Die optionale Wartung wird wöchentlich vor dem Beenden durchgeführt.
if __name__ == "__main__": if len(sys.argv) != 2: print("Usage: processor.py <full_csv_path>") sys.exit(1) try: ret = main(sys.argv[1]) # Optional maintenance if datetime.now().weekday() == 6: clean_old_reports(30) sys.exit(ret) except Exception as e: print("ERROR:", e) traceback.print_exc() sys.exit(1)
Zusammenspiel zwischen MetaTrader 5 EA und Python-Skript
- Dateinamen-Konventionen: Der EA erstellt einen datumsformatierten CSV-Dateinamen (History_YYYYMMDD.csv) und das Python-Skript erwartet genau ein Argument, das auf diese Datei verweist.
- Verzeichnisausrichtung: Beide Komponenten arbeiten im Ordner MQL5\Files von MetaTrader 5 und gewährleisten so eine nahtlose Dateisuche.
- Fehlerfortpflanzung: Der EA leitet stdout und stderr von Python in eine mit einem Zeitstempel versehene Protokolldatei um; jede Ausnahme im Skript (z. B. fehlende CSV, Parsing-Fehler) wird vom Protokollleser des EA erfasst und in das Expertenprotokoll ausgegeben.
- Terminplanung: Die 24-Stunden-Timer-Logik des EA bestimmt, wann Python ausgeführt wird; das Skript selbst bleibt über die Verarbeitung seiner Eingaben hinaus zustandslos und verlässt sich darauf, dass der EA es zum richtigen Zeitpunkt aufruft.
- Koordinierung der Wartung: Die wöchentliche Bereinigung von PDFs wird aus dem Skript heraus ausgelöst, aber nur, wenn es sonntags aufgerufen wird, was der wöchentlichen Kadenzprüfung des EA entspricht, falls diese erweitert wurde.
Tests
In diesem Abschnitt setzen wir den Reporting EA auf einem MetaTrader 5 Chart ein. Auf einem Windows-Computer muss der DLL-Import aktiviert werden, um die Ausführung externer Prozesse zu ermöglichen. Während des Tests erreichte der EA erfolgreich sein Ziel: den Export der Handelshistorie als CSV-Datei und die Auslösung des Python-Skripts, das für die Verarbeitung der Daten verantwortlich ist. Das Skript generiert dann die erforderlichen Berichtsmetriken und exportiert sie als ausgefeiltes PDF-Dokument, das per E-Mail verschickt oder zur Überprüfung archiviert werden kann.

Einsatz des Reporting EA
Berichterstattung EA Experts log:
2025.07.24 20:44:57.061 Reporting EA (GBPJPY.0,M1) >> Reporting EA initializing… 2025.07.24 20:44:57.061 Reporting EA (GBPJPY.0,M1) !! Python executable not found at: C:\path_to\python.exe 2025.07.24 20:44:57.061 Reporting EA (GBPJPY.0,M1) !! Python script not found at: C:\path_to\reports_processor.py 2025.07.24 20:44:57.062 Reporting EA (GBPJPY.0,M1) ✔ Write permission confirmed. 2025.07.24 20:44:57.062 Reporting EA (GBPJPY.0,M1) >> Timer set to 30 seconds. 2025.07.24 20:44:57.062 Reporting EA (GBPJPY.0,M1) >> Test mode: running initial export. 2025.07.24 20:44:57.063 Reporting EA (GBPJPY.0,M1) ✔ CSV exported: C:\TERMINAL_PATH\MQL5\Files\History_20250724.csv 2025.07.24 20:44:57.063 Reporting EA (GBPJPY.0,M1) → Launching: cmd.exe /c "C:\path_to\python.exe" "C:\path_to\reports_processor.py" "C:\TERMINAL_PATH\MQL5\Files\History_20250724.csv" >> "C:\TERMINAL_PATH\MQL5\Files\ProcLog_20250724.txt" 2>&1 2025.07.24 20:44:57.124 Reporting EA (GBPJPY.0,M1) ← ShellExecute returned: 42 2025.07.24 20:45:00.124 Reporting EA (GBPJPY.0,M1) !! Log file not created: C:\Users\TERMINAL_PATH\MQL5\Files\ProcLog_20250724.txt 2025.07.24 20:45:00.124 Reporting EA (GBPJPY.0,M1) Report & log generated: C:\Users\TERMINAL_PATH\Files\History_20250724.csv
Das oben abgebildete Expertenprotokoll zeigt einen Initialisierungsversuch des Reporting EA, bei dem das System die angegebene ausführbare Python-Datei und das Skript nicht finden konnte. Dies geschah, weil die Dateipfade im Code zu Demonstrations- oder Platzhalterzwecken absichtlich umbenannt wurden (z. B. C:\pfad_zu\python.exe und C:\pfad_zu\reports_processor.py). Infolgedessen konnte der EA das Python-Skript nicht ausführen oder die erwartete Protokollausgabe (ProcLog_20250724.txt) erzeugen. Trotzdem bestätigte der EA erfolgreich die Schreibberechtigung und exportierte den Handelsverlauf als CSV-Datei.
Dieser Test verdeutlicht, wie wichtig es ist, die Dateipfade in Ihrem EA korrekt zu konfigurieren – mit Verweis auf den tatsächlichen Python-Interpreter und das Verarbeitungsskript – um eine nahtlose Ende-zu-Ende-Berichterstellung zu gewährleisten. Überprüfen Sie immer, ob die absoluten Pfade zu Ihrer lokalen Systemkonfiguration passen, um solche Probleme zu vermeiden und die volle Funktionalität des Berichtstools zu nutzen.
Schlussfolgerung
Die Diskussion konzentrierte sich in erster Linie auf das Verständnis von Handelsberichten, die Einrichtung eines funktionalen Arbeitsablaufs und die Entwicklung der Werkzeuge, die für die Bereitstellung von nutzerdefinierten Handelsberichten in einem portablen Dokumentenformat (PDF) erforderlich sind. Die letzten Schritte des Versands der erzeugten PDF-Datei per E-Mail sind einer späteren Veröffentlichung vorbehalten, um diese Präsentation nicht zu überfrachten. Der Prozess der PDF-Erzeugung, der auf der exportierten CSV-Datei basiert, wurde jedoch erfolgreich mit Python-Bibliotheken durchgeführt. Weitere Verbesserungen, wie z. B. die Einbeziehung von Charts und erweiterten Berichtsfunktionen, werden in der nächsten Diskussion vorgestellt.
Jetzt, da sowohl der Expert Advisor als auch das dazugehörige Python-Skript fertig sind, sind wir gut aufgestellt, um noch mehr zu erreichen. Zusammenfassend lässt sich sagen, dass dieses Projekt die Herausforderung löst, planmäßige, anpassbare Handelsberichte zu erhalten, die dem Nutzer das Verständnis erleichtern. So wie die Buchhaltung für jedes Unternehmen unerlässlich ist, ist auch die regelmäßige Berichterstattung im Handel unerlässlich – sie fördert das Leistungsbewusstsein, die Disziplin und das psychologische Wachstum der Händler.
Wichtige Lektionen
| Lektion | Beschreibung |
|---|---|
| 1. Modularer Aufbau | Die Trennung der CSV-Exportlogik (MQL5) von der Berichtserstellung (Python) fördert die Wartungsfreundlichkeit und ermöglicht eine unabhängige Entwicklung der einzelnen Komponenten. |
| 2. Robuste Fehlerbehandlung | Durch die Validierung von Dateipfaden, das Abfangen von Ausnahmen in Python und die Protokollierung von Fehlern wird sichergestellt, dass das System ordnungsgemäß ausfällt und debuggbar bleibt. |
| 3. Sprachübergreifende Integration | Der Aufruf von externen Skripten über ShellExecute zeigt, wie Handelsplattformen leistungsstarke externe Bibliotheken und Ökosysteme nutzen können. |
| 4. Automatisierte Terminplanung | Die Verwendung von Timer-Rückmeldungen in MQL5 zum Auslösen täglicher Exporte stellt sicher, dass die Berichte ohne manuelles Eingreifen ausgeführt werden, was die Konsistenz und Zuverlässigkeit verbessert. |
| 5. Zentralisierte Protokollierung | Das Schreiben von Protokollen in die Registerkarte „MetaTrader 5 Experts“ und in externe Textdateien bietet einen klaren Einblick in jeden Schritt des Arbeitsablaufs. |
| 6. Validierung der Umgebung | Die Überprüfung der Verfügbarkeit von Python und Skripten beim Start verhindert Überraschungen während der Laufzeit und führt die Nutzer durch die Einrichtungsanforderungen. |
| 7. Open-Source-Werkzeuge | Der Rückgriff auf kostenlose, weit verbreitete Bibliotheken (Pandas, FPDF) und Standard-APIs senkt die Einstiegshürden und fördert die Zusammenarbeit in der Gemeinschaft. |
| 8. Nutzer-konfigurierbare Parameter | Die Eingabe von Pfaden, Zeitplänen und Benachrichtigungen macht den EA flexibel und anpassungsfähig an verschiedene Handelsumgebungen. |
Anlagen
| Dateiname | Version | Beschreibung |
|---|---|---|
| reporting_processor.py | Python-Skript, das eine CSV-Datei mit der Handelshistorie lädt, zusammenfassende Analysen (Nettogewinn, Handelsanzahl, Top-Symbol) berechnet, einen PDF-Bericht über FPDF erstellt und optional ältere Berichte bereinigt. | |
| Reporting EA.mq5 | 1.0 | MetaTrader 5 Expert Advisor, der die letzten 30 Tage des Handelsverlaufs in eine CSV-Datei exportiert, processor.py aufruft, seinen Exit-Code erfasst, auf das generierte PDF prüft und eine Push-Benachrichtigung sendet. |
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/18882
Warnung: Alle Rechte sind von MetaQuotes Ltd. vorbehalten. Kopieren oder Vervielfältigen untersagt.
Dieser Artikel wurde von einem Nutzer der Website verfasst und gibt dessen persönliche Meinung wieder. MetaQuotes Ltd übernimmt keine Verantwortung für die Richtigkeit der dargestellten Informationen oder für Folgen, die sich aus der Anwendung der beschriebenen Lösungen, Strategien oder Empfehlungen ergeben.
Implementierung von praktischen Modulen aus anderen Sprachen in MQL5 (Teil 03): Zeitplan-Modul von Python, das OnTimer-Ereignis auf Steroiden
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 76): Verwendung von Mustern des Awesome Oszillators und der Envelope-Kanäle mit überwachtem Lernen
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 77): Verwendung des Gator-Oszillators und des Akkumulations-/Distributions-Oszillators
Selbstoptimierende Expert Advisors in MQL5 (Teil 11): Eine sanfte Einführung in die Grundlagen der linearen Algebra
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.