最終更新: 2026年06月
ChatGPTでMQL5のEAコードを生成することは、2026年現在、実際に行われているFX EA開発の手法のひとつだ。
「プロンプトを送れば完成品が出てくる」というイメージは半分正しく、半分誤りだ。シンプルな戦略なら初回でコンパイルが通るコードが出てくる。複雑なロジックや細かいMQL5仕様(スプレッド条件・ポジション管理の状態遷移など)になると、複数回の修正サイクルが必要になる。
本稿では、実際にChatGPT(GPT-4o)でMQL5コードを生成する際のプロンプト設計、よくあるエラーパターン、動作検証の手順を整理する。
免責事項: EAは損失を生む可能性があります。生成されたコードは必ずデモ口座で検証してください。
生成AIでEA開発が変わったこと
まず現状を正直に述べる。
変わったこと:
- MQL5の文法を完全に覚えていなくてもコードが出てくる
- ボイラープレート(OnInit/OnTick構造・ハンドル管理・リリース処理)が自動化される
- エラーメッセージをそのまま貼り付けて修正依頼できる
- アイデアを実装するまでの時間が大幅に短縮された
変わらないこと:
- どういう戦略でエントリーするかの設計は人間が考える
- バックテスト・フォワードテストによる検証は必須
- 生成されたコードが意図通りに動くかの確認は人間が行う
基本的なプロンプト設計
コードの品質は、プロンプトの具体性に比例する。
低品質になるプロンプト(悪い例)
RSIとMACDを使ったEAを作ってください。
何も決まっていない。パラメータ・エントリー条件・SL/TP・ロット管理——全部曖昧だ。生成されるコードも曖昧になる。
高品質になるプロンプト(良い例)
以下の仕様でMQL5のEAを生成してください。
【環境】
- プラットフォーム: MT5(MQL5)
- 使用ライブラリ: CTrade, CPositionInfo
【エントリー条件】
ロング:
- EMA(20) > EMA(50)(トレンドフィルター)
- RSI(14) が 45〜65 の範囲内
- 前バーが陽線(Close > Open)
ショート:
- EMA(20) < EMA(50)
- RSI(14) が 35〜55 の範囲内
- 前バーが陰線
- 同方向ポジションが既存の場合は新規エントリー禁止
【エグジット条件】
- ストップロス: エントリー時ATR(14) × 1.5 pips
- テイクプロフィット: エントリー時ATR(14) × 2.5 pips
- トレーリングストップ: なし
【リスク管理】
- 1トレードリスク: 口座残高の1%
- ロット: SL幅から自動計算(SymbolInfoDouble使用)
【入力パラメータ(全て外部公開)】
- MagicNumber: 12345
- EMA_Fast: 20
- EMA_Slow: 50
- RSI_Period: 14
- ATR_Period: 14
- RiskPercent: 1.0
【コード品質要件】
- インジケータハンドルはOnInit()で作成、OnDeinit()でRelease
- CopyBuffer()の戻り値を必ずチェック
- バッファ参照は[1](前バー確定値)を使用
- Print()でエラーログを出力
- OnTick()内では新バー開始時のみメインロジックを実行
【出力】
MQL5コードのみ。コメント・説明文は最小限。
このレベルで書くと、コンパイルが通るコードが出てくる確率が大幅に上がる。
よくある生成エラーと対処法
ChatGPTが生成したMQL5コードには、特定のパターンのエラーが出やすい。代表的なものと修正プロンプトを示す。
エラー1:CopyBuffer()の戻り値未チェック
よくある生成コード:
double rsi_buf[];
CopyBuffer(handle_rsi, 0, 0, 3, rsi_buf); // 戻り値チェックなし
double rsi = rsi_buf[1]; // CopyBufferが失敗していたら未定義動作
修正後の正しいコード:
double rsi_buf[];
ArraySetAsSeries(rsi_buf, true);
if (CopyBuffer(handle_rsi, 0, 0, 3, rsi_buf) < 3) {
Print("RSIバッファ取得失敗");
return;
}
double rsi = rsi_buf[1]; // 前バーの確定値
修正プロンプト:
生成されたコードのCopyBuffer()呼び出しを全て確認し、戻り値チェック
(if (CopyBuffer(...) < 必要な要素数) return;)を追加してください。
また、ArraySetAsSeries(buf, true)をCopyBufferの前に追加してください。
エラー2:ロット計算の誤り
よくある生成コード(問題あり):
double lot = AccountInfoDouble(ACCOUNT_BALANCE) * RiskPercent / 100.0 / stop_pips;
// ← stop_pipsの単位が混乱していることが多い
正しいロット計算:
double CalcLotSize(double stop_distance_points) {
double account_balance = AccountInfoDouble(ACCOUNT_BALANCE);
double risk_amount = account_balance * RiskPercent / 100.0;
double tick_value = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE);
double tick_size = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE);
if (tick_value <= 0 || tick_size <= 0 || stop_distance_points <= 0)
return SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN);
double lot = risk_amount / (stop_distance_points / tick_size * tick_value);
double lot_min = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN);
double lot_max = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MAX);
double lot_step = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_STEP);
lot = MathMax(lot_min, MathMin(lot_max, lot));
lot = MathRound(lot / lot_step) * lot_step;
return lot;
}
修正プロンプト:
ロット計算関数を修正してください。
stop_distance はATR × 係数で計算したpoints単位の値です。
SymbolInfoDouble(SYMBOL_TRADE_TICK_VALUE)とSYMBOL_TRADE_TICK_SIZEを
使って正確に計算してください。lot_step に合わせた丸め処理も必須です。
エラー3:ポジション重複エントリー
よくある生成コード(問題あり):
if (PositionsTotal() == 0) {
trade.Buy(...);
}
マジックナンバーを指定しないと、他のEAのポジションも含めてカウントされる。
正しい実装:
bool HasPositionByMagic(int magic) {
for (int i = PositionsTotal() - 1; i >= 0; i--) {
ulong ticket = PositionGetTicket(i);
if (PositionSelectByTicket(ticket)) {
if ((int)PositionGetInteger(POSITION_MAGIC) == magic &&
PositionGetString(POSITION_SYMBOL) == Symbol()) {
return true;
}
}
}
return false;
}
// OnTick内で使用
if (!HasPositionByMagic(MagicNumber)) {
// エントリーロジック
}
修正プロンプト:
ポジション確認ロジックを修正してください。
MagicNumber と Symbol() の両方で絞り込んだ HasPosition() 関数を作り、
PositionsTotal() の代わりに使ってください。
エラー4:インジケータハンドルの不適切な管理
よくある生成コード(問題あり):
void OnTick() {
int handle_rsi = iRSI(Symbol(), PERIOD_CURRENT, 14, PRICE_CLOSE); // OnTickで毎回作成
// ...
IndicatorRelease(handle_rsi); // Releaseを忘れることもある
}
正しい実装:
// グローバル変数で保持
int g_handle_rsi;
int g_handle_ema_fast;
int g_handle_ema_slow;
int g_handle_atr;
int OnInit() {
g_handle_rsi = iRSI(Symbol(), PERIOD_CURRENT, 14, PRICE_CLOSE);
g_handle_ema_fast = iMA(Symbol(), PERIOD_CURRENT, 20, 0, MODE_EMA, PRICE_CLOSE);
g_handle_ema_slow = iMA(Symbol(), PERIOD_CURRENT, 50, 0, MODE_EMA, PRICE_CLOSE);
g_handle_atr = iATR(Symbol(), PERIOD_CURRENT, 14);
if (g_handle_rsi == INVALID_HANDLE || g_handle_ema_fast == INVALID_HANDLE ||
g_handle_ema_slow == INVALID_HANDLE || g_handle_atr == INVALID_HANDLE) {
Print("インジケータ初期化失敗");
return INIT_FAILED;
}
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason) {
IndicatorRelease(g_handle_rsi);
IndicatorRelease(g_handle_ema_fast);
IndicatorRelease(g_handle_ema_slow);
IndicatorRelease(g_handle_atr);
}
動作検証の手順
コードが生成されたら、以下の順序で動作確認する。
手順1:MetaEditorでコンパイル
MetaEditorを開き(MT5のツールメニュー → MetaEditor)、生成コードを貼り付けてF7でコンパイル。エラーが出たら、エラーメッセージをそのままChatGPTに貼り付けて修正依頼。
// ChatGPTへの修正依頼フォーマット
以下のコンパイルエラーを修正してください。
【エラーメッセージ】
error: 'OnTick' - wrong parameters count (ea_test.mq5, 45, 5)
error: 'CopyBuffer' - undeclared identifier (ea_test.mq5, 67, 5)
【エラーが出たコード箇所】
(該当行の前後10行を貼り付ける)
手順2:ストラテジーテスターで動作確認
コンパイルが通ったら、MT5のストラテジーテスターでバックテストを実行。まず短期間(1〜3ヶ月)で動作確認し、以下を確認する。
- トレードが発生しているか: 0トレードの場合、エントリー条件が厳しすぎるかロジックに誤りがある
- ロットが正常か: 0.01lot固定や異常なlot数になっていないか
- SL/TPが設定されているか: 注文履歴でSL/TPを確認
- グラフの形が妥当か: 急激な資金曲線の崩壊は何かがおかしい
手順3:デモ口座でのフォワードテスト
バックテストで問題がなければ、デモ口座で1〜3ヶ月のフォワードテストを行う。バックテストとフォワードテストの乖離が大きい場合(PFが大きく下がるなど)、過学習か実装上のバグを疑う。
プロンプト集(コピペで使える)
よく使うパターンのプロンプトをまとめる。
スプレッドフィルター追加:
エントリー条件にスプレッドフィルターを追加してください。
現在のスプレッドが SymbolInfoInteger(Symbol(), SYMBOL_SPREAD) で取得でき、
20ポイント(2.0pips)を超えている場合はエントリーしない条件を追加してください。
時間帯フィルター追加:
東京時間・ロンドン時間のみエントリー可能にしてください。
東京: 9:00〜18:00 JST(UTC+9)
ロンドン: 15:00〜24:00 JST
MqlDateTime を使って TimeCurrent() から現在時刻を取得し、
有効時間帯以外はエントリーしない条件を追加してください。
トレーリングストップ追加:
以下の条件でトレーリングストップを追加してください。
- エントリーからの含み益が ATR(14) × 1.0 を超えたら、
SLを ATR(14) × 0.5 の含み益確保ラインに移動する
- その後は価格がATR(14) × 0.5 分逆行するたびにSLをスライドさせる
- PositionModify() を使って実装する
ChatGPT vs Claude:MQL5コード生成の比較
2026年時点での主観的な比較。
| 観点 | ChatGPT(GPT-4o) | Claude(Sonnet) | |---|---|---| | 初回コードの品質 | 同程度 | 同程度 | | エラー修正の精度 | 高い | 高い | | 日本語プロンプトへの対応 | 良好 | 良好 | | 長いコードの一貫性 | 中程度 | やや高い | | MQL5特有仕様の知識 | 良好(学習データが多い) | 良好 |
実用上は「どちらを使っても似たような結果」だ。複数のモデルで同じプロンプトを試し、より良いコードを選ぶ使い方が効率的だ。
まとめ
ChatGPTによるMQL5コード生成をうまく使うポイント:
- プロンプトを具体的にする — 曖昧な指示は曖昧なコードを生む
- エラーは丸ごと貼り付ける — エラーメッセージ + 該当行を一緒に渡す
- 修正サイクルを前提にする — 複雑なEAは数回の修正が普通
- 検証を必ず行う — コンパイル通過 → バックテスト → デモフォワードの順
- ロジックは自分で理解する — 理解できないコードを本番で動かさない
AIが担うのはコードの「書き起こし」だ。「何を作るか」の設計判断と「本当に正しく動くか」の検証判断は、引き続き人間の仕事だ。
免責事項: 本記事のコードおよびプロンプト例は教育目的のサンプルです。EAは損失を生む可能性があります。FX取引には元本割れリスクがあります。本番運用前に必ずデモ口座で十分な動作検証を行ってください。
