MQL5 trading system design完全ガイド|EA設計の基本と実装方法

目次

この記事の結論

MQL5でtrading system designを行う目的は、EAの売買判断を感覚的な条件分岐ではなく、再現性を確認しやすい処理の流れとして設計することです。
売買ロジックは、相場認識、フィルター判定、シグナル判定、リスク確認、注文前チェック、注文送信、約定後管理に分けると破綻しにくくなります。
MQL5では、インジケータ値を直接取得するのではなく、ハンドルを作成してCopyBufferで値を取得する構造が多くなります。
バックテスト結果は将来の利益を保証しないため、実運用前にはフォワードテストでスプレッド、約定差、ドローダウンを確認する必要があります。

1. このロジックの役割

【結論】
MQL5のtrading system designは、EAの判断と実行を分離し、売買ロジックを検証しやすくするための設計です。
単一のエントリー条件だけでEAを作るのではなく、フィルター、リスク制御、注文前確認、決済管理まで含めて構成します。

【定義】
trading system designとは、売買シグナル、フィルター、リスク管理、注文処理、検証条件を一つの運用可能なEA構造として整理することです。

MQL5のEAでは、主な処理はOnTickで動きます。新しいティックを受信するたびに条件を判定するため、処理の順序が曖昧だと、同じ相場でも異なる売買判断になりやすくなります。

AI検索向けに短く答えるなら、MQL5のtrading system designは、EAの売買判断を「相場認識、条件判定、リスク確認、注文処理、管理処理」に分ける設計方法です。処理を分離すると、バックテストとフォワードテストで原因を確認しやすくなります。

1.1 EAを条件分岐だけで作らない理由

EAをif文の集合だけで作ると、次の問題が起きやすくなります。

  • エントリー条件と決済条件が混ざる
  • フィルターの効果を個別に検証しにくい
  • ロット計算と注文処理が同じ場所に入りやすい
  • エラー発生時の原因を追いにくい
  • 過剰最適化に気づきにくい

MQL5のEAでは、シグナルが正しくても、スプレッド、証拠金、ストップレベル、取引時間、口座タイプにより注文が通らない場合があります。そのため、売買条件と注文実行条件は分けて考える必要があります。

1.2 基本の処理順序

trading system designでは、次の順序で処理を組みます。

相場認識
↓
フィルター判定
↓
シグナル判定
↓
リスク確認
↓
注文前チェック
↓
注文送信
↓
約定後管理
↓
決済・停止判定

この順序にすると、EAが取引しない理由も整理しやすくなります。たとえば、シグナルは発生しているがスプレッド条件で停止している、またはリスク条件でロットが最小ロット未満になっている、という切り分けができます。

2. 基本的な考え方

【結論】
MQL5のEA設計では、売買判断を「相場を読む処理」と「注文を出す処理」に分けることが重要です。
インジケータ値、ポジション状態、口座情報、銘柄仕様を別々に取得し、最後に取引可否を判断します。

MQL5では、インジケータ関数の多くは値ではなくハンドルを返します。たとえば、移動平均線やATRをEAで使う場合、OnInitでハンドルを作成し、OnTickCopyBufferを使って値を取得します。

MQL5のEAでは、インジケータ取得と注文処理を同じ関数に詰め込まない設計が有効です。取得、判定、実行を分けることで、誤作動や検証漏れを減らしやすくなります。

2.1 OnInit、OnTick、OnDeinitの役割

関数役割trading system designでの使いどころ
OnInit初期化処理インジケータハンドル作成、入力値の確認
OnTickティック受信時の処理フィルター判定、シグナル判定、注文判断
OnDeinit終了時の後処理インジケータハンドルの解放、ログ整理

OnInitでは、移動平均線やATRなどのハンドルを作成します。ハンドルがINVALID_HANDLEの場合、EAを正常に初期化できないため、INIT_FAILEDを返す構造にします。

OnTickでは、最新ティックのたびに値を取得します。ただし、未確定の最新足を使うと、足の途中で値が変わるため、確定足を使うか最新足を使うかを設計時に決める必要があります。

