1. iSpread関数の概要と実務での活用法
MQL5のiSpread関数は、指定した通貨ペアおよび時間軸における「スプレッド(売値と買値の差)」を取得するためのテクニカル指標ハンドルを作成する関数です。
実務開発において、スプレッドは「取引コスト」そのものです。特にスキャルピングや高頻度トレード(HFT)のロジックを組む際、スプレッドの拡大を無視してエントリーすると、期待期待値が大幅に削られ、バックテストの結果とは乖離した「負けトレード」を量産することになります。
初心者がつまずきやすいポイントは、MQL5のiSpreadはMQL4のように数値を直接返すのではなく、指標の「ハンドル(識別番号)」を返すという点です。このハンドルを使って、後述するCopySpreadなどの関数で実際のデータを取得する必要があります。実務では「スプレッドが一定値以上の時はエントリーを制限する」といった、フィルタリング機能として活用するのが一般的です。
2. 構文と戻り値
iSpread関数の構文は以下の通りです。
int iSpread(
string symbol, // 通貨ペア名(NULLなら現在のチャート)
ENUM_TIMEFRAMES period // 時間軸(PERIOD_CURRENTなど)
);
パラメーター
- symbol: データを取得したい通貨ペアを指定します(例:
"EURUSD")。NULLまたは_Symbolを指定すると、現在のチャートの通貨ペアになります。 - period: 時間軸を指定します。現在の時間軸なら
PERIOD_CURRENTを指定します。
戻り値
- 成功した場合、スプレッド指標のハンドル(int型)を返します。
- 失敗した場合は
INVALID_HANDLEを返します。
※取得されるスプレッドの単位は「ポイント(Point)」です。例えば、米ドル/円でスプレッドが0.3ピップスの場合、戻り値から取得できるデータは「3」となります(5桁表示ブローカーの場合)。
3. 具体的な使い方・実践サンプルコード
以下に、iSpreadを使用して現在のスプレッドを取得し、許容範囲内(フィルタ設定)であればログに出力する実用的なコード例を示します。
//+------------------------------------------------------------------+
//| SpreadMonitor.mq5 |
//+------------------------------------------------------------------+
#property strict
// 入力パラメーター:許容最大スプレッド(ポイント単位)
input int MaxSpreadPoints = 20; // 2.0ピップスの場合は20を指定
int spreadHandle; // iSpreadのハンドルを格納する変数
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// iSpreadのハンドルを作成
spreadHandle = iSpread(_Symbol, PERIOD_CURRENT);
if(spreadHandle == INVALID_HANDLE)
{
Print("iSpreadハンドルの作成に失敗しました。");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
int spreadData[]; // スプレッド値を格納する配列
ArraySetAsSeries(spreadData, true); // 最新のデータをインデックス0にする
// ハンドルを使用して、最新1本分のスプレッドデータをコピー
if(CopySpread(_Symbol, PERIOD_CURRENT, 0, 1, spreadData) > 0)
{
int currentSpread = spreadData[0];
// スプレッドの状態を判定
if(currentSpread > MaxSpreadPoints)
{
Comment("警告:スプレッド拡大中 (", currentSpread, " points)");
}
else
{
Comment("スプレッド正常 (", currentSpread, " points)");
// ここにエントリーロジックなどを記述
}
}
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 作成したハンドルを解放してメモリを節約
IndicatorRelease(spreadHandle);
}
4. 使用上の注意点とよくあるエラー
- 「ポイント」と「ピップス」の混同:
多くの初心者が、0.1ピップスを「1」と数えるか「0.1」と数えるかで混乱します。iSpreadで取得できるのは最小単位の「ポイント」です。3桁/5桁表示のブローカーでは、通常10 points = 1 pipとなります。計算時は_Digitsや_Pointを考慮するようにしましょう。 - ハンドルの解放漏れ:
OnInitで作成したハンドルは、OnDeinitでIndicatorReleaseを呼び出して解放するのがベストプラクティスです。解放を忘れると、EAの再起動やパラメータ変更を繰り返した際にターミナルの動作が重くなる原因になります。 - データ未受信の考慮:
起動直後や相場急変時、CopySpreadが一時的に失敗したり、古いデータを返したりすることがあります。戻り値の確認(0以上か等)を怠らないようにしましょう。 - 現在のスプレッドのみが必要な場合:
過去のスプレッド履歴が不要で、単に「今この瞬間のスプレッド」を知りたいだけであれば、SymbolInfoInteger(_Symbol, SYMBOL_SPREAD)を使用する方がハンドルの管理が不要なため、コードが簡潔になります。
5. 【重要】自動売買における約定スピードと環境の罠
アルゴリズムトレードにおいて、iSpreadでどれだけ厳密にコストを計算しても、プログラムを実行する「環境」が悪ければすべてが無意味になります。一般的な家庭用PCや家庭用光回線では、プロバイダーの混雑やOSのバックグラウンド更新による一時的な負荷、そして物理的な距離に起因する「ネットワーク遅延(レイテンシ)」が避けられません。FXにおける数ミリ秒の遅延は、滑り(スリッページ)を引き起こし、本来得られるはずだった利益を瞬時に奪い去ります。
プロのクオンツや専業トレーダーにとって、ブローカーのサーバーと同じデータセンター内、あるいは至近距離に位置する「専用VPS(仮想専用サーバー)」の導入は、単なる推奨事項ではなく「必須条件」です。24時間365日の安定稼働はもちろん、極限まで低減されたレイテンシ環境でEAを動作させることで初めて、ロジック本来の優位性が発揮されます。コンマ一秒を争う自動売買の世界で勝率を1%でも高めたいのであれば、まずはインフラ環境の最適化を最優先してください。
💡 この記事の内容を実運用で活かすには?
この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント