MQL5 EAアーキテクチャ設計ガイド|構造・実装・注意点

目次

1. MQL5におけるEAアーキテクチャとは

【結論】
EAアーキテクチャとは「自動売買ロジックをどのような構造で設計・分割するか」を指す。
設計を理解していないと、バグ・再現性の欠如・運用破綻につながる。

【定義】
EA(Expert Advisor)アーキテクチャとは、MQL5で作成する自動売買プログラムを「データ取得・判断・注文・管理」といった機能単位に分解し、再現性と拡張性を担保するための設計構造である。

1.1 EAアーキテクチャの基本的な考え方

MQL5におけるEAは、単なる「売買ロジックの記述」ではなく、以下のような構造で動作する。

  • 市場データ(価格・indicator)を取得
  • 条件に基づいてシグナルを生成
  • 注文を実行(execution)
  • ポジションやリスクを管理

この一連の流れを「整理された構造」として設計するのがEAアーキテクチャである。

重要なポイントは次の通り。

  • ロジックと実行処理を分離する
  • 再利用可能な構造にする
  • 実運用(スプレッド・スリッページ)を考慮する

この設計を行わない場合、以下の問題が発生しやすい。

  • OnTickに全処理を書いて可読性が崩壊する
  • 同じ条件で複数回エントリーしてしまう
  • バックテストでは動くが実運用で崩れる

1.2 MQL5の基本構造(イベント駆動モデル)

MQL5のEAは「イベント駆動」で動作する。
つまり、特定のタイミング(イベント)で関数が呼ばれる仕組みである。

代表的なイベントは以下の3つ。

  • OnInit:初期化処理(EA起動時に1回だけ実行)
  • OnTick:価格更新時に実行(メイン処理)
  • OnDeinit:終了処理(EA停止時)

最小構成の例は以下。

int OnInit()
{
   // 初期化(インジケータ作成など)
   return(INIT_SUCCEEDED);
}

void OnTick()
{
   // 毎Tickで実行される
   // シグナル判定 → 注文処理
}

void OnDeinit(const int reason)
{
   // 後処理
}

この構造を理解していないと、

  • 不要な処理を毎Tickで実行してしまう
  • パフォーマンス低下
  • ロジックの誤作動

といった問題が発生する。

特にOnTickは「毎回呼ばれる」ため、処理を最小限に設計することが重要である。

1.3 なぜEAアーキテクチャが重要なのか

EAアーキテクチャが重要な理由は、主に3つある。

① 再現性の確保

EAの最大の価値は「同じ条件で同じ動作をすること」である。
しかし、設計が曖昧だと以下のズレが発生する。

  • バックテストとフォワードの乖離
  • execution条件(slippage・spread)による差
  • タイミング依存のバグ

構造化された設計により、このズレを最小化できる。

② バグの抑制

設計が整理されていない場合、

  • 条件分岐が複雑化
  • 状態管理が不明確
  • デバッグ困難

といった問題が発生する。

特に初心者は「1つの関数に全て書く」傾向があり、これが最大の失敗要因となる。

③ 拡張性・実運用対応

EAは一度作って終わりではない。

  • ロジック追加
  • フィルター(spread / slippage)追加
  • リスク制御強化

など、継続的な改善が必要になる。

アーキテクチャが適切であれば、

  • 機能追加が容易
  • 他EAへの流用が可能
  • ポートフォリオ運用にも対応

となる。

逆に設計がない場合、後からの修正コストは指数的に増加する。

2. EAアーキテクチャの全体構成

【結論】
EAは「データ取得 → シグナル生成 → 注文実行 → リスク管理 → 状態管理」の5要素で構成する。
この分割ができれば、再現性・デバッグ性・拡張性が大幅に向上する。

MQL5 Expert Advisor execution pipeline diagram showing system architecture and execution flow, including data retrieval, signal generation, state management, order execution, and risk control, with code example and trading chart illustrating how market data triggers signal evaluation and automated order placement in MetaTrader 5.

2.1 基本コンポーネント一覧

EAは以下の5つのコンポーネントに分解して設計するのが基本である。

① データ取得(Market Data)

  • 価格(Bid / Ask)
  • 時系列データ(CopyRates)
  • インジケータ(iMA, iRSIなど)

役割:判断に必要な入力データを取得する

double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