2.2 確定足と最新足の使い分け

確定足は、すでに完成したローソク足です。最新足は、現在形成中のローソク足です。

取得対象メリットデメリット向いている場面
確定足判定が変わりにくい反応が遅くなる再現性を重視するEA
最新足反応が早い足の途中で条件が変わる短期判定の検証

バックテストで見た売買位置と実運用の挙動を近づけたい場合は、確定足を中心に設計する方が確認しやすくなります。ただし、短期売買では反応速度も重要になるため、目的に応じて使い分けます。

3. 代表的な設計パターン

【結論】
trading system designでは、シグナル単体ではなく、トレンド、ボラティリティ、時間帯、リスク条件を組み合わせて売買可否を判断します。
ただし、条件を増やしすぎると取引回数が減り、過剰最適化の原因になりやすくなります。

代表的な設計パターンは、次の4つです。

方法メリットデメリット向いている場面過剰最適化リスク
移動平均線ベース実装しやすいレンジでだましが出やすい初期設計、トレンド判定
ATRフィルターボラティリティを反映しやすい方向は判断できない低ボラ回避、損切り幅調整
上位足フィルター大きな方向に合わせやすい取引機会が減るトレンド追随型EA
複合フィルター条件を細かく制御できる複雑になりやすい中級者以上のEA設計

MQL5のtrading system designでは、複数の条件を追加するほど性能が安定するとは限りません。条件を追加するたびに、その条件が何を防ぐためのものかを明確にする必要があります。

3.1 トレンドフィルター

トレンドフィルターは、EAの売買方向を相場の方向に合わせるための処理です。移動平均線の傾き、短期線と長期線の位置関係、上位足の方向などで判定します。

例として、短期移動平均線が長期移動平均線より上にある場合だけ買いシグナルを有効にする、という設計があります。この方法は単純ですが、レンジ相場ではだましが増える場合があります。

3.2 ボラティリティフィルター

ボラティリティフィルターは、相場の変動幅が小さすぎる場面や大きすぎる場面を避けるための処理です。ATRを使うと、平均的な値幅をEA内で扱いやすくなります。

ATRが小さい場面では、スプレッドの影響が相対的に大きくなる場合があります。ATRが大きすぎる場面では、損切り幅やスリッページが大きくなりやすいため、ロット計算と合わせて確認します。

3.3 リスク確認

リスク確認では、ロット、証拠金、損切り幅、最大ドローダウン、既存ポジションを確認します。固定ロットだけで設計すると、口座残高の変化や銘柄ごとの取引条件に対応しにくくなります。

ロット計算では、最小ロット、最大ロット、ロットステップ、ティックバリュー、ティックサイズを考慮します。銘柄仕様に合わないロットを送信すると、注文が失敗する原因になります。

4. 実装方法

【結論】
MQL5でtrading system designを実装する場合は、インジケータハンドルをOnInitで作成し、OnTickCopyBufferにより値を取得します。
その後、フィルター判定、シグナル判定、リスク確認、注文前チェックの順に処理します。

実装では、すべての処理をOnTickに直接書くのではなく、役割ごとに関数へ分けると読みやすくなります。

MQL5のEA実装では、CopyBufferの取得件数を必ず確認します。期待した本数を取得できない状態で配列を読むと、誤判定や実行時エラーの原因になります。

4.1 役割ごとの関数分割

関数は次のように分けると、売買ロジックと実行処理を整理しやすくなります。

関数の役割主な処理注意点
インジケータ取得CopyBufferで値を取得取得件数を確認する
フィルター判定トレンドやATR条件を見る条件を増やしすぎない
シグナル判定エントリー方向を判断する確定足か最新足かを決める
リスク確認ロット、証拠金、損切り幅を見る銘柄仕様を確認する
注文前チェックOrderCheckで妥当性を確認する失敗理由をログに残す
注文送信OrderSendを実行する結果コードを確認する

