この記事の結論
MQL5でブローカー差を考慮したEA設計を行う目的は、バックテストでは正常でもリアル口座で挙動が変わる問題を減らすことです。
ブローカー差は、スプレッド、約定方式、最小ロット、ロットステップ、ストップレベル、フリーズレベル、取引時間、口座タイプの違いとして現れます。
EAでは、売買ロジックだけでなく、注文前チェック、ロット補正、銘柄仕様の取得、エラー処理、ログ出力を分離して設計する必要があります。
バックテスト結果は将来の利益を保証しないため、実運用前にフォワードテストで約定差やスプレッド拡大時の挙動を確認する必要があります。
1. この設計が必要な理由
【結論】
MQL5のEAでは、同じコードでもブローカーや口座タイプによって注文結果、ロット制限、約定条件が変わる場合があります。
ブローカー差を無視すると、テスターでは動いたEAがリアル口座で注文失敗、ロットエラー、ストップ設定エラーを起こしやすくなります。
MQL5のEAは、売買シグナルが正しいだけでは安定して動きません。実際の注文では、銘柄ごとの取引条件、口座設定、取引時間、証拠金、約定方式が関係します。
特に、次のような差はEAの挙動に直接影響します。
- スプレッドが広いと、エントリー条件や損益比が変わる
- 最小ロットやロットステップが異なると、計算ロットをそのまま使えない
- ストップレベルが広いと、損切りや利確を注文時に置けない場合がある
- フリーズレベルがあると、ポジション変更や決済注文が制限される場合がある
- netting口座とhedging口座では、ポジション管理の考え方が異なる
- 取引可能時間が異なると、同じOnTick処理でも注文できない時間帯が出る
MQL5でブローカー差に強いEAを作るには、シグナル判定と注文処理を分ける必要があります。EAは「条件が成立したらすぐ注文」ではなく、「条件成立後に取引可能性を確認してから注文する」構造にするべきです。
1.1 ブローカー差が表面化しやすい場面
ブローカー差は、通常時よりも相場変動が大きい場面で表面化しやすくなります。スプレッド拡大、約定遅延、スリッページ、注文拒否は、バックテストよりリアル口座で目立つ場合があります。
EAでは、次の場面を特に警戒します。
- 経済指標前後
- 市場開始直後
- ロールオーバー時間帯
- 流動性が低い時間帯
- 急変動後の価格更新が速い場面
- CFDや指数など取引条件が銘柄ごとに大きく異なる銘柄
1.2 売買ロジックだけでは不十分な理由
売買ロジックは、相場条件を判定する部分です。しかし、注文が実際に通るかどうかは、取引環境に依存します。
たとえば、移動平均クロスが発生しても、スプレッドが広すぎる場合はエントリーを見送る設計が必要です。ロット計算で0.13 lotが算出されても、ロットステップが0.10の場合は、銘柄仕様に合わせた補正が必要です。
MQL5のEAでは、相場判断と注文実行を別の責務として扱うことで、ブローカー差への耐性を高めやすくなります。
2. EA全体の設計思想
【結論】
ブローカー差に対応するEAは、売買判断、リスク確認、銘柄仕様確認、注文前チェック、注文送信、約定後管理を段階的に処理します。
各段階を分けることで、エラーの原因を特定しやすくなり、検証条件も整理しやすくなります。
ブローカー差を考慮したEAでは、処理の流れを固定しておくと設計が安定します。代表的な流れは次のとおりです。
相場認識
↓
フィルター判定
↓
シグナル判定
↓
リスク確認
↓
銘柄仕様確認
↓
注文前チェック
↓
注文送信
↓
約定後管理
↓
決済・停止判定
この構造では、エントリー条件が成立しても、取引条件が悪い場合は注文を送信しません。EAの目的は取引回数を増やすことではなく、設計した条件で再現性を確認しやすい状態にすることです。
2.1 OnInit、OnTick、OnDeinitの役割
MQL5のEAでは、イベント関数の役割を分けて使います。
| 関数 | 役割 | ブローカー差対応での使いどころ |
|---|---|---|
| OnInit | 初期化処理 | インジケータハンドル作成、初期パラメータ確認 |
| OnTick | 新しいティック受信時の処理 | シグナル判定、取引条件確認、注文管理 |
| OnDeinit | 終了時の後処理 | インジケータハンドル解放、終了ログ出力 |
インジケータを使うEAでは、OnInitでハンドルを作成し、OnTickでCopyBufferを使って値を取得します。MQL5では、多くのインジケータ関数が値を直接返すのではなく、ハンドルを作成してからバッファ値を取得する流れになります。
2.2 netting口座とhedging口座の違い
MQL5では、口座タイプによりポジション管理が変わります。netting口座では、同一銘柄のポジションは基本的に集約されます。hedging口座では、同一銘柄で複数ポジションを持てる場合があります。
EAでは、口座タイプを意識せずに「同じ銘柄に何本でもポジションを持てる」と決めつけるべきではありません。ポジション選択、追加エントリー、決済処理は、口座タイプに合わせて設計する必要があります。
3. 基本構造
【結論】
ブローカー差に対応する基本構造は、銘柄仕様の取得、ロット補正、スプレッド確認、ストップ距離確認、OrderCheck、OrderSendを順番に処理する形です。
この順番にすると、注文失敗の原因をログで追いやすくなります。
EAの基本構造は、次のモジュールに分けると整理しやすくなります。
- シグナル判定モジュール
- フィルター判定モジュール
- ロット計算モジュール
- 銘柄仕様確認モジュール
- 注文前チェックモジュール
- 注文送信モジュール
- ポジション管理モジュール
- エラーハンドリングモジュール
- ログ出力モジュール
この分離により、バックテストで問題が出た場合も、売買ロジックの問題なのか、取引条件の問題なのかを切り分けやすくなります。