注意点:

  • 毎Tickで重いデータ取得を行うとパフォーマンス低下
  • CopyBufferの呼びすぎは遅延の原因

② シグナル生成(Signal Logic)

  • エントリー条件
  • 決済条件
  • フィルター(時間・トレンドなど)

役割:「売る・買う・何もしない」を決定する

bool isBuy = (ma_fast > ma_slow);

注意点:

  • ロジックと注文処理を混ぜない
  • シグナルは「状態」ではなく「判断」に限定する

③ 注文処理(Execution)

  • OrderSend
  • 注文条件(価格・ロット・SL/TP)
  • executionタイミング

役割:実際に市場へ注文を出す

MqlTradeRequest request;
MqlTradeResult result;
// request設定 → OrderSend

重要ポイント:

  • slippage(許容価格ズレ)を考慮
  • 約定失敗(requote, off quotes)への対応

④ リスク管理(Risk Control)

  • ロットサイズ(lot)
  • ストップロス(SL)
  • スプレッドフィルター(spread)

役割:損失を制御する

if(spread > max_spread) return;

注意点:

  • spread未考慮は実運用で破綻しやすい
  • 固定ロットはリスク管理として不十分

⑤ 状態管理(State Management)

  • ポジション有無
  • エントリー済フラグ
  • 複数ポジション管理

役割:EAの現在状態を保持する

bool hasPosition = PositionSelect(_Symbol);

重要:

  • 状態管理がないと「多重エントリー」になる
  • 実運用では最重要コンポーネント

2.2 データフロー(処理の流れ)

EAは以下の流れで動作する。

  1. Tick発生(OnTick呼び出し)
  2. データ取得(価格・indicator)
  3. シグナル判定
  4. 条件を満たせば注文実行
  5. 状態更新

この流れをコードで整理すると以下のようになる。

void OnTick()
{
   // 1. データ取得
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

   // 2. シグナル生成
   bool isBuySignal = CheckBuySignal();

   // 3. 状態確認
   bool hasPosition = PositionSelect(_Symbol);

   // 4. 注文実行
   if(isBuySignal && !hasPosition)
   {
      ExecuteBuy();
   }
}

この「流れを崩さない」ことが最も重要である。


2.3 よくある構造ミス(初心者が詰まるポイント)

以下は典型的な失敗例。

① 全処理をOnTickに直書き

  • 可読性が低下
  • 修正時にバグ混入

② 状態管理がない

  • 同じ条件で何度もエントリー
  • ポジション爆発

③ データ取得とロジックが混在

  • 再利用できない
  • テスト困難

④ executionを軽視

  • slippage未考慮
  • 約定失敗でロジック崩壊

2.4 なぜこの分割が有効なのか

この5分割構造にすることで以下が実現できる。

  • ロジック単体テストが可能
  • デバッグが局所化される
  • 機能追加が容易
  • 他EAへ流用可能

特に重要なのは、

「シグナル」と「execution」を分離すること

である。

理由:

  • シグナルは理想条件
  • executionは現実条件(spread・slippage)

この2つを混ぜると、バックテストと実運用の乖離が発生する。

3. EAアーキテクチャの実装手順

【結論】
EAは「テンプレ構造を作る → 各機能を分離実装 → 実運用条件を追加」の順で構築する。
最初から完璧を目指さず、動く最小構成 → 改善が最も再現性が高い。


3.1 最短構築ステップ(テンプレ)

初心者は以下の順序で実装する。

  1. EAファイル作成(MetaEditor)
  2. OnInitで初期化
  3. OnTickに最小ロジックを書く
  4. 注文関数を作る(Buy/Sell)
  5. バックテストで確認

最小構成の流れ:

int OnInit()
{
   return(INIT_SUCCEEDED);
}

void OnTick()
{
   if(CheckBuySignal())
   {
      ExecuteBuy();
   }
}

ここでは「まず動かす」ことが目的。

注意点:

  • 初期段階ではリスク管理を簡略化してOK
  • ただし、後で必ず追加する

3.2 実装テンプレ(構造分離)

次に、アーキテクチャとして重要な「分離」を行う。

推奨構造

  • CheckSignal(判断)
  • ExecuteOrder(注文)
  • RiskControl(制御)
bool CheckBuySignal()
{
   // シグナルのみ判定
   return(true);
}