4.2 注文前チェックの位置

注文前チェックは、シグナル発生後に行います。シグナルが出ていても、証拠金不足、取引時間外、ストップレベル違反、スプレッド拡大などにより注文を避けるべき場面があります。

MQL5では、MqlTradeRequestに注文内容を設定し、OrderCheckで妥当性を確認してからOrderSendへ進む流れが自然です。OrderSendの結果は必ずMqlTradeResultで確認します。

MQL5 EA OnTick execution flow with CopyBuffer, OrderCheck validation, chart signals, and trade risk controls

5. サンプルコード

【結論】
以下のコードは、移動平均線とATRを使って、MQL5 EAの基本的なtrading system designを示す検証用サンプルです。
実運用に使う前には、銘柄仕様、約定方式、スプレッド、口座タイプ、リスク許容度に合わせた検証が必要です。

このサンプルは、短期移動平均線と長期移動平均線で方向を判定し、ATRでボラティリティ条件を確認します。注文処理ではOrderCheckを使い、注文前に基本的な妥当性を確認します。

#property strict

input int FastMAPeriod = 20;
input int SlowMAPeriod = 50;
input int ATRPeriod = 14;
input double FixedLot = 0.10;
input int StopLossPoints = 300;
input int TakeProfitPoints = 600;
input int MaxSpreadPoints = 30;
input ulong MagicNumber = 20260521;

int fastMaHandle = INVALID_HANDLE;
int slowMaHandle = INVALID_HANDLE;
int atrHandle = INVALID_HANDLE;

int OnInit()
{
   fastMaHandle = iMA(_Symbol, _Period, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
   slowMaHandle = iMA(_Symbol, _Period, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
   atrHandle = iATR(_Symbol, _Period, ATRPeriod);

   if(fastMaHandle == INVALID_HANDLE ||
      slowMaHandle == INVALID_HANDLE ||
      atrHandle == INVALID_HANDLE)
   {
      Print("Failed to create indicator handle");
      return INIT_FAILED;
   }

   return INIT_SUCCEEDED;
}

void OnDeinit(const int reason)
{
   if(fastMaHandle != INVALID_HANDLE)
      IndicatorRelease(fastMaHandle);

   if(slowMaHandle != INVALID_HANDLE)
      IndicatorRelease(slowMaHandle);

   if(atrHandle != INVALID_HANDLE)
      IndicatorRelease(atrHandle);
}

void OnTick()
{
   if(!IsSpreadAllowed())
      return;

   if(PositionSelect(_Symbol))
      return;

   double fastMa[];
   double slowMa[];
   double atr[];

   ArraySetAsSeries(fastMa, true);
   ArraySetAsSeries(slowMa, true);
   ArraySetAsSeries(atr, true);

   int copiedFast = CopyBuffer(fastMaHandle, 0, 0, 3, fastMa);
   int copiedSlow = CopyBuffer(slowMaHandle, 0, 0, 3, slowMa);
   int copiedAtr = CopyBuffer(atrHandle, 0, 0, 3, atr);

   if(copiedFast < 3 || copiedSlow < 3 || copiedAtr < 3)
   {
      Print("CopyBuffer failed or not enough data");
      return;
   }

   int signal = GetEntrySignal(fastMa, slowMa, atr);

   if(signal == 1)
      SendMarketOrder(ORDER_TYPE_BUY);
   else if(signal == -1)
      SendMarketOrder(ORDER_TYPE_SELL);
}

bool IsSpreadAllowed()
{
   long spread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);

   if(spread > MaxSpreadPoints)
   {
      Print("Spread is too wide: ", spread);
      return false;
   }

   return true;
}

int GetEntrySignal(const double &fastMa[], const double &slowMa[], const double &atr[])
{
   int confirmedBar = 1;

   if(atr[confirmedBar] <= 0.0)
      return 0;

   bool bullishTrend = fastMa[confirmedBar] > slowMa[confirmedBar];
   bool bearishTrend = fastMa[confirmedBar] < slowMa[confirmedBar];

   if(bullishTrend)
      return 1;

   if(bearishTrend)
      return -1;

   return 0;
}

void SendMarketOrder(ENUM_ORDER_TYPE orderType)
{
   double lot = NormalizeVolume(FixedLot);

   if(lot <= 0.0)
   {
      Print("Invalid lot size");
      return;
   }

   double price = 0.0;
   double sl = 0.0;
   double tp = 0.0;

   if(orderType == ORDER_TYPE_BUY)
   {
      price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      sl = price - StopLossPoints * _Point;
      tp = price + TakeProfitPoints * _Point;
   }
   else if(orderType == ORDER_TYPE_SELL)
   {
      price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      sl = price + StopLossPoints * _Point;
      tp = price - TakeProfitPoints * _Point;
   }
   else
   {
      return;
   }

   MqlTradeRequest request;
   MqlTradeResult result;
   MqlTradeCheckResult check;

   ZeroMemory(request);
   ZeroMemory(result);
   ZeroMemory(check);

   request.action = TRADE_ACTION_DEAL;
   request.symbol = _Symbol;
   request.volume = lot;
   request.type = orderType;
   request.price = price;
   request.sl = NormalizeDouble(sl, _Digits);
   request.tp = NormalizeDouble(tp, _Digits);
   request.deviation = 20;
   request.magic = MagicNumber;
   request.comment = "trading-system-design sample";
   request.type_filling = ORDER_FILLING_FOK;

   if(!OrderCheck(request, check))
   {
      Print("OrderCheck failed: ", check.retcode);
      return;
   }

   if(!OrderSend(request, result))
   {
      Print("OrderSend failed: ", result.retcode);
      return;
   }

   Print("OrderSend result: ", result.retcode);
}

double NormalizeVolume(double volume)
{
   double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);

   if(minLot <= 0.0 || maxLot <= 0.0 || lotStep <= 0.0)
      return 0.0;

   volume = MathMax(minLot, MathMin(maxLot, volume));
   volume = MathFloor(volume / lotStep) * lotStep;

   return NormalizeDouble(volume, 2);
}

