【MQL5】iSpread関数の使い方と自動売買実装コード

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. 使用上の注意点とよくあるエラー

  1. 「ポイント」と「ピップス」の混同:
    多くの初心者が、0.1ピップスを「1」と数えるか「0.1」と数えるかで混乱します。iSpreadで取得できるのは最小単位の「ポイント」です。3桁/5桁表示のブローカーでは、通常 10 points = 1 pip となります。計算時は _Digits_Point を考慮するようにしましょう。
  2. ハンドルの解放漏れ:
    OnInitで作成したハンドルは、OnDeinitIndicatorReleaseを呼び出して解放するのがベストプラクティスです。解放を忘れると、EAの再起動やパラメータ変更を繰り返した際にターミナルの動作が重くなる原因になります。
  3. データ未受信の考慮:
    起動直後や相場急変時、CopySpreadが一時的に失敗したり、古いデータを返したりすることがあります。戻り値の確認(0以上か等)を怠らないようにしましょう。
  4. 現在のスプレッドのみが必要な場合:
    過去のスプレッド履歴が不要で、単に「今この瞬間のスプレッド」を知りたいだけであれば、SymbolInfoInteger(_Symbol, SYMBOL_SPREAD) を使用する方がハンドルの管理が不要なため、コードが簡潔になります。

5. 【重要】自動売買における約定スピードと環境の罠

アルゴリズムトレードにおいて、iSpreadでどれだけ厳密にコストを計算しても、プログラムを実行する「環境」が悪ければすべてが無意味になります。一般的な家庭用PCや家庭用光回線では、プロバイダーの混雑やOSのバックグラウンド更新による一時的な負荷、そして物理的な距離に起因する「ネットワーク遅延(レイテンシ)」が避けられません。FXにおける数ミリ秒の遅延は、滑り(スリッページ)を引き起こし、本来得られるはずだった利益を瞬時に奪い去ります。

プロのクオンツや専業トレーダーにとって、ブローカーのサーバーと同じデータセンター内、あるいは至近距離に位置する「専用VPS(仮想専用サーバー)」の導入は、単なる推奨事項ではなく「必須条件」です。24時間365日の安定稼働はもちろん、極限まで低減されたレイテンシ環境でEAを動作させることで初めて、ロジック本来の優位性が発揮されます。コンマ一秒を争う自動売買の世界で勝率を1%でも高めたいのであれば、まずはインフラ環境の最適化を最優先してください。

💡 この記事の内容を実運用で活かすには?

この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント

タイトルとURLをコピーしました