iEnvelopesは、移動平均の上下にバンドを描く、

MQL4の組み込み関数です。

「価格から何%離れたら帯の外」とみなす基準は、

deviationという引数で指定します。

既刊のテクニカルインジケーター関数一覧記事で名前だけは触れていましたが、

このサイトではまだiEnvelopes単独の解説記事がありませんでした。

この記事では、iEnvelopesの引数と戻り値を整理したうえで、

価格が上下バンドに「タッチした瞬間」だけを検知して通知する、

実際に動くインジケーターの作り方を解説します。

この記事で分かること
・iEnvelopesの9つの引数と戻り値の意味
・既刊iBands・既刊iStdDevとの計算方法の違い
・MQL4とMQL5でiEnvelopesの戻り値の種類が違う点
・実際に動くコード全体

設計思想: なぜ「%の逸脱」で見る必要があるか

まず、iEnvelopesが既刊のバンド系指標と何が違うのかを整理します。

既刊iBands(標準偏差ベース)との計算方法の違い

iBandsは、過去N本の値動きの「標準偏差」を使ってバンドの幅を決めます。

相場が荒れればバンドは自動的に広がり、落ち着けば自動的に狭まります。

一方、iEnvelopesは移動平均に対して、

常に同じ%(例えば0.2%)だけ離れた位置にバンドを引きます。

指標 バンド幅の決め方 相場の荒れ具合への追従
iBands(既刊) 標準偏差×倍率 自動で変化する
iEnvelopes(本記事) 移動平均からの固定% 変化しない(固定幅)

バンド幅が固定だからこそ、

「普段どのくらい離れたら行き過ぎか」を自分で決めやすい、という利点があります。

既刊iStdDev記事との関係

既刊のiStdDev記事では、

散らばりの大きさそのものを数値として取り出す方法を解説しました。

3つのバンド系・散らばり系指標の関係
・iStdDev: 散らばりの大きさを数値で取得する
・iBands: その散らばりを使って可変幅のバンドを描く
・iEnvelopes: 散らばりを使わず固定%でバンドを描く

iEnvelopesは標準偏差を一切使わないため、

既刊2記事とは計算の出発点そのものが異なります。

iEnvelopes関数の引数と戻り値

公式リファレンス(MQL4 Reference: iEnvelopes)の内容を整理します。

9つの引数の意味

double iEnvelopes(
   string symbol,        // 通貨ペア名(NULLで現在のチャート)
   int    timeframe,     // 時間足(0で現在の時間足)
   int    ma_period,     // 移動平均の期間
   int    ma_method,     // 移動平均の計算方法(MODE_SMA等)
   int    ma_shift,      // 移動平均のシフト
   int    applied_price, // 適用価格(PRICE_CLOSE等)
   double deviation,     // 移動平均からの逸脱率(%、例: 0.2は0.2%)
   int    mode,          // MODE_MAIN(中心線)/MODE_UPPER(上)/MODE_LOWER(下)
   int    shift          // 何本前のバーの値を取得するか
);

iMAやiBandsと似た並び方ですが、

deviationとmodeの2つがiEnvelopes特有の引数です。

MQL5版との違い: 戻り値が直接の値かハンドルか

MQL4のiEnvelopesは、バンドの値をdoubleで直接返します。

一方、MQL5のiEnvelopes(MQL5 Reference: iEnvelopes)は、

値ではなくインジケーターのハンドル(int)を返します。

MQL5移行時の注意
・MQL5のiEnvelopesはハンドルを返すだけで、値そのものは返さない
・実際の値はCopyBuffer()で別途取得する必要がある
・さらにMQL5版は引数にmodeが無く、上下バンドはバッファ番号(1/2)で区別する

既刊のMQL4→MQL5移行チェックリストと同じ、

テクニカル指標のハンドル方式化という変化点がここにも当てはまります。

サンプルインジケーター: バンドタッチを検知する設計

単にバンドを描画するだけでなく、

「価格がバンドに触れた瞬間」だけを矢印で知らせます。

上下バンドの値を取得する

double upper = iEnvelopes(NULL, 0, InpMaPeriod, MODE_SMA, 0, PRICE_CLOSE, InpDeviation, MODE_UPPER, i);
double lower = iEnvelopes(NULL, 0, InpMaPeriod, MODE_SMA, 0, PRICE_CLOSE, InpDeviation, MODE_LOWER, i);

MODE_UPPERとMODE_LOWERをそれぞれ別の呼び出しで取得する点が、

iBandsの呼び出し方と共通しています。

タッチ判定と矢印バッファ

高値が上バンド以上、または安値が下バンド以下になった本だけに、

矢印バッファへ値をセットします。

連続して矢印が出続けないよう、

直前のバーでタッチしていなかった場合だけ矢印を出す設計にしています。

実際に動くコード全体

実際にMetaEditorでコンパイルできる、

エンベロープバンドとタッチ矢印を表示するインジケーターです。

//+------------------------------------------------------------------+
//|                                       EnvelopesTouchIndicator.mq4 |
//|                     Copyright 2026, FX-EA System Project Creator |
//|                        https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, FX-EA System Project Creator"
#property link      "https://creator.fx-ea-system-project.com/"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 DodgerBlue
#property indicator_color2 DodgerBlue
#property indicator_color3 Red
#property indicator_color4 Lime
#property indicator_width3 2
#property indicator_width4 2

input int    InpMaPeriod   = 20;    //移動平均の期間
input double InpDeviation  = 0.2;   //移動平均からの逸脱率(%)

double UpperBuffer[];
double LowerBuffer[];
double TouchUpperArrow[];
double TouchLowerArrow[];

