English 日本語
preview
Entwicklung des Price Action Analysis Toolkit (Teil 34): Umwandlung von Marktrohdaten in Prognosemodellen mithilfe einer fortschrittlichen Pipeline der Datenerfassung

Entwicklung des Price Action Analysis Toolkit (Teil 34): Umwandlung von Marktrohdaten in Prognosemodellen mithilfe einer fortschrittlichen Pipeline der Datenerfassung

MetaTrader 5Beispiele |
106 0
Christian Benjamin
Christian Benjamin
In der dynamischen Welt des Handels hängt das Streben nach einem Wettbewerbsvorteil oft von der Fähigkeit ab, historische Kursbewegungen zu entschlüsseln und zukünftige Entwicklungen vorherzusagen. Die Preisaktionsanalyse, ein wichtiges Instrument für Händler, beinhaltet die Identifizierung von entscheidenden Unterstützungs- und Widerstandsniveaus, die sich aus vergangenen Kursschwankungen ergeben. Diese Niveaus prägen das Verhalten der Märkte und beeinflussen die strategischen Entscheidungen in Handelsumgebungen von Boom und Crash. Doch ohne eine rigorose Methodik zur Erfassung, Verarbeitung und Auswertung historischer Muster wird der Handel spekulativ, ohne die Vorhersagekraft, die eine fundierte Datenanalyse bietet.


Einführung

Das Kursgeschehen und die künftige Kursentwicklung beruhen vollständig auf historischem Verhalten: Entscheidende Unterstützungs- und Widerstandsniveaus kristallisieren sich aus vergangenen Kursausschlägen heraus, und Händler der Indices von Boom und Crash werden von plötzlichen Ausschlägen oft überrumpelt – oder kommen zu spät, um sie zu nutzen. Ohne eine systematische Methode, diese Vergangenheit zu erfassen, zu verarbeiten und daraus zu lernen, ist jeder Handel eine Vermutung.

In dieser Folge von „Entwicklung des Price Action Analysis Toolkit“ stellen wir ein End-to-End-System vor, das rohe MetaTrader 5-Historie in messerscharfe Echtzeit-Handelssignale durch maschinelles Lernen umwandelt. Die beiden Seiten des Motors arbeiten zusammen:

MQL5-Datenerfassung

  • Automatisiertes Stückelung: Ein leichtgewichtiges Skript, das an ein beliebiges Chart des MetaTrader 5 angehängt wird, zerlegt die Historie der Balken von mehreren Symbolen in grössensichere JSON-Datensendungen. Es halbiert dynamisch die Größe der Stücke, wenn sie 14 MiB überschreiten – damit Sie nie wieder an das Upload-Limit von MetaTrader 5 stoßen oder eine CSV-Datei manuell exportieren müssen.
  • Robuste Lieferung: Jede Datensendung wird über WebRequest mit Wiederholungslogik und detaillierter Protokollierung gepostet. Sie erhalten klare Rückmeldungen zu Stück-Bereichen, HTTP-Statuscodes und Fehlern und können so sicherstellen, dass keine Datenlücken in Ihrem Trainingssatz entstehen.

Python ML Back-End

  • Vereinheitlichte Merkmalsmatrix: Eingehende Historie und EA-generierte Logs werden in einer einzigen Tabelle zusammengeführt und vektorisiert, um Spike-Größe, MACD-Divergenz, RSI, ATR, von Kalman abgeleitete Trendflanken, Envelope-Bänder und Prophet-basierte Future-Deltas zu berechnen – alles an einem Ort.
  • Asynchrone Modellkompilierung und Caching: Prophet-Modelle werden einmal pro Symbol angepasst (eine Stunde lang zwischengespeichert) und Gradient-Boosting-Klassifikatoren werden bei Bedarf trainiert, sodass die Live-Analyse nie ins Stocken gerät. Ein globales Fallback-Modell gewährleistet die Abdeckung, wenn einzelne Symboldaten spärlich sind.
  • Umfassende API und CLI: Flask-Endpunkte (/upload_history, /upload_spike_csv, /analyze) handhaben Bulk-Backfills, Live-Sammelschleifen und Echtzeit-Signalanfragen, während eine einheitliche CLI History-Import, Training, Backtesting und Diagnose abdeckt.

Bevor ein Modell lernen kann, Spitzen von Boom und Crash zu antizipieren, benötigt es eine verlässliche Historie mit hohen Volumina. Das Modul History Ingest ist unser Arbeitspferd in Sachen Daten:

  • Chart-agnostische Konsistenz: Unabhängig davon, welches Instrument oder welchen Zeitraum (M1, H1 usw.) Sie testen, wird die Angabe identischer Parameter für die Symbol- und Zeitrahmenauswahl immer denselben Datensatz ergeben – eine wesentliche Voraussetzung für reproduzierbare Forschung.
  • Einhaltung der Größenbeschränkungen: Jede JSON-Datensendung bleibt unter 14 MiB, wodurch die 16-MiB-Obergrenze von MetaTrader 5 oder halb gesendete Daten nicht gefährdet werden.
  • Latenzarmer Betrieb: Selbst 20.000 Balken werden in weniger als einer Sekunde hochgeladen, sodass sowohl umfangreiche Historien als auch Live-Daten möglich sind, ohne den MetaTrader 5 zu verlangsamen.
  • Zentralisierte Protokollierung und Prüfung: Die Ausdrucke zeigen Stück-Indizes, Sendungsgrößen, HTTP-Antwortdetails und Anzahl der Wiederholungsversuche – so können Sie genau nachvollziehen, welche Daten Ihre Python-Engine wann erreicht haben.

