MQL4 インジケーター関数リファレンス|iMA・iRSI・iBands・iMACD・iCustom完全ガイド

MQL4 インジケーター関数を体系的にまとめました。iMA(移動平均線)、iRSI、iBands(ボリンジャーバンド)、iMACD、iATR、iStochastic、iCCI、iADX、iIchimoku(一目均衡表)など主要テクニカル指標の直接取得方法、iCustom()によるカスタムインジケーター呼び出し、マルチタイムフレーム分析、バッファインデックスの仕組みまで、MT4 EA開発に必要なインジケーター処理のすべてをコード付きで解説します。

MQL4 インジケーター関数 リファレンスカード
目次

MQL4とMQL5のインジケーター取得方式の違い

MQL4とMQL5ではインジケーター値の取得方法が根本的に異なります。MQL4は関数を呼ぶだけで直接値が返りますが、MQL5はハンドルを作成してからバッファにコピーする2段階方式です。

項目MQL4MQL5
値の取得関数呼び出しで直接値が返るハンドル作成→CopyBuffer()で配列にコピー
使い方double val = iMA(…)int h = iMA(…); CopyBuffer(h,…,buf); val = buf[0]
パフォーマンス毎回再計算(非効率な場合あり)ハンドル共有で効率的
マルチTF引数にtimeframeを指定するだけ同じ方式だがバッファ管理が必要
カスタムインジケーターiCustom()で直接値取得iCustom()でハンドル取得→CopyBuffer()

MQL4のインジケーター関数はMQL5よりはるかにシンプルです。1行で値を取得でき、OnInit()でのハンドル管理も不要です。ただし毎回再計算されるため、ループ内での大量呼び出しには注意が必要です。

iMA:移動平均線

double iMA(
   string       symbol,       // 通貨ペア(NULL=現在のチャート)
   int          timeframe,    // 時間軸(0=現在のチャート)
   int          ma_period,    // 移動平均の期間
   int          ma_shift,     // 表示シフト
   int          ma_method,    // 平均化メソッド
   int          applied_price,// 適用価格
   int          shift         // バーシフト(0=現在のバー)
);
// 戻り値: 指定バーのMA値

平均化メソッド

定数説明
MODE_SMA0単純移動平均
MODE_EMA1指数移動平均
MODE_SMMA2平滑移動平均
MODE_LWMA3線形加重移動平均

適用価格