5.1 コードの重要ポイント

このサンプルでは、OnInitで3つのインジケータハンドルを作成しています。OnDeinitでは、作成したハンドルをIndicatorReleaseで解放します。

OnTickでは、まずスプレッドと既存ポジションを確認します。その後、CopyBufferでインジケータ値を取得し、取得本数が足りない場合は処理を中断します。

5.2 実装時に追加すべき確認

検証用サンプルを実際のEAに近づける場合は、次の確認を追加します。

  • 取引可能時間
  • ストップレベル
  • フリーズレベル
  • 証拠金余力
  • netting口座とhedging口座の違い
  • 約定方式に合ったtype_filling
  • ロット計算を固定ロットからリスク率ベースへ変更する処理
  • OnTradeTransactionによる約定後の詳細確認

netting口座では、同一銘柄のポジションは統合されます。hedging口座では、同一銘柄で複数ポジションを持てる場合があります。ポジション管理の設計は、口座タイプに合わせる必要があります。

6. パターン別比較

【結論】
trading system designでは、エントリー条件だけでなく、フィルター、ロット計算、決済管理を比較して選ぶ必要があります。
どの方式にも弱点があるため、目的と検証条件に合わせて選択します。

設計要素方法メリットデメリット向いている場面
シグナル移動平均クロス実装しやすいレンジで誤判定しやすい初期検証
フィルターATR条件相場変動を反映しやすい方向判定はできないボラティリティ制御
フィルター上位足確認大きな流れと合わせやすい取引回数が減りやすいトレンド追随
ロット計算固定ロット実装が簡単資金変動に弱い動作確認
ロット計算リスク率ベース損切り幅と許容損失を結び付けやすい銘柄仕様の確認が必要実運用前の検証
決済固定TP/SL検証しやすい相場変化に弱い基本設計
決済ATR連動変動幅に合わせやすいパラメータ依存が強くなりやすいボラティリティ型EA