Auf dieser Grundlage garantiert unsere Pipeline eine reichhaltige, konsistente Historie, die für das Training von Modellen erforderlich ist, die Preisspitzen erkennen und darauf reagieren, bevor sie Sie überraschen.

Kommende Sektionen:

  1. Es wird unsere Feature-Engineering-Suite unter die Lupe genommen und gezeigt, wie wir rohe Balken in prädiktive Inputs verwandeln.
  2. Vertiefung des Modelltrainings, Caching-Strategien und Leistungsoptimierung.
  3. Demonstration des Einsatzes dieser Modelle in MetaTrader 5 für Signalwarnungen auf dem Chart und Handelsausführung.

Am Ende dieser Serie werden Sie über ein kugelsicheres, vollautomatisches Toolkit verfügen – von der Erfassung historischer Daten bis hin zu ML-gesteuerten Live-Handelssignalen, die Ihnen in schnelllebigen Märkten von Boom und Crash einen Vorteil verschaffen.


Umsetzung

MQL5-Datenerfassung

In diesem Abschnitt wird erläutert, wie die Datenerfassung in MQL5 implementiert wird. Folgen Sie den nachfolgenden schrittweisen Anweisungen, um sie in Ihr Projekt zu integrieren.

Skript-Metadaten und Eingaben

Im oberen Teil des Skripts werden Metadaten wie Copyright, Version und Autor angegeben, gefolgt von vom Nutzer konfigurierbaren Eingabeparametern. Dazu gehören:

  • DaysBack: wie viele Tage historische Daten abgerufen werden sollen.
  • Timeframe: der Zeitrahmen des Charts (z. B. M1).
  • StartChunkBars: anfängliche Größe der zu versendenden Daten-Stücke.
  • Timeout_ms: wie lange auf eine Antwort vom Python-Server gewartet werden soll.
  • MaxRetry: wie oft ein fehlgeschlagener POST wiederholt werden soll.
  • PauseBetween_ms: Pausendauer zwischen POST-Anfragen.
  • PythonURL: der Endpunkt des lokalen Python-Servers.

Durch diese Eingaben lässt sich das Skript an verschiedene Bedürfnisse und Netzwerkumgebungen anpassen.

#property strict
#property script_show_inputs
#property version   "1.0"

input int              DaysBack        = 120;             // how many days of history to fetch
input ENUM_TIMEFRAMES  Timeframe       = PERIOD_M1;       // timeframe for bars
input int              StartChunkBars  = 5000;            // initial slice size (bars)
input int              Timeout_ms      = 120000;          // WebRequest timeout in ms
input int              MaxRetry        = 3;               // retry attempts per chunk
input int              PauseBetween_ms = 200;             // gap between chunk posts
input string           PythonURL       = "http://127.0.0.1:5000/upload_history";

Konstanten und Inline-Hilfsfunktionen

Einige #define-Konstanten werden für die Kontrolle der maximalen JSON-Größe (MAX_BYTES) und der minimalen Daten-Stückgröße (MIN_CHUNK) gesetzt. Dann werden Hilfsfunktionen wie L2S (long to string) und D2S (double to string) für die Formatierung numerischer Werte definiert. Die Funktion add() fügt einen Wert an eine wachsende JSON-Zeichenkette an und fügt optional ein Komma hinzu, um den JSON-Erstellungsprozess später im Skript zu vereinfachen.

#define MAX_BYTES  14000000   // keep under MT5’s 16 MiB limit
#define MIN_CHUNK  1000       // don’t slice smaller than this many bars

inline string L2S(long v)        { return StringFormat("%I64d", v); }
inline string D2S(double v)      { return StringFormat("%.5f", v); }
void add(string& s, const string v, bool comma) { s += v; if(comma) s += ","; }

JSON Builder Funktion

Die Funktion BuildJSON() konstruiert einen JSON-String aus einem Teil der historischen Datenfelder (time, close, high und low). Es erstellt eine saubere JSON-Struktur, die ein Stück historischer Balken von von bis zu darstellt, die zum Senden an das Python-Backend geeignet ist. Dieser Ansatz gewährleistet die Konsistenz und Kompaktheit der Daten und macht gleichzeitig jedes Stück einzeln serialisierbar.

string BuildJSON(
    const string& sym,
    const long& T[], const double& C[],
    const double& H[], const double& L[],
    int from, int to
) {
    // start JSON with symbol & time array
    string j = "{\"symbol\":\"" + sym + "\",\"time\":[";
    for(int i = from; i < to; i++)
        add(j, L2S(T[i]), i < to - 1);
    j += "],\"close\":[";
    // append close prices
    for(int i = from; i < to; i++)
        add(j, D2S(C[i]), i < to - 1);
    // likewise for high
    j += "],\"high\":[";
    for(int i = from; i < to; i++)
        add(j, D2S(H[i]), i < to - 1);
    // and low
    j += "],\"low\":[";
    for(int i = from; i < to; i++)
        add(j, D2S(L[i]), i < to - 1);
    j += "]}";
    return j;
}

POST-Sender mit Wiederholungslogik

