プライスアクション分析ツールキットの開発(第34回):高度なデータ取得パイプラインを用いた生の市場データからの予測モデル構築
はじめに
プライスアクションと将来の価格変動はすべて過去の挙動に依存しています。重要なサポートラインやレジスタンスラインは過去の価格変動から形成され、Boom-and-Crashトレーダーは突然のスパイクに驚かされたり、機会を逃してしまうことがあります。過去のデータを体系的に取得、処理、学習する方法がなければ、すべての取引は推測に過ぎません。
「プライスアクション分析ツールキット開発」の今回の記事では、MetaTrader 5の生データをエンドツーエンドで処理し、機械学習を用いてリアルタイムの取引シグナルに変換するフレームワークを紹介します。このエンジンは以下の2つの側面で連携します。
MQL5データ取得
- 自動チャンク分割:任意のMetaTrader 5チャートに取り付け可能な軽量スクリプトが、複数銘柄のバー履歴をサイズ安全なJSONペイロードに分割します。14MiBを超えた場合は動的にチャンクサイズを半分にするため、MetaTrader 5のアップロード制限に引っかかることや、CSVを手動でエクスポートする必要はありません。
- 堅牢な送信:各ペイロードはWebRequestでPOSTされ、リトライロジックと詳細なログ記録がおこなわれます。チャンク範囲、HTTPステータスコード、およびエラーの詳細なフィードバックが得られるため、学習セットにデータ欠損が生じません。
Python MLバックエンド
- 統合特徴量行列:取得した履歴データとEAが生成したログを統合してベクトル化し、スパイクの大きさ、MACDのダイバージェンス、RSI、ATR、カルマンフィルタによるトレンド傾き、エンベロープバンド、Prophetによる将来の変化量などを1つの表にまとめます。
- 非同期モデル構築とキャッシュ:Prophetモデルは銘柄ごとに1回だけ適合され(1時間キャッシュ)、勾配ブースティング分類器はオンデマンドで学習します。これにより、ライブ分析でも処理が止まることはありません。データが不足している場合でも、グローバルフォールバックモデルが対応します。
- 包括的APIとCLI:Flaskエンドポイント(/upload_history、/upload_spike_csv、/analyze)がバックフィル、ライブ収集ループ、リアルタイムシグナル要求を処理し、統一されたCLIは履歴インポート、学習、バックテスト、診断をカバーします。
モデルがBoom-and-Crashのスパイクを予測するには、信頼性が高く大量の履歴データが必要です。History Ingestモジュールはそのためのデータワークホースです。
- チャート非依存の一貫性:どの通貨ペアや時間足(M1、H1など)をテストする場合でも、同一の銘柄・時間足選択パラメータを指定すれば、常に同じデータセットが返ります。再現性のある研究には不可欠です。
- サイズ制限の遵守:すべてのJSONペイロードは14MiB未満に収められ、MetaTrader 5の16MiB上限や不完全な送信のリスクはありません。
- 低遅延操作:20,000バーでも1秒以内でアップロード可能なため、バックフィルやライブポーリングがMetaTrader 5を遅延させることはありません。
- ログと監査の一元化:チャンクインデックス、ペイロードサイズ、HTTPレスポンス詳細、リトライ回数が出力され、どのデータがいつPythonエンジンに到達したかを正確に追跡できます。
この基盤により、スパイクを検知し、驚かされる前に行動できるモデルを学習させるために必要な、豊富で一貫性のある履歴データフィードが確保されます。
今後の内容
- 特徴量エンジニアリングスイートの詳細を解説し、生データをどのように予測入力に変換するかを示します。
- モデルの学習、キャッシュ戦略、性能チューニングについて掘り下げます。
- それらのモデルをMetaTrader 5に戻し、チャート上でのシグナルアラートや取引実行に活用する方法を示します。
連載の最後には、履歴データ取得からライブML取引シグナルまでを完全自動化したツールキットを手に入れ、Boom-and-Crash市場で優位に立つことができるようになります。
実装
MQL5データ取得
このセクションでは、MQL5でデータ取得を実装する方法について説明します。以下のステップバイステップの指示に従って、プロジェクトに統合してください。
スクリプトのメタデータと入力パラメータ
スクリプトの冒頭部分では、著作権情報、バージョン、作成者などのメタデータを宣言した後、ユーザーが設定可能な入力パラメータを定義します。主なパラメータは以下の通りです。
- DaysBack:取得する履歴データの日数
- Timeframe:チャートの時間足(例:M1)
- StartChunkBars:送信を試みるデータスライスの初期サイズ
- Timeout_ms:Pythonサーバーからの応答を待つ最大時間(ミリ秒)
- MaxRetry:POSTに失敗した場合の再試行回数
- PauseBetween_ms:POSTリクエスト間の待機時間(ミリ秒)
- PythonURL:ローカルPythonサーバーのエンドポイント
これらの入力パラメータにより、スクリプトはさまざまな要件やネットワーク環境に柔軟に対応できます。
#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";
定数とインラインヘルパー関数
いくつかの#define定数が設定されており、JSONの最大サイズ(MAX_BYTES)や最小チャンクサイズ(MIN_CHUNK)を制御します。その後、L2S(longを文字列に変換)やD2S(doubleを文字列に変換)などのヘルパー関数が定義され、数値を文字列としてフォーマットできるようにしています。さらに、add()関数は、値を増大中のJSON文字列に追加し、必要に応じてカンマも付加します。これにより、スクリプト後半でJSONを組み立てる作業が効率化されます。
#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ビルダー関数
BuildJSON()関数は、履歴データ配列(time、close、high、low)のスライスからJSON文字列を構築します。この関数により、指定された範囲(fromからtoまで)の履歴バーのチャンクを表す、整然としたJSON構造を作成できます。作成されたJSONはPythonバックエンドに送信するのに適しており、各チャンクを個別にシリアライズ可能にすることで、データの一貫性とコンパクトさを確保しています。
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送信
PostChunk()関数は、JSONチャンクをPythonサーバーにWebRequestで送信する役割を担います。この関数では、HTTPヘッダーを構築し、JSONをバイト配列に変換した上で、接続失敗やHTTPエラーが発生した場合にMaxRetry回まで再試行します。各試行ではステータス情報がログに記録されるため、送信失敗時のデバッグが容易になります。すべての再試行が失敗した場合は、そのチャンクはスキップされ、処理は中断されます。
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; }
OnStart()のメインロジック
メインルーチンは、まずアップローダーが準備完了であることをログに記録することから始まります。その後、DaysBackパラメータに基づき、現在のサーバー時刻から要求された履歴ウィンドウ(t1 … t2)を算出します。CopyRates()を使用してその期間のOHLCデータを取得し、結果をタイムスタンプ、終値、高値、安値の別々の配列に分割します。これにより、データを効率的にシリアライズできます。
バーのデータはチャンク単位で送信されます。 ループはユーザーが指定したStartChunkBarsサイズから開始し、そのスライスをBuildJSON()でJSONペイロードに変換します。 作成したペイロードがMAX_BYTESを下回っているかどうかを確認し、超えている場合はペイロードが収まるまでチャンクサイズを半分にします。ただし、最小チャンクサイズのMIN_CHUNKに達した場合はそこで調整を止めます。 条件を満たしたチャンクはPostChunk()を使ってPythonバックエンドに送信され、スクリプトはPauseBetween_msの間一時停止した後、次のスライスの処理に進みます。
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; }
MetaEditorで「History Ingestor」を設定するには、MetaTrader 5を開き、F4キーを押してMetaEditorを起動し、以下を選択します。
[ファイル] → [新規作成] → [MQL5スクリプト]
スクリプトに名前を付けます(例:HistoryIngestor)そしてウィザードを終了します。生成されたテンプレートを、#property宣言やOnStart関数を含む自分のコードで置き換え、Scriptsフォルダに保存します。F7キーを押してコンパイルし、「0 errors, 0 warnings」と表示されることを確認してください。MetaTrader 5のナビゲータでScriptsの下にあるHistoryIngestorをチャートにドラッグし、入力ダイアログで以下のパラメータを調整します。
DaysBack、Timeframe、chunk sizes、timeouts、PythonURL
以下の場所でPythonURLドメインを許可してください。
[ツール] → [オプション] → [エキスパートアドバイザ]
これはWebRequest呼び出しのために必要です。また、CopyRatesが要求されたバーを取得できるように、十分なチャート履歴がロードされていることを確認してください。[OK]をクリックすると、[エキスパート]タブと[操作ログ]タブでアップロードの進捗や再試行、エラーのメッセージを確認できます。
Python MLバックエンド
このシステムは、スパイク検知用のモデルを含む複数のPythonライブラリに依存していますが、本記事では主にデータ取得部分に焦点を当てています。他のコンポーネントについては、今後の記事で取り上げます。以下に、サードパーティライブラリとその目的の完全なリストと、使用される標準ライブラリモジュールを示します。
サードパーティライブラリ
- numpy、pandas:配列やDataFrameの操作
- pyarrow(またはfastparquet):列指向データのシリアライズ
- flask:軽量web API
- MetaTrader 5:市場データの取得
- ta:テクニカル分析指標
- scikit-learn、joblib:モデルの学習と保存
- prophet、cmdstanpy:時系列予測
- pykalman:カルマンフィルタリング
- pytz:タイムゾーンのサポート
これらは以下のコマンドでインストールできます。
pip install numpy pandas pyarrow flask MetaTrader5 ta scikit-learn \ joblib prophet cmdstanpy pykalman pytz
Prophetをインストールすると、tqdm、holidays、lunarcalendarなどの依存ライブラリも自動的にインストールされます。
内蔵(インストール不要)
os, sys, logging, warnings, argparse, threading, io, datetime, pathlib, typing, time
| パッケージ | スクリプト内での用途 | 使用箇所 |
|---|---|---|
| Numpy | 大規模配列上でのベクトル演算。Pandas、TA-lib、scikit-learnの基盤として使用 | すべての特徴量ヘルパー(np.diff、np.std、predict_probaなど) |
| pandas | 時系列DataFrame操作、CSV/Parquetの高速入出力、ローリングウィンドウ | /upload_historyでDataFrame構築、重複削除、特徴量作成、モデル学習、バックテスト |
| pyarrow(またはfastparquet) | df.to_parquet() / read_parquet()のエンジン。CSVより高速・小容量でナノ秒単位タイムスタンプ保持 | アップロードされた履歴データを銘柄ごとにディスク保存 |
| flask | 軽量HTTPサーバー(/upload_history、/upload_spike_csv、/analyze)提供、JSON-Python変換 | すべてのRESTエンドポイント |
| MetaTrader 5 | ヘッドレスMetaTrader 5ターミナルとPythonのブリッジ。ログイン、copy_rates_range、銘柄購読 | 履歴インポート、ライブ収集ループ、バックテスト |
| ta | 純Pythonテクニカル指標(MACD、RSI、ATR) | macd_div、rsi_val、offline_atrの特徴量 |
| scikit-learn | 機械学習コア(StandardScaler、GradientBoostingClassifier、Pipeline) | モデル学習、/analyze内およびバックテストでの確率推定 |
| joblib | scikitモデルの高速シリアライズ/デシリアライズ、銘柄ごとのモデルキャッシュ | models/*.pklの読み書き全般 |
| cmdstanpy | Prophetが内部でコンパイルするStanバックエンド。これがないとProphetは適合不可 | Prophetのfit()時に間接的にインポートされる |
| pykalman | 線形カルマンフィルタによるスムージング。最後のバーや5バーの傾きを返す | kalman_slope()特徴量 |
| pytz | UTCへの明示的な日時ローカライズ、ブローカー時刻とシステム時刻の混乱防止 | 履歴取得・バックテスト範囲の日時変換 |
| prophet | 低周波トレンド予測、「delta」特徴量(将来価格推定値)提供 | prophet_delta()ヘルパー、非同期コンパイルキャッシュ |
次に、モデル学習の直前におこなわれるデータ収集と保存を担当するコード部分について説明します。
WebRequestによるMetaTrader 5履歴データの受信
Python側では、軽量のFlask API(通常はhttp://127.0.0.1:5000/upload_historyで稼働)を用意し、HTTP POSTリクエストの受信を処理します。MQL5スクリプトが、銘柄名、タイムスタンプ、OHLC配列を含む履歴データのJSONペイロードをPOSTすると、このFlaskエンドポイントがデータを解析し、検証します。これにより、手動でCSVを扱う必要がなくなり、Pythonバックエンドは任意のMetaTrader 5チャートやEAスクリプトからアップローダーを使ってリアルタイムにデータを自動で受信できるようになります。
@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)})
データの保存と前処理
受信したJSONペイロードは、まずPandasのDataFrameに解析されます。必要に応じて、ローカルファイル(例:.parquet、.csv、.feather)に保存したり、時系列データベースに書き込んだりすることも可能です。これにより、データの耐久性が確保され、過去の市況を必要に応じて再現することができます。取り込んだバーのデータは、クリーンアップされ、重複が削除され、タイムスタンプをインデックスとして設定することで、アップロードやセッションを繰り返しても一貫した動作を保証します。前処理には、タイムゾーンの正規化やゼロバーのフィルタリングなども含まれることがあります。
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
特徴量エンジニアリングパイプライン
生のOHLC履歴データは、クラシックなテクニカル指標や機械学習に関連する指標を含む豊富な特徴量行列に変換されます。これらの特徴量には、スパイクの強度(独自の計算式)、MACD値、RSI、ATR、カルマンフィルタ処理された傾き、Prophetによるトレンドのデルタなどが含まれる場合があります。これらの特徴量により、モデルは短期的なボラティリティと長期的なトレンドの両方を理解できるようになり、価格スパイクや重要なブレイクアウトを正確に予測するために不可欠な情報を提供します。
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()
銘柄ごとのモデルキャッシュと管理
取り込まれた各銘柄に対して、Pythonシステムは銘柄ごとの機械学習モデルを保持します。これらのモデルは、アップロードされた履歴データを用いて新規に学習するか、あるいはインクリメンタルに更新されます。モデルはjoblib、Pickle、またはONNXを使ってシリアライズされ、専用のキャッシュに保存されます。この設計により、シグナルを提供する際に各銘柄の最新モデルを簡単にロードでき、再現性と処理速度の両方が確保されます。
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
学習と推論のためのコマンドラインおよびAPIアクセス
Pythonツールは、コマンドラインユーティリティ(例:python train.py --symbol BOOM500)およびライブFlaskエンドポイント(例:/predict)の両方を提供しています。これにより、モデルの学習を開始したり、バックテストを実行したり、ライブ予測を取得したりできます。この二重インターフェースにより、バッチ処理だけでなく、EAやダッシュボードとのリアルタイム統合もサポートされます。たとえば、モデルが学習済みの場合、MQL5 EAは後で「/predict」エンドポイントを問い合わせ、「BUY」「SELL」「NO ACTION」といったシグナルを受け取ることができます。
@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'})
バックフィル、再学習、継続的学習
データ取得システムは、継続モードでも動作可能です。新しい履歴チャンクやライブバーの到着を監視し、定期的に再学習やシグナル生成をトリガーすることができます。これにより、市場の挙動が変化しても最新の状態を維持できる適応型モデルをサポートします。特にBoom/Crashのような合成金融商品では、ボラティリティやスパイクの頻度が時間とともに変化するため、この機能は非常に有用です。
def backfill_and_train(symbol): df = load_preprocess(symbol) df = generate_features(df) train_model(symbol, df)
ログ、監視、デバッグツール
透明性を確保するために、Python側では、すべてのアップロード、特徴量生成の各ステップ、モデル学習イベント、生成されたシグナルをログとして記録します。これらのログは、必要に応じてファイルや外部ダッシュボードに保存することも可能です。これにより、パイプラインの監査が可能となり、モデルの挙動を追跡できるだけでなく、開発者やトレーダーが、なぜ特定の予測がおこなわれたのかを理解できるようになります。
def log_upload(symbol, rows): logging.info(f"{symbol} upload received with {rows} rows.")
履歴データの取り込み
このセクションでは、私たちの自動化システムがどのように動作するかを示します。MetaTrader 5側とPython側の環境を設定した後、まずコマンドプロンプトでPythonスクリプトが存在するディレクトリに移動します。フォルダへのパスC:\Users\hp>cd C:\Users\hp\Pictures\Saved Pictures\Analysis EA次に、次のコマンドでサーバーを起動します。python script_name.py serveサーバーが正常に起動したことがわかります。私の場合、コンソールには次のようなものが表示されました。
* Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:5000
サーバーが起動したら、スクリプトをMetaTrader 5チャートにドラッグするだけで、データの取得と統合が即座に開始されます。

MetaTrader 5 [エキスパート]タブのログ
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"}
コマンドプロンプトでのPythonログ
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
ログを見ると、Crash 1000およびBoom 1000の両インデックスに対して4,990行の履歴データが取得され、Pythonサーバーに正常にPOSTされたことが確認できます(HTTP 200)。その後、cmdstanpyを介してCmdStanが各インデックス用のProphetモデルをコンパイルするために最適化チェーンを実行しました。各チェーンの開始と完了、および両インストゥルメントに対する最終的な「Prophet compiled」メッセージが確認されました。
結論
MetaTrader 5で履歴価格データを無事に取得し、Pythonサービスに送信してモデル学習用に保存することができました。これは、MetaTrader 5の[エキスパート]タブやPCのコンソールログの両方で確認できます。この堅牢なデータ取得パイプラインにより、スパイク検知システムの基盤が整いました。次に、Pythonで検知モデルを学習させ、MQL5 EAを通じて再びMetaTrader 5に統合します。これにより、リアルタイムのシグナルを生成し、取引プラットフォーム上で直接受信できるようになります。MetaTrader 5で履歴価格データを無事に取得し、Pythonサービスに送信してモデル学習用に保存することができました。これは、MetaTrader 5の[エキスパート]タブやPCのコンソールログの両方で確認できます。この堅牢なデータ取得パイプラインにより、スパイク検知システムの基盤が整いました。
次に、Pythonで検知モデルを学習させ、MQL5 EAを通じて再びMetaTrader 5に統合します。これにより、リアルタイムのシグナルを生成し、取引プラットフォーム上で直接受信できるようになります。
セットアップ中に問題が発生した場合は、いつでもお気軽にご連絡ください。
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/18979
警告: これらの資料についてのすべての権利はMetaQuotes Ltd.が保有しています。これらの資料の全部または一部の複製や再プリントは禁じられています。
この記事はサイトのユーザーによって執筆されたものであり、著者の個人的な見解を反映しています。MetaQuotes Ltdは、提示された情報の正確性や、記載されているソリューション、戦略、または推奨事項の使用によって生じたいかなる結果についても責任を負いません。
MQL5取引ツール(第7回):複数銘柄ポジションと口座監視のための情報ダッシュボード
MQL5で自己最適化エキスパートアドバイザーを構築する(第10回):行列分解
プライスアクション分析ツールキットの開発(第35回):予測モデルの学習とデプロイ
初心者からエキスパートへ:Reporting EA - ワークフローの設定
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索