MQL5 EA設計実務ノート|signal・execution・risk・exitを分ける理由
MQL5でEAを作る時、最初に整理しておきたいのが責務分離です。
EAは、エントリー条件だけで動いているわけではありません。シグナルを作る処理、注文を出す処理、ロットや保有上限を確認する処理、既存ポジションを管理する処理、ログを出す処理、チャート表示を更新する処理が組み合わさって動いています。
これらを1つの関数や1つのOnTickへ詰め込むと、EAが動かない時に原因を切り分けにくくなります。シグナルが出ていないのか、発注前のリスク制御で止まっているのか、OrderSendで失敗しているのか、既存ポジション管理が優先されているのかを、ログから判断できなくなるためです。
この記事では、MQL5 EA設計におけるsignal・execution・risk・exitの分け方を、開発実務ノートとして整理します。技術講座のように基礎から順番に説明する記事ではなく、開発依頼前・実装前・検証前に確認したい実務判断をまとめます。
完成EAソース全文、外部シート制御、認証、endpoint、token、URL実値、実運用set値、中核Entry条件、中核Trail/Nanpin判定、独自優位性のある売買判定式は公開しません。本記事は、投資判断や売買指示ではなく、EA設計の確認観点を整理するための技術記事です。
- この記事で扱う実務課題
- なぜこの設計判断が必要になるのか
- signal / execution / risk / exit の基本定義
- GATE / SCORE / SPECIAL FILTERS / ENTRY の基本構造
- GATEは売買条件ではなく安全確認
- SCOREは候補評価であり発注許可ではない
- SPECIAL FILTERSは通常条件から分離する
- ENTRYはexecutionへ渡す前の候補整理
- TREND / REVERSE / RANGEでsignalの意味は変わる
- entry条件とrisk条件を混同しない理由
- 発注処理をsignal側に書かない理由
- executionは注文実行と結果確認に集中する
- exitとriskを分ける理由
- 新規Entry停止と既存ポジション管理を分ける
- 最小コード例:責務を分けて候補を渡す
- 最小コード例:GATEで止める理由を分ける
- 最小コード例:signalからexecutionへ直接進まない
- 最小コード例:ログでどの層で止まったかを残す
- ログで追跡できる設計
- 仕様書作成前に整理すること
- よくある失敗例
- 導入前・開発依頼前に整理する情報
- 関連する技術講座・商品導線
- FAQ
- 関連する開発実務ノート
- まとめ
この記事で扱う実務課題
| 項目 | この記事で扱う内容 | 扱わない内容 |
|---|---|---|
| 目的 | EA設計でsignal・execution・risk・exitを分ける理由 | 利益を狙う売買ロジック、具体的なエントリー条件 |
| 主な対象 | 責務分離、GATE、SCORE、SPECIAL FILTERS、ENTRY、ログ設計 | 完成EAソース全文、実運用コード全文 |
| 設計観点 | 不具合調査、改修、検証、販売後サポート | 認証ロジック、外部制御、実運用set値 |
| 確認資料 | 仕様書、Expertsログ、Journalログ、setファイル、スクリーンショット | 実口座情報、顧客情報、実運用成績 |
| 読者 | MQL5開発者、EA改修依頼前に設計を整理したい人、検証担当者 | 売買判断や推奨設定を知りたい人 |
なぜこの設計判断が必要になるのか
EAの不具合相談では、「エントリーしない」「決済しない」「同じ場所で何度も入る」「ログを見ても分からない」という状態がよく起きます。
この時、EA内部の責務が分かれていないと、原因を特定しにくくなります。
| 現象 | 原因の例 | 見るべき責務 |
|---|---|---|
| シグナルが出ない | 条件未成立、インジケーター値取得失敗、確定足待ち | signal |
| シグナルはあるが発注しない | スプレッド超過、同一バー制御、保有上限、運用停止 | risk / GATE |
| 発注したが通らない | ロット不正、価格不正、証拠金不足、TRADE_RETCODEエラー | execution |
| 新規Entryが止まっている | 運用停止、時間制限、外部制御、認証NG | auth / external control |
| 既存ポジションだけ動いている | exit処理、trail、break even、risk closeが優先されている | exit / risk |
| 表示はREADYだが内部状態がNG | UI表示とruntime stateの不一致 | UI / runtime |
同じ「動かない」でも、確認する場所は異なります。設計段階で責務を分けておくと、ログ、検証、修正、サポートのすべてが楽になります。
signal / execution / risk / exit の基本定義
EA設計では、少なくとも次の4つを分けて考えます。
| 責務 | 役割 | 混同すると起きる問題 |
|---|---|---|
| signal | エントリー候補を作る | 条件判定と発注処理が混ざり、原因調査が難しくなる |
| execution | 注文・決済・modifyを実行する | OrderSend結果、retcode、失敗理由を追えなくなる |
| risk | ロット、保有上限、損失制御、発注前guardを扱う | シグナル不成立なのか、リスクで止めたのか分からなくなる |
| exit | 既存ポジションの決済、建値移動、トレール、保護決済を扱う | 新規Entry停止と既存ポジション管理を混同する |
signalは「候補を作る層」です。executionは「実際に注文を出す層」です。riskは「候補があっても実行してよいか確認する層」です。exitは「既存ポジションをどう扱うかを決める層」です。
この分離ができていると、EAがエントリーしない時にも、次のように切り分けられます。
- signalがNO_SIGNALなら、判定条件やインジケーター値を見る
- signalはREADYだがGATEで止まるなら、riskや発注前条件を見る
- executionで失敗するなら、OrderSend結果やretcodeを見る
- exitが動いているなら、新規Entryではなく既存ポジション管理を見る
GATE / SCORE / SPECIAL FILTERS / ENTRY の基本構造
EAのエントリー判定は、単純なif文だけで考えるより、次の4段階に分けると整理しやすくなります。
| 段階 | 役割 | 例 |
|---|---|---|
| GATE | そもそも判定・実行してよい状態かを確認する | 稼働ON、取引時間、スプレッド、取引許可、重複制御 |
| SCORE | シグナル候補の強さや条件一致数を評価する | 複数条件の一致、方向、優先度、候補強度 |
| SPECIAL FILTERS | 通常条件とは別の除外条件を確認する | 指標前後、急変動、連続損失、特殊時間帯 |
| ENTRY | 最終的に発注候補としてexecutionへ渡す | BUY候補、SELL候補、NO_ENTRY、BLOCK理由 |
この構造にすると、どの段階で止まったのかをログで追いやすくなります。
たとえば、SCOREは十分でも、SPECIAL FILTERSで止まる場合があります。GATEで止まっていれば、そもそもシグナル評価へ進む前に安全側で見送っている状態です。ENTRYで止まっていれば、候補はあるものの最終発注へ進んでいない状態です。
GATEは売買条件ではなく安全確認
GATEは、売買の優位性を判定する場所ではありません。EAが今、判定や発注に進んでよい状態かを確認する入口です。
| GATE項目 | 確認すること |
|---|---|
| runtime ready | EA初期化が完了しているか |
| trade allowed | 自動売買や銘柄取引が可能か |
| spread gate | スプレッドが許容範囲か |
| time gate | 取引対象時間か |
| duplicate gate | 同一バー・同一方向・同一requestの重複発注ではないか |
| position gate | 既存ポジションや保有上限と矛盾しないか |
GATEで止めた場合は、シグナル不成立ではありません。ログでは、NO_SIGNALではなく、GATE_BLOCKやENTRY_SKIPとして理由を残すべきです。
SCOREは候補評価であり発注許可ではない
SCOREは、複数条件の一致度や候補の強さを整理するために使います。
ただし、SCOREが高いからといって、必ず発注してよいわけではありません。SCOREはあくまでsignal側の評価であり、risk、GATE、SPECIAL FILTERS、execution前確認を通過する必要があります。
| 状態 | 扱い |
|---|---|
| SCORE不足 | signal候補なし |
| SCORE条件達成 | entry候補として扱える |
| SCORE達成 + GATE NG | 候補はあるが安全条件で見送り |
| SCORE達成 + SPECIAL FILTERS NG | 通常条件は成立したが特殊除外で見送り |
| SCORE達成 + execution失敗 | 判定ではなく注文実行側の問題 |
このように分けると、検証時に「条件は出ていたが発注しなかった」のか、「条件そのものが出ていなかった」のかを判断できます。
SPECIAL FILTERSは通常条件から分離する
SPECIAL FILTERSは、通常のsignal条件とは別に扱う方が安全です。
たとえば、通常のBUY条件が成立していても、指標前後、急変動、連続損失、スプレッド急拡大、特殊時間帯などで見送る場合があります。
これらを通常のsignal条件へ混ぜ込むと、「なぜシグナルが出なかったのか」が分かりにくくなります。
| 特殊条件 | 混ぜると起きる問題 | 分離した場合 |
|---|---|---|
| 経済指標前後 | 通常シグナル不成立に見える | EVENT_FILTER_BLOCKとして追える |
| 急変動 | 条件式が複雑化する | VOLATILITY_BLOCKとして追える |
| 連続損失 | riskとsignalが混ざる | RISK_FILTER_BLOCKとして追える |
| 特殊時間帯 | 時間条件と売買条件が混ざる | TIME_FILTER_BLOCKとして追える |
SPECIAL FILTERSを分けることで、通常条件は成立していたのか、それとも特殊除外で止めたのかをログで確認できます。
ENTRYはexecutionへ渡す前の候補整理
ENTRYは、signal、GATE、SCORE、SPECIAL FILTERSの結果を整理し、executionへ渡す前の候補を作る段階です。
ENTRY段階で整理したい情報は次の通りです。
- BUY候補かSELL候補か
- entryを許可するか見送るか
- 見送る場合のreason
- どのrouteから来た候補か
- 発注前risk確認が必要か
- 実行対象のsymbol、side、logic_id
ENTRY段階では、まだOrderSendを直接呼ばない方が安全です。ENTRYは候補整理であり、実行はexecution層に渡してから行います。
TREND / REVERSE / RANGEでsignalの意味は変わる
signalという言葉は1つでも、EAの性格によって意味が変わります。特に、TREND、REVERSE、RANGEでは、signalの役割を同じものとして扱うと設計が崩れやすくなります。
| タイプ | signalの意味 | 注意点 |
|---|---|---|
| TREND | 方向に乗る候補を作る | 押し戻り、継続方向、ブレイク後の追随をどう扱うか |
| REVERSE | 反転候補を作る | 逆張りのため、急変動・含み損・ナンピン方針と分離する |
| RANGE | レンジ内の上下限候補を作る | トレンド化した時の停止条件やSPECIAL FILTERSが重要になる |
TRENDのsignalは「方向に乗る候補」であり、REVERSEのsignalは「反転を狙う候補」です。RANGEのsignalは「レンジ内での反応候補」です。
同じBUY候補でも、TRENDのBUYとREVERSEのBUYでは、risk、exit、SPECIAL FILTERSの設計が変わります。signal層だけで完結させず、EAタイプごとにGATE、SCORE、ENTRY、exitの役割を分ける必要があります。
entry条件とrisk条件を混同しない理由
entry条件は「入る候補があるか」を見るものです。risk条件は「候補があっても入ってよいか」を見るものです。
この2つを混同すると、EAがなぜ入らなかったのか分かりにくくなります。
| 分類 | 例 | ログ上の扱い |
|---|---|---|
| entry条件 | 方向、インジケーター値、足確定、パターン条件 | SIGNAL_OK / NO_SIGNAL |
| risk条件 | 最大保有数、許容ロット、含み損上限、日次停止 | RISK_BLOCK / GATE_BLOCK |
| 環境条件 | スプレッド、取引時間、AutoTrading、銘柄仕様 | ENV_BLOCK / TRADE_BLOCK |
| 実行条件 | OrderSend成功、retcode、約定、注文登録 | ORDER_RESULT / SEND_FAIL |
entry条件が成立していても、risk条件で止めることは正常動作です。これをログで区別できないと、利用者は「シグナルが出ているのにEAが壊れている」と誤解しやすくなります。
発注処理をsignal側に書かない理由
signal関数の中でOrderSendを呼ぶ設計は避けるべきです。
理由は、判定と実行が混ざるからです。
| 混在する設計 | 起きやすい問題 |
|---|---|
| signal内でOrderSendする | シグナル検証だけをしたい時にも発注処理が混ざる |
| signal内でrisk判定する | NO_SIGNALなのかRISK_BLOCKなのか分からなくなる |
| signal内でログを直接書き散らす | ログ表記が揺れ、追跡しにくくなる |
| signal内でUI更新する | 表示の失敗が判定に影響しやすくなる |
| signal内で外部制御を見る | 判定条件と運用停止条件が混ざる |
signalは、あくまで候補を返す層に留める方が安全です。発注はexecutionへ渡し、execution側でrequest作成、precheck、OrderSend、result確認を行います。
executionは注文実行と結果確認に集中する
execution層は、注文リクエストを作り、OrderSendを呼び、結果を確認する責務です。
execution層で確認したい項目です。
- 注文requestの内容
- symbol、side、volume、price、sl、tp、magic
- OrderSendの戻り値
- 取引サーバー側の結果コード
- deal、order、server comment
- GetLastError
- 成功、失敗、再評価、停止対象の分類
execution層には、中核signal条件を入れません。signal側から来た候補をもとに、発注してよいrequestかどうかを最終確認し、結果をログに残します。
exitとriskを分ける理由
exitとriskは似て見えますが、役割が違います。
| 分類 | 役割 | 例 |
|---|---|---|
| risk | 損失や保有上限、発注可否を制御する | 最大ロット、最大保有数、日次停止、含み損上限 |
| exit | 既存ポジションをどの条件で閉じるか扱う | TP、SL、建値移動、Trail、signal exit |
riskは、新規Entryの前にも、保有中にも関係します。exitは、保有中ポジションをどう閉じるかを扱います。
たとえば、「含み損が一定以上だから新規Entryを止める」はriskです。一方、「既存ポジションを決済する」はexitです。この2つを同じ処理へ入れると、新規Entry停止と決済実行の関係が分かりにくくなります。
新規Entry停止と既存ポジション管理を分ける
EA設計では、新規Entryを止めることと、既存ポジション管理を止めることを混同しないようにします。
実務上は、次のように分けると安全です。
| 状態 | 新規Entry | 既存ポジション管理 |
|---|---|---|
| 通常稼働 | 許可 | 継続 |
| 外部停止 | 停止 | 継続 |
| risk停止 | 停止 | 必要に応じて継続または保護強化 |
| 認証NG | 停止 | 設計方針に応じて安全側へ |
| 緊急停止 | 停止 | 停止または指定方針に従う |
新規Entryだけを止めたいのに、Trailや建値移動まで止めてしまうと、既存ポジション保護が働かなくなる可能性があります。
逆に、緊急停止時に何を継続し、何を止めるかも仕様として明確にする必要があります。
最小コード例:責務を分けて候補を渡す
以下は、設計判断を理解するために一般化した学習用コード例です。完成EAのソース全文ではありません。
// 学習用に一般化した責務分離の例です。
// 実運用EAの完成ソースではありません。
enum SignalSide
{
SIDE_NONE = 0,
SIDE_BUY,
SIDE_SELL
};
struct SignalResult
{
bool ready;
SignalSide side;
int score;
string reason;
};
struct GateResult
{
bool pass;
string reason;
};
struct EntryCandidate
{
bool allowed;
SignalSide side;
string route;
string reason;
};
SignalResult EvaluateSignal()
{
SignalResult result;
result.ready = false;
result.side = SIDE_NONE;
result.score = 0;
result.reason = "NO_SIGNAL";
// ここでは中核Entry条件は扱いません。
// 実際のEAでは、signal条件を別責務として評価します。
return result;
}この例では、signalは発注せず、候補だけを返します。OrderSendや決済実行は別の層へ分けます。
最小コード例:GATEで止める理由を分ける
以下は、設計判断を理解するために一般化した学習用コード例です。完成EAのソース全文ではありません。
// 学習用に一般化したGATE確認の例です。
// 実運用EAの完成ソースではありません。
GateResult CheckEntryGate()
{
GateResult gate;
gate.pass = false;
gate.reason = "INIT";
bool runtimeReady = true;
bool spreadOk = true;
bool duplicateOk = true;
if(!runtimeReady)
{
gate.reason = "RUNTIME_NOT_READY";
return gate;
}
if(!spreadOk)
{
gate.reason = "SPREAD_BLOCK";
return gate;
}
if(!duplicateOk)
{
gate.reason = "DUPLICATE_BLOCK";
return gate;
}
gate.pass = true;
gate.reason = "GATE_PASS";
return gate;
}GATEで止まった場合は、NO_SIGNALではありません。ログ上もGATE_BLOCK、SPREAD_BLOCK、DUPLICATE_BLOCKのように理由を分けると確認しやすくなります。
最小コード例:signalからexecutionへ直接進まない
以下は、設計判断を理解するために一般化した学習用コード例です。完成EAのソース全文ではありません。
// 学習用に一般化したentry候補整理の例です。
// 実運用EAの完成ソースではありません。
EntryCandidate BuildEntryCandidate()
{
EntryCandidate candidate;
candidate.allowed = false;
candidate.side = SIDE_NONE;
candidate.route = "NONE";
candidate.reason = "INIT";
SignalResult signal = EvaluateSignal();
if(!signal.ready)
{
candidate.reason = signal.reason;
return candidate;
}
GateResult gate = CheckEntryGate();
if(!gate.pass)
{
candidate.reason = gate.reason;
return candidate;
}
candidate.allowed = true;
candidate.side = signal.side;
candidate.route = "SIGNAL_TO_EXECUTION";
candidate.reason = "ENTRY_READY";
return candidate;
}
void RouteToExecution(const EntryCandidate &candidate)
{
if(!candidate.allowed)
return;
// 実際のEAでは、ここで発注前precheckやOrderSend層へ渡します。
// この記事では注文実行コードは扱いません。
}この構造にすると、signal、GATE、ENTRY、executionの境界をログで追いやすくなります。
最小コード例:ログでどの層で止まったかを残す
以下は、設計判断を理解するために一般化した学習用コード例です。完成EAのソース全文ではありません。
// 学習用に一般化したログ出力例です。
// 実運用EAの完成ソースではありません。
void WriteEaTrace(string layer,
string side,
string eventName,
string reason,
string detail)
{
if(layer == "")
layer = "GENERAL";
if(reason == "")
reason = "NO_REASON";
Print("DIAG/", layer,
": side=", side,
" event=", eventName,
" reason=", reason,
" detail=", detail);
}
void TraceEntryDecision(const EntryCandidate &candidate)
{
string sideText = "NONE";
if(candidate.side == SIDE_BUY)
sideText = "BUY";
if(candidate.side == SIDE_SELL)
sideText = "SELL";
if(candidate.allowed)
{
WriteEaTrace("ENTRY", sideText, "READY", candidate.reason, candidate.route);
}
else
{
WriteEaTrace("ENTRY", sideText, "SKIP", candidate.reason, candidate.route);
}
}ログには、layer、side、event、reason、detailを分けて残します。こうしておくと、EAが止まった理由をあとから確認しやすくなります。
ログで追跡できる設計
責務分離は、コードの見通しだけでなく、ログ追跡にも直結します。
ログには、どの層で、どちら側で、何が起きて、なぜ止めたのかを残します。
| ログ層 | ログ例 | 確認できること |
|---|---|---|
| SIGNAL | SIGNAL_OK / NO_SIGNAL | 候補があったか |
| GATE | GATE_PASS / GATE_BLOCK | 発注前の安全条件を通過したか |
| RISK | RISK_BLOCK / LOT_INVALID | ロットや上限で止めたか |
| ENTRY | ENTRY_READY / ENTRY_SKIP | executionへ渡す候補があるか |
| ORDER | ORDER_SEND_OK / ORDER_SEND_FAIL | OrderSend結果 |
| EXIT | EXIT_CHECK / EXIT_DONE / EXIT_SKIP | 決済管理の状態 |
| RUNTIME | RUNTIME_INIT_OK / RUNTIME_NOT_READY | EA全体の稼働状態 |
ログ設計では、成功ログだけでなく、見送り理由を残すことが重要です。EAが入らなかった時に、NO_SIGNALなのか、GATE_BLOCKなのか、RISK_BLOCKなのか、ORDER_SEND_FAILなのかを分けて確認できる必要があります。
仕様書作成前に整理すること
EA開発を依頼する前、または既存EAを改修する前には、次の情報を整理しておくと仕様のすれ違いを減らせます。
| 整理項目 | 確認すること |
|---|---|
| signal | どの条件でBUY / SELL候補を作るか |
| GATE | 時間、スプレッド、重複制御、稼働状態をどう扱うか |
| SCORE | 複数条件を点数化するか、必須条件にするか |
| SPECIAL FILTERS | 指標、急変動、時間帯、連続損失などで止めるか |
| ENTRY | 最終的にどの状態でexecutionへ渡すか |
| execution | OrderSend、retcode、retry、失敗ログをどう扱うか |
| risk | ロット、保有上限、損失制御、日次停止をどう扱うか |
| exit | TP / SL / Trail / BE / signal exitをどう分けるか |
| log | どの層でどのreasonを出すか |
| UI | 表示はruntime stateから作るか、操作requestをどう扱うか |
この整理をせずに「この条件でEA化してください」とだけ依頼すると、実装後に「止めたい時に止まらない」「止まってほしくない処理まで止まる」「ログを見ても原因が分からない」という問題が起きやすくなります。
よくある失敗例
失敗1:signal内でOrderSendする
signal内で発注すると、判定だけを確認したい時にも実行処理が混ざります。signalは候補生成、executionは注文実行として分けるべきです。
失敗2:entry条件とrisk条件を同じif文に入れる
entry条件とrisk条件を同じif文に入れると、条件不成立なのかリスク制御で止めたのか分かりません。ログ上もNO_SIGNALとRISK_BLOCKを分ける必要があります。
失敗3:exit処理をrisk処理に混ぜる
riskは新規Entry制御や損失制御、exitは既存ポジション決済です。混ぜると、Entry停止と決済管理の関係が曖昧になります。
失敗4:GATEで止めたのにNO_SIGNALとしてログを出す
GATEで止めた場合、シグナル不成立ではありません。GATE_BLOCK、ENTRY_SKIP、SPREAD_BLOCKなどのreasonで分けて出す方が調査しやすくなります。
失敗5:UI表示を判定の真実として扱う
パネル表示やラベル文字は表示結果です。判定の真実はruntime stateで管理し、UIはそこから作ります。
失敗6:TREND / REVERSE / RANGEを同じsignalとして扱う
同じBUY候補でも、TRENDのBUY、REVERSEのBUY、RANGEのBUYでは、リスクや決済の考え方が変わります。EAタイプごとのsignalの意味を分けずに実装すると、後から改修しにくくなります。
失敗7:ログが成功時だけになっている
成功ログだけでは、EAがなぜ動かなかったのか分かりません。見送り、block、failの理由を出すことが重要です。
導入前・開発依頼前に整理する情報
EA開発や改修を依頼する場合は、次の情報を整理しておくと、仕様確認がスムーズになります。
- EAの目的
- BUY / SELLの判定条件
- TREND / REVERSE / RANGEのどれを主軸にするか
- バー確定型か、リアルタイム反応型か
- GATE条件
- SCORE条件
- SPECIAL FILTERSの有無
- 新規Entryの停止条件
- 既存ポジション管理を継続する条件
- 発注前precheck
- OrderSend失敗時の扱い
- risk制御
- exit制御
- ログに出したい項目
- setファイルとして外に出す項目
- パネルや通知が必要か
仕様書、setファイル、ログ、スクリーンショットを整理する場合は、次のページも参考にしてください。
MT5開発依頼前に用意する資料まとめ|仕様書・setファイル・ログ・スクリーンショット
関連する技術講座・商品導線
| ページ | 確認できること |
|---|---|
| 技術講座ハブ | MQL5やMT5開発に関する講座一覧 |
| MQL5 EA設計パターン完全ガイド | EA設計全体の基本構造 |
| MQL5注文・ポジション・履歴管理完全ガイド | 注文、ポジション、履歴管理の基本 |
| MQL5デバッグ・ログファースト開発完全ガイド | ログ確認、デバッグ、原因調査の基本 |
| MQL5標準ライブラリ・CTrade完全ガイド | CTradeや標準ライブラリの基本 |
| MQL5ロット・証拠金・銘柄仕様完全ガイド | ロット、証拠金、銘柄仕様の確認 |
| MT5 EA・インジケーター開発代行の選び方 | 開発依頼先を選ぶ時の確認観点 |
| 免責事項・リスク説明 | 投資判断、損益、利用上の注意に関する確認 |
FAQ
この設計にしないとEAは動かないのですか?
EA自体は責務分離が不十分でも動く場合があります。ただし、不具合調査、改修、検証、長時間運用、販売後サポートが難しくなります。特にMQL5 EAでは、signal、execution、risk、exitを分けておくと原因を切り分けやすくなります。
初心者でもこの記事の内容を理解する必要がありますか?
すべてを実装できる必要はありません。ただし、EA開発を依頼する場合でも、どの条件がsignalで、どの条件がriskで、どの処理がexitなのかを整理できると、仕様のすれ違いを減らせます。
開発依頼前に最低限どの情報を整理すべきですか?
最低限、BUY / SELL条件、Entryを止める条件、既存ポジションを管理する条件、ロットや保有上限、決済条件、ログに残したい情報を整理してください。
TREND / REVERSE / RANGEは最初に決める必要がありますか?
できるだけ最初に整理した方がよいです。TREND、REVERSE、RANGEでは、同じBUY / SELL候補でも意味が変わり、riskやexitの設計も変わるためです。
既存EAや既存インジケーターの改修にも関係しますか?
関係します。既存EAの改修では、どの処理がsignalで、どの処理がexecutionで、どの処理がriskやexitなのかを把握しないまま修正すると、別の挙動へ影響することがあります。
ログやsetファイルはどのタイミングで送るべきですか?
不具合調査や改修相談では、最初の相談時点で、発生前後のExpertsログ、Journalログ、使用setファイル、スクリーンショット、再現手順を整理して送ると確認が早くなります。token、URL、口座番号などの機密情報はマスクしてください。
商品化・配布前には追加で何を確認すべきですか?
入力項目、初期値、HELP、ログ粒度、認証、UserLive化、エラー時の表示、サポート用ログ、免責表記、販売後の問い合わせ導線を確認する必要があります。
実装コードがなくても開発相談はできますか?
可能です。実装コードがなくても、仕様書、画面イメージ、売買条件、停止条件、決済条件、ログで確認したい項目が整理されていれば、開発相談は進めやすくなります。
関連する開発実務ノート
EA設計の責務分離を整理した後は、ログ設計、外部連携、パネルUI、マルチロジック設計も確認しておくと、実装後の不具合調査や改修が進めやすくなります。
- MQL5ログファースト開発実務ノート|不具合調査しやすいEA・インジの作り方
- MQL5外部連携EA実務ノート|WebRequest・JSON・Webhookを安全に扱う設計
- MQL5パネルEA・チャートUI実務ノート|表示系と判定系を分ける設計
- MQL5マルチロジックEA実務ノート|複数戦略・Magic Number・状態管理の考え方
- MT4資産をMT5へ作り直す実務ノート|移植ではなく再設計で考える理由
まとめ
MQL5 EA設計では、エントリー条件を作るだけでなく、signal、execution、risk、exitを分けて考えることが重要です。
特に、次の4点を分けると、不具合調査と保守がしやすくなります。
- signal:エントリー候補を作る
- execution:注文・決済・modifyを実行し、結果を確認する
- risk:ロット、保有上限、損失制御、発注前guardを扱う
- exit:既存ポジションの決済、建値移動、トレール、保護決済を扱う
さらに、GATE、SCORE、SPECIAL FILTERS、ENTRYを分けることで、シグナル不成立なのか、安全条件で止めたのか、特殊条件で除外したのか、注文実行で失敗したのかをログから追いやすくなります。
TREND、REVERSE、RANGEでは、signalの意味そのものが変わります。同じBUY候補でも、順張り、逆張り、レンジ反応では、riskやexitの設計が異なります。
完成EAの中核ロジックを公開しなくても、責務分離の考え方を理解しておくことで、開発依頼、既存EA改修、検証、不具合調査、販売後サポートの品質を上げやすくなります。