void ExecuteBuy()
{
   // 注文処理のみ
}

void OnTick()
{
   if(CheckBuySignal())
   {
      ExecuteBuy();
   }
}

重要ポイント:

  • 「判定」と「実行」を絶対に混ぜない
  • シグナルは「true/false」で返す

理由:

  • ロジック検証が容易になる
  • execution依存のバグを分離できる

3.3 実務向け改善手順(必須)

実運用では以下を追加する。

① スプレッドフィルター

double spread = (Ask - Bid) / _Point;
if(spread > 20) return;

理由:

  • spreadが広いと不利な価格で約定する

② ポジション制御(多重エントリー防止)

if(PositionSelect(_Symbol)) return;

理由:

  • 同条件で連続エントリーを防ぐ

③ スリッページ考慮

注文時に許容価格ズレを設定。

ポイント:

  • executionは理論通りに動かない
  • slippageは必ず発生する

④ ロットサイズ管理

double lot = 0.1; // 仮(実務ではリスクベース)

注意:

  • 固定ロットは長期運用で破綻リスクあり
  • 将来的に「risk per trade」へ移行する

3.4 実装時によくある失敗

① いきなり複雑なロジックを書く

→ デバッグ不能になる

② OnTickに全て書く

→ 可読性崩壊・修正困難

③ 状態管理を後回しにする

→ 多重エントリー発生

④ バックテストのみで判断

→ 実運用で崩れる(execution差)


3.5 最小構成→実運用構成への進化

段階的に改善するのが最適。

ステップ1(最小)

  • シグナル + 注文

ステップ2(中間)

  • 状態管理追加
  • spreadフィルター

ステップ3(実運用)

  • リスク管理
  • execution最適化
  • ロジック分離

この順序を守ることで、

  • 無駄な作り直しを防げる
  • 検証精度が上がる

3.6 他手法との違い(軽い補足)

  • 初心者:OnTick直書き → 短期は速いが破綻しやすい
  • 本手法:分離設計 → 初期コストは高いが長期安定

4. なぜこの構造が必要なのか

【結論】
EAアーキテクチャが必要なのは、MQL5のEAが「毎Tick動く不確実な実行環境」で動作するからである。
ロジックを分離しないと、価格変動・約定差・状態ずれに耐えられず、バックテストと実運用が乖離しやすい。

4.1 MQL5のEAは毎回同じ条件で動くとは限らない

MQL5のEAは、OnTick が呼ばれるたびに処理される。
しかし、Tickは一定間隔では来ない。相場が静かな時間は少なく、指標発表時や急変時は非常に多くなる。

この性質により、EAには次の問題が発生しやすい。

  • 同じロジックでも実行タイミングが毎回違う
  • 条件判定の直後に価格が変わる
  • 連続Tickで同じ条件が何度も成立する
  • 約定前後で状態がずれる

つまり、EAは「静的なプログラム」ではなく、変動する市場環境に追従するプログラムである。
このため、単純に「条件が成立したら買う」と書くだけでは不十分になる。

たとえば、次のようなコードは初心者に多い。

void OnTick()
{
   if(CheckBuySignal())
   {
      ExecuteBuy();
   }
}

この形自体は間違いではないが、以下が不足しやすい。

  • すでにポジションを持っているか
  • spreadが広すぎないか
  • 注文可能な状態か
  • 同一バー内の重複エントリーを防げているか

そのため、実務では「シグナル判定」と「実行条件」を分ける必要がある。

4.2 市場では理論通りに約定しない

EAのロジックが正しくても、注文は理論通りには通らない場合がある。
主な原因は、executionまわりの不確実性である。

代表例は以下。

  • spreadの拡大
  • slippageの発生
  • requote
  • 約定拒否
  • 市場クローズ
  • volume条件不一致

たとえば、バックテストでは狭いspread前提で成立していた戦略でも、実運用ではコスト増で崩れることがある。
特に短期売買やスキャルピング寄りのロジックでは、この影響が大きい。

そのため、EAアーキテクチャでは次の分離が重要になる。

  • シグナル:理論上の売買判断
  • execution:実際に発注してよいかの確認

この分離をしないと、ロジックの良し悪しと約定環境の悪さが混ざってしまう。
結果として、「戦略が悪いのか」「執行条件が悪いのか」が判別できなくなる。

4.3 モジュール化しないと修正コストが急増する