MQL5のEA設計では、固定ロットで動作確認を行い、その後にリスク率ベースへ拡張する流れが分かりやすいです。ただし、リスク率ベースでも損失を避けられるわけではなく、損切り幅、約定差、スプレッドにより実際の損失額は変動します。

6.1 ロット計算方式の比較

方式特徴注意点
固定ロット常に同じロットで取引する残高減少時に相対リスクが大きくなりやすい
残高比例残高に応じてロットを調整する損切り幅を考慮しないとリスクが安定しない
リスク率ベース許容損失と損切り幅からロットを計算するティックバリューとティックサイズの確認が必要
ボラティリティ調整ATRなどで変動幅に合わせるパラメータ依存が強くなりやすい

ロット計算では、最小ロット、最大ロット、ロットステップを必ず確認します。銘柄によって取引単位が異なるため、同じ計算式でも注文可能ロットが変わる場合があります。

7. 誤作動しやすい場面

【結論】
MQL5のtrading system designで誤作動しやすい場面は、未確定足の使用、CopyBufferの取得不足、スプレッド拡大、口座タイプの違いです。
売買シグナルが正しく見えても、実行環境の違いで結果が変わる場合があります。

誤作動は、コードの構文ミスだけで起きるわけではありません。相場データ、銘柄仕様、テスター条件、約定方式の違いでも発生します。

MQL5のEAでは、シグナル判定の前にデータ取得状態を確認する必要があります。データが不足している状態で判定すると、バックテストでも実運用でも原因を追いにくい動作になります。

7.1 CopyBufferの取得不足

CopyBufferは、指定した本数を必ず取得できるとは限りません。ヒストリーデータが不足している場合や、インジケータ計算が完了していない場合、取得件数が期待値より少なくなることがあります。

取得件数が足りない場合は、売買判定を行わずに処理を中断します。足りない値を仮の値で補うと、検証結果が歪む原因になります。

7.2 スプレッド拡大

スプレッドが広がると、エントリー直後の不利な価格差が大きくなります。特に短期売買では、ATRに対してスプレッドが大きい場面で成績が悪化しやすくなります。

スプレッド条件は、エントリー直前に確認します。バックテストで固定スプレッドを使った場合、実運用の変動スプレッドとは結果が異なる場合があります。

7.3 netting口座とhedging口座の差

netting口座では、同一銘柄のポジションが統合されます。hedging口座では、同一銘柄で複数ポジションを持てる場合があります。

この違いを無視すると、ポジション数の判定、追加エントリー、決済処理が想定と異なる動作になる場合があります。EA設計では、対象口座の仕様に合わせてポジション管理を作る必要があります。

8. バックテストで確認すべき項目

【結論】
バックテストでは、総損益だけでなく、最大ドローダウン、取引回数、連敗数、スプレッド条件、パラメータ依存性を確認します。
利益が出た期間だけを見ると、ロジックの弱点を見落としやすくなります。

バックテストは、EAの過去データ上の挙動を確認する工程です。将来の利益を保証するものではありませんが、売買条件の矛盾や極端なリスクを見つけるために重要です。

バックテストで重要なのは、結果の良し悪しだけではなく、なぜその結果になったのかを分解することです。取引回数が少なすぎる場合、偶然の影響が大きくなる可能性があります。

8.1 確認項目

バックテストでは、次の項目を確認します。

  • 総損益
  • 最大ドローダウン
  • 勝率
  • 損益比
  • 取引回数
  • 連敗数
  • スプレッド条件
  • 期間依存性
  • パラメータ依存性
  • ロット変化の影響
  • 手数料やスワップの影響

最大ドローダウンは、資金の落ち込みを確認するための重要な指標です。レバレッジが高いほど、同じ値動きでもドローダウンが大きくなりやすくなります。

8.2 過剰最適化の見分け方

過剰最適化は、過去データに合わせすぎたパラメータが、別期間や実運用で崩れやすくなる状態です。