3.1 銘柄仕様を取得する項目
EAでは、注文前に銘柄仕様を取得します。代表的な確認項目は次のとおりです。
| 項目 | 目的 | 設計上の注意点 |
|---|---|---|
| 最小ロット | 発注可能な最小数量を確認する | 計算ロットが下回る場合は注文しないか補正する |
| 最大ロット | 発注可能な最大数量を確認する | 過大ロットを防ぐ |
| ロットステップ | ロット刻みを確認する | 端数を銘柄仕様に合わせる |
| ストップレベル | SL/TPの最小距離を確認する | 近すぎるSL/TPを避ける |
| フリーズレベル | 変更制限距離を確認する | 決済や変更が制限される場面を考慮する |
| ティックサイズ | 価格変動単位を確認する | 損益計算や価格丸めに使う |
| ティックバリュー | 1ティックあたりの価値を確認する | リスク率ベースのロット計算に使う |
MQL5のEAでは、銘柄仕様を固定値で決め打ちしないことが重要です。通貨ペア、貴金属、指数、暗号資産CFDなどでは、桁数やティックバリューが大きく異なる場合があります。
3.2 注文前チェックの基本
注文前チェックでは、少なくとも次を確認します。
- 取引が許可されているか
- スプレッドが許容範囲内か
- 計算ロットが銘柄仕様に合っているか
- 必要証拠金が足りるか
- SL/TPがストップレベルを満たすか
- 既存ポジションが設計条件と矛盾しないか
- 取引時間内か
MQL5では、注文送信前にMqlTradeRequestを組み立て、必要に応じてOrderCheckで妥当性を確認します。OrderCheckを使うと、証拠金不足や注文条件の不整合を注文送信前に検出しやすくなります。
4. 主要モジュールの役割
【結論】
ブローカー差に強いEAでは、売買シグナル、リスク管理、ロット計算、注文チェック、ポジション管理を別々の役割として実装します。
役割を分けることで、ブローカーごとの仕様差を一部の処理に閉じ込めやすくなります。
EAを単一のOnTick内に大きく書くと、後から原因を追いにくくなります。ブローカー差を扱う場合は、仕様差を吸収する処理を明確に分ける必要があります。
4.1 シグナル判定とフィルター判定
シグナル判定は、エントリー候補を作る処理です。フィルター判定は、その候補を取引してよいか制限する処理です。
たとえば、移動平均クロスをシグナルに使う場合でも、スプレッドが広い、ATRが極端に大きい、取引時間外に近いといった条件ではエントリーを見送る設計が考えられます。
4.2 リスク管理とロット計算
ロット計算は、口座残高や有効証拠金だけでなく、損切り幅、ティックバリュー、ティックサイズ、最小ロット、最大ロット、ロットステップを考慮します。
代表的なロット計算方式は次のとおりです。
| 方法 | メリット | デメリット | 向いている場面 |
|---|---|---|---|
| 固定ロット | 実装が簡単 | 資金変動や損切り幅を反映しにくい | 初期検証 |
| 残高比例 | 資金に合わせて調整しやすい | 損切り幅を無視するとリスクがぶれやすい | 資金規模に合わせた調整 |
| リスク率ベース | 許容損失と損切り幅から計算できる | ティックバリューや銘柄仕様の理解が必要 | 実運用前提の検証 |
| ボラティリティ調整 | ATRなどで相場変動を反映しやすい | パラメータ依存が強くなりやすい | 変動幅が大きい銘柄 |
リスク率ベースのロット計算でも、最終的にはブローカーのロット制限に合わせた補正が必要です。補正後のロットが最小ロットを下回る場合は、無理に注文せず見送る設計が安全です。
4.3 注文管理と約定後管理
注文管理では、MqlTradeRequestとMqlTradeResultを使って注文内容と結果を明確に扱います。注文が失敗した場合は、結果コード、ロット、価格、SL/TP、スプレッド、口座状態をログに残します。
約定後管理では、ポジションの有無、建値、損益、SL/TP、保有時間、決済条件を確認します。netting口座ではポジションが集約されるため、チケット単位だけでなく銘柄単位の状態管理が重要になります。
5. 実装パターン
【結論】
実装パターンは、固定条件型、銘柄仕様取得型、注文前検証型、環境適応型に分けられます。
実運用を想定する場合は、銘柄仕様取得型と注文前検証型を組み合わせる設計が扱いやすくなります。
ブローカー差への対応は、一度に複雑化させる必要はありません。最初は固定条件型で検証し、その後に銘柄仕様取得、OrderCheck、ログ出力を追加すると整理しやすくなります。
5.1 固定条件型
固定条件型は、ロット、許容スプレッド、SL/TP幅を入力値として固定する設計です。実装は簡単ですが、銘柄やブローカーが変わると条件が合わない場合があります。
この方式は、学習用や初期検証に向いています。ただし、実運用では銘柄仕様を取得して補正する処理が必要です。
5.2 銘柄仕様取得型
銘柄仕様取得型は、SymbolInfoDoubleやSymbolInfoIntegerを使って、最小ロット、最大ロット、ロットステップ、スプレッド関連情報などを取得する設計です。
この方式では、EAが銘柄ごとの取引条件を読み取ってから注文処理に進みます。固定値の思い込みを減らせるため、複数銘柄EAや複数ブローカーでの検証に向いています。
5.3 注文前検証型
注文前検証型は、MqlTradeRequestを作成したあと、OrderCheckで注文条件を確認する設計です。
OrderCheckは、注文送信前に証拠金や注文条件の問題を確認するために使います。OrderCheckに通っても約定を保証するものではありませんが、明らかな条件不一致を事前に見つけやすくなります。
6. サンプルコード
【結論】
サンプルコードでは、銘柄仕様の取得、ロット補正、スプレッド確認、OrderCheck、OrderSendを分けて実装します。
このコードは検証用の基本形であり、実運用では銘柄、時間足、ブローカー条件に合わせた追加検証が必要です。
以下は、ブローカー差を考慮するための最小構成に近いMQL5のサンプルです。売買ロジックそのものは単純化し、注文前チェックの流れを見やすくしています。
#property strict
input double RiskLot = 0.10;
input int MaxSpreadPoints = 30;
input int StopLossPoints = 300;
input int TakeProfitPoints = 600;
double NormalizeLotBySymbol(const string symbol, double lot)
{
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)
{
Print("Invalid symbol volume settings: ", symbol);
return 0.0;
}
lot = MathMax(minLot, MathMin(maxLot, lot));
lot = MathFloor(lot / lotStep) * lotStep;
lot = NormalizeDouble(lot, 2);
if(lot < minLot)
{
Print("Lot is smaller than minimum lot after normalization");
return 0.0;
}
return lot;
}
bool IsSpreadAcceptable(const string symbol)
{
MqlTick tick;
if(!SymbolInfoTick(symbol, tick))
{
Print("Failed to get tick: ", symbol);
return false;
}
double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
if(point <= 0.0)
{
Print("Invalid point value: ", symbol);
return false;
}
int spreadPoints = (int)MathRound((tick.ask - tick.bid) / point);
if(spreadPoints > MaxSpreadPoints)
{
Print("Spread is too wide: ", spreadPoints);
return false;
}
return true;
}
bool SendBuyOrder(const string symbol)
{
if(!IsSpreadAcceptable(symbol))
return false;
MqlTick tick;
if(!SymbolInfoTick(symbol, tick))
{
Print("Failed to get latest tick");
return false;
}
double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
if(point <= 0.0 || digits <= 0)
{
Print("Invalid price settings");
return false;
}
double lot = NormalizeLotBySymbol(symbol, RiskLot);
if(lot <= 0.0)
return false;
double sl = NormalizeDouble(tick.ask - StopLossPoints * point, digits);
double tp = NormalizeDouble(tick.ask + TakeProfitPoints * point, digits);
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 = ORDER_TYPE_BUY;
request.price = tick.ask;
request.sl = sl;
request.tp = tp;
request.deviation = 20;
request.type_filling = ORDER_FILLING_FOK;
request.comment = "broker difference check sample";
if(!OrderCheck(request, check))
{
Print("OrderCheck failed. retcode=", check.retcode);
return false;
}
if(check.retcode != TRADE_RETCODE_DONE)
{
Print("OrderCheck rejected. retcode=", check.retcode);
return false;
}
if(!OrderSend(request, result))
{
Print("OrderSend failed. retcode=", result.retcode);
return false;
}
if(result.retcode != TRADE_RETCODE_DONE && result.retcode != TRADE_RETCODE_PLACED)
{
Print("OrderSend was not completed. retcode=", result.retcode);
return false;
}
Print("Buy order sent. ticket=", result.order, " volume=", lot);
return true;
}
int OnInit()
{
Print("EA initialized");
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
Print("EA deinitialized. reason=", reason);
}
void OnTick()
{
if(PositionSelect(_Symbol))
return;
bool sampleSignal = false;
if(sampleSignal)
{
SendBuyOrder(_Symbol);
}
}
6.1 コードの読み方
このサンプルでは、注文前にスプレッド確認、ロット補正、OrderCheckを行っています。MQL5では、MqlTradeRequestに注文内容を入れ、MqlTradeResultで送信結果を受け取ります。
sampleSignalは検証用の仮条件です。実際のEAでは、移動平均、ATR、RSI、価格条件などのシグナル判定に置き換えます。
6.2 実運用前に追加すべき処理
実運用を想定する場合は、次の処理を追加します。
- 取引時間の確認
- ストップレベルとフリーズレベルの確認
- 証拠金維持率の確認
- netting口座とhedging口座の分岐
- 約定方式に応じたtype_fillingの調整
- 失敗時の再試行制限
- ログの詳細化
- VPS停止や通信不安定時の扱い
注文の再試行を行う場合でも、無制限に再送信する設計は避けます。相場急変時に意図しない連続注文へつながる場合があります。
7. 設計パターン比較
【結論】
ブローカー差への対応では、固定条件型よりも、銘柄仕様取得型、注文前検証型、環境適応型のほうが実運用の差を検出しやすくなります。
ただし、複雑な適応処理は過剰最適化や検証漏れの原因にもなります。
| 方法 | メリット | デメリット | 向いている場面 | 実装難易度 |
|---|---|---|---|---|
| 固定条件型 | 実装しやすい | ブローカー差に弱い | 学習用、初期検証 | 低 |
| 銘柄仕様取得型 | 銘柄ごとの差を反映しやすい | 取得値の扱いを誤ると不具合になる | 複数銘柄EA | 中 |
| 注文前検証型 | 注文失敗の原因を事前に見つけやすい | OrderCheck後も約定差は残る | 実運用前提のEA | 中 |
| 環境適応型 | スプレッドや時間帯に応じて制御しやすい | 条件が複雑になりやすい | フォワード検証後の改善 | 高 |
設計パターンは、複雑なほど良いわけではありません。まずはログで差を見える化し、実際に問題が出た部分から制御を追加するほうが検証しやすくなります。
7.1 過剰最適化を避ける考え方
ブローカー差に対応しようとして条件を増やしすぎると、特定期間や特定ブローカーだけに合ったEAになりやすくなります。過剰最適化は、バックテストでは良く見えてもフォワードテストで崩れやすい原因になります。
条件を追加する場合は、追加前後で次を確認します。
- 取引回数が極端に減っていないか
- 最大ドローダウンが一部期間だけ改善していないか
- パラメータを少し変えると成績が大きく崩れないか
- スプレッド条件を変えても挙動が破綻しないか
- 複数期間で同じ傾向があるか
8. バックテストで確認すべき項目
【結論】
バックテストでは、利益額だけでなく、最大ドローダウン、取引回数、損益比、連敗数、スプレッド条件、期間依存性を確認します。
ブローカー差を想定する場合は、スプレッドや約定条件を変えたテストも必要です。
バックテストは、EAの構造を検証するための手段です。バックテスト結果は将来の利益を保証しません。特にブローカー差を扱う場合、テスター上の条件とリアル口座の条件が一致しない場合があります。
確認すべき項目は次のとおりです。
| 項目 | 確認する理由 | 注意点 |
|---|---|---|
| 総損益 | 全体傾向を見る | 単独では判断しない |
| 最大ドローダウン | 資金変動リスクを見る | 許容範囲を事前に決める |
| 勝率 | 取引の当たりやすさを見る | 損益比とセットで見る |
| 損益比 | 利益と損失のバランスを見る | 勝率だけで評価しない |
| 取引回数 | 統計的な偏りを見る | 少なすぎる結果は判断しにくい |
| 連敗数 | 資金管理の耐性を見る | ロット計算と合わせて確認する |
| スプレッド条件 | ブローカー差の影響を見る | 固定スプレッドだけに依存しない |
| 期間依存性 | 特定期間だけの有効性を避ける | 相場局面を分けて見る |
| パラメータ依存性 | 過剰最適化を確認する | 少しの変更で崩れる設定に注意する |
8.1 スプレッド条件を変える
ブローカー差を想定するEAでは、スプレッド条件を複数パターンで確認します。狭いスプレッドでのみ成立するロジックは、リアル口座でスプレッドが広がったときに成績が悪化する場合があります。
スキャルピング寄りのEAほど、スプレッドと約定差の影響を受けやすくなります。損切り幅や利確幅が小さい設計では、数ポイントの差でも期待値が大きく変わることがあります。
8.2 パラメータ依存性を見る
パラメータを少し変えただけで結果が大きく崩れるEAは、再現性が低い可能性があります。最適値だけを見るのではなく、近い値でも似た傾向があるかを確認します。
バックテストでは、単一の最良結果よりも、複数条件で破綻しにくい構造を重視します。
9. フォワードテストで確認すべき項目
【結論】
フォワードテストでは、バックテストでは見えにくい約定差、スプレッド拡大、取引頻度、ブローカー差、VPS環境での安定性を確認します。
リアル口座に近い条件で小さく検証することで、実運用前のリスクを把握しやすくなります。
フォワードテストは、未来の価格データに対してEAがどのように動くかを見る検証です。ブローカー差を扱う記事では、フォワードテストの重要性が特に高くなります。
確認すべき項目は次のとおりです。
- 約定価格が想定とどの程度ずれるか
- スプレッド拡大時に注文を見送れているか
- バックテストと取引頻度が大きく違わないか
- ドローダウンが許容範囲内か
- ブローカーごとに注文失敗が出ていないか
- VPS環境でEAが止まらず動くか
- 通信遅延や再接続後の状態管理が破綻しないか
9.1 デモ口座とリアル口座の差
デモ口座とリアル口座では、約定条件やスプレッド条件が異なる場合があります。デモ口座で問題が出ないEAでも、リアル口座ではスリッページや注文拒否が出ることがあります。
そのため、フォワードテストでは、取引量を抑えた段階的な検証が必要です。EAの目的は利益を保証することではなく、設計した条件でどのような挙動をするか確認することです。
9.2 ログで確認する項目
フォワードテストでは、注文結果だけでなく、注文前の状態をログに残します。
ログに残す項目の例は次のとおりです。
- シグナル発生時刻
- スプレッド
- 計算ロット
- 補正後ロット
- SL/TP距離
- OrderCheckの結果
- OrderSendの結果
- ポジション状態
- 口座残高と有効証拠金
ログがあれば、ブローカー差による問題なのか、EAのロジックによる問題なのかを切り分けやすくなります。
10. 実運用での注意点
【結論】
実運用では、スプレッド、約定遅延、スリッページ、取引時間、証拠金、レバレッジ、口座タイプの違いを考慮する必要があります。
バックテストで安定して見えるEAでも、リアル口座では条件差により成績が変動する場合があります。
EAを実運用に近づけるほど、相場以外の要因が重要になります。特に、ブローカー仕様はEAの注文結果に直接影響します。
実運用で注意すべき項目は次のとおりです。
- スプレッド拡大で期待値が悪化する場合がある
- 約定遅延やスリッページが発生する場合がある
- ストップレベルによりSL/TPを近くに置けない場合がある
- フリーズレベルにより注文変更が制限される場合がある
- レバレッジが高いほどドローダウンも大きくなりやすい
- 証拠金不足により注文が拒否される場合がある
- 口座タイプによりポジション管理が変わる
- 取引時間外やメンテナンス時間に注文できない場合がある
10.1 リスク上限を先に決める
EAを動かす前に、許容ドローダウン、1回あたりの許容損失、連敗時の停止条件を決めます。損失が出てからロットや停止条件を変更すると、検証結果と実運用の条件がずれます。
リスク上限は、売買ロジックとは別の安全装置として設計します。たとえば、日次損失、週次損失、最大ポジション数、最大ロットを制限する方法があります。
10.2 ブローカー変更時の再検証
ブローカーを変更した場合は、同じEAでも再検証が必要です。銘柄名、桁数、スプレッド、ティックバリュー、取引時間、ロット制限が変わる場合があります。
EAのパラメータをそのまま移すのではなく、銘柄仕様と約定条件を確認してからバックテストとフォワードテストを行います。
11. よくある設計ミス
【結論】
よくある設計ミスは、ロット制限の無視、スプレッド確認の不足、OrderCheckなしの注文、口座タイプ差の未考慮、バックテスト結果の過信です。
これらのミスは、リアル口座で注文失敗や想定外のポジション管理につながります。
ブローカー差に関する不具合は、コードのコンパイルエラーとして出ないことが多くあります。EAは動いているように見えても、注文が拒否されていたり、想定より悪い価格で約定していたりする場合があります。
11.1 固定ロットをそのまま使う
固定ロットを使う場合でも、最小ロット、最大ロット、ロットステップを確認する必要があります。計算上のロットが有効でも、銘柄仕様に合っていなければ注文に失敗する場合があります。
11.2 スプレッドを見ない
スプレッドを見ずにエントリーすると、特に短期売買で期待値が崩れやすくなります。エントリー前に現在のスプレッドを確認し、許容範囲を超える場合は見送る設計が必要です。
11.3 OrderSendの結果だけを見る
OrderSendが呼び出されたことと、注文が意図どおり成立したことは同じではありません。MqlTradeResultのretcodeを確認し、完了、拒否、リクオート、証拠金不足などの状態をログに残します。
11.4 口座タイプを考慮しない
netting口座とhedging口座では、同一銘柄のポジション管理が異なります。複数ポジションを前提にしたEAは、netting口座で想定どおりに動かない場合があります。
11.5 バックテストだけで判断する
バックテストは重要ですが、実運用の約定差やスプレッド変動を完全には再現できません。フォワードテストで実際の取引環境に近い挙動を確認する必要があります。
12. まとめ
【結論】
MQL5でブローカー差に対応するEAを設計するには、売買ロジックと注文実行条件を分離することが重要です。
銘柄仕様の取得、ロット補正、スプレッド確認、OrderCheck、ログ出力を組み込むことで、環境差による不具合を見つけやすくなります。
ブローカー差は、EAの実運用で避けられない要素です。スプレッド、約定、ロット制限、ストップレベル、口座タイプ、取引時間は、同じMQL5コードでも結果を変える原因になります。
設計では、次の考え方を基本にします。
- シグナル判定と注文処理を分ける
- 銘柄仕様を固定値で決め打ちしない
- 注文前にロット、スプレッド、証拠金、SL/TP距離を確認する
- OrderCheckで注文条件を確認する
- OrderSend後はMqlTradeResultを必ず確認する
- バックテストとフォワードテストを分けて評価する
- 実運用ではブローカー差と約定差を前提にする
EAの品質は、エントリー条件の良し悪しだけでは決まりません。MQL5では、取引環境の差を吸収する設計、失敗時のログ、リスク上限、検証手順まで含めてEAを作る必要があります。
FAQ
MQL5でブローカー差とは何ですか?
MQL5でのブローカー差とは、スプレッド、約定方式、最小ロット、ロットステップ、ストップレベル、取引時間、口座タイプなどの違いです。同じEAでも、これらの条件により注文結果や成績が変わる場合があります。
ブローカー差に対応するEAで最初に確認すべき項目は何ですか?
最初に確認すべき項目は、銘柄仕様、スプレッド、ロット制限、取引時間、口座タイプです。注文処理を行う前に、EAが現在の取引環境で発注可能か確認する必要があります。
OrderCheckを使えば注文失敗は防げますか?
OrderCheckは注文前に証拠金や注文条件を確認するための処理ですが、約定を保証するものではありません。OrderCheck後も、価格変動、スリッページ、約定方式によりOrderSendの結果が変わる場合があります。
netting口座とhedging口座ではEA設計が変わりますか?
netting口座とhedging口座ではポジション管理が変わります。netting口座では同一銘柄のポジションが集約されやすく、hedging口座では複数ポジションを持てる場合があるため、エントリー管理と決済管理を分けて設計する必要があります。
固定ロットEAでもロット制限の確認は必要ですか?
固定ロットEAでもロット制限の確認は必要です。ブローカーや銘柄により最小ロット、最大ロット、ロットステップが異なるため、固定値をそのまま注文に使うと発注に失敗する場合があります。
バックテストで良い結果なら実運用でも同じ結果になりますか?
バックテスト結果は将来の利益を保証しません。実運用ではスプレッド拡大、約定遅延、スリッページ、ブローカー仕様の違いにより、バックテストと異なる結果になる場合があります。
フォワードテストでは何を確認すべきですか?
フォワードテストでは、約定差、スプレッド拡大時の挙動、取引頻度、ドローダウン、注文失敗、VPS環境での安定性を確認します。バックテストとの乖離を記録し、実運用前にリスクを把握することが重要です。