EAは一度作ったら終わりではない。
実際には、以下のような改善が繰り返し発生する。

  • フィルターを追加したい
  • ロット計算を変えたい
  • 損切り条件を調整したい
  • 複数通貨対応にしたい
  • ログ出力を増やしたい

このとき、全処理が OnTick に密集していると、1か所の修正が別の不具合を生みやすい。
典型例は次の通り。

  • エントリー条件を修正したら決済条件まで壊れた
  • spreadフィルター追加で既存ロジックの順序が崩れた
  • ポジション判定の追加で多重エントリーが発生した

これを防ぐには、機能ごとに役割を分ける必要がある。

  • データ取得関数
  • シグナル判定関数
  • 注文実行関数
  • リスク管理関数
  • 状態管理関数

この構造なら、どこに問題があるか切り分けやすい。
また、特定の関数だけ差し替えることもできる。

4.4 状態管理がないEAは実運用で崩れやすい

初心者が見落としやすいのが「状態管理」である。
状態管理とは、EAが今どの状態にあるかを把握する仕組みである。

代表的な状態は以下。

  • ポジションなし
  • 買いポジション保有中
  • 売りポジション保有中
  • 注文直後
  • 決済待ち
  • 同一バー内でエントリー済み

これを持たないEAは、相場が速い場面で同じ条件に何度も反応しやすい。
その結果、次のような問題が起きる。

  • 同時に複数回エントリーする
  • 決済前に逆方向へ新規注文する
  • バックテストでは見えにくい重複発注が起きる

状態管理は、見た目には地味だが、実運用では中核である。
特に、複数ポジション・複数通貨・時間足またぎのロジックでは必須に近い。

4.5 なぜ最初から構造化したほうが有利なのか

「最初は簡単に作って、後で整理すればよい」と考える人も多い。
これは小規模な検証用EAなら一部正しいが、実務では不利になりやすい。

理由は次の通り。

  • 動いたコードほど後で触りにくい
  • 成果が出たロジックほど複雑化しやすい
  • 後からの分離は、最初から分けるより手間が大きい

特に、売買ロジックに利益が出始めると、そのコードを中心に追加修正が積み重なる。
その状態で設計し直すと、既存の挙動を壊さずに再構成する必要があり、難易度が一気に上がる。

そのため、初心者でも最低限は次の方針を守ったほうがよい。

  • 判定と発注を分ける
  • 状態確認を入れる
  • 実運用コスト(spread, slippage)を無視しない

この3点だけでも、EAの耐久性は大きく変わる。

5. EA設計の代表パターン

【結論】
EAの設計は「シンプル型 → モジュール型 → ステートマシン型」の順で進化させるのが最も効率的である。
実運用ではモジュール型以上がほぼ必須になる。


5.1 シンプル構造(初心者向け)

最も基本的な構造は、すべての処理を OnTick にまとめる方法である。

void OnTick()
{
   double ma_fast = iMA(_Symbol, 0, 5, 0, MODE_SMA, PRICE_CLOSE, 0);
   double ma_slow = iMA(_Symbol, 0, 20, 0, MODE_SMA, PRICE_CLOSE, 0);

   if(ma_fast > ma_slow)
   {
      // Buy処理
   }
}

特徴:

  • 実装が最も簡単
  • 学習コストが低い
  • 短時間で動くものが作れる

デメリット:

  • 可読性が急速に悪化する
  • ロジック追加で破綻しやすい
  • 状態管理が難しい
  • 実運用に耐えにくい

よくある失敗:

  • 条件が増えて if がネスト地獄になる
  • 同じコードが複数箇所に分散する
  • 多重エントリーが発生する

この構造は「検証用」または「超シンプル戦略」に限定するのが現実的である。


5.2 モジュール型(推奨構造)

シンプル構造を改善したものが「モジュール型」である。
機能ごとに処理を分離する。

bool CheckBuySignal()
{
   return(true);
}

bool CanExecute()
{
   double spread = (Ask - Bid) / _Point;
   if(spread > 20) return(false);

   if(PositionSelect(_Symbol)) return(false);

   return(true);
}

void ExecuteBuy()
{
   // OrderSend処理
}

void OnTick()
{
   if(CheckBuySignal() && CanExecute())
   {
      ExecuteBuy();
   }
}

