MQL5マルチロジックEA実務ノート|複数戦略・Magic Number・状態管理の考え方
MQL5でEAを拡張していくと、1つのEA内に複数の戦略や複数のロジックを入れたくなることがあります。
たとえば、順張りロジック、逆張りロジック、レンジ用ロジック、時間足違いのロジック、BUY専用・SELL専用ロジック、検証中の追加ロジックなどです。
複数ロジックEAは便利ですが、設計を間違えると危険です。どのロジックのポジションか分からなくなる、別ロジックのポジションを決済してしまう、ロジック別の成績が追えない、検証中のロジックが実売買へつながる、という問題が起きやすくなります。
マルチロジックEAで重要なのは、ロジックごとの状態、マジックナンバー、Position Snapshot、Close Scope、risk、executionを分けることです。
この記事では、MQL5で複数戦略EAを作る時の設計判断を、開発実務ノートとして整理します。完成EAソース全文、外部シート制御ロジック、認証ロジック、endpoint、token、URL実値、実運用set値、中核Entry条件は公開しません。
本記事は、投資判断や売買指示ではなく、MQL5のマルチロジックEAを設計・検証・サポートしやすくするための技術記事です。
- この記事で扱う実務課題
- なぜマルチロジックEAでは状態管理が重要なのか
- LogicSlotとは何か
- マジックナンバーをロジック別に分ける理由
- Position Snapshotをロジック別に持つ
- Close Scopeを狭くする
- audit onlyとtrade routeを分ける
- ロジック別riskとEA全体riskを分ける
- 実コード例1:LogicSlotを定義する
- 実コード例2:マジックナンバー重複を確認する
- 実コード例3:ロジック別Position Snapshotを作る
- 実コード例4:audit onlyでロジック状態を確認する
- ログで確認するポイント
- よくある失敗例
- 導入前・開発依頼前に整理する情報
- 関連する技術講座・確認ページ
- FAQ
- 関連する開発実務ノート
- まとめ
この記事で扱う実務課題
| 項目 | この記事で扱う内容 | 扱わない内容 |
|---|---|---|
| 目的 | 複数戦略EAでロジック別の状態・注文・決済を分ける設計 | 利益を狙う売買ロジック、具体的なEntry条件 |
| 主な対象 | LogicSlot、マジックナンバー、Position Snapshot、Close Scope、audit only | 完成EAソース全文、実運用コード全文 |
| 設計観点 | 誤発注防止、誤決済防止、ロジック別検証、販売後サポート | 認証ロジック、外部制御、実運用set値 |
| コード例 | 一般化したLogicSlot、Position Snapshot、Close Scope、audit log例 | 実Entry条件、実Trail条件、実Nanpin条件 |
| 読者 | MQL5開発者、複数ロジックEAを依頼したい人、検証担当者 | 売買判断や推奨設定を知りたい人 |
なぜマルチロジックEAでは状態管理が重要なのか
1つのEAに複数ロジックを入れる場合、単に条件式を増やすだけでは不十分です。
それぞれのロジックが、どのマジックナンバーを使い、どのポジションを管理し、どの決済scopeを持ち、どのrisk条件で止まるのかを分ける必要があります。
| 問題 | 起きる原因 | 分けるべき責務 |
|---|---|---|
| 別ロジックのポジションを決済する | Close Scopeが広すぎる | exit / close scope |
| ポジション集計が混ざる | マジックナンバーやlogic_idで集計していない | Position Snapshot |
| 検証中ロジックが実売買する | audit onlyとtrade routeを分けていない | runtime state / execution |
| ロジック別成績が分からない | 注文・決済・ログにlogic_idがない | log / order identification |
| risk停止の範囲が曖昧 | 全体riskとロジック別riskを混同している | risk |
| 既存ロジックに追加ロジックが影響する | 状態変数や発注経路を共有しすぎている | LogicSlot / route separation |
マルチロジックEAでは、「EA全体の状態」と「ロジックごとの状態」を分けて管理することが重要です。
LogicSlotとは何か
LogicSlotとは、1つのロジックを管理するための単位です。
1つのEAに複数ロジックを入れる場合、それぞれをLogicSlotとして扱うと、設定、状態、マジックナンバー、ポジション集計、実行可否を整理しやすくなります。
| 項目 | 役割 |
|---|---|
| logic_id | ロジックを識別する番号 |
| logic_name | ログや表示で使うロジック名 |
| magic | 注文・ポジション識別用のマジックナンバー |
| enabled | ロジック自体を有効にするか |
| trade_route_enabled | 実売買へ接続するか |
| runtime_reason | 現在の状態理由 |
| risk_state | ロジック別risk状態 |
| position_snapshot | ロジック別ポジション集計 |
LogicSlotを持たないまま条件式を増やすと、どのロジックがどのポジションを持っているのか、どのロジックが停止中なのかを追いにくくなります。
マジックナンバーをロジック別に分ける理由
マジックナンバーは、EAの注文やポジションを識別するための重要な情報です。
複数ロジックEAでは、原則としてロジックごとにマジックナンバーを分けます。同じマジックナンバーを複数ロジックで使うと、ポジション集計や決済対象が混ざります。
| 分けない場合の問題 | 内容 |
|---|---|
| 誤決済 | Logic2がLogic1のポジションを閉じる可能性がある |
| 集計混在 | ロジック別の保有数や損益が分からない |
| 検証不能 | どのロジックの成績か分からない |
| risk混在 | ロジック別上限と全体上限が混ざる |
| ログ追跡困難 | 注文・決済の原因ロジックを追えない |
ただし、マジックナンバーを分けるだけでは不十分です。ログ、Position Snapshot、Close Scope、OrderSend request、決済処理も同じ識別情報で揃える必要があります。
Position Snapshotをロジック別に持つ
Position Snapshotとは、現在のポジション状態を集計した情報です。
マルチロジックEAでは、EA全体のポジション数だけでなく、ロジック別のPosition Snapshotを持つことが重要です。
| Snapshot項目 | 確認する理由 |
|---|---|
| position_count | 対象ロジックの保有数を確認するため |
| buy_count / sell_count | 方向別の保有状態を確認するため |
| total_volume | ロジック別の合計ロットを確認するため |
| floating_profit | ロジック別の含み損益を確認するため |
| has_position | 新規Entryや決済管理の前提に使うため |
| magic | どのマジックナンバーで集計したか確認するため |
| logic_id | どのロジックの状態か確認するため |
全体ポジションだけを見ていると、Logic1は保有中だがLogic2はノーポジション、という状態を区別できません。
Close Scopeを狭くする
Close Scopeとは、決済対象の範囲です。
複数ロジックEAでは、決済処理が他ロジックのポジションを巻き込まないように、Close Scopeを明確にする必要があります。
| 確認項目 | 理由 |
|---|---|
| symbol一致 | 別銘柄のポジションを閉じないため |
| magic一致 | 別ロジックのポジションを閉じないため |
| logic_id一致 | 管理対象ロジックを明確にするため |
| side一致 | BUY / SELLの対象を間違えないため |
| ticket確認 | 対象ポジションを明確にするため |
| close reason | なぜ閉じるのかをログで追うため |
特に、symbolだけで決済対象を選ぶ設計は危険です。複数ロジック、複数EA、手動ポジションが混在する環境では、magic、logic_id、scopeを確認する必要があります。
audit onlyとtrade routeを分ける
新しいロジックを追加する時は、いきなり実売買へ接続しない方が安全です。
まずはaudit onlyとして、シグナル候補、GATE、risk、Position Snapshot、ログだけを確認し、その後にtrade routeを有効化します。
| 段階 | 状態 | 確認内容 |
|---|---|---|
| defined | LogicSlotだけ定義 | logic_id、name、magicが重複していないか |
| snapshot only | ポジション集計だけ行う | 対象ポジションを正しく集計できるか |
| audit only | 判定結果をログに出す | 候補、block理由、risk状態が追えるか |
| pre-route gate | 実行前条件まで確認する | spread、duplicate、position gateが通るか |
| trade route enable | 実売買へ接続する | OrderSend、retcode、position反映を確認する |
この段階を分けておくと、既存ロジックを壊さずに新ロジックを検証しやすくなります。
ロジック別riskとEA全体riskを分ける
マルチロジックEAでは、risk管理も2層に分ける必要があります。
1つはロジック別riskです。もう1つはEA全体riskです。
| risk分類 | 確認すること | 例 |
|---|---|---|
| ロジック別risk | 対象ロジックだけの上限を確認する | Logic1最大1ポジション、Logic2最大2ポジション |
| EA全体risk | EA全体としての上限を確認する | 全体最大ロット、全体最大ポジション数 |
| 方向別risk | BUY / SELL別の偏りを確認する | BUY最大数、SELL最大数 |
| 口座・日次risk | 口座全体や日次停止を確認する | 日次損失停止、連続損失停止 |
ロジック別riskで許可されていても、EA全体riskで止める場合があります。この場合は、NO_SIGNALではなく、RISK_BLOCKとしてログに残します。
実コード例1:LogicSlotを定義する
以下は、設計判断を理解するために一般化した学習用コード例です。完成EAのソース全文ではありません。
// 学習用に一般化したLogicSlot例です。
// 実運用EAの完成ソースではありません。
struct LogicSlot
{
int id;
string name;
long magic;
bool enabled;
bool tradeRouteEnabled;
string runtimeReason;
};
#define LOGIC_COUNT 3
LogicSlot g_logicSlots[LOGIC_COUNT];
void InitLogicSlots()
{
g_logicSlots[0].id = 1;
g_logicSlots[0].name = "Logic1";
g_logicSlots[0].magic = 910001;
g_logicSlots[0].enabled = true;
g_logicSlots[0].tradeRouteEnabled = true;
g_logicSlots[0].runtimeReason = "OK";
g_logicSlots[1].id = 2;
g_logicSlots[1].name = "Logic2";
g_logicSlots[1].magic = 910002;
g_logicSlots[1].enabled = true;
g_logicSlots[1].tradeRouteEnabled = false;
g_logicSlots[1].runtimeReason = "AUDIT_ONLY";
g_logicSlots[2].id = 3;
g_logicSlots[2].name = "Logic3";
g_logicSlots[2].magic = 910003;
g_logicSlots[2].enabled = false;
g_logicSlots[2].tradeRouteEnabled = false;
g_logicSlots[2].runtimeReason = "DISABLED";
}この例では、enabledとtradeRouteEnabledを分けています。enabledはロジックを確認対象にするかどうか、tradeRouteEnabledは実売買へ接続するかどうかです。
実コード例2:マジックナンバー重複を確認する
以下は、設計判断を理解するために一般化した学習用コード例です。完成EAのソース全文ではありません。
// 学習用に一般化したマジックナンバー重複チェック例です。
// 実運用EAの完成ソースではありません。
bool ValidateLogicMagicNumbers()
{
for(int i = 0; i < LOGIC_COUNT; i++)
{
if(g_logicSlots[i].magic <= 0)
{
Print("DIAG/LOGIC: event=VALIDATION_FAIL",
" logic=", g_logicSlots[i].name,
" reason=INVALID_MAGIC");
return false;
}
for(int j = i + 1; j < LOGIC_COUNT; j++)
{
if(g_logicSlots[i].magic == g_logicSlots[j].magic)
{
Print("DIAG/LOGIC: event=VALIDATION_FAIL",
" reason=DUPLICATE_MAGIC",
" logic_a=", g_logicSlots[i].name,
" logic_b=", g_logicSlots[j].name);
return false;
}
}
}
Print("DIAG/LOGIC: event=VALIDATION_OK",
" reason=UNIQUE_MAGIC");
return true;
}マジックナンバーの重複は、複数ロジックEAで特に避けたい事故です。起動時に検出し、重複があれば安全側で止める設計が必要です。
実コード例3:ロジック別Position Snapshotを作る
以下は、設計判断を理解するために一般化した学習用コード例です。完成EAのソース全文ではありません。
// 学習用に一般化したPosition Snapshot例です。
// 実運用EAの完成ソースではありません。
struct PositionSnapshot
{
int count;
int buyCount;
int sellCount;
double totalVolume;
double floatingProfit;
bool hasPosition;
};
PositionSnapshot BuildPositionSnapshotForMagic(long magic)
{
PositionSnapshot snap;
snap.count = 0;
snap.buyCount = 0;
snap.sellCount = 0;
snap.totalVolume = 0.0;
snap.floatingProfit = 0.0;
snap.hasPosition = false;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(ticket == 0)
continue;
if(!PositionSelectByTicket(ticket))
continue;
if(PositionGetString(POSITION_SYMBOL) != _Symbol)
continue;
if((long)PositionGetInteger(POSITION_MAGIC) != magic)
continue;
long type = PositionGetInteger(POSITION_TYPE);
double volume = PositionGetDouble(POSITION_VOLUME);
double profit = PositionGetDouble(POSITION_PROFIT);
snap.count++;
snap.totalVolume += volume;
snap.floatingProfit += profit;
if(type == POSITION_TYPE_BUY)
snap.buyCount++;
if(type == POSITION_TYPE_SELL)
snap.sellCount++;
}
snap.hasPosition = (snap.count > 0);
return snap;
}この例では、symbolとマジックナンバーで対象ポジションを絞り込んでいます。ロジック別にSnapshotを作ることで、他ロジックのポジションを誤って管理しにくくなります。
実コード例4:audit onlyでロジック状態を確認する
以下は、設計判断を理解するために一般化した学習用コード例です。完成EAのソース全文ではありません。
// 学習用に一般化したLogicSlot監査例です。
// 実運用EAの完成ソースではありません。
void PrintLogicAudit(LogicSlot slot,
PositionSnapshot snap,
string eventName,
string reason)
{
Print("DIAG/LOGIC_AUDIT: logic=", slot.name,
" magic=", slot.magic,
" event=", eventName,
" reason=", reason,
" pos_count=", snap.count,
" buy=", snap.buyCount,
" sell=", snap.sellCount,
" trade_route=", slot.tradeRouteEnabled);
}
void RunLogicSlotAudit()
{
for(int i = 0; i < LOGIC_COUNT; i++)
{
LogicSlot slot = g_logicSlots[i];
PositionSnapshot snap = BuildPositionSnapshotForMagic(slot.magic);
if(!slot.enabled)
{
PrintLogicAudit(slot, snap, "SKIP", "LOGIC_DISABLED");
continue;
}
if(!slot.tradeRouteEnabled)
{
PrintLogicAudit(slot, snap, "AUDIT_ONLY", slot.runtimeReason);
continue;
}
PrintLogicAudit(slot, snap, "READY", "TRADE_ROUTE_ENABLED");
// 実際のEAでは、この後にsignal / gate / risk / executionへ分けて渡します。
// この記事では中核Entry条件や実発注処理は扱いません。
}
}audit onlyを使うと、新ロジックを実売買へ接続する前に、対象ポジション、候補、停止理由をログで確認できます。
ログで確認するポイント
マルチロジックEAでは、ログにlogic_idやマジックナンバーがないと、原因を追いにくくなります。
| ログ区分 | 確認できること | 例 |
|---|---|---|
| LOGIC_INIT | ロジック定義が正しく初期化されたか | logic_id、name、magic、enabled |
| LOGIC_AUDIT | ロジックごとの状態 | AUDIT_ONLY、TRADE_ROUTE_ENABLED |
| POSITION_SNAPSHOT | ロジック別保有状態 | count、buy、sell、volume、profit |
| GATE | ロジック別に実行前条件を通過したか | GATE_PASS、SPREAD_BLOCK、DUPLICATE_BLOCK |
| RISK | ロジック別riskや全体riskで止まったか | LOGIC_RISK_BLOCK、GLOBAL_RISK_BLOCK |
| ORDER | どのロジックが注文したか | logic_id、magic、retcode |
| CLOSE_SCOPE | 決済対象が正しいか | symbol、magic、ticket、reason |
ログには、sideだけでなく、logic_id、magic、route、reasonを含めると確認しやすくなります。
よくある失敗例
失敗1:複数ロジックで同じマジックナンバーを使う
同じマジックナンバーを使うと、ポジション集計、決済対象、risk管理、成績確認が混ざります。ロジックごとに一意のマジックナンバーを割り当てることが基本です。
失敗2:全体ポジションだけを見ている
EA全体の保有数だけを見ると、どのロジックがポジションを持っているのか分かりません。ロジック別Position Snapshotが必要です。
失敗3:Close Scopeが広すぎる
symbolだけで決済対象を選ぶと、他ロジックや他EAのポジションを巻き込む可能性があります。symbol、magic、logic_id、ticketを確認します。
失敗4:検証中ロジックをいきなり実売買へつなぐ
新ロジックは、defined、snapshot only、audit only、pre-route gate、trade route enableの段階を分けて確認する方が安全です。
失敗5:ロジック別riskと全体riskを混同する
ロジック別には許可されていても、EA全体riskで止める場合があります。LOGIC_RISK_BLOCKとGLOBAL_RISK_BLOCKを分けます。
失敗6:ログにlogic_idがない
複数ロジックEAでlogic_idやmagicがログにないと、どのロジックが何を判断したのか分かりません。
失敗7:追加ロジックが既存ロジックの状態変数を使い回す
状態変数の使い回しは、意図しない停止、誤発注、誤決済の原因になります。LogicSlotごとに状態を分けます。
導入前・開発依頼前に整理する情報
マルチロジックEAを開発・改修する場合、次の情報を整理しておくと仕様確認がスムーズになります。
- ロジック数
- 各ロジックの役割
- 各ロジックのマジックナンバー
- 各ロジックのBUY / SELL対象
- 同時稼働するか、排他制御するか
- ロジック別risk
- EA全体risk
- ロジック別Position Snapshotの項目
- Close Scopeの範囲
- 新ロジックをaudit onlyから始めるか
- 実売買へ接続する条件
- ログに出すlogic_id、magic、route、reason
- 既存ロジックへ影響させないための検証手順
マルチロジックEAは、条件を増やすだけではなく、識別、状態、risk、決済、ログを分けて設計する必要があります。
関連する技術講座・確認ページ
| ページ | 確認できること |
|---|---|
| 技術講座ハブ | MQL5やMT5開発に関する講座一覧 |
| MQL5 EA設計パターン完全ガイド | EA設計全体の基本構造 |
| MQL5注文・ポジション・履歴管理完全ガイド | 注文、ポジション、履歴管理の基本 |
| MQL5デバッグ・ログファースト開発完全ガイド | ログ確認、デバッグ、原因調査の基本 |
| MQL5ロット・証拠金・銘柄仕様完全ガイド | ロット、証拠金、銘柄仕様の確認 |
| MT5開発依頼前に用意する資料まとめ | 仕様書、setファイル、ログ、スクリーンショットの整理 |
| 不具合報告・調査依頼について | 不具合相談前に送る情報 |
| 免責事項・リスク説明 | 投資判断、損益、利用上の注意に関する確認 |
FAQ
マルチロジックEAとは何ですか?
1つのEA内で複数の戦略やロジックを扱うEAです。順張り、逆張り、レンジ、時間足違い、BUY専用、SELL専用などを同じEA内で扱う場合があります。
ロジックごとにマジックナンバーを分ける必要がありますか?
基本的には分けるべきです。同じマジックナンバーを使うと、ポジション集計や決済対象が混ざり、誤決済や検証不能につながる可能性があります。
enabledとtradeRouteEnabledは何が違いますか?
enabledはロジックを確認対象にするかどうか、tradeRouteEnabledは実売買へ接続するかどうかです。enabled=trueでもtradeRouteEnabled=falseなら、audit onlyとしてログ確認だけ行えます。
Position Snapshotはなぜ必要ですか?
ロジックごとの保有数、方向、ロット、損益を分けて確認するためです。全体集計だけでは、どのロジックのポジションか切り分けにくくなります。
Close Scopeとは何ですか?
決済対象の範囲です。マルチロジックEAでは、symbolだけでなく、magic、logic_id、ticketなどで対象を限定し、他ロジックのポジションを巻き込まないようにします。
新しいロジックはすぐ実売買へ接続してよいですか?
避けた方が安全です。まずはLogicSlot定義、Snapshot確認、audit only、pre-route gateの順に進め、ログ確認後にtrade routeを有効化する流れが安全です。
全体riskとロジック別riskはどちらを優先しますか?
仕様によりますが、実務上はロジック別riskとEA全体riskを両方確認します。ロジック別には許可されていても、EA全体riskで止める場合があります。
実装コードがなくてもマルチロジックEAの相談はできますか?
可能です。ロジック数、役割、マジックナンバー、同時稼働方針、risk、Close Scope、ログ項目が整理されていれば、相談を進めやすくなります。
関連する開発実務ノート
マルチロジックEAでは、ロジック別の状態管理だけでなく、EA全体の責務分離、ログ設計、バックテスト条件、商品化前チェックも重要です。
- MQL5 EA設計実務ノート|signal・execution・risk・exitを分ける理由
- MQL5ログファースト開発実務ノート|不具合調査しやすいEA・インジの作り方
- MQL5バックテスト実務ノート|検証条件・最適化・リアル差分を記録する考え方
- MQL5商品化・配布前チェック実務ノート|Inputs・HELP・Snapshot・manual・UserLive化の基本
まとめ
MQL5でマルチロジックEAを作る場合、単に条件式を増やすだけでは不十分です。
特に、次の4点を分けると、誤発注、誤決済、検証不能、既存ロジックへの影響を防ぎやすくなります。
- LogicSlot:ロジックごとの設定・状態・実行可否を管理する
- マジックナンバー:注文とポジションをロジック単位で識別する
- Position Snapshot:ロジック別の保有数・方向・損益を固定して確認する
- Close Scope:決済対象をsymbol、magic、logic_id、ticketで限定する
また、新しいロジックは、いきなり実売買へ接続せず、defined、snapshot only、audit only、pre-route gate、trade route enableのように段階を分けて確認する方が安全です。
完成EAの中核ロジックを公開しなくても、マルチロジックEAの状態管理、マジックナンバー、Snapshot、Close Scope、risk分離を理解しておくことで、開発依頼、既存EA改修、検証、不具合調査、販売後サポートの品質を上げやすくなります。