int OnInit()
  {
   SetIndexBuffer(0, UpperBuffer);
   SetIndexStyle(0, DRAW_LINE);
   SetIndexBuffer(1, LowerBuffer);
   SetIndexStyle(1, DRAW_LINE);

   SetIndexBuffer(2, TouchUpperArrow);
   SetIndexStyle(2, DRAW_ARROW, EMPTY, 2);
   SetIndexArrow(2, 242);
   SetIndexEmptyValue(2, EMPTY_VALUE);

   SetIndexBuffer(3, TouchLowerArrow);
   SetIndexStyle(3, DRAW_ARROW, EMPTY, 2);
   SetIndexArrow(3, 241);
   SetIndexEmptyValue(3, EMPTY_VALUE);

   IndicatorShortName("Envelopes Touch Detector");
   return(INIT_SUCCEEDED);
  }

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   int needed = InpMaPeriod + 2;
   if(rates_total < needed)
      return(0);

   int limit = (prev_calculated == 0) ? rates_total - needed : rates_total - prev_calculated + 1;

   for(int i = limit; i >= 0; i--)
     {
      double upper = iEnvelopes(NULL, 0, InpMaPeriod, MODE_SMA, 0, PRICE_CLOSE, InpDeviation, MODE_UPPER, i);
      double lower = iEnvelopes(NULL, 0, InpMaPeriod, MODE_SMA, 0, PRICE_CLOSE, InpDeviation, MODE_LOWER, i);
      UpperBuffer[i] = upper;
      LowerBuffer[i] = lower;

      TouchUpperArrow[i] = EMPTY_VALUE;
      TouchLowerArrow[i] = EMPTY_VALUE;

      bool touchedUpperNow  = (high[i] >= upper);
      bool touchedUpperPrev = (i + 1 < rates_total) && (high[i + 1] >= UpperBuffer[i + 1]);
      if(touchedUpperNow && !touchedUpperPrev)
         TouchUpperArrow[i] = high[i] + 10 * Point;

      bool touchedLowerNow  = (low[i] <= lower);
      bool touchedLowerPrev = (i + 1 < rates_total) && (low[i + 1] <= LowerBuffer[i + 1]);
      if(touchedLowerNow && !touchedLowerPrev)
         TouchLowerArrow[i] = low[i] - 10 * Point;
     }

   return(rates_total);
  }

MetaEditorでのコンパイル・実行手順

実際にMT4で動かすまでの手順です。

  1. MetaEditorで新規インジケーター「EnvelopesTouchIndicator」を作成し、上のコードを貼り付けてコンパイルする
  2. エラー・警告が0件であることを確認する
  3. チャート上にバンドのライン2本が表示されることを確認する
  4. 価格がバンドにタッチしたバーに矢印が出ることを確認する
  5. InpDeviationの値を大きく(例: 0.5)してバンド幅が広がり、タッチの頻度が減ることを確認する

よくあるエラーと注意点

実装でつまずきやすいポイントをまとめます。

deviationの単位を取り違える

deviationは「%そのもの」を指定します。

0.2は0.2%という意味で、0.002のような小数表記にすると、

バンド幅が実質ゼロに近くなり、常にタッチ判定になってしまいます。

modeを両方取得し忘れる

iEnvelopesはiBandsと同じく、

MODE_UPPERとMODE_LOWERをそれぞれ別の呼び出しで取得する必要があります。

片方だけ取得して「上バンドの値を下バンドとして使う」ミスに注意してください。

MQL5移植時にmode引数が無いことを忘れる

前述のとおり、MQL5版は引数にmodeが無く、

CopyBuffer()で指定するバッファ番号(1が上、2が下)で上下を区別します。

既刊のMQL4→MQL5移行チェックリストと合わせて確認してください。

既刊のバンド系・ボラティリティ系記事との使い分け

似た目的の記事が複数あるため、使い分けを整理します。

記事 バンド幅の決め方 用途
本記事(iEnvelopes) 移動平均からの固定% 決めた逸脱率を超えた瞬間を検知
iBands記事(既刊) 標準偏差×倍率(可変) 相場の荒れ具合に応じたバンドを可視化
iStdDev記事(既刊) (バンドではなく散らばりの数値) 普段より散らばっているかを検知

よくある質問

iEnvelopesについて、よくある疑問に回答します。

iEnvelopesとiBands、どちらを使うべきですか?

目的によって使い分けます。

相場の荒れ具合に応じてバンド幅が自動で変わってほしいならiBands、

いつも同じ%ルールで行き過ぎを判定したいならiEnvelopesが向いています。

このインジケーターをEAのフィルターに使えますか?

使えます。

本記事のタッチ判定部分だけを関数化すれば、

「上バンドにタッチしたら売り、

下バンドにタッチしたら買い」という逆張りEAの条件に組み込めます。

InpDeviationはどれくらいの値が適切ですか?

通貨ペアや時間足によって適切な値は変わります。

まずは既定値の0.2から始め、

チャートを見ながらタッチの頻度が多すぎないか少なすぎないかを調整することをおすすめします。

【MQL4】iEnvelopesで価格の「上下バンドからの逸脱」を検知し、タッチ時に通知するインジケーターの作り方:まとめ

iEnvelopesは、既刊iBands・既刊iStdDevとは違い、

標準偏差を使わず移動平均からの固定%でバンドを描く関数です。

上下バンドへのタッチを検知することで、

「決めたルールを超えて価格が逸脱したか」を一瞬で判定できます。

MQL5では戻り値がハンドルに変わり、modeの指定方法も変わる点に注意してください。

関連記事