特徴:

  • ロジックが整理される
  • デバッグしやすい
  • 機能追加が容易

メリット:

  • シグナルとexecutionを分離できる
  • spread / slippageなど現実条件を組み込める
  • 再利用性が高い

デメリット:

  • 初期実装の手間が増える
  • 設計意識が必要

実務評価:

  • 最もバランスが良い
  • 単体EA〜複数戦略まで対応可能

重要ポイント:

  • CheckSignal(理論)
  • CanExecute(現実条件)
  • Execute(発注)

この3分割が基本となる。


5.3 ステートマシン型(中級者〜上級者)

状態遷移でEAを制御する構造。

例:

enum State
{
   STATE_NONE,
   STATE_ENTRY,
   STATE_HOLD,
   STATE_EXIT
};

State currentState = STATE_NONE;

void OnTick()
{
   switch(currentState)
   {
      case STATE_NONE:
         if(CheckBuySignal())
         {
            ExecuteBuy();
            currentState = STATE_HOLD;
         }
         break;

      case STATE_HOLD:
         if(CheckExitSignal())
         {
            ExecuteSell();
            currentState = STATE_NONE;
         }
         break;
   }
}

特徴:

  • 状態を明示的に管理
  • ロジックの流れが可視化される

メリット:

  • 多段階ロジックに強い
  • 複数条件の整合性を保てる
  • ポジション管理が安定する

デメリット:

  • 実装難易度が高い
  • 設計ミスで複雑化しやすい

向いているケース:

  • 複数エントリー条件
  • ナンピン・グリッド
  • 複数ポジション制御

5.4 どの構造を選ぶべきか

結論としては以下。

  • 学習段階 → シンプル構造
  • 実運用 → モジュール型
  • 高度戦略 → ステートマシン型

判断基準:

  • ロジックが単純か
  • ポジション数が1か複数か
  • execution条件が複雑か

5.5 他手法との違い(軽い比較)

他の実装スタイルとの違い:

  • スクリプト型(単発実行)
    → EAと異なり継続監視できない
  • インジケータ型
    → シグナルは出るが発注できない
  • EA(本記事の対象)
    → 自動実行+状態管理が可能

5.6 よくある設計ミス

  • モジュール化せず巨大関数化
  • 状態遷移を考えず条件追加
  • executionを軽視
  • ロジックと表示(Print等)が混在

特に注意:

「設計を後回しにすると、後で修正できなくなる」

6. 他手法との比較

【結論】
EAアーキテクチャは「シンプル型・モジュール型・ステートマシン型」で選択する。
実運用では、モジュール型以上でないとexecution(約定条件)やリスク管理に対応できない

6.1 比較対象の整理

比較する設計パターンは以下の3つ。

  • シンプル型:OnTickに直接記述
  • モジュール型:機能ごとに分離
  • ステートマシン型:状態遷移で制御

それぞれは「目的」と「適用範囲」が異なる。


6.2 比較表(全体像)

構造 難易度 拡張性 バグ耐性 実務適性 向いている用途
シンプル型 学習・検証
モジュール型 単体EA・実運用
ステートマシン型 複雑戦略

重要ポイント:

  • 実運用では「拡張性」と「バグ耐性」が最優先
  • 難易度だけで選ぶと後で破綻する

6.3 シンプル型 vs モジュール型

違いの本質

  • シンプル型:ロジックとexecutionが混在
  • モジュール型:ロジックとexecutionが分離

この違いが最も重要である。

実務上の差

観点 シンプル型 モジュール型
デバッグ 困難 容易
ロジック変更 影響大 局所修正
spread対応 難しい 容易
slippage対応 難しい 容易

結論:

  • シンプル型は短期効率
  • モジュール型は長期安定

6.4 モジュール型 vs ステートマシン型

違いの本質

  • モジュール型:処理を分離
  • ステートマシン型:状態を制御

実務上の差

観点 モジュール型 ステートマシン型
実装難易度
状態管理 簡易 厳密
多ポジション対応
ロジック表現力

結論:

  • 単純〜中程度のEA → モジュール型で十分
  • 複雑ロジック → ステートマシン型が有利

6.5 実運用での最適選択

実務ベースでの推奨は以下。

  • 単一通貨・単純戦略 → モジュール型
  • 複数条件・分岐あり → モジュール型+状態管理
  • グリッド・複数ポジション → ステートマシン型