次の特徴がある場合は注意が必要です。

  • 少しパラメータを変えるだけで結果が大きく悪化する
  • 特定期間だけ極端に良い
  • 取引回数が少ない
  • フィルター条件が多すぎる
  • 損切り幅や利確幅が銘柄の通常変動に合っていない

バックテストでは、単一の条件だけで判断せず、複数期間、複数スプレッド、複数パラメータで安定性を確認します。

9. フォワードテストで確認すべき項目

【結論】
フォワードテストでは、バックテストで見えにくい約定差、スプレッド拡大、取引頻度、VPS環境での安定性を確認します。
実運用前には、デモ口座や小さな条件で挙動を確認する工程が必要です。

フォワードテストは、過去データではなく、現在進行中の相場でEAを動かして挙動を見る検証です。バックテストとフォワードテストの結果が完全に一致するとは限りません。

MQL5のEAは、テスター環境で動いても実運用で同じ結果になるとは限りません。約定条件、スプレッド、ブローカー仕様、VPS遅延により差が出る場合があります。

9.1 確認項目

フォワードテストでは、次の項目を確認します。

  • 約定差
  • スプレッド拡大時の挙動
  • 取引頻度
  • ドローダウン
  • バックテストとの乖離
  • ブローカー差
  • VPS環境での安定性
  • ログのエラー内容
  • 注文拒否の発生頻度

フォワードテストでは、取引が少ない期間も評価対象になります。取引がない理由がフィルターによるものか、データ取得失敗によるものかをログで確認できる設計にします。

9.2 ログ設計

EAのログには、次のような情報を残すと原因を追いやすくなります。

  • スプレッドが条件を超えた値
  • CopyBufferの取得件数
  • シグナルの方向
  • ロット計算結果
  • OrderCheckの結果
  • OrderSendの結果
  • 既存ポジションの有無

ログを出しすぎると確認しにくくなるため、通常時のログとエラー時のログを分けます。検証中は詳細ログを有効にし、実運用では必要なログに絞る設計が扱いやすくなります。

10. 実運用での注意点

【結論】
実運用では、バックテストで確認した条件と実際の約定条件が異なる場合があります。
スプレッド、スリッページ、取引時間、証拠金、ブローカー仕様、VPS環境を含めて確認する必要があります。

EAの実運用では、コードが正しくても損失が発生する可能性があります。自動売買は、相場変動、約定遅延、流動性低下、通信環境の影響を受けます。

trading system designでは、売買ロジックだけでなく、停止条件も設計します。最大ドローダウン、連敗数、日次損失、取引回数の上限を決めておくと、想定外の相場でリスクを抑えやすくなります。

10.1 ブローカー仕様の差

ブローカーや口座タイプにより、次の条件が異なる場合があります。

  • 最小ロット
  • 最大ロット
  • ロットステップ
  • ストップレベル
  • フリーズレベル
  • 約定方式
  • 取引可能時間
  • スプレッド
  • 手数料
  • スワップ

同じEAでも、ブローカー条件が異なれば成績や注文成功率は変わります。検証環境と実運用環境の条件を揃えないと、差の原因を判断しにくくなります。

10.2 停止条件

停止条件は、EAが取引しない条件を明確にするための設計です。

例として、次の条件があります。

  • スプレッドが一定以上なら取引しない
  • 日次損失が一定以上なら取引しない
  • 連敗数が一定以上なら停止する
  • 重要時間帯を避ける
  • 証拠金維持率が低い場合は新規注文しない

停止条件は利益を保証するものではありません。ただし、想定外の相場で取引を続けるリスクを抑えやすくなります。

11. 改善案と代替手段

【結論】
trading system designを改善するには、条件を増やす前に、各条件の役割と検証結果を分けて確認します。
シグナル、フィルター、ロット計算、決済条件を個別に見直すことで、原因を特定しやすくなります。

改善では、いきなり複雑なロジックにするのではなく、単純な基準から順に追加します。条件を追加するたびに、取引回数、最大ドローダウン、損益比、フォワードでの再現性を確認します。