定数説明
PRICE_CLOSE0終値
PRICE_OPEN1始値
PRICE_HIGH2高値
PRICE_LOW3安値
PRICE_MEDIAN4(High+Low)/2
PRICE_TYPICAL5(High+Low+Close)/3
PRICE_WEIGHTED6(High+Low+Close+Close)/4
bool IsGoldenCross(int fastPeriod, int slowPeriod)
  {
   // 現在のバーと1つ前のバーのMA値を取得
   double fastMA0 = iMA(NULL, 0, fastPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
   double fastMA1 = iMA(NULL, 0, fastPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
   double slowMA0 = iMA(NULL, 0, slowPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
   double slowMA1 = iMA(NULL, 0, slowPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);

   // 前のバーでは短期 < 長期、現在のバーでは短期 > 長期
   if(fastMA1 < slowMA1 && fastMA0 > slowMA0)
      return true;

   return false;
  }

bool IsDeadCross(int fastPeriod, int slowPeriod)
  {
   double fastMA0 = iMA(NULL, 0, fastPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
   double fastMA1 = iMA(NULL, 0, fastPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
   double slowMA0 = iMA(NULL, 0, slowPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
   double slowMA1 = iMA(NULL, 0, slowPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);

   if(fastMA1 > slowMA1 && fastMA0 < slowMA0)
      return true;

   return false;
  }

iRSI:RSI(相対力指数)

double iRSI(
   string symbol,        // 通貨ペア
   int    timeframe,     // 時間軸
   int    period,        // RSI期間
   int    applied_price, // 適用価格
   int    shift          // バーシフト
);
// 戻り値: 0〜100のRSI値
int CheckRSISignal(int period, double overBought, double overSold)
  {
   double rsi0 = iRSI(NULL, 0, period, PRICE_CLOSE, 0);
   double rsi1 = iRSI(NULL, 0, period, PRICE_CLOSE, 1);

   // 売られすぎから回復 → 買いシグナル
   if(rsi1 < overSold && rsi0 >= overSold)
      return 1;  // Buy

   // 買われすぎから反落 → 売りシグナル
   if(rsi1 > overBought && rsi0 <= overBought)
      return -1; // Sell

   return 0;  // No signal
  }

iBands:ボリンジャーバンド

double iBands(
   string symbol,
   int    timeframe,
   int    period,         // 期間(目安:20)
   double deviation,      // 標準偏差の倍数(目安:2.0)
   int    bands_shift,    // 表示シフト
   int    applied_price,  // 適用価格
   int    mode,           // MODE_MAIN(0)=中央線, MODE_UPPER(1)=上限, MODE_LOWER(2)=下限
   int    shift           // バーシフト
);
int CheckBBRSI(int bbPeriod, double bbDev, int rsiPeriod)
  {
   double upper = iBands(NULL, 0, bbPeriod, bbDev, 0, PRICE_CLOSE, MODE_UPPER, 0);
   double lower = iBands(NULL, 0, bbPeriod, bbDev, 0, PRICE_CLOSE, MODE_LOWER, 0);
   double middle = iBands(NULL, 0, bbPeriod, bbDev, 0, PRICE_CLOSE, MODE_MAIN, 0);
   double rsi   = iRSI(NULL, 0, rsiPeriod, PRICE_CLOSE, 0);

   // 価格がBB下限以下 + RSI30以下 → 買い
   if(Close[0] <= lower && rsi < 30)
      return 1;

   // 価格がBB上限以上 + RSI70以上 → 売り
   if(Close[0] >= upper && rsi > 70)
      return -1;

   return 0;
  }

iMACD:MACD

double iMACD(
   string symbol,
   int    timeframe,
   int    fast_ema_period,   // 短期EMA期間(目安:12)
   int    slow_ema_period,   // 長期EMA期間(目安:26)
   int    signal_period,     // シグナル期間(目安:9)
   int    applied_price,     // 適用価格
   int    mode,              // MODE_MAIN(0)=MACDライン, MODE_SIGNAL(1)=シグナルライン
   int    shift              // バーシフト
);
int CheckMACDSignal()
  {
   double macd0   = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 0);
   double signal0 = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_SIGNAL, 0);
   double macd1   = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1);
   double signal1 = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_SIGNAL, 1);

   // MACDがシグナルを上抜け → 買い
   if(macd1 < signal1 && macd0 > signal0)
      return 1;

   // MACDがシグナルを下抜け → 売り
   if(macd1 > signal1 && macd0 < signal0)
      return -1;

   return 0;
  }

iATR:ATR(真の値幅)

double iATR(
   string symbol,
   int    timeframe,
   int    period,    // ATR期間(目安:14)
   int    shift      // バーシフト
);
// 戻り値: ATR値(価格単位)
void GetATRBasedSLTP(double &sl, double &tp, double atrMultSL, double atrMultTP)
  {
   double atr = iATR(NULL, 0, 14, 1);  // 確定バーのATR

   // 買いの場合
   sl = NormalizeDouble(Ask - atr * atrMultSL, Digits);
   tp = NormalizeDouble(Ask + atr * atrMultTP, Digits);
  }

iStochastic:ストキャスティクス

double iStochastic(
   string symbol,
   int    timeframe,
   int    Kperiod,       // %K期間
   int    Dperiod,       // %D期間
   int    slowing,       // スローイング
   int    method,        // 平均化メソッド(MODE_SMA等)
   int    price_field,   // 0=Low/High, 1=Close/Close
   int    mode,          // MODE_MAIN(0)=%K, MODE_SIGNAL(1)=%D
   int    shift
);
int CheckStochSignal()
  {
   double k0 = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_MAIN, 0);
   double d0 = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_SIGNAL, 0);
   double k1 = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_MAIN, 1);
   double d1 = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_SIGNAL, 1);

   // %Kが%Dを上抜け(売られすぎゾーン) → 買い
   if(k1 < d1 && k0 > d0 && k0 < 20)
      return 1;

   // %Kが%Dを下抜け(買われすぎゾーン) → 売り
   if(k1 > d1 && k0 < d0 && k0 > 80)
      return -1;

   return 0;
  }

iCCI:CCI(商品チャネル指数)

double iCCI(
   string symbol,
   int    timeframe,
   int    period,         // CCI期間(目安:14)
   int    applied_price,  // 適用価格
   int    shift
);
// 戻り値: CCI値(-200〜+200が目安)
int CheckCCISignal(int period)
  {
   double cci0 = iCCI(NULL, 0, period, PRICE_TYPICAL, 0);
   double cci1 = iCCI(NULL, 0, period, PRICE_TYPICAL, 1);

   // CCI -100以下から回復 → 買い
   if(cci1 < -100 && cci0 >= -100)
      return 1;

   // CCI +100以上から反落 → 売り
   if(cci1 > 100 && cci0 <= 100)
      return -1;

   return 0;
  }