PostChunk() ist für das Senden des JSON-Stücks an den Python-Server mittels WebRequest verantwortlich. Es erstellt die HTTP-Header, konvertiert das JSON in ein Byte-Array und führt im Falle von Verbindungsfehlern oder HTTP-Fehlern Wiederholungsversuche bis zu einer MaxRetry-Zahl durch. Bei jedem Versuch werden Statusinformationen protokolliert, was die Fehlersuche bei fehlgeschlagenen Übertragungen erleichtert. Wenn alle Wiederholungsversuche fehlschlagen, wird das Stück übersprungen und der Vorgang abgebrochen.

bool PostChunk(const string& json, int from, int to) {
    // convert the JSON string into a UTF‑8 char array
    char body[];
    StringToCharArray(json, body, 0, StringLen(json), CP_UTF8);
    char reply[];
    string hdr = "Content-Type: application/json\r\n", rep_hdr;

    for(int r = 1; r <= MaxRetry; r++) {
        int http = WebRequest("POST", PythonURL, hdr, Timeout_ms,
                              body, reply, rep_hdr);
        if(http != -1 && http < 400) {
            PrintFormat("Chunk %d-%d  HTTP %d  %s", from, to, http,
                        CharArrayToString(reply, 0, WHOLE_ARRAY, CP_UTF8));
            return true;
        }
        // on failure, log and retry
        PrintFormat("Chunk %d-%d  retry %d failed (http=%d err=%d)",
                    from, to, r, http, GetLastError());
        Sleep(500);
    }
    return false;
}

Hauptlogik in OnStart()

Die Hauptroutine beginnt mit der Protokollierung, dass der Uploader bereit ist, und leitet dann das angeforderte Zeitfenster (t1 ... t2) aus der aktuellen Serverzeit und dem Parameter DaysBack ab. Mithilfe von CopyRates() werden die OHLC-Daten für dieses Fenster abgerufen und das Ergebnis in separate Arrays unterteilt – Zeitstempel, Schlusskurs, Hoch und Tief – damit die Informationen effizient serialisiert werden können.

Balkendaten werden in Stücken übertragen.  Die Schleife beginnt mit der nutzerdefinierten Größe StartChunkBars, konvertiert diesen Teil mittels BuildJSON() in eine JSON-Datensendung und überprüft, ob die Datensendung kleiner als MAX_BYTES ist.  Wenn die Datensendung den Grenzwert überschreitet, wird die Größe des Stücks halbiert, bis die Datensendung passt oder der Sicherheitsschwellenwert MIN_CHUNK erreicht ist.  Ein gleichartiges Stück wird mit PostChunk() an das Python-Backend gesendet, das Skript pausiert für PauseBetween_ms und fährt dann mit dem nächsten Stück fort.

int OnStart() {
    Print("History Ingestor v1.0 ready (timeout=", Timeout_ms, " ms)");
    datetime t2 = TimeCurrent();
    datetime t1 = t2 - (datetime)DaysBack * 24 * 60 * 60;

    // 1) Pull bar history from MT5
    MqlRates r[];
    int total = CopyRates(_Symbol, Timeframe, t1, t2, r);
    if(total <= 0) {
        Print("CopyRates error ", GetLastError());
        return INIT_FAILED;
    }
    ArraySetAsSeries(r, false);

    // 2) Unpack into simple arrays
    long   T[];  double Cl[], Hi[], Lo[];
    ArrayResize(T, total);
    ArrayResize(Cl, total);
    ArrayResize(Hi, total);
    ArrayResize(Lo, total);
    for(int i = 0; i < total; i++) {
        T[i]  = r[i].time;
        Cl[i] = r[i].close;
        Hi[i] = r[i].high;
        Lo[i] = r[i].low;
    }

    // 3) Loop over the data in chunks
    for(int i = 0; i < total;) {
        int  step = StartChunkBars;
        bool sent = false;

        // adaptively shrink chunk until it fits
        while(step >= MIN_CHUNK) {
            int to      = MathMin(total, i + step);
            string js   = BuildJSON(_Symbol, T, Cl, Hi, Lo, i, to);
            double size = double(StringLen(js)) / 1e6;
            PrintFormat("Testing %d–%d  size=%.2f MB", i, to, size);

            if(StringLen(js) < MAX_BYTES) {
                // post & advance index
                if(!PostChunk(js, i, to))
                    return INIT_FAILED;
                i    = to;
                sent = true;
                Sleep(PauseBetween_ms);
                break;
            }
            step /= 2;
        }

        // abort if even the minimum chunk is too big
        if(!sent) {
            Print("Unable to fit minimum chunk – aborting");
            return INIT_FAILED;
        }
    }

    Print("Upload finished: ", total, " bars.");
    return INIT_SUCCEEDED;
}

Um den „History Ingestor“ in MetaEditor einzurichten, öffnen Sie MetaTrader 5 und drücken Sie F4, um MetaEditor zu starten, und wählen Sie dann:

Datei → Neu → MQL5-Skript