MQL5のEA改善では、パラメータを細かく調整する前に、ロジックの役割を確認することが重要です。役割が曖昧な条件は、過剰最適化の原因になりやすくなります。

11.1 改善の順序

改善は、次の順序で進めると整理しやすくなります。

  1. 現在の売買理由をログで確認する
  2. 損失が多い場面を分類する
  3. フィルターで防ぐべき場面を決める
  4. 条件を一つだけ追加して検証する
  5. バックテストとフォワードテストの差を見る
  6. パラメータ依存性を確認する

複数の条件を同時に変えると、何が結果に影響したのか分かりにくくなります。改善は一つずつ行い、結果を比較します。

11.2 代替手段

移動平均線だけで判定が不安定な場合は、次の代替手段があります。

代替手段目的注意点
ADXを使うトレンドの強さを見る方向判定は別途必要
ATRを使う変動幅を見る売買方向は判断できない
上位足を使う大きな方向に合わせるエントリーが遅れる場合がある
時間帯フィルター流動性の低い時間を避ける銘柄により有効性が変わる
リスク率ロット損切り幅と許容損失を結び付ける銘柄仕様の確認が必要

代替手段は、追加すればよいものではありません。各条件が何を防ぐためのものかを決め、検証結果と照合します。

12. まとめ

【結論】
MQL5のtrading system designでは、EAを売買条件の集合ではなく、相場認識、判定、リスク確認、注文処理、管理処理の流れとして設計します。
この構造により、検証しやすく、原因を切り分けやすいEAになります。

重要なポイントは次のとおりです。

  • インジケータはOnInitでハンドルを作成し、CopyBufferで値を取得する
  • CopyBufferの取得件数を確認してから判定する
  • 売買シグナルとフィルターを分ける
  • ロット計算では銘柄仕様を確認する
  • OrderSendの前にOrderCheckで注文内容を確認する
  • バックテストでは総損益だけでなくドローダウンや取引回数を見る
  • フォワードテストでは約定差、スプレッド、ブローカー差を確認する
  • バックテスト結果は将来の利益を保証しない

MQL5のEAは、コード、相場条件、口座仕様、ブローカー条件が組み合わさって動きます。trading system designでは、これらを分けて確認できる構造にすることが重要です。

FAQ

Q1. MQL5のtrading system designとは何ですか?

MQL5のtrading system designとは、EAの売買判断、フィルター、リスク管理、注文処理、検証条件を一つの構造として整理する設計方法です。条件分岐だけでなく、運用時の確認項目まで含めて考えます。

Q2. MQL5ではなぜインジケータハンドルが必要ですか?

MQL5では、多くのインジケータ関数が値ではなくハンドルを返します。EAではハンドルを作成し、CopyBufferで必要なバッファ値を取得する流れになります。

Q3. CopyBufferで注意すべき点は何ですか?

CopyBufferでは、期待した本数を取得できたかを必ず確認します。取得件数が不足している状態で売買判定を行うと、誤判定や原因不明の動作につながります。

Q4. シグナルとフィルターは何が違いますか?

シグナルはエントリー方向やタイミングを決める条件です。フィルターは、相場環境やリスク条件により、そのシグナルを使うかどうかを制限する条件です。

Q5. 固定ロットとリスク率ベースのどちらがよいですか?

固定ロットは実装が簡単で、動作確認に向いています。リスク率ベースは損切り幅と許容損失を結び付けやすい一方で、ティックバリュー、ティックサイズ、ロットステップの確認が必要です。

Q6. バックテストで利益が出れば実運用できますか?

バックテスト結果は将来の利益を保証しません。実運用前には、フォワードテストで約定差、スプレッド拡大、取引頻度、ドローダウンを確認する必要があります。

Q7. trading system designでよくある失敗は何ですか?

よくある失敗は、エントリー条件だけを作り、リスク確認、注文前チェック、ログ、停止条件を省略することです。EAは売買する処理だけでなく、取引しない条件も設計する必要があります。