iADX:ADX(平均方向性指数)

double iADX(
   string symbol,
   int    timeframe,
   int    period,         // ADX期間(目安:14)
   int    applied_price,  // 適用価格
   int    mode,           // MODE_MAIN(0)=ADX, MODE_PLUSDI(1)=+DI, MODE_MINUSDI(2)=-DI
   int    shift
);
bool IsTrending(int period, double threshold)
  {
   double adx = iADX(NULL, 0, period, PRICE_CLOSE, MODE_MAIN, 0);
   return (adx > threshold);  // 25以上でトレンド発生中
  }

int CheckADXSignal(int period)
  {
   double plusDI  = iADX(NULL, 0, period, PRICE_CLOSE, MODE_PLUSDI, 0);
   double minusDI = iADX(NULL, 0, period, PRICE_CLOSE, MODE_MINUSDI, 0);
   double adx     = iADX(NULL, 0, period, PRICE_CLOSE, MODE_MAIN, 0);

   if(adx < 25) return 0;  // トレンドなし

   if(plusDI > minusDI) return 1;   // 上昇トレンド
   if(minusDI > plusDI) return -1;  // 下降トレンド

   return 0;
  }

iIchimoku:一目均衡表

double iIchimoku(
   string symbol,
   int    timeframe,
   int    tenkan_sen,      // 転換線期間(目安:9)
   int    kijun_sen,       // 基準線期間(目安:26)
   int    senkou_span_b,   // 先行スパンB期間(目安:52)
   int    mode,            // 取得するライン
   int    shift
);
// mode: MODE_TENKANSEN(1), MODE_KIJUNSEN(2),
//       MODE_SENKOUSPANA(3), MODE_SENKOUSPANB(4), MODE_CHIKOUSPAN(5)
bool IsIchimokuBullish()
  {
   double tenkan  = iIchimoku(NULL, 0, 9, 26, 52, MODE_TENKANSEN, 0);
   double kijun   = iIchimoku(NULL, 0, 9, 26, 52, MODE_KIJUNSEN, 0);
   double spanA   = iIchimoku(NULL, 0, 9, 26, 52, MODE_SENKOUSPANA, 0);
   double spanB   = iIchimoku(NULL, 0, 9, 26, 52, MODE_SENKOUSPANB, 0);
   double chikou  = iIchimoku(NULL, 0, 9, 26, 52, MODE_CHIKOUSPAN, 26);

   // 三役好転: 転換線>基準線, 価格>雲, 遅行線>過去の価格
   bool tenkanAboveKijun = (tenkan > kijun);
   bool priceAboveCloud  = (Close[0] > MathMax(spanA, spanB));
   bool chikouAbovePrice = (chikou > Close[26]);

   return (tenkanAboveKijun && priceAboveCloud && chikouAbovePrice);
  }
shift=0 と shift=1 の使い分け
  • shift=0: 現在の(未確定の)バーの値。ティックごとに変化するため、シグナル判定に使うと「ダマシ」が多くなる
  • shift=1: 1つ前の確定バーの値。確定後は変化しないため、シグナル判定に適している
  • 実用的なEAではshift=1で確定バーを判定し、shift=0は参考値として使うのが一般的
  • バックテストではshift=0でも問題が出にくいが、ライブ運用で差が出る

iCustom:カスタムインジケーター

double iCustom(
   string symbol,
   int    timeframe,
   string name,       // インジケーターファイル名(.ex4なし)
   ...                // インジケーターの入力パラメータ(可変長)
   int    mode,       // バッファインデックス
   int    shift       // バーシフト
);
// カスタムインジケーター「SuperTrend」の値を取得する例
// パラメータ: Period=10, Multiplier=3.0
// バッファ0=トレンドライン, バッファ1=方向(1=上昇,-1=下降)

double GetSuperTrend(int shift)
  {
   return iCustom(NULL, 0,"SuperTrend", 10, 3.0, 0, shift);
  }

int GetSuperTrendDirection(int shift)
  {
   double dir = iCustom(NULL, 0,"SuperTrend", 10, 3.0, 1, shift);
   return (int)dir;
  }
iCustomの注意点
  • インジケーターのパラメータ順と型を正確に合わせる必要がある
  • バッファインデックスは0から始まる。どのバッファに何が格納されているかはインジケーターのソースコードを確認する
  • インジケーターファイル(.ex4)がIndicatorsフォルダに存在する必要がある
  • パラメータのデフォルト値を使う場合も、modeとshiftの前に省略できない

マルチタイムフレーム分析

