MQL5のテクニカル指標関数を完全網羅。iMA・iRSI・iBollinger Bands・iMACD・iATR・iStochastic・iCCI・iADXなど、EA開発で使うすべてのインジケーター関数をコード付きで解説します。MQL4との違いも併記。
MQL5とMQL4のインジケーター関数の根本的な違い
MQL4とMQL5ではインジケーター関数の使い方がまったく異なります。MQL4は1行で値が取れましたが、MQL5は「ハンドル取得→バッファコピー→値参照」の3ステップが必要です。
| 項目 | MQL4 | MQL5 |
|---|---|---|
| 値の取得 | iMA(NULL,0,20,0,MODE_SMA,PRICE_CLOSE,0) | ハンドル取得→CopyBuffer()→配列参照 |
| 戻り値 | double(インジケーター値そのもの) | int(ハンドル番号) |
| メモリ管理 | 自動 | IndicatorRelease()で明示的に解放 |
| パフォーマンス | 毎回計算 | ハンドルで一度だけ作成、以降はキャッシュ |
| 複数バッファ | modeパラメータで指定 | CopyBufferのbuffer_numで指定 |
MQL5の基本パターン(全インジケーター共通)
// ステップ1: OnInit()でハンドルを取得(1回だけ)
int maHandle;
int OnInit()
{
maHandle = iMA(_Symbol, PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE);
if(maHandle == INVALID_HANDLE)
{
Print("インジケーター作成失敗");
return INIT_FAILED;
}
return INIT_SUCCEEDED;
}
// ステップ2: OnTick()でバッファをコピーして値を取得
void OnTick()
{
double ma[];
ArraySetAsSeries(ma, true); // 最新バーが[0]
if(CopyBuffer(maHandle, 0, 0, 3, ma) < 3)
{
Print("データ取得失敗");
return;
}
// ma[0] = 現在のバー、ma[1] = 1本前、ma[2] = 2本前
double currentMA = ma[0];
double prevMA = ma[1];
}
// ステップ3: OnDeinit()でハンドルを解放
void OnDeinit(const int reason)
{
if(maHandle != INVALID_HANDLE)
IndicatorRelease(maHandle);
}ArraySetAsSeries(ma, true)を忘れると、配列のインデックスが逆になります([0]が最古のバー)。EA開発では必ず設定してください。
iMA — 移動平均線
最も基本的なインジケーター関数です。SMA(単純移動平均)、EMA(指数移動平均)、SMMA(平滑移動平均)、LWMA(線形加重移動平均)の4種類に対応しています。
関数シグネチャ
// MQL5
int iMA(
string symbol, // 通貨ペア(_Symbolまたは別銘柄)
ENUM_TIMEFRAMES period, // 時間足(PERIOD_CURRENT等)
int ma_period, // 期間
int ma_shift, // 表示シフト(通常0)
ENUM_MA_METHOD ma_method, // 移動平均の種類
ENUM_APPLIED_PRICE applied_price // 適用価格
);
// 戻り値: インジケーターハンドル(失敗時INVALID_HANDLE)
// MQL4
double iMA(
string symbol, int timeframe, int period,
int ma_shift, int ma_method, int applied_price, int shift
);
// 戻り値: インジケーター値(double)移動平均の種類(ENUM_MA_METHOD)
| 定数 | 名称 | 特徴 |
|---|---|---|
| MODE_SMA | 単純移動平均 | 全期間を均等に平均。安定だが遅い |
| MODE_EMA | 指数移動平均 | 直近のデータに重み。SMAより反応が速い |
| MODE_SMMA | 平滑移動平均 | SMAの平滑版。最もなめらか |
| MODE_LWMA | 線形加重移動平均 | 直近ほど大きな重み。EMAより更に敏感 |
適用価格(ENUM_APPLIED_PRICE)
| 定数 | 説明 |
|---|---|
| PRICE_CLOSE | 終値(最も一般的) |
| PRICE_OPEN | 始値 |
| PRICE_HIGH | 高値 |
| PRICE_LOW | 安値 |
| PRICE_MEDIAN | 中央値 (High+Low)/2 |
| PRICE_TYPICAL | 代表値 (High+Low+Close)/3 |
| PRICE_WEIGHTED | 加重値 (High+Low+Close+Close)/4 |
ゴールデンクロス・デッドクロスの検出
int maFastHandle, maSlowHandle;
int OnInit()
{
maFastHandle = iMA(_Symbol, PERIOD_CURRENT, 20, 0, MODE_EMA, PRICE_CLOSE);
maSlowHandle = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_EMA, PRICE_CLOSE);
if(maFastHandle == INVALID_HANDLE || maSlowHandle == INVALID_HANDLE)
return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnTick()
{
double fast[], slow[];
ArraySetAsSeries(fast, true);
ArraySetAsSeries(slow, true);
if(CopyBuffer(maFastHandle, 0, 0, 3, fast) < 3) return;
if(CopyBuffer(maSlowHandle, 0, 0, 3, slow) < 3) return;
// ゴールデンクロス: 短期MAが長期MAを下から上に抜けた
bool goldenCross = fast[1] > slow[1] && fast[2] <= slow[2];
// デッドクロス: 短期MAが長期MAを上から下に抜けた
bool deadCross = fast[1] < slow[1] && fast[2] >= slow[2];
if(goldenCross)
Print("ゴールデンクロス発生 fast=", fast[1], " slow=", slow[1]);
if(deadCross)
Print("デッドクロス発生 fast=", fast[1], " slow=", slow[1]);
}クロス判定は確定足([1]と[2])で行います。[0]は形成中のバーなので、確定前に判定するとシグナルが消える(リペイント)可能性があります。
iRSI — RSI(相対力指数)
RSI(Relative Strength Index)は買われすぎ・売られすぎを判定する代表的なオシレーター系指標です。0〜100の範囲で推移し、一般的に70以上で買われすぎ、30以下で売られすぎと判断します。
// MQL5
int iRSI(
string symbol, // 通貨ペア
ENUM_TIMEFRAMES period, // 時間足
int ma_period, // RSI期間(標準14)
ENUM_APPLIED_PRICE applied_price // 適用価格
);
// MQL4
double iRSI(string symbol, int timeframe, int period, int applied_price, int shift);RSIによる売買判定
int rsiHandle;
input int RSI_Period = 14;
input double RSI_Upper = 70.0;
input double RSI_Lower = 30.0;
int OnInit()
{
rsiHandle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE);
if(rsiHandle == INVALID_HANDLE) return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnTick()
{
double rsi[];
ArraySetAsSeries(rsi, true);
if(CopyBuffer(rsiHandle, 0, 0, 3, rsi) < 3) return;
// 売られすぎからの反転(買いシグナル)
// RSIが30以下から30以上に戻った瞬間
bool buySignal = rsi[2] < RSI_Lower && rsi[1] >= RSI_Lower;
// 買われすぎからの反転(売りシグナル)
// RSIが70以上から70以下に戻った瞬間
bool sellSignal = rsi[2] > RSI_Upper && rsi[1] <= RSI_Upper;
if(buySignal)
Print("RSI買いシグナル: RSI=", rsi[1]);
if(sellSignal)
Print("RSI売りシグナル: RSI=", rsi[1]);
}iBands — ボリンジャーバンド
ボリンジャーバンドは移動平均線を中心に、標準偏差で上下のバンドを描画するインジケーターです。バンドの収縮(スクイーズ)から拡大(エクスパンション)への転換でブレイクアウトを狙います。
// MQL5
int iBands(
string symbol, // 通貨ペア
ENUM_TIMEFRAMES period, // 時間足
int bands_period, // 期間(標準20)
int bands_shift, // シフト(通常0)
double deviation, // 標準偏差の倍数(標準2.0)
ENUM_APPLIED_PRICE applied_price // 適用価格
);
// バッファ: 0=ベース(中央線)、1=上バンド、2=下バンド
// MQL4
double iBands(string symbol, int timeframe, int period, double deviation,
int bands_shift, int applied_price, int mode, int shift);
// mode: MODE_MAIN(0)=中央線, MODE_UPPER(1)=上, MODE_LOWER(2)=下ボリンジャーバンド逆張り戦略
int bbHandle;
int OnInit()
{
bbHandle = iBands(_Symbol, PERIOD_CURRENT, 20, 0, 2.0, PRICE_CLOSE);
if(bbHandle == INVALID_HANDLE) return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnTick()
{
double base[], upper[], lower[];
ArraySetAsSeries(base, true);
ArraySetAsSeries(upper, true);
ArraySetAsSeries(lower, true);
// バッファ0=中央線、1=上バンド、2=下バンド
if(CopyBuffer(bbHandle, 0, 0, 3, base) < 3) return;
if(CopyBuffer(bbHandle, 1, 0, 3, upper) < 3) return;
if(CopyBuffer(bbHandle, 2, 0, 3, lower) < 3) return;
double close1 = iClose(_Symbol, PERIOD_CURRENT, 1);
double close2 = iClose(_Symbol, PERIOD_CURRENT, 2);
// 下バンドタッチからの反発(買い)
bool buySignal = close2 <= lower[2] && close1 > lower[1];
// 上バンドタッチからの反発(売り)
bool sellSignal = close2 >= upper[2] && close1 < upper[1];
// バンド幅(ボラティリティ判定に使用)
double bandWidth = (upper[1] - lower[1]) / base[1] * 100;
if(buySignal)
Print("BB買いシグナル: Close=", close1, " Lower=", lower[1], " BW=", bandWidth, "%");
if(sellSignal)
Print("BB売りシグナル: Close=", close1, " Upper=", upper[1], " BW=", bandWidth, "%");
}ボリンジャーバンドの逆張りはレンジ相場では有効ですが、強いトレンド相場ではバンドウォーク(価格がバンドに沿って動き続ける現象)が発生し、大きな損失になります。必ずトレンドフィルターと併用してください。
iMACD — MACD
MACD(Moving Average Convergence Divergence)はトレンドの方向と強さを測定するインジケーターです。MACDラインとシグナルラインのクロス、ゼロラインとの位置関係、ヒストグラムの増減で判断します。
// MQL5
int iMACD(
string symbol, // 通貨ペア
ENUM_TIMEFRAMES period, // 時間足
int fast_ema_period, // 短期EMA(標準12)
int slow_ema_period, // 長期EMA(標準26)
int signal_period, // シグナル期間(標準9)
ENUM_APPLIED_PRICE applied_price // 適用価格
);
// バッファ: 0=MACDライン、1=シグナルライン
// MQL4
double iMACD(string symbol, int timeframe, int fast_ema_period,
int slow_ema_period, int signal_period, int applied_price,
int mode, int shift);
// mode: MODE_MAIN(0)=MACDライン, MODE_SIGNAL(1)=シグナルラインMACDクロスによる売買判定
int macdHandle;
int OnInit()
{
macdHandle = iMACD(_Symbol, PERIOD_CURRENT, 12, 26, 9, PRICE_CLOSE);
if(macdHandle == INVALID_HANDLE) return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnTick()
{
double macdLine[], signalLine[];
ArraySetAsSeries(macdLine, true);
ArraySetAsSeries(signalLine, true);
if(CopyBuffer(macdHandle, 0, 0, 3, macdLine) < 3) return;
if(CopyBuffer(macdHandle, 1, 0, 3, signalLine) < 3) return;
// ヒストグラム(MACDライン - シグナルライン)
double hist1 = macdLine[1] - signalLine[1];
double hist2 = macdLine[2] - signalLine[2];
// MACDラインがシグナルラインを上抜け(買い)
bool buySignal = macdLine[1] > signalLine[1] && macdLine[2] <= signalLine[2];
// MACDラインがシグナルラインを下抜け(売り)
bool sellSignal = macdLine[1] < signalLine[1] && macdLine[2] >= signalLine[2];
// ゼロラインより上でのクロスはより信頼性が高い
if(buySignal && macdLine[1] < 0)
Print("MACD買い(ゼロ以下でのクロス=強いシグナル)");
if(sellSignal && macdLine[1] > 0)
Print("MACD売り(ゼロ以上でのクロス=強いシグナル)");
}iATR — ATR(真の値幅)
ATR(Average True Range)はボラティリティ(値動きの大きさ)を測定するインジケーターです。売買シグナルには使いませんが、SL/TPの設定、ポジションサイジング、エントリーフィルターとして非常に重要です。
// MQL5
int iATR(
string symbol, // 通貨ペア
ENUM_TIMEFRAMES period, // 時間足
int ma_period // 期間(標準14)
);
// バッファ: 0=ATR値
// MQL4
double iATR(string symbol, int timeframe, int period, int shift);ATRベースのSL/TP設定
int atrHandle;
input double ATR_SL_Multi = 2.0; // SL = ATR × 2.0
input double ATR_TP_Multi = 3.0; // TP = ATR × 3.0
int OnInit()
{
atrHandle = iATR(_Symbol, PERIOD_CURRENT, 14);
if(atrHandle == INVALID_HANDLE) return INIT_FAILED;
return INIT_SUCCEEDED;
}
// ATRに基づくSL/TPを計算して返す
bool GetATR_SLTP(double &slDistance, double &tpDistance)
{
double atr[];
ArraySetAsSeries(atr, true);
if(CopyBuffer(atrHandle, 0, 0, 2, atr) < 2) return false;
slDistance = atr[1] * ATR_SL_Multi; // 確定足のATRを使用
tpDistance = atr[1] * ATR_TP_Multi;
return true;
}
// 使用例
void OpenBuyWithATR(double lot)
{
double slDist, tpDist;
if(!GetATR_SLTP(slDist, tpDist)) return;
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double sl = NormalizeDouble(ask - slDist, _Digits);
double tp = NormalizeDouble(ask + tpDist, _Digits);
trade.Buy(lot, _Symbol, ask, sl, tp, "ATR-based SL/TP");
}固定pipsではなくATRベースでSL/TPを設定すると、ボラティリティに応じて自動調整されます。ボラが高い時はSLが広がり、低い時は狭まるため、ストップ狩りに遭いにくくなります。
iStochastic — ストキャスティクス
ストキャスティクスは一定期間の高値・安値の範囲内で、現在の終値がどの位置にあるかを示すオシレーター指標です。%Kライン(メイン)と%Dライン(シグナル)の2本で構成されます。
// MQL5
int iStochastic(
string symbol, // 通貨ペア
ENUM_TIMEFRAMES period, // 時間足
int Kperiod, // %K期間(標準5)
int Dperiod, // %D期間(標準3)
int slowing, // スローイング(標準3)
ENUM_MA_METHOD ma_method, // 平均化方法
ENUM_STO_PRICE price_field // 計算価格
);
// バッファ: 0=%Kライン(メイン)、1=%Dライン(シグナル)
// MQL4
double iStochastic(string symbol, int timeframe, int Kperiod, int Dperiod,
int slowing, int method, int price_field, int mode, int shift);
// mode: MODE_MAIN(0)=%K, MODE_SIGNAL(1)=%Dストキャスティクス売買判定
int stoHandle;
int OnInit()
{
stoHandle = iStochastic(_Symbol, PERIOD_CURRENT, 5, 3, 3, MODE_SMA, STO_LOWHIGH);
if(stoHandle == INVALID_HANDLE) return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnTick()
{
double kLine[], dLine[];
ArraySetAsSeries(kLine, true);
ArraySetAsSeries(dLine, true);
if(CopyBuffer(stoHandle, 0, 0, 3, kLine) < 3) return; // %K
if(CopyBuffer(stoHandle, 1, 0, 3, dLine) < 3) return; // %D
// 売られすぎゾーン(20以下)で%Kが%Dを上抜け → 買い
bool buySignal = kLine[2] < 20 && dLine[2] < 20
&& kLine[1] > dLine[1] && kLine[2] <= dLine[2];
// 買われすぎゾーン(80以上)で%Kが%Dを下抜け → 売り
bool sellSignal = kLine[2] > 80 && dLine[2] > 80
&& kLine[1] < dLine[1] && kLine[2] >= dLine[2];
if(buySignal)
Print("ストキャス買い: K=", kLine[1], " D=", dLine[1]);
if(sellSignal)
Print("ストキャス売り: K=", kLine[1], " D=", dLine[1]);
}iCCI — CCI(商品チャネル指数)
CCI(Commodity Channel Index)は統計的な平均からの乖離度を測定するオシレーターです。+100以上で買われすぎ、-100以下で売られすぎと判断します。トレンドフォローにも逆張りにも使える汎用性の高い指標です。
// MQL5
int iCCI(
string symbol, // 通貨ペア
ENUM_TIMEFRAMES period, // 時間足
int ma_period, // 期間(標準14)
ENUM_APPLIED_PRICE applied_price // 適用価格
);
// バッファ: 0=CCI値
// MQL4
double iCCI(string symbol, int timeframe, int period, int applied_price, int shift);CCI逆張り戦略
int cciHandle;
int OnInit()
{
cciHandle = iCCI(_Symbol, PERIOD_CURRENT, 14, PRICE_TYPICAL);
if(cciHandle == INVALID_HANDLE) return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnTick()
{
double cci[];
ArraySetAsSeries(cci, true);
if(CopyBuffer(cciHandle, 0, 0, 3, cci) < 3) return;
// CCI -100以下からの回復 → 買い
bool buySignal = cci[2] < -100 && cci[1] >= -100;
// CCI +100以上からの回復 → 売り
bool sellSignal = cci[2] > 100 && cci[1] <= 100;
if(buySignal)
Print("CCI買いシグナル: CCI=", cci[1]);
if(sellSignal)
Print("CCI売りシグナル: CCI=", cci[1]);
}iADX — ADX(方向性指数)
ADX(Average Directional Index)はトレンドの強さを測定する指標です。方向は示しませんが、ADXが25以上ならトレンド相場、20以下ならレンジ相場と判断できます。+DI/-DIと組み合わせてトレンド方向を判定します。
// MQL5
int iADX(
string symbol, // 通貨ペア
ENUM_TIMEFRAMES period, // 時間足
int adx_period // 期間(標準14)
);
// バッファ: 0=ADXメインライン、1=+DI、2=-DI
// MQL4
double iADX(string symbol, int timeframe, int period, int applied_price, int mode, int shift);
// mode: MODE_MAIN(0)=ADX, MODE_PLUSDI(1)=+DI, MODE_MINUSDI(2)=-DIADXトレンドフィルター + DI クロス
int adxHandle;
input double ADX_Threshold = 25.0;
int OnInit()
{
adxHandle = iADX(_Symbol, PERIOD_CURRENT, 14);
if(adxHandle == INVALID_HANDLE) return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnTick()
{
double adx[], plusDI[], minusDI[];
ArraySetAsSeries(adx, true);
ArraySetAsSeries(plusDI, true);
ArraySetAsSeries(minusDI, true);
if(CopyBuffer(adxHandle, 0, 0, 3, adx) < 3) return; // ADX
if(CopyBuffer(adxHandle, 1, 0, 3, plusDI) < 3) return; // +DI
if(CopyBuffer(adxHandle, 2, 0, 3, minusDI) < 3) return; // -DI
// トレンド判定
bool isTrending = adx[1] >= ADX_Threshold;
// +DIが-DIを上抜け かつ トレンド中 → 買い
bool buySignal = isTrending
&& plusDI[1] > minusDI[1] && plusDI[2] <= minusDI[2];
// -DIが+DIを上抜け かつ トレンド中 → 売り
bool sellSignal = isTrending
&& minusDI[1] > plusDI[1] && minusDI[2] <= plusDI[2];
if(buySignal)
Print("ADX買い: ADX=", adx[1], " +DI=", plusDI[1], " -DI=", minusDI[1]);
if(sellSignal)
Print("ADX売り: ADX=", adx[1], " +DI=", plusDI[1], " -DI=", minusDI[1]);
}iIchimoku — 一目均衡表
一目均衡表は日本発のテクニカル指標で、5本の線と雲(先行スパン)で構成されます。トレンドの方向、強さ、転換点を総合的に判断できる強力なインジケーターです。
// MQL5
int iIchimoku(
string symbol, // 通貨ペア
ENUM_TIMEFRAMES period, // 時間足
int tenkan_sen, // 転換線期間(標準9)
int kijun_sen, // 基準線期間(標準26)
int senkou_span_b // 先行スパンB期間(標準52)
);
// バッファ: 0=転換線、1=基準線、2=先行スパンA、3=先行スパンB、4=遅行スパン
// MQL4
double iIchimoku(string symbol, int timeframe, int tenkan_sen, int kijun_sen,
int senkou_span_b, int mode, int shift);
// mode: 1=転換線, 2=基準線, 3=先行スパンA, 4=先行スパンB, 5=遅行スパン一目均衡表の雲ブレイク戦略
int ichiHandle;
int OnInit()
{
ichiHandle = iIchimoku(_Symbol, PERIOD_CURRENT, 9, 26, 52);
if(ichiHandle == INVALID_HANDLE) return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnTick()
{
double tenkan[], kijun[], spanA[], spanB[];
ArraySetAsSeries(tenkan, true);
ArraySetAsSeries(kijun, true);
ArraySetAsSeries(spanA, true);
ArraySetAsSeries(spanB, true);
if(CopyBuffer(ichiHandle, 0, 0, 3, tenkan) < 3) return;
if(CopyBuffer(ichiHandle, 1, 0, 3, kijun) < 3) return;
if(CopyBuffer(ichiHandle, 2, 0, 3, spanA) < 3) return;
if(CopyBuffer(ichiHandle, 3, 0, 3, spanB) < 3) return;
double close1 = iClose(_Symbol, PERIOD_CURRENT, 1);
// 雲の上端・下端
double cloudTop = MathMax(spanA[1], spanB[1]);
double cloudBottom = MathMin(spanA[1], spanB[1]);
// 三役好転(強い買いシグナル)
// 1. 転換線 > 基準線
// 2. 価格が雲の上
// 3. 遅行スパンが価格の上(ここでは省略)
bool bullish = tenkan[1] > kijun[1] && close1 > cloudTop;
// 三役逆転(強い売りシグナル)
bool bearish = tenkan[1] < kijun[1] && close1 < cloudBottom;
// 転換線と基準線のクロス
bool tenkanCrossBull = tenkan[1] > kijun[1] && tenkan[2] <= kijun[2];
bool tenkanCrossBear = tenkan[1] < kijun[1] && tenkan[2] >= kijun[2];
if(tenkanCrossBull && close1 > cloudTop)
Print("一目買い: 転換線クロス+雲上");
if(tenkanCrossBear && close1 < cloudBottom)
Print("一目売り: 転換線クロス+雲下");
}一目均衡表の先行スパンは26本先にシフトされて表示されます。CopyBufferで取得する場合は現在のバーの値を参照するだけで、シフトは自動的に適用済みです。
iEnvelopes — エンベロープ
エンベロープは移動平均線から一定の割合(%)を上下に乖離させたバンドです。ボリンジャーバンドと似ていますが、標準偏差ではなく固定割合で計算するため、バンド幅が一定です。
// MQL5
int iEnvelopes(
string symbol, // 通貨ペア
ENUM_TIMEFRAMES period, // 時間足
int ma_period, // MA期間(標準14)
int ma_shift, // シフト
ENUM_MA_METHOD ma_method, // MA種類
ENUM_APPLIED_PRICE applied_price, // 適用価格
double deviation // 乖離率%(標準0.1)
);
// バッファ: 0=上バンド、1=下バンド
int envHandle;
int OnInit()
{
envHandle = iEnvelopes(_Symbol, PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE, 0.1);
if(envHandle == INVALID_HANDLE) return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnTick()
{
double upper[], lower[];
ArraySetAsSeries(upper, true);
ArraySetAsSeries(lower, true);
if(CopyBuffer(envHandle, 0, 0, 3, upper) < 3) return;
if(CopyBuffer(envHandle, 1, 0, 3, lower) < 3) return;
double close1 = iClose(_Symbol, PERIOD_CURRENT, 1);
if(close1 < lower[1])
Print("エンベロープ下限タッチ(買い候補): ", close1);
if(close1 > upper[1])
Print("エンベロープ上限タッチ(売り候補): ", close1);
}iSAR — パラボリックSAR
パラボリックSAR(Stop and Reverse)はトレンド追従型のインジケーターです。価格の上または下にドットが表示され、ドットが価格の下にあれば上昇トレンド、上にあれば下降トレンドと判定します。
// MQL5
int iSAR(
string symbol, // 通貨ペア
ENUM_TIMEFRAMES period, // 時間足
double step, // ステップ(標準0.02)
double maximum // 最大値(標準0.2)
);
// バッファ: 0=SAR値
// MQL4
double iSAR(string symbol, int timeframe, double step, double maximum, int shift);
int sarHandle;
int OnInit()
{
sarHandle = iSAR(_Symbol, PERIOD_CURRENT, 0.02, 0.2);
if(sarHandle == INVALID_HANDLE) return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnTick()
{
double sar[];
ArraySetAsSeries(sar, true);
if(CopyBuffer(sarHandle, 0, 0, 3, sar) < 3) return;
double close1 = iClose(_Symbol, PERIOD_CURRENT, 1);
double close2 = iClose(_Symbol, PERIOD_CURRENT, 2);
// SARが価格の下に移動(上昇トレンド転換)
bool buySignal = sar[1] < close1 && sar[2] >= close2;
// SARが価格の上に移動(下降トレンド転換)
bool sellSignal = sar[1] > close1 && sar[2] <= close2;
// SARをトレーリングストップとして使用
if(sar[1] < close1)
Print("上昇トレンド中 SL候補=", sar[1]);
}iWPR — ウィリアムズ%R
ウィリアムズ%Rはストキャスティクスの%Kを反転させたようなオシレーターです。-100〜0の範囲で推移し、-20以上で買われすぎ、-80以下で売られすぎと判断します。
// MQL5
int iWPR(
string symbol, // 通貨ペア
ENUM_TIMEFRAMES period, // 時間足
int calc_period // 期間(標準14)
);
// バッファ: 0=WPR値(-100〜0)
int wprHandle;
int OnInit()
{
wprHandle = iWPR(_Symbol, PERIOD_CURRENT, 14);
if(wprHandle == INVALID_HANDLE) return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnTick()
{
double wpr[];
ArraySetAsSeries(wpr, true);
if(CopyBuffer(wprHandle, 0, 0, 3, wpr) < 3) return;
// 売られすぎ(-80以下)からの回復 → 買い
bool buySignal = wpr[2] < -80 && wpr[1] >= -80;
// 買われすぎ(-20以上)からの回復 → 売り
bool sellSignal = wpr[2] > -20 && wpr[1] <= -20;
}iMomentum — モメンタム
モメンタムは現在の価格とN期間前の価格の比率を計算するシンプルなインジケーターです。100を基準として、100以上なら上昇モメンタム、100以下なら下降モメンタムです。
// MQL5
int iMomentum(
string symbol, // 通貨ペア
ENUM_TIMEFRAMES period, // 時間足
int mom_period, // 期間(標準14)
ENUM_APPLIED_PRICE applied_price // 適用価格
);
// バッファ: 0=モメンタム値(100基準)
int momHandle;
int OnInit()
{
momHandle = iMomentum(_Symbol, PERIOD_CURRENT, 14, PRICE_CLOSE);
if(momHandle == INVALID_HANDLE) return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnTick()
{
double mom[];
ArraySetAsSeries(mom, true);
if(CopyBuffer(momHandle, 0, 0, 3, mom) < 3) return;
// 100ラインの上抜け → 上昇モメンタム
bool bullish = mom[1] > 100 && mom[2] <= 100;
// 100ラインの下抜け → 下降モメンタム
bool bearish = mom[1] < 100 && mom[2] >= 100;
}iMAOnArray相当(MQL5でのカスタム計算)
MQL4にあったiMAOnArray()(配列データに対してMAを計算する関数)はMQL5には存在しません。代わりに自分で計算するか、iCustom()を使います。
// 配列に対してSMAを計算する関数(iMAOnArrayの代替)
double SimpleMA(const double &array[], int position, int period)
{
if(position < period - 1) return 0;
double sum = 0;
for(int i = 0; i < period; i++)
sum += array[position - i];
return sum / period;
}
// 配列に対してEMAを計算する関数
void CalcEMA(const double &src[], double &dst[], int period)
{
int size = ArraySize(src);
if(size < period) return;
ArrayResize(dst, size);
double k = 2.0 / (period + 1);
// SMA = 最初のperiod個の平均値
double sum = 0;
for(int i = 0; i < period; i++)
sum += src[i];
dst[period - 1] = sum / period;
// EMA計算(period以降)
for(int i = period; i < size; i++)
dst[i] = src[i] * k + dst[i - 1] * (1 - k);
}iCustom — カスタムインジケーター
iCustom()はユーザーが作成したカスタムインジケーターをEAから呼び出す関数です。標準関数にないインジケーター(ATR Bands、Keltner Channel、SuperTrend等)を使う場合に必要です。
// MQL5
int iCustom(
string symbol, // 通貨ペア
ENUM_TIMEFRAMES period, // 時間足
string name, // インジケーター名(パス)
... // インジケーターのinputパラメータ
);
// MQL4
double iCustom(string symbol, int timeframe, string name, ..., int mode, int shift);カスタムインジケーターの呼び出し例
// カスタムインジケーター「Examples\\SuperTrend」を呼び出す
int stHandle;
int OnInit()
{
// Indicatorsフォルダからの相対パス
// パラメータはインジケーターのinput変数に対応
stHandle = iCustom(_Symbol, PERIOD_CURRENT,
"Examples\\SuperTrend", // インジケーター名
10, // Period
3.0 // Multiplier
);
if(stHandle == INVALID_HANDLE)
{
Print("カスタムインジケーター作成失敗: ", GetLastError());
return INIT_FAILED;
}
return INIT_SUCCEEDED;
}
void OnTick()
{
double buffer0[], buffer1[];
ArraySetAsSeries(buffer0, true);
ArraySetAsSeries(buffer1, true);
// バッファ番号はカスタムインジケーターのSetIndexBuffer()に対応
if(CopyBuffer(stHandle, 0, 0, 3, buffer0) < 3) return;
if(CopyBuffer(stHandle, 1, 0, 3, buffer1) < 3) return;
Print("Buffer0=", buffer0[1], " Buffer1=", buffer1[1]);
}iCustom()で指定するインジケーター名は、Indicatorsフォルダからの相対パスです。サブフォルダにある場合は"MyFolder\\MyIndicator"のように指定します。拡張子(.ex5)は不要です。
価格データの直接取得(iOpen / iHigh / iLow / iClose / iVolume)
インジケーターではありませんが、EA開発で頻繁に使う価格データ取得関数です。MQL5では単独の関数として用意されています。
// MQL5 — 各関数は1本のバーの値を返す
double open1 = iOpen(_Symbol, PERIOD_CURRENT, 1); // 1本前の始値
double high1 = iHigh(_Symbol, PERIOD_CURRENT, 1); // 1本前の高値
double low1 = iLow(_Symbol, PERIOD_CURRENT, 1); // 1本前の安値
double close1 = iClose(_Symbol, PERIOD_CURRENT, 1); // 1本前の終値
long vol1 = iVolume(_Symbol, PERIOD_CURRENT, 1); // 1本前のティック量
datetime time1 = iTime(_Symbol, PERIOD_CURRENT, 1); // 1本前の時刻
int bars = iBars(_Symbol, PERIOD_CURRENT); // バー数
// 複数本を一括取得(CopyRatesが高速)
MqlRates rates[];
ArraySetAsSeries(rates, true);
if(CopyRates(_Symbol, PERIOD_CURRENT, 0, 100, rates) > 0)
{
// rates[0] = 現在のバー、rates[1] = 1本前...
double close = rates[1].close;
double high = rates[1].high;
double low = rates[1].low;
double open = rates[1].open;
long vol = rates[1].tick_volume;
}CopyBuffer — バッファコピーの詳細
CopyBuffer()はMQL5のインジケーターから値を取得する唯一の方法です。3つのオーバーロードがあります。
// 方法1: 位置と本数で指定(最も一般的)
int CopyBuffer(
int indicator_handle, // インジケーターハンドル
int buffer_num, // バッファ番号
int start_pos, // 開始位置(0=最新バー)
int count, // 取得本数
double buffer[] // 格納先配列
);
// 方法2: 日時で範囲指定
int CopyBuffer(int handle, int buffer_num,
datetime start_time, int count, double buffer[]);
// 方法3: 日時範囲で指定
int CopyBuffer(int handle, int buffer_num,
datetime start_time, datetime stop_time, double buffer[]);
// 戻り値: コピーされたデータ数(失敗時-1)
// 使用例
double ma[];
ArraySetAsSeries(ma, true);
// 最新から10本分を取得
int copied = CopyBuffer(maHandle, 0, 0, 10, ma);
if(copied < 10)
Print("データ不足: ", copied, "本しか取得できませんでした");
// 特定の日時から取得
datetime from = D'2024.01.01 00:00';
copied = CopyBuffer(maHandle, 0, from, 100, ma);IndicatorRelease — ハンドル解放
不要になったインジケーターハンドルはIndicatorRelease()で解放します。解放しないとメモリリークの原因になります。
void OnDeinit(const int reason)
{
// すべてのハンドルを解放
if(maHandle != INVALID_HANDLE)
{
IndicatorRelease(maHandle);
maHandle = INVALID_HANDLE;
}
if(rsiHandle != INVALID_HANDLE)
{
IndicatorRelease(rsiHandle);
rsiHandle = INVALID_HANDLE;
}
// ... 他のハンドルも同様
}マルチタイムフレーム分析
異なる時間足のインジケーター値をEAで取得する方法です。例えば1時間足のEAで日足のMAトレンドを参照するケースです。
int maH1Handle; // 1時間足のMA
int maD1Handle; // 日足のMA
int OnInit()
{
// 同じ通貨ペアの異なる時間足
maH1Handle = iMA(_Symbol, PERIOD_H1, 20, 0, MODE_EMA, PRICE_CLOSE);
maD1Handle = iMA(_Symbol, PERIOD_D1, 20, 0, MODE_EMA, PRICE_CLOSE);
if(maH1Handle == INVALID_HANDLE || maD1Handle == INVALID_HANDLE)
return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnTick()
{
double maH1[], maD1[];
ArraySetAsSeries(maH1, true);
ArraySetAsSeries(maD1, true);
if(CopyBuffer(maH1Handle, 0, 0, 3, maH1) < 3) return;
if(CopyBuffer(maD1Handle, 0, 0, 3, maD1) < 3) return;
double close = SymbolInfoDouble(_Symbol, SYMBOL_BID);
// 日足が上昇トレンド(価格が日足MA上)のときだけ
// 1時間足のMAクロスで買いエントリー
bool dailyBullish = close > maD1[0];
bool h1CrossUp = maH1[1] > maH1[0]; // 省略: 実際にはMAクロス等の条件
if(dailyBullish && h1CrossUp)
Print("マルチTF買い: 日足上昇 + H1シグナル");
}上位時間足のデータは、その時間足のバーが確定するまで更新されません。例えば日足のMAは、1時間足のEAでティックごとに変化するわけではなく、日足のバーが切り替わるタイミングでのみ変わります。
インジケーター関数一覧
MQL5で利用可能なすべてのテクニカル指標関数の一覧です。
| 関数 | インジケーター名 | バッファ数 | 主な用途 |
|---|---|---|---|
| iMA | 移動平均線 | 1 | トレンド判定、クロス売買 |
| iRSI | RSI | 1 | 買われすぎ・売られすぎ |
| iBands | ボリンジャーバンド | 3 | ボラティリティ、逆張り |
| iMACD | MACD | 2 | トレンド方向・強さ |
| iATR | ATR | 1 | ボラティリティ測定、SL/TP |
| iStochastic | ストキャスティクス | 2 | 買われすぎ・売られすぎ |
| iCCI | CCI | 1 | 乖離度測定 |
| iADX | ADX | 3 | トレンド強度、DI方向 |
| iIchimoku | 一目均衡表 | 5 | 総合的なトレンド判定 |
| iEnvelopes | エンベロープ | 2 | 乖離トレード |
| iSAR | パラボリックSAR | 1 | トレンド転換、トレーリング |
| iWPR | ウィリアムズ%R | 1 | 買われすぎ・売られすぎ |
| iMomentum | モメンタム | 1 | 勢い判定 |
| iDeMarker | デマーカー | 1 | 買われすぎ・売られすぎ |
| iForce | フォースインデックス | 1 | 売買圧力 |
| iOsMA | OsMA | 1 | MACDヒストグラム |
| iOBV | OBV | 1 | 出来高分析 |
| iVolumes | ボリューム | 1 | 出来高 |
| iMFI | マネーフローインデックス | 1 | 出来高加重オシレーター |
| iAO | Awesome Oscillator | 1 | モメンタム |
| iAC | Accelerator/Decelerator | 1 | モメンタム加速度 |
| iFrAMA | フラクタル適応MA | 1 | 適応型トレンド |
| iAMA | 適応型移動平均 | 1 | ノイズ適応MA |
| iDEMA | 二重指数移動平均 | 1 | 高速トレンド |
| iTEMA | 三重指数移動平均 | 1 | 超高速トレンド |
| iVIDyA | 可変インデックス動的平均 | 1 | ボラティリティ適応MA |
| iBWMFI | BW MFI | 1 | ビル・ウィリアムズMFI |
| iFractals | フラクタル | 2 | スイングポイント |
| iAlligator | アリゲーター | 3 | トレンド判定 |
| iGator | ゲーターオシレーター | 2 | アリゲーター補助 |
| iChaikin | チャイキンオシレーター | 1 | 出来高ベース |
| iStdDev | 標準偏差 | 1 | ボラティリティ |
| iRVI | 相対活力指数 | 2 | トレンド強度 |
| iTriX | TRIX | 1 | トリプル平滑化 |
実践:複数インジケーターの組み合わせ
実際のEA開発では、複数のインジケーターを組み合わせてシグナルの精度を高めます。ここでは代表的な組み合わせパターンを紹介します。
MA + RSI + ADXフィルター
#include <Trade\Trade.mqh>
CTrade trade;
int maFastHandle, maSlowHandle, rsiHandle, adxHandle;
input int MA_Fast = 20;
input int MA_Slow = 50;
input int RSI_Period = 14;
input double RSI_Lower = 40.0; // RSIフィルター下限
input double RSI_Upper = 60.0; // RSIフィルター上限
input double ADX_Min = 25.0; // 最低ADX値
input double Lot = 0.1;
input int SL_Points = 500;
input int TP_Points = 1000;
input long MagicNumber = 20240301;
int OnInit()
{
trade.SetExpertMagicNumber(MagicNumber);
maFastHandle = iMA(_Symbol, PERIOD_CURRENT, MA_Fast, 0, MODE_EMA, PRICE_CLOSE);
maSlowHandle = iMA(_Symbol, PERIOD_CURRENT, MA_Slow, 0, MODE_EMA, PRICE_CLOSE);
rsiHandle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE);
adxHandle = iADX(_Symbol, PERIOD_CURRENT, 14);
if(maFastHandle == INVALID_HANDLE || maSlowHandle == INVALID_HANDLE
|| rsiHandle == INVALID_HANDLE || adxHandle == INVALID_HANDLE)
return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnTick()
{
// ポジションチェック(1ポジションのみ)
int posCount = 0;
for(int i = 0; i < PositionsTotal(); i++)
{
ulong ticket = PositionGetTicket(i);
if(PositionGetInteger(POSITION_MAGIC) == MagicNumber
&& PositionGetString(POSITION_SYMBOL) == _Symbol)
posCount++;
}
if(posCount > 0) return;
// インジケーター値取得
double fast[], slow[], rsi[], adx[];
ArraySetAsSeries(fast, true);
ArraySetAsSeries(slow, true);
ArraySetAsSeries(rsi, true);
ArraySetAsSeries(adx, true);
if(CopyBuffer(maFastHandle, 0, 0, 3, fast) < 3) return;
if(CopyBuffer(maSlowHandle, 0, 0, 3, slow) < 3) return;
if(CopyBuffer(rsiHandle, 0, 0, 3, rsi) < 3) return;
if(CopyBuffer(adxHandle, 0, 0, 3, adx) < 3) return;
// 条件判定(確定足[1][2]を使用)
bool maCrossUp = fast[1] > slow[1] && fast[2] <= slow[2];
bool maCrossDown = fast[1] < slow[1] && fast[2] >= slow[2];
bool trendStrong = adx[1] >= ADX_Min;
// 買いシグナル: MAゴールデンクロス + RSIがまだ低い + トレンド強い
if(maCrossUp && rsi[1] < RSI_Upper && trendStrong)
{
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double sl = NormalizeDouble(ask - SL_Points * _Point, _Digits);
double tp = NormalizeDouble(ask + TP_Points * _Point, _Digits);
trade.Buy(Lot, _Symbol, ask, sl, tp, "MA+RSI+ADX Buy");
}
// 売りシグナル: MAデッドクロス + RSIがまだ高い + トレンド強い
if(maCrossDown && rsi[1] > RSI_Lower && trendStrong)
{
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double sl = NormalizeDouble(bid + SL_Points * _Point, _Digits);
double tp = NormalizeDouble(bid - TP_Points * _Point, _Digits);
trade.Sell(Lot, _Symbol, bid, sl, tp, "MA+RSI+ADX Sell");
}
}
void OnDeinit(const int reason)
{
IndicatorRelease(maFastHandle);
IndicatorRelease(maSlowHandle);
IndicatorRelease(rsiHandle);
IndicatorRelease(adxHandle);
}- MAクロスでエントリータイミングを決定
- RSIフィルターで買われすぎ・売られすぎでのエントリーを回避
- ADXフィルターでレンジ相場でのダマシを排除
プロが開発したEAをお探しの方は → シストレ.COM EA一覧





