1. iDEMA関数の概要と実務での活用法
iDEMA(Double Exponential Moving Average:二重指数移動平均線)は、通常の指数移動平均(EMA)にさらにEMAを重ねることで、「移動平均線の滑らかさを維持しつつ、価格追従の遅延(ラグ)を極限まで減らす」ことを目的に開発されたインジケーターです。
実務開発において、通常のSMAやEMAではトレンドの発生を確認してからエントリーするまでにどうしてもタイムラグが発生します。iDEMAはこのラグを数学的に相殺するように設計されているため、短期スキャルピングや敏感なトレンド転換の判定に非常に有効です。
しかし、初心者がつまずきやすいポイントは「MT5(MQL5)のiDEMA関数は、価格そのものを返すわけではない」という点です。MQL5では「ハンドルの取得」→「データのコピー」というステップを踏む必要があり、ここがMT4(MQL4)経験者やプログラミング初心者にとって最初の大きな壁となります。
2. 構文と戻り値
iDEMA関数は、インジケーターの計算設定を行い、その設定を識別するための「ハンドル(整数値)」を返します。
構文
int iDEMA(
string symbol, // 通貨ペア名(NULLで現在のチャート)
ENUM_TIMEFRAMES period, // 時間軸(0で現在の時間軸)
int ma_period, // 平均期間
int ma_shift, // 横方向へのシフト(ずらし)
ENUM_APPLIED_PRICE applied_price // 適用価格(CLOSE, OPEN, HL2など)
);
戻り値
- int型: 成功すれば「インジケーターのハンドル」を返します。
- 失敗した場合は
INVALID_HANDLEを返します。
※このハンドルを使って、後述の CopyBuffer 関数により実際の移動平均線の値を取得します。
3. 具体的な使い方・実践サンプルコード
以下は、iDEMAを使って最新の値を読み取り、ログに出力するシンプルなEA(エキスパートアドバイザー)のテンプレートです。
//+------------------------------------------------------------------+
//| iDEMA_Sample_EA.mq5 |
//| Copyright 2023, Quant Engineer |
//| https://example.com |
//+------------------------------------------------------------------+
#property strict
// --- 入力パラメーター
input int InpPeriod = 14; // DEMAの期間
input int InpShift = 0; // シフト
input ENUM_APPLIED_PRICE InpPrice = PRICE_CLOSE; // 適用価格
// --- グローバル変数
int handleDEMA; // iDEMAのハンドルを格納する変数
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// 1. iDEMAのハンドルを取得(初期化時に一度だけ実行)
handleDEMA = iDEMA(_Symbol, _Period, InpPeriod, InpShift, InpPrice);
// ハンドル取得に失敗した場合はエラー終了
if(handleDEMA == INVALID_HANDLE)
{
Print("iDEMAハンドルの取得に失敗しました。エラーコード:", GetLastError());
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
double demaValues[]; // 値を格納する動的配列
// 2. 配列を時系列順(最新がインデックス0)に設定
ArraySetAsSeries(demaValues, true);
// 3. CopyBufferを使用してハンドルからデータをコピー
// 0番目のバッファ(DEMAの値)から、最新の2本分を取得
if(CopyBuffer(handleDEMA, 0, 0, 2, demaValues) < 0)
{
Print("データのコピーに失敗しました。エラー:", GetLastError());
return;
}
// 4. 値の利用(例:現在の値と1本前の値を比較)
double currentDEMA = demaValues[0];
double prevDEMA = demaValues[1];
Comment("現在のDEMA: ", DoubleToString(currentDEMA, _Digits), "\n",
"1本前のDEMA: ", DoubleToString(prevDEMA, _Digits));
// ここにエントリーロジックなどを記述
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 5. メモリ解放のためにハンドルをリリース
IndicatorRelease(handleDEMA);
}
4. 使用上の注意点とよくあるエラー
-
ハンドルの作成はOnInitで行う
OnTick内で毎回iDEMA関数を呼び出すのは厳禁です。PCのリソースを著しく消費し、プラットフォームの動作が重くなる原因になります。必ずOnInitで一度だけ取得し、使い回してください。 -
配列の時系列(時系列方向)
MQL5のデフォルト配列は、古いデータが0番目になっています。ArraySetAsSeries(array, true)を実行せずにデータを取り出すと、「インデックス0番=最も古いデータ」となり、ロジックが逆転するバグに繋がりやすいため注意が必要です。 -
計算に必要なバーの数
チャートに表示されているバーの数が、設定したma_periodよりも少ない場合、CopyBufferは失敗します。稼働開始直後のエラーチェックを怠らないようにしましょう。
5. 【重要】自動売買における約定スピードと環境の罠
アルゴリズムトレードにおいて、iDEMAのような低遅延インジケーターを採用しても、実行環境が適切でなければその優位性は完全に失われます。自宅のPCや一般的な光回線でEAを稼働させる場合、ブローカーのサーバーとの物理的な距離により、数十から数百ミリ秒(ms)のネットワーク遅延(レイテンシ)が必ず発生します。
この遅延は、iDEMAが捉えた一瞬のエントリーチャンスを逃すだけでなく、激しい値動きの中では「約定拒否」や「著しいスリッページ」を招き、期待期待値を大幅に削り取ります。プロのクオンツ環境では、ブローカーのデータセンターと同じ建物、あるいは極めて至近距離にある専用のVPS(仮想専用サーバー)を利用するのが常識です。約定スピードを1ミリ秒でも短縮することが、最終的な損益曲線(エクイティカーブ)を安定させるための最もコストパフォーマンスの高い投資となります。
💡 この記事の内容を実運用で活かすには?
この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント