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

1. iMA関数の概要と実務での活用法

MQL5におけるiMA関数は、テクニカル分析の基本中の基本である「移動平均線(Moving Average)」の数値を計算するための関数です。

実務開発において、初心者が最もつまずきやすいポイントは、「iMA関数を呼び出しても、直接価格(数値)が返ってくるわけではない」という点です。MQL4では関数を呼べばその場の価格が取得できましたが、MQL5では「インジケータのハンドル(識別番号)」を取得し、そのハンドルを介して「バッファからデータをコピーする」という2段階の手順が必要になります。

実務では単にトレンドの方向を見るだけでなく、短期・長期のMAのクロス(ゴールデンクロス等)の判定や、価格とMAの乖離率を用いたボラティリティ・フィルタとして活用するのが一般的です。計算負荷が非常に軽いため、大量の通貨ペアを監視するマルチ通貨EAの開発にも適しています。


2. 構文と戻り値

iMA関数の構文は以下の通りです。

int  iMA(
   string               symbol,            // 通貨ペア名(NULLで現在のチャート)
   ENUM_TIMEFRAMES      period,            // 時間足(0で現在の時間足)
   int                  ma_period,         // 平均期間
   int                  ma_shift,          // 水平シフト
   ENUM_MA_METHOD       ma_method,         // 平均化メソッド(SMA, EMA, SMMA, LWMA)
   ENUM_APPLIED_PRICE   applied_price      // 適用価格(終値、始値など)
   );

戻り値

  • 成功した場合:作成されたインジケータのハンドルint型の数値)を返します。
  • 失敗した場合:INVALID_HANDLE を返します。

この「ハンドル」は、後述するCopyBuffer関数で実際のMAの値を取り出す際に必要となる「整理番号」のようなものです。


3. 具体的な使い方・実践サンプルコード

以下は、EMA(指数平滑移動平均線)のゴールデンクロスを判定するための基本的なEAの構造です。

//--- グローバル変数
int handle_fast; // 短期MAのハンドル
int handle_slow; // 長期MAのハンドル

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    // 短期EMA(14期間)のハンドルを取得
    handle_fast = iMA(_Symbol, _Period, 14, 0, MODE_EMA, PRICE_CLOSE);

    // 長期EMA(50期間)のハンドルを取得
    handle_slow = iMA(_Symbol, _Period, 50, 0, MODE_EMA, PRICE_CLOSE);

    // ハンドルの取得に失敗した場合はエラー
    if(handle_fast == INVALID_HANDLE || handle_slow == INVALID_HANDLE)
    {
        Print("iMAハンドルの取得に失敗しました。");
        return(INIT_FAILED);
    }

    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    double ma_fast[2]; // 短期MA値を格納する配列
    double ma_slow[2]; // 長期MA値を格納する配列

    // 配列を時系列(最新がインデックス0)にセット
    ArraySetAsSeries(ma_fast, true);
    ArraySetAsSeries(ma_slow, true);

    // ハンドルを使って最新のデータを配列にコピー(最新から2個分)
    if(CopyBuffer(handle_fast, 0, 0, 2, ma_fast) < 2) return;
    if(CopyBuffer(handle_slow, 0, 0, 2, ma_slow) < 2) return;

    // ゴールデンクロスの判定(1本前でクロスが発生したか)
    bool is_crossed = (ma_fast[1] > ma_slow[1]) && (ma_fast[2] <= ma_slow[2]);

    if(is_crossed)
    {
        Print("ゴールデンクロス発生!");
        // ここにエントリーロジックを記述
    }
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    // メモリ解放のためハンドルを削除
    IndicatorRelease(handle_fast);
    IndicatorRelease(handle_slow);
}

4. 使用上の注意点とよくあるエラー

  1. ハンドルの重複作成を避ける:
    iMA関数は必ずOnInit内で1回だけ呼び出すようにしてください。OnTick内で毎回呼び出すと、新しいハンドルが無限に作成され、PCやサーバーのメモリを激しく消費し、最終的にプラットフォームがフリーズします。

  2. 計算未完了のチェック:
    MT5の起動直後や時間足を切り替えた直後は、データの計算が完了しておらず、CopyBufferがエラーを返すことがあります。必ず戻り値をチェックし、コピーに成功したことを確認してからロジックを進めてください。

  3. ハンドルの解放:
    OnDeinitIndicatorReleaseを呼び出す習慣をつけましょう。小規模なEAでは問題になりにくいですが、複雑なシステムではリソース管理が重要になります。

  4. ma_shiftの勘違い:
    iMAの引数にあるma_shiftは「インジケータの描画を右にずらす」設定です。「過去のデータ(1本前など)を参照したい」場合は、CopyBufferの引数で開始位置を指定するか、配列のインデックスで調整してください。


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

アルゴリズムトレードにおいて、ロジックと同じかそれ以上に重要なのが実行環境です。iMAで完璧なエントリーシグナルを捉えたとしても、ご自宅のPC環境からの注文では、物理的な距離による「ネットワーク遅延(レイテンシ)」が必ず発生します。FX市場はミリ秒単位で価格が変動しており、数ミリ秒の遅れがスリッページを引き起こし、期待した利益を削り取ります。

プロのクオンツやトレーダーにとって、取引サーバーの目と鼻の先に位置する専用のVPS(仮想専用サーバー)を利用することは、もはやオプションではなく「必須条件」です。自宅PCでの運用は、停電やアップデートによる強制再起動のリスクに加え、ネットワーク遅延という致命的な弱点を抱えています。極限まで約定スピードを高め、エッジ(優位性)を確実に利益に変えるためには、24時間365日安定稼働し、低遅延を保証するトレード専用のインフラ環境を整えることから始めてください。

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

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

コメント

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