判断基準:

  • ポジションが1つか複数か
  • エントリー条件が単一か複数か
  • execution条件が厳しいか

6.6 よくある選択ミス

① シンプル型で実運用しようとする

→ spread・slippageで崩壊

② ステートマシンを過剰に使う

→ 設計過多でバグ増加

③ モジュール化が中途半端

→ 結局OnTick肥大化


6.7 他手法との位置づけ

EAアーキテクチャは、他の手法と以下の関係にある。

手法 特徴 EAとの違い
インジケータ シグナルのみ 注文不可
スクリプト 単発実行 継続監視不可
EA 自動売買 フル制御可能

つまり、

  • EAは最も自由度が高い
  • その分、設計(アーキテクチャ)が重要

7. よくある失敗と注意点

【結論】
EAが実運用で崩れる原因の多くは「設計不足」ではなく「基本ミスの積み重ね」である。
特に、状態管理・execution条件・過剰最適化の3点を外すと再現性が失われる。


7.1 ロジックをOnTickに詰め込みすぎる

最も多い失敗は、すべての処理を OnTick に直接書くことである。

void OnTick()
{
   if(condition1 && condition2 && condition3)
   {
      // 注文処理
   }
}

問題点:

  • 条件が増えると可読性が崩壊
  • バグの発見が困難
  • 修正時に他ロジックへ影響

対策:

  • CheckSignal関数に分離
  • 条件ごとに関数化
  • ロジックを「意味単位」で分ける

理由:

構造化することで「どこが壊れているか」を特定できるようになる。


7.2 状態管理がなく多重エントリーする

初心者が見落としやすいが、最も危険なミス。

if(CheckBuySignal())
{
   ExecuteBuy();
}

このコードは、条件が成立する限り何度でも注文する。

結果:

  • 同一条件で連続エントリー
  • ポジションが急増
  • 想定外のリスク拡大

対策:

if(CheckBuySignal() && !PositionSelect(_Symbol))
{
   ExecuteBuy();
}

さらに厳密にするなら:

  • 同一バーで1回制限
  • フラグ管理(isEnteredなど)

理由:

EAは「状態を持つプログラム」であり、条件だけでは制御できない。


7.3 スプレッド・スリッページ未考慮

バックテストでは問題なく見えても、実運用で崩れる典型例。

// フィルターなし
ExecuteBuy();

問題:

  • spread拡大時に不利な価格で約定
  • slippageでエントリー位置がズレる
  • 利益がコストで消える

対策:

double spread = (Ask - Bid) / _Point;
if(spread > maxSpread) return;

補足:

  • スキャルピング系ほど影響が大きい
  • executionは戦略の一部と考える

7.4 バックテスト結果を過信する

非常に多い誤解。

バックテストでは:

  • spread固定
  • slippageなし
  • 約定成功前提

実運用では:

  • spread変動
  • 約定拒否
  • execution遅延

結果:

  • PF(プロフィットファクター)が崩れる
  • DD(ドローダウン)が増加

対策:

  • フォワードテスト必須
  • execution条件を再現する
  • 保守的なパラメータ設定

重要:

バックテストは「仮説検証」であり、結果保証ではない。


7.5 ロットサイズ管理が不適切

固定ロットのまま運用するケース。

double lot = 0.1;

問題:

  • 資金増減に対応できない
  • DD時に過剰リスク
  • 長期運用で破綻しやすい

対策:

  • リスクベースロット(risk per trade)
  • 証拠金・残高に応じた調整

理由:

EAは継続運用が前提のため、資金管理が最重要になる。


7.6 条件の過剰最適化(オーバーフィッティング)

バックテスト結果を良くするために条件を増やしすぎる。

例:

  • MA期間を細かく調整
  • 特定期間に最適化
  • 条件を追加しすぎる

問題:

  • 過去データにのみ適合
  • 未来で再現しない

対策:

  • シンプルなロジック維持
  • パラメータを少なくする
  • 異なる期間で検証

重要:

「再現性 > 最適化精度」


7.7 execution失敗を考慮しない

注文は必ず成功するとは限らない。

問題例:

  • OrderSendの戻り値を確認しない
  • エラー処理なし

結果:

  • 注文失敗に気づかない
  • ロジックと実際の状態が乖離