Geben sie ihm einen Namen (z.B. HistoryIngestor) und beenden Sie den Assistenten; ersetzen Sie die generierte Vorlage durch Ihren vollständigen Code (einschließlich der #Property-Deklarationen und der OnStart-Funktion), speichern Sie es im Ordner Scripts und drücken Sie F7 zum Kompilieren – bestätigen Sie „0 Fehler, 0 Warnungen“. Zurück im MetaTrader 5 Navigator unter Skripte, ziehen Sie HistoryIngestor auf einen Chart und stellen Sie im Eingabedialog Parameter ein wie

DaysBack, Timeframe, Stückgrößen, Timeouts und PythonURL

Stellen Sie sicher, dass Sie Ihre PythonURL-Domäne unter zulassen:

Werkzeuge → Optionen → Expert Advisors

Dies gilt für WebRequest-Aufrufe und stellt sicher, dass genügend der Chart-Historie geladen ist, damit CopyRates die angeforderten Balken abrufen kann. Nachdem Sie auf OK geklickt haben, beobachten Sie auf den Registerkarten Experten und Journal den Fortschritt des Uploads und eventuelle Wiederholungs- oder Fehlermeldungen.

Python ML Back-End

Dieses System stützt sich auf eine Reihe von Python-Bibliotheken (einschließlich Modellen für die Spike-Erkennung), aber dieser Artikel konzentriert sich in erster Linie auf die Datenerfassung; andere Komponenten werden in späteren Ausgaben behandelt. Nachfolgend finden Sie eine vollständige Liste der Bibliotheken von Drittanbietern mit Angabe ihres Verwendungszwecks, gefolgt von den verwendeten Standardbibliotheksmodulen:

Bibliotheken von Drittanbietern

  • numpy, pandas: Array- und DataFrame-Verarbeitung
  • pyarrow (oder fastparquet): Serialisierung spaltenförmiger Daten
  • flask: leichtgewichtige Web-API
  • MetaTrader 5: Abruf von Marktdaten
  • ta: Indikatoren für die technische Analyse
  • scikit-learn, joblib: Modelltraining und Persistenz
  • prophet, cmdstanpy: Zeitreihenprognose
  • pykalman: Kalman-Filterung
  • pytz: Unterstützung von Zeitzonen

Sie können sie installieren mit:

pip install numpy pandas pyarrow flask MetaTrader5 ta scikit-learn \
            joblib prophet cmdstanpy pykalman pytz

Die Installation von prophet bezieht automatisch Abhängigkeiten wie tqdm, holidays und lunarcalendar mit ein.

Bereits integriert (keine Installation erforderlich):

os, sys, logging, warnings, argparse, threading, io, datetime, pathlib, typing, time

Paket Zweck des Skripts Wo es verwendet wird
Numpy Vektorisierte Mathematik auf großen Arrays; Grundlage für Pandas, TA-lib, scikit-learn. Alle Hilfsfunktionen (np.diff, np.std, predict_proba, ...).
pandas Zeitreihen DataFrame, schnelle CSV/Parquet IO, rollende Fenster. Konstruktion von DF in /upload_history, Deduplizierung, Feature Engineering, Modelltraining, Backtests.
pyarrow (oder fastparquet) Engine für df.to_parquet() / read_parquet(); viel kleiner und schneller als CSV, hält die Zeitstempel im Nanosekundenbereich.
cDisk-Speicherung der hochgeladenen Historie pro Symbol.
flask Leichtgewichtiger HTTP-Server mit den Funktionen /upload_history, /upload_spike_csv, /analyze. Konvertiert JSON – Python. Alle REST-Endpunkte.
MetaTrader 5 Python-Brücke zu einem MetaTrader 5 Terminal ohne Header: login, copy_rates_range , symbol subscription.
Geschichtsimport, Live-Sammelschleife, Backtester.
ta Reine Python-Indikatoren für die technische Analyse (MACD, RSI, ATR). Merkmale macd_div, rsi_val, offline_atr.
scikit-learn Kern des maschinellen Lernens (StandardScaler + GradientBoostingClassifier + Pipeline). Training von Modellen, Wahrscheinlichkeitsableitung in /analyze und back-test.
joblib Schnelle (De-)Serialisierung von scikit-Modellen; implementiert den Modell-Cache pro Symbol. joblib.dump/load überall models/*.pkl gelesen oder geschrieben werden.
cmdstanpy Stan-Backend, in das Prophet kompiliert wird; ohne dieses Backend ist Prophet nicht einsetzbar. Wird indirekt von Prophet während fit() importiert.
pykalman Lineare Kalman-Filter-Glättung; liefert die Steigung der letzten/5-Balken. kalman_slope() Funktion.
pytz Explizite UTC-Lokalisierung von Datetime-Objekten zur Vermeidung von Verwechslungen zwischen Broker- und Systemzeit. Umrechnungen in Historie/Backtestbereiche.
prophet Trendprognose mit niedriger Frequenz; bietet „Delta“-Funktion (Schätzung zukünftiger Preise). prophet_delta()-Helfer und asynchroner Kompilierungs-Cache.

Als Nächstes befassen wir uns mit dem Teil des Codes, der für die Datenerfassung und -speicherung zuständig ist – direkt vor dem Modelltraining.

Empfang der MetaTrader 5 Historie über WebRequest

Auf der Python-Seite wird eine leichtgewichtige Flask-API (normalerweise unter http://127.0.0.1:5000/upload_history) eingerichtet, um eingehende HTTP-POST-Anfragen zu bearbeiten. Wenn das MQL5-Skript eine JSON-Sendung mit historischen Daten (Symbolname, Zeitstempel, OHLC-Arrays) sendet, analysiert und validiert dieser Flask-Endpunkt die Daten. Dadurch wird die manuelle CSV-Bearbeitung vermieden und sichergestellt, dass das Python-Backend Daten in Echtzeit und automatisch von jedem MetaTrader 5-Chart oder EA-Skript empfangen kann, das den Uploader verwendet.

@app.route('/upload_history', methods=['POST'])
def upload_history():
    data = request.get_json()
    df = pd.DataFrame({
        'time': pd.to_datetime(data['time'], unit='s'),
        'close': data['close'],
        'high': data['high'],
        'low': data['low']
    })
    symbol = data['symbol']
    os.makedirs('uploaded_history', exist_ok=True)
    df.to_parquet(f'uploaded_history/{symbol}.parquet', index=False)
    return jsonify({"status": "ok", "rows": len(df)})

Speichern und Vorverarbeiten der Daten

Nach dem Empfang wird die JSON-Datensendung in einen Pandas DataFrame geparst und optional in einer lokalen Datei (z. B. .parquet, .csv oder .feather) gespeichert oder in eine Zeitseriendatenbank geschrieben. Dies sorgt für Langlebigkeit und ermöglicht es dem System, vergangene Marktbedingungen bei Bedarf zu wiederholen. Die aufgenommenen Balkendaten werden bereinigt, dedupliziert und mit Zeitstempeln indiziert, um ein konsistentes Verhalten bei wiederholten Uploads oder Sitzungen zu gewährleisten. Die Vorverarbeitung kann auch eine Normalisierung der Zeitzonen oder eine Null-Bar-Filterung umfassen.

def load_preprocess(symbol):
    df = pd.read_parquet(f'uploaded_history/{symbol}.parquet')
    df.drop_duplicates(subset='time', inplace=True)
    df.set_index('time', inplace=True)
    return df

Pipeline für die Eingenschaftsentwicklung

Die rohe OHLC-Historie wird in eine umfangreiche Merkmalsmatrix umgewandelt, die sowohl klassische technische Indikatoren als auch ML-relevante Metriken enthält. Diese Merkmale können Spike-Intensität (nutzerdefinierte Formeln), MACD-Werte, RSI, ATR, Kalman-gefilterte Steigungen und von Prophet generierte Trenddeltas umfassen. Diese Funktionen ermöglichen es dem Modell, sowohl die kurzfristige Volatilität als auch den langfristigen Trendkontext zu verstehen, was für die korrekte Vorhersage von Preisspitzen oder signifikanten Ausbrüchen entscheidend ist.

def generate_features(df):
    df['return'] = df['close'].pct_change()
    df['volatility'] = df['return'].rolling(10).std()
    df['range'] = df['high'] - df['low']
    df['spike'] = (df['range'] > df['range'].rolling(50).mean() * 2).astype(int)
    return df.dropna()

Zwischenspeicherung und Verwaltung des Modells pro Symbol

Für jedes aufgenommene Symbol unterhält das Python-System ein ML-Modell pro Symbol. Diese Modelle werden entweder anhand der hochgeladenen historischen Daten neu trainiert oder schrittweise aktualisiert. Sie werden serialisiert (über joblib, Pickle oder ONNX) und in einem speziellen Cache gespeichert. Dieses Design macht es einfach, das neueste Modell für jedes Symbol zu laden, wenn Signale bedient werden müssen, was sowohl Reproduzierbarkeit als auch Geschwindigkeit ermöglicht.

def train_model(symbol, df):
    X = df[['return', 'volatility', 'range']]
    y = df['spike']
    model = RandomForestClassifier(n_estimators=100)
    model.fit(X, y)
    os.makedirs('models', exist_ok=True)
    joblib.dump(model, f'models/{symbol}_model.pkl')
    return model

Befehlszeilen- und API-Zugriff für Training und Inferenz

Das Python-Tool bietet sowohl Befehlszeilen-Dienstprogramme (z. B. python train.py --symbol BOOM500) als auch Live-Flask-Endpunkte (z. B. /predict), um das Modelltraining auszulösen, Backtests durchzuführen oder Live-Vorhersagen abzurufen. Diese doppelte Schnittstelle unterstützt sowohl Batch-Operationen als auch die Echtzeitintegration mit EAs oder Dashboards. Sobald ein Modell trainiert ist, kann ein MQL5 EA beispielsweise später den /predict Endpunkt abfragen und „BUY“, „SELL“ oder „NO ACTION“ Signale erhalten.

@app.route('/predict', methods=['POST'])
def predict():
    data = request.get_json()
    features = pd.DataFrame([data['features']])
    model = joblib.load(f"models/{data['symbol']}_model.pkl")
    prediction = model.predict(features)[0]
    return jsonify({'signal': 'BUY' if prediction == 1 else 'NO ACTION'})

Nachbesetzung, Retraining und kontinuierliches Lernen

Das Erfassungssystem kann auch in einem kontinuierlichen Modus arbeiten, d. h. es kann auf neue historische Slices oder Live-Balken warten, sobald diese eintreffen, und ein periodisches Retraining oder Signalerzeugung auslösen. Dies unterstützt adaptive Modelle, die auf dem neuesten Stand bleiben, wenn sich das Marktverhalten ändert. Dies ist besonders wertvoll bei synthetischen Instrumenten wie Boom/Crash, die ihre Volatilität oder Spike-Häufigkeit im Laufe der Zeit ändern können.

def backfill_and_train(symbol):
    df = load_preprocess(symbol)
    df = generate_features(df)
    train_model(symbol, df)

Protokollierungs-, Überwachungs- und Debugging-Tools

Um die Transparenz zu unterstützen, protokolliert die Python-Seite jeden Upload, jeden Schritt der Feature-Generierung, jedes Ereignis der Modelltraining und jedes ausgegebene Signal. Diese Protokolle werden optional in Dateien oder externen Dashboards gespeichert. Dies macht die Pipeline überprüfbar, hilft bei der Nachverfolgung des Modellverhaltens und stellt sicher, dass sowohl Entwickler als auch Händler nachvollziehen können, warum bestimmte Vorhersagen getroffen wurden.

def log_upload(symbol, rows):
    logging.info(f"{symbol} upload received with {rows} rows.")


Historische Datenerfassung

In diesem Abschnitt werde ich zeigen, wie unser automatisiertes System funktioniert. Nachdem wir die Umgebungen auf der MetaTrader 5 und Python Seite konfiguriert haben, navigieren wir mit Hilfe der Eingabeaufforderung zu dem Verzeichnis, in dem sich unser Python Skript befindet: PFAD ZU IHREM ORDNER
C:\Users\hp>cd C:\Users\hp\Pictures\Saved Pictures\Analysis EA
Starten Sie dann den Server mit:
python script_name.py serve
Sie sollten sehen, dass der Server erfolgreich gestartet wurde – in meinem Fall zeigte die Konsole etwas Ähnliches an:
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000

Sobald der Server in Betrieb ist, ziehen Sie das Skript einfach auf den MetaTrader 5 Chart – die Datenerfassung und Integration beginnt sofort.

MetaTrader 5 Experten Registerkarte Protokolle: 

2025.07.28 22:37:58.239 History Ingestor (Crash 1000 Index,M1)  HistoryUploader v3.20  (timeout=120000 ms) ready
2025.07.28 22:37:58.365 History Ingestor (Crash 1000 Index,M1)  Test 0-5000  size=0.22 MB
2025.07.28 22:38:01.895 History Ingestor (Crash 1000 Index,M1)  Chunk 0-5000  HTTP 200  {"rows_written":4990,"status":"ok"}
2025.07.28 22:38:01.895 History Ingestor (Crash 1000 Index,M1)  
2025.07.28 22:38:02.185 History Ingestor (Crash 1000 Index,M1)  Test 5000-10000  size=0.22 MB
2025.07.28 22:38:07.794 History Ingestor (Crash 1000 Index,M1)  Chunk 5000-10000  HTTP 200  {"rows_written":4990,"status":"ok"}
2025.07.28 22:38:07.794 History Ingestor (Crash 1000 Index,M1)  
2025.07.28 22:38:08.118 History Ingestor (Crash 1000 Index,M1)  Test 10000-15000  size=0.22 MB
2025.07.28 22:38:13.531 History Ingestor (Boom 1000 Index,M1)   HistoryUploader v3.20  (timeout=120000 ms) ready
2025.07.28 22:38:13.677 History Ingestor (Boom 1000 Index,M1)   Test 0-5000  size=0.24 MB
2025.07.28 22:38:17.710 History Ingestor (Boom 1000 Index,M1)   Chunk 0-5000  HTTP 200  {"rows_written":4990,"status":"ok"}

Eingabeaufforderung Python Logs: 

Crash 1000 Index            4990 rows
22:38:01  INFO    127.0.0.1 - - [28/Jul/2025 22:38:01] "POST /upload_history HTTP/1.1" 200 -
22:38:01  DEBUG   cmd: where.exe tbb.dll
cwd: None
22:38:02  DEBUG   Adding TBB (C:\Users\hp\AppData\Local\Programs\Python\Python313\Lib\site-packages\
prophet\stan_model\cmdstan-2.33.1\stan\lib\stan_math\lib\tbb) to PATH
22:38:02  DEBUG   input tempfile: C:\Users\hp\AppData\Local\Temp\tmpjw4u6es7\0j91e5cb.json
22:38:02  DEBUG   input tempfile: C:\Users\hp\AppData\Local\Temp\tmpjw4u6es7\lzpoq1nb.json
22:38:02  DEBUG   idx 0
22:38:02  DEBUG   running CmdStan, num_threads: None
22:38:02  DEBUG   CmdStan args: ['C:\\Users\\hp\\AppData\\Local\\Programs\\Python\\Python313
\\Lib\\site-packages\\prophet\\stan_model\\prophet_model.bin', 'random', 'seed=46049', 'data', 
'file=C:\\Users\\hp\\AppData\\Local\\Temp\\tmpjw4u6es7\\0j91e5cb.json', 'init=C:\\Users\\hp\\
AppData\\Local\\Temp\\tmpjw4u6es7\\lzpoq1nb.json', 'output', 'file=C:\\Users\\hp\\AppData\\
Local\\Temp\\tmpjw4u6es7\\prophet_modelo4ioyzqc\\prophet_model-20250728223802.csv', 
'method=optimize', 'algorithm=lbfgs', 'iter=10000']
22:38:02 - cmdstanpy - INFO - Chain [1] start processing
22:38:02  INFO    Chain [1] start processing
22:38:07  DEBUG   cmd: where.exe tbb.dll
cwd: None
Crash 1000 Index            4990 rows
22:38:07  INFO    127.0.0.1 - - [28/Jul/2025 22:38:07] "POST /upload_history HTTP/1.1" 200 -
22:38:07  DEBUG   TBB already found in load path
22:38:07  DEBUG   input tempfile: C:\Users\hp\AppData\Local\Temp\tmpjw4u6es7\flzd3tj5.json
22:38:08  DEBUG   input tempfile: C:\Users\hp\AppData\Local\Temp\tmpjw4u6es7\et_obcyf.json
22:38:08  DEBUG   idx 0
22:38:08  DEBUG   running CmdStan, num_threads: None
22:38:08  DEBUG   CmdStan args: ['C:\\Users\\hp\\AppData\\Local\\Programs\\Python\\Python313
\\Lib\\site-packages\\prophet\\stan_model\\prophet_model.bin', 'random', 'seed=15747', 'data'
, 'file=C:\\Users\\hp\\AppData\\Local\\Temp\\tmpjw4u6es7\\flzd3tj5.json', 'init=C:\\Users\\hp
\\AppData\\Local\\Temp\\tmpjw4u6es7\\et_obcyf.json', 'output', 'file=C:\\Users\\hp\\AppData\\
Local\\Temp\\tmpjw4u6es7\\prophet_modelgjfhjsn1\\prophet_model-20250728223808.csv', 
'method=optimize', 'algorithm=lbfgs', 'iter=10000']
22:38:08 - cmdstanpy - INFO - Chain [1] start processing
22:38:08  INFO    Chain [1] start processing
22:38:10 - cmdstanpy - INFO - Chain [1] done processing
22:38:10  INFO    Chain [1] done processing
22:38:10  INFO    Prophet compiled for Crash 1000 Index
22:38:15 - cmdstanpy - INFO - Chain [1] done processing
22:38:15  INFO    Chain [1] done processing
22:38:15  INFO    Prophet compiled for Crash 1000 Index
22:38:17  DEBUG   cmd: where.exe tbb.dll
cwd: None
Boom 1000 Index             4990 rows
22:38:17  INFO    127.0.0.1 - - [28/Jul/2025 22:38:17] "POST /upload_history HTTP/1.1" 200 -
22:38:17  DEBUG   TBB already found in load path
22:38:17  DEBUG   input tempfile: C:\Users\hp\AppData\Local\Temp\tmpjw4u6es7\9tu4ni1m.json
22:38:17  DEBUG   input tempfile: C:\Users\hp\AppData\Local\Temp\tmpjw4u6es7\dbjg87e6.json
22:38:17  DEBUG   idx 0
22:38:17  DEBUG   running CmdStan, num_threads: None
22:38:17  DEBUG   CmdStan args: ['C:\\Users\\hp\\AppData\\Local\\Programs\\Python\\Python313
\\Lib\\site-packages\\prophet\\stan_model\\prophet_model.bin', 'random', 'seed=45546', 'data',
 'file=C:\\Users\\hp\\AppData\\Local\\Temp\\tmpjw4u6es7\\9tu4ni1m.json', 'init=C:\\Users\\hp
\\AppData\\Local\\Temp\\tmpjw4u6es7\\dbjg87e6.json', 'output', 'file=C:\\Users\\hp\\AppData
\\Local\\Temp\\tmpjw4u6es7\\prophet_modele7mw_egb\\prophet_model-20250728223817.csv', 
'method=optimize', 'algorithm=lbfgs', 'iter=10000']
22:38:17 - cmdstanpy - INFO - Chain [1] start processing
22:38:17  INFO    Chain [1] start processing
Crash 1000 Index            4990 rows
22:38:18  INFO    127.0.0.1 - - [28/Jul/2025 22:38:18] "POST /upload_history HTTP/1.1" 200 -
22:38:23 - cmdstanpy - INFO - Chain [1] done processing
22:38:23  INFO    Chain [1] done processing
22:38:24  INFO    Prophet compiled for Boom 1000 Index
Boom 1000 Index             4990 rows
22:38:27  INFO    127.0.0.1 - - [28/Jul/2025 22:38:27] "POST /upload_history HTTP/1.1" 200 -
Crash 1000 Index            4990 rows
22:38:28  INFO    127.0.0.1 - - [28/Jul/2025 22:38:28] "POST /upload_history HTTP/1.1" 200 -
Boom 1000 Index             4990 rows
22:38:37  INFO    127.0.0.1 - - [28/Jul/2025 22:38:37] "POST /upload_history HTTP/1.1" 200 -
Crash 1000 Index            4990 rows
22:38:38  INFO    127.0.0.1 - - [28/Jul/2025 22:38:38] "POST /upload_history HTTP/1.1" 200 -
22:38:49  DEBUG   cmd: where.exe tbb.dll

Aus den Protokollen geht hervor, dass 4.990 Zeilen historischer Daten für die Indizes Crash 1000 und Boom 1000 abgerufen und erfolgreich an den Python-Server gesendet wurden (HTTP 200), woraufhin CmdStan über cmdstanpy Optimierungsketten durchlief, um Prophet-Modelle für jeden Index zu kompilieren – wobei Start und Abschluss jeder Kette sowie die abschließende Meldung „Prophet compiled“ für beide Instrumente bestätigt wurden.


Schlussfolgerung

Wir haben erfolgreich historische Kursdaten in MetaTrader 5 gesammelt, sie an einen Python-Dienst weitergeleitet und für das Modelltraining gespeichert – ein Beweis dafür ist sowohl in der Registerkarte Experten von MetaTrader 5 als auch in den Konsolenprotokollen unseres PCs zu finden. Diese robuste Pipeline der Datenerfassung bildet die Grundlage für unser System zur Erkennung plötzlicher Ausreißer (spikes). Als Nächstes werden wir das Erkennungsmodell in Python trainieren und es über einen MQL5 EA in den MetaTrader 5 integrieren, sodass Echtzeitsignale direkt auf der Handelsplattform erzeugt und empfangen werden können. Wir haben erfolgreich historische Kursdaten in MetaTrader 5 gesammelt, sie an einen Python-Dienst weitergeleitet und für das Modelltraining gespeichert – ein Beweis dafür ist sowohl in der Registerkarte Experten von MetaTrader 5 als auch in den Konsolenprotokollen unseres PCs zu finden. Diese robuste Pipeline der Datenerfassung bildet die Grundlage für unser System zur Erkennung plötzlicher Ausreißer (spikes).

Als Nächstes werden wir das Erkennungsmodell in Python trainieren und es über einen MQL5 EA in den MetaTrader 5 integrieren, sodass Echtzeitsignale direkt auf der Handelsplattform erzeugt und empfangen werden können.

Sollten Sie bei der Einrichtung auf Schwierigkeiten stoßen, können Sie mich jederzeit kontaktieren.




   
Chart Projector
Analytical Comment
Analytics Master
Analytics Forecaster 
Volatility Navigator
Der Mean Reversion Signal Reaper
Signal Pulse 
Metrics Board 
External Flow
VWAP
Heikin Ashi   FibVWAP  
RSI DIVERGENCE
Parabolic Stop and Reverse (PSAR) 
Quarters Drawer Script
Intrusion Detector
TrendLoom Tool  Quarters Board 
ZigZag Analyzer  Correlation Pathfinder  Market Structure Flip Detector Tool
Correlation Dashboard   Währungsstärkemesser 
PAQ-Analyse-Tool 
Dual EMA Fractal Breaker
Pin-Bar, Engulfing und RSI-Divergenz
Liquidity Sweep Werkzeug zum Ausbrechen aus dem Eröffnungsbereich Ausleger und Crash Interceptor CCI Zero-Line EA
Erkennen von Kerzenmuster Kerzenerkennung mit Ta-Lib Tool Candle Range MetaTrader 5 Datenabruf    

Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/18979

Beigefügte Dateien |
engine.py (23.27 KB)
Klassische Strategien neu interpretieren (Teil 14): Analyse mehrerer Strategien Klassische Strategien neu interpretieren (Teil 14): Analyse mehrerer Strategien
In diesem Artikel setzen wir unsere Erforschung der Erstellung eines Ensembles von Handelsstrategien und der Verwendung des MT5 genetischen Optimierers zur Abstimmung der Strategieparameter fort. Heute haben wir die Daten in Python analysiert. Dabei hat sich gezeigt, dass unser Modell besser vorhersagen kann, welche Strategie besser abschneiden wird, und eine höhere Genauigkeit erreicht als die direkte Vorhersage der Marktrenditen. Als wir unsere Anwendung jedoch mit ihren statistischen Modellen testeten, fielen unsere Leistungswerte drastisch ab. In der Folge stellten wir fest, dass der genetische Optimierer leider stark korrelierte Strategien bevorzugte, was uns dazu veranlasste, unsere Methode zu überarbeiten, um die Stimmgewichte fest zu halten und die Optimierung stattdessen auf Indikatoreinstellungen zu konzentrieren.
MQL5-Handelswerkzeuge (Teil 6): Dynamisches holografisches Dashboard mit Impulsanimationen und Steuerelementen MQL5-Handelswerkzeuge (Teil 6): Dynamisches holografisches Dashboard mit Impulsanimationen und Steuerelementen
In diesem Artikel erstellen wir ein dynamisches holografisches Dashboard in MQL5 zur Überwachung von Symbolen und Zeitrahmen mit RSI, Volatilitätswarnungen und Sortieroptionen. Wir fügen eine pulsierende Animationen, interaktive Schaltflächen und holografische Effekte hinzu, um das Tool visuell ansprechend und reaktionsschnell zu gestalten.
MQL5-Handelswerkzeuge (Teil 7): Informatives Dashboard für Multi-Symbol-Positionen und Kontoüberwachung MQL5-Handelswerkzeuge (Teil 7): Informatives Dashboard für Multi-Symbol-Positionen und Kontoüberwachung
In diesem Artikel entwickeln wir ein Informations-Dashboard in MQL5 zur Überwachung von Multi-Symbol-Positionen und Kontometriken wie Kontostand, Kapital und freie Marge. Wir implementieren ein sortierbares Raster mit Echtzeit-Updates, CSV-Export und einen leuchtenden Header-Effekt, um die Nutzerfreundlichkeit und den visuellen Reiz zu verbessern.
Datenwissenschaft und ML (Teil 46): Aktienmarktprognosen mit N-BEATS in Python Datenwissenschaft und ML (Teil 46): Aktienmarktprognosen mit N-BEATS in Python
N-BEATS ist ein revolutionäres Deep-Learning-Modell, das für die Prognose von Zeitreihen entwickelt wurde. Es wurde veröffentlicht, um die klassischen Modelle für Zeitreihenprognosen wie ARIMA, PROPHET, VAR usw. zu übertreffen. In diesem Artikel werden wir dieses Modell erörtern und es für die Vorhersage des Aktienmarktes verwenden.