MQL4では、インジケーター関数のtimeframe引数を変えるだけで上位足の値を取得できます。上位足でトレンド方向を確認し、下位足でエントリータイミングを計るのが基本戦略です。NULLまたは0を指定すると現在のチャートの時間軸になります。

// 時間軸定数
// PERIOD_M1(1), PERIOD_M5(5), PERIOD_M15(15), PERIOD_M30(30),
// PERIOD_H1(60), PERIOD_H4(240), PERIOD_D1(1440),
// PERIOD_W1(10080), PERIOD_MN1(43200)

int CheckMultiTFSignal()
  {
   // 日足のMA方向(トレンド判定)
   double dailyMA0 = iMA(NULL, PERIOD_D1, 20, 0, MODE_SMA, PRICE_CLOSE, 0);
   double dailyMA1 = iMA(NULL, PERIOD_D1, 20, 0, MODE_SMA, PRICE_CLOSE, 1);
   bool dailyUptrend = (dailyMA0 > dailyMA1);

   // 4時間足のRSI(過熱感チェック)
   double h4RSI = iRSI(NULL, PERIOD_H4, 14, PRICE_CLOSE, 0);

   // 1時間足のMACDクロス(エントリータイミング)
   double h1MACD0   = iMACD(NULL, PERIOD_H1, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 0);
   double h1Signal0 = iMACD(NULL, PERIOD_H1, 12, 26, 9, PRICE_CLOSE, MODE_SIGNAL, 0);
   double h1MACD1   = iMACD(NULL, PERIOD_H1, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1);
   double h1Signal1 = iMACD(NULL, PERIOD_H1, 12, 26, 9, PRICE_CLOSE, MODE_SIGNAL, 1);

   // 日足上昇 + H4 RSI50以下 + H1 MACDゴールデンクロス → 買い
   if(dailyUptrend && h4RSI < 50 && h1MACD1 < h1Signal1 && h1MACD0 > h1Signal0)
      return 1;

   // 日足下降 + H4 RSI50以上 + H1 MACDデッドクロス → 売り
   if(!dailyUptrend && h4RSI > 50 && h1MACD1 > h1Signal1 && h1MACD0 < h1Signal0)
      return -1;

   return 0;
  }
バッファインデックス(mode)の考え方

複数のラインを持つインジケーターでは、mode引数でどのラインの値を取得するか指定します。

  • iBands: MODE_MAIN(0)=中央線, MODE_UPPER(1)=上限, MODE_LOWER(2)=下限
  • iMACD: MODE_MAIN(0)=MACDライン, MODE_SIGNAL(1)=シグナルライン
  • iStochastic: MODE_MAIN(0)=%K, MODE_SIGNAL(1)=%D
  • iADX: MODE_MAIN(0)=ADX, MODE_PLUSDI(1)=+DI, MODE_MINUSDI(2)=-DI
  • iIchimoku: 1=転換線, 2=基準線, 3=先行スパンA, 4=先行スパンB, 5=遅行スパン

その他のインジケーター関数

関数説明主なパラメータ
iAO()Awesome Oscillatorsymbol, timeframe, shift
iAC()Accelerator Oscillatorsymbol, timeframe, shift
iBearsPower()ベアパワーperiod, applied_price
iBullsPower()ブルパワーperiod, applied_price
iDeMarker()デマーカーperiod
iEnvelopes()エンベロープperiod, deviation, mode
iForce()フォースインデックスperiod, method, applied_price
iMFI()マネーフローインデックスperiod
iMomentum()モメンタムperiod, applied_price
iOBV()オンバランスボリュームapplied_price
iOsMA()OsMA(MACDヒストグラム)fast, slow, signal, applied_price
iRVI()相対活力指数period, mode
iSAR()パラボリックSARstep, maximum
iWPR()ウィリアムズ%Rperiod

インジケーター関数一覧(MQL5対応表)

MQL4関数MQL5対応バッファ数
iMA()iMA() + CopyBuffer()1
iRSI()iRSI() + CopyBuffer()1
iBands()iBands() + CopyBuffer()3 (Main/Upper/Lower)
iMACD()iMACD() + CopyBuffer()2 (Main/Signal)
iATR()iATR() + CopyBuffer()1
iStochastic()iStochastic() + CopyBuffer()2 (%K/%D)
iCCI()iCCI() + CopyBuffer()1
iADX()iADX() + CopyBuffer()3 (ADX/+DI/-DI)
iIchimoku()iIchimoku() + CopyBuffer()5
iCustom()iCustom() + CopyBuffer()インジケーターによる

まとめ