対策:

  • 戻り値チェック
  • エラーハンドリング

7.8 ログ・検証不足

問題が起きても原因が追えないケース。

対策:

  • Printでログ出力
  • 条件成立ログを残す
  • execution結果を記録

理由:

EAはブラックボックス化しやすいため、可視化が重要。


7.9 まとめ(重要ポイントの短文化)

  • OnTick肥大化は設計崩壊の原因
  • 状態管理がないと多重エントリーになる
  • spread・slippageは必ず考慮する
  • バックテストは参考値に過ぎない
  • ロット管理は長期生存の核心

8. 実務での使いどころ

【結論】
EAアーキテクチャは「検証用」「単体運用」「複数戦略運用」で設計レベルを変えるべきである。
目的に応じて構造を選ばないと、過剰設計または設計不足で非効率になる。


8.1 検証用EA(プロトタイプ段階)

最もシンプルな用途は「ロジック検証」である。

特徴:

  • 単一ロジック
  • 短期間テスト
  • バックテスト中心

推奨構造:

  • シンプル構造 or 軽量モジュール型
void OnTick()
{
   if(CheckBuySignal())
   {
      ExecuteBuy();
   }
}

ポイント:

  • 実装速度を優先
  • 完璧な設計は不要
  • 条件検証に集中

注意点:

  • このまま実運用に移行しない
  • execution(spread / slippage)は後で必ず追加

8.2 単体EAの実運用

最も一般的な用途。

特徴:

  • 単一通貨(例:EURUSD)
  • 1戦略
  • 継続運用

推奨構造:

  • モジュール型(必須)
void OnTick()
{
   if(CheckSignal() && CanExecute())
   {
      ExecuteOrder();
   }
}

追加すべき要素:

  • spreadフィルター
  • slippage考慮
  • ロット管理(riskベース)
  • 状態管理

重要ポイント:

  • executionは戦略の一部
  • ロジック単体では利益は出ない

失敗例:

  • バックテスト結果だけで投入
  • 固定ロット運用
  • 状態管理なし

8.3 複数通貨・ポートフォリオ運用

より高度な運用。

特徴:

  • 複数シンボル(EURUSD / USDJPYなど)
  • 複数ロジック
  • リスク分散

推奨構造:

  • モジュール型 + 状態管理強化
  • 必要に応じてステートマシン型

追加要素:

  • シンボルごとの状態管理
  • ポジション総量制御
  • 相関(correlation)管理

重要:

  • 単体EAより設計の重要性が高い
  • リスク管理が最優先

8.4 高度戦略(グリッド・ナンピン・複数ポジション)

難易度が高い領域。

特徴:

  • 同時に複数ポジション
  • エントリー段階が複数
  • 状態遷移が複雑

推奨構造:

  • ステートマシン型(ほぼ必須)

理由:

  • 状態が複雑すぎてif文では管理不能
  • ポジションの整合性が重要

典型的な状態:

  • 初回エントリー
  • 追加エントリー
  • 平均価格管理
  • 全決済

注意点:

  • 設計ミス=即破綻リスク
  • テスト環境必須

8.5 VPS・実運用環境でのポイント

EAは環境にも依存する。

重要要素:

  • VPS(低遅延)
  • 安定した通信
  • MT5ログ監視

影響する要素:

  • execution速度
  • slippage
  • 約定成功率

注意:

  • ローカルとVPSで挙動が変わることがある
  • ログ分析(エラー・約定)必須

8.6 実務での設計優先順位

実運用で重要な順序は以下。

  1. リスク管理(最優先)
  2. execution条件(spread / slippage)
  3. 状態管理
  4. ロジック精度

初心者がやりがちな誤り:

  • ロジック精度ばかり追う
  • executionとリスクを軽視

結果:

  • バックテストは良いが実運用で崩壊

8.7 戦略レベルでの設計思考

EAは「コード」ではなく「システム」として設計する。

重要視点:

  • どの場面で取引しないか
  • どの条件で停止するか
  • DD(ドローダウン)許容範囲

補足:

  • フィルター(時間・ニュース)
  • ボラティリティ制御(ATRなど)

8.8 まとめ(短文化)

  • 検証段階 → シンプル構造
  • 実運用 → モジュール型必須
  • 高度戦略 → ステートマシン型
  • executionとリスクが最重要

