MQL4のインジケーター関数を体系的にまとめました。iMA(移動平均線)、iRSI、iBands(ボリンジャーバンド)、iMACD、iATR、iStochastic、iCCI、iADX、iIchimoku(一目均衡表)など主要テクニカル指標の直接取得方法、iCustom()によるカスタムインジケーター呼び出し、マルチタイムフレーム分析、バッファインデックスの仕組みまで、MT4 EA開発に必要なインジケーター処理のすべてをコード付きで解説します。
目次
MQL4とMQL5のインジケーター取得方式の違い
MQL4とMQL5ではインジケーター値の取得方法が根本的に異なります。MQL4は関数を呼ぶだけで直接値が返りますが、MQL5はハンドルを作成してからバッファにコピーする2段階方式です。
| 項目 | MQL4 | MQL5 |
|---|---|---|
| 値の取得 | 関数呼び出しで直接値が返る | ハンドル作成→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_SMA | 0 | 単純移動平均 |
| MODE_EMA | 1 | 指数移動平均 |
| MODE_SMMA | 2 | 平滑移動平均 |
| MODE_LWMA | 3 | 線形加重移動平均 |
適用価格
| 定数 | 値 | 説明 |
|---|---|---|
| PRICE_CLOSE | 0 | 終値 |
| PRICE_OPEN | 1 | 始値 |
| PRICE_HIGH | 2 | 高値 |
| PRICE_LOW | 3 | 安値 |
| PRICE_MEDIAN | 4 | (High+Low)/2 |
| PRICE_TYPICAL | 5 | (High+Low+Close)/3 |
| PRICE_WEIGHTED | 6 | (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 Oscillator | symbol, timeframe, shift |
| iAC() | Accelerator Oscillator | symbol, 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() | パラボリックSAR | step, maximum |
| iWPR() | ウィリアムズ%R | period |
インジケーター関数一覧(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行で値を取得できます。EA開発での重要なポイントは以下の通りです。
- shift=0は未確定バー — シグナル判定にはshift=1(確定バー)を使うのが安全
- マルチタイムフレームはtimeframe引数を変えるだけ — 上位足の方向に順張りする戦略が有効
- 複数インジケーターの組み合わせ — トレンド系(MA, ADX)+ オシレーター系(RSI, Stoch)で精度を高める
- iCustom()のバッファインデックス — ソースコードでSetIndexBuffer()の順番を確認する
次のステップとして、MQLリファレンス総合ガイドで取引関数と組み合わせた実践的なEA開発を学びましょう。