MQL4のインジケーター関数はMQL5に比べてシンプルで使いやすく、1行で値を取得できます。実際に試したところ、iMA()のshift=0(未確定バー)を使うと再描画でシグナルがずれるケースがあり、shift=1(確定バー)に変えると安定しました。EA開発で押さえておきたいポイントは以下の通りです。

  • shift=0は未確定バー:シグナル判定にはshift=1(確定バー)を使うのが安全
  • マルチタイムフレームはtimeframe引数を変えるだけ:上位足の方向に順張りする戦略が有効
  • 複数インジケーターの組み合わせ:トレンド系(MA, ADX)+ オシレーター系(RSI, Stoch)で精度を高める
  • iCustom()のバッファインデックス:ソースコードでSetIndexBuffer()の順番を確認する

次のステップとして、MQLリファレンス総合ガイドで取引関数と組み合わせた実践的なEA開発を学びましょう。

MQL4インジケーター関数 よくある質問

MQL4のインジケーター関数の使い方は?

iMA(symbol, timeframe, period, shift, method, price, bar_shift)のように引数を指定して1つの値を直接返します。MQL4では事前にハンドルを作成する必要がなく、呼び出しごとに計算結果を返します。iRSI/iBands/iMACD等の組み込みインジケーターも同じ形式です。

MQL4でiMAを使う方法は?

iMA(Symbol(), 0, 20, 0, MODE_SMA, PRICE_CLOSE, 0)で現在チャートの20期間SMAの最新値を取得します。第7引数のshift=1で1本前のバーの値を取得できます。barシフトを変えてループで複数バーの値を配列に格納できます。

MQL4でiCustomを使う方法は?

iCustom(symbol, timeframe, “IndiName”, param1, …, buffer_num, bar_shift)でカスタムインジケーターの値を取得します。buffer_numはインジケーターのSetIndexBuffer()で定義したバッファ番号です。インジケーターファイルはMQL4/Indicatorsフォルダに配置してください。

MQL4で複数インジケーターを効率的に使う方法は?

各OnTick()の先頭でiMA等の値を変数に格納して再利用します。同じパラメータで複数回呼ぶと毎回計算するため非効率です。また異なる時間足の値を取得する場合はRefreshRates()を先に呼んで価格データを更新することが重要です。

MQL4でインジケーターの値がEMPTY_VALUEになる場合は?

EMPTY_VALUE(2147483647)が返る場合、バーデータが不足しているか計算できない状態です。iMA等のperiodより短い履歴しかない場合に発生します。戻り値をEMPTY_VALUEと比較して処理をスキップするガードが必要です。

MQL4とMQL5のインジケーター関数の違いは?

MQL5ではiMA()等の戻り値がハンドルに変わり、CopyBuffer(handle, buffer, start, count, array)でデータを一括コピーします。事前にIndicatorRelease()でハンドルを解放する必要があります。MQL4の直接値返し方式よりコード量が増えますが一括取得が効率的です。

MQL4リファレンス 関連記事

シストレ.COM編集部|200種類以上のEAをフォワード計測する運営3年の検証メディア。MetaTrader (MT4/MT5) を実運用してきた編集部が監修・執筆しています。

⚠ リスクに関する注意事項

本記事は情報提供を目的としており、特定の金融商品の売買を推奨するものではありません。FX取引はレバレッジ取引の特性上、預託した証拠金以上の損失が生じる可能性があります。取引の際は、ご自身の判断と責任において行ってください。詳しくは特定商取引法に基づく表記をご確認ください。

シストレ.COMで実績のあるEAが使い放題!/
無料会員登録はこちら
FX自動売買でEAを探すなら
シストレ.COM 記事下バナー
実績あるEAが無料
厳格な審査を乗り越えた実績のあるEAが無料で使えます!
自由な口座選び
有料版を購入し柔軟な口座選びが可能!
フォワードテスト公開
全EAのフォワードテスト結果を公開中!
FX初心者も安心
初心者の方も安心して取引を始められます。
多様なEA選択肢
様々な種別のEAをご用意!自分の手法にあった取引が可能です。
信頼のFX会社と提携
人気のFX会社と提携中!様々なFX会社から選べます。
1分で登録完了!EA探すならシストレ.COM!/
無料会員登録はこちら

この記事が気に入ったら
フォローしてね!

お役立ち情報をシェアする
  • URLをコピーしました!

この記事を書いた人

シストレ.COM編集部は、FX自動売買(EA)とテクニカル分析を専門とするインターネットメディア「シストレ.COM」の編集チームです。200本以上のEAのフォワードテスト結果を公開し、実際の運用データに基づいた客観的な情報を発信しています。記事の執筆・監修はMetaTrader(MT4/MT5)での実運用経験を持つスタッフが担当。

目次