9. FAQ(よくある質問)

【結論】
EAアーキテクチャは「最初に最低限の設計を入れる」ことで、その後の開発効率と再現性が大きく変わる。
迷った場合は「モジュール型」を基準に考えると失敗しにくい。


9.1 EAアーキテクチャは初心者でも必要?

必要。
最初から完璧な設計は不要だが、「シグナルと注文を分離する」だけでも大きく安定する。
設計なしで作ると、後から修正コストが急増する。


9.2 OnTickだけでEAを作っても問題ない?

小規模な検証用なら問題ない。
ただし実運用では、状態管理・spread・slippage未対応になりやすく、破綻リスクが高い。
実運用に移行する段階で必ず分離設計にする。


9.3 モジュール化はどこから始めるべき?

最低限、以下の3分割から始める。

  • シグナル判定(CheckSignal)
  • 実行条件(CanExecute)
  • 注文処理(ExecuteOrder)

この分離だけで、ほとんどのバグを回避できる。


9.4 ステートマシンは必須?

必須ではない。
単一ポジション・単純戦略ならモジュール型で十分。

必要になるケース:

  • 複数ポジション管理
  • ナンピン・グリッド
  • 複数段階のエントリー

9.5 スプレッド(spread)はどの程度考慮すべき?

必須。
特に短期売買では、spreadが利益を直接削る。

対策:

  • エントリー前に上限チェック
  • 通貨ペアごとに閾値調整

9.6 スリッページ(slippage)はどこまで影響する?

無視できない。
特に以下で影響が大きい。

  • 指標発表時
  • 流動性が低い時間帯
  • 急変相場

executionは理論ではなく「実環境」で評価する必要がある。


9.7 バックテスト結果はどこまで信用できる?

完全には信用できない。
バックテストは以下が簡略化されている。

  • slippageなし
  • 約定100%前提
  • spread固定

そのため、必ずフォワードテストで確認する。


9.8 最適なEAアーキテクチャはどれ?

結論:

  • 初心者 → シンプル構造(短期)
  • 実運用 → モジュール型(基本)
  • 高度戦略 → ステートマシン型

迷った場合は「モジュール型」を選べば問題ない。


9.9 ロットサイズは固定でもよい?

短期検証なら問題ない。
実運用ではリスクベース(資金割合)にするべき。

理由:

  • DD耐性が変わる
  • 長期運用での生存率に直結

9.10 EAで最も重要な要素は何?

優先順位は以下。

  1. リスク管理
  2. execution条件(spread / slippage)
  3. 状態管理
  4. ロジック精度

ロジックだけでは利益は出ない。

10. まとめ

【結論】
EAアーキテクチャは「再現性・安定性・拡張性」を担保するための設計であり、実運用では必須である。
特に「シグナル・execution・リスク管理の分離」が最重要ポイントになる。


10.1 本記事の要点整理

  • EAは「データ取得 → 判断 → 実行 → 管理」で構成する
  • OnTickに全て書くと設計が破綻する
  • シグナルとexecutionは必ず分離する
  • 状態管理がないと多重エントリーが発生する
  • spread・slippageは必ず考慮する
  • バックテストは参考であり、実運用とは異なる

10.2 実務での最適アプローチ

実務では以下の流れが最も効率的。

  1. 最小構成で動作確認
  2. モジュール化して分離
  3. リスク管理とexecution条件を追加
  4. フォワードテストで検証

この順序により、

  • 開発効率
  • 再現性
  • 安定性

を同時に高めることができる。


10.3 設計レベル別の指針

  • 検証段階 → シンプル構造
  • 実運用 → モジュール型必須
  • 高度戦略 → ステートマシン型

無理に高度な設計を使う必要はないが、
実運用でシンプル構造を使い続けるのはリスクが高い。


10.4 最も重要な考え方

EAは「コード」ではなく「システム」である。

重要なのは以下。

  • どの条件で取引しないか
  • どの条件で停止するか
  • どの程度の損失を許容するか

これらを含めて設計することで、
初めて実運用に耐えるEAになる。


10.5 次のステップ

次に取り組むべき内容:

  • モジュール型テンプレの実装
  • ロットサイズ計算(risk per trade)
  • spreadフィルター設計
  • フォワードテスト環境構築

これらを実装することで、
EAは「検証ツール」から「運用システム」へ進化する。