iStdDevは、終値が移動平均からどれだけ散らばっているか(標準偏差)を、
MQL4で直接取得できる組み込み関数です。
既刊のiATR記事(値幅の平均)とは測る対象が違うにもかかわらず、
このサイトではまだiStdDev単独の解説記事がありませんでした。
この記事では、iStdDevの引数と戻り値を整理したうえで、
直近の平均的な標準偏差と比較して「今は普段より価格が散らばっているか」を検知する、
実際に動くインジケーターの作り方を解説します。
・iStdDevの7つの引数と戻り値の意味
・既刊iATR・既刊iBandsとの計算対象の違い
・MQL4とMQL5でiStdDevの戻り値の種類が違う点
・実際に動くコード全体
設計思想: なぜ標準偏差を単独で見る必要があるか
まず、iStdDevがどんな場面で役に立つのかを整理します。
既刊iATR(真の値幅の平均)との計算対象の違い
ATRは「1本の値幅(高値-安値、前日終値とのギャップも考慮)」の平均です。
一方、標準偏差は「終値が移動平均からどれだけ離れているか」の散らばりを測ります。
| 指標 | 何を測るか | ギャップ(窓)の扱い |
|---|---|---|
| iATR(既刊) | 1本ごとの値幅の平均 | 前日終値とのギャップも含める |
| iStdDev(本記事) | 移動平均からの終値の散らばり | 考慮しない(終値だけを見る) |
同じ「ボラティリティ系」の指標に見えても、
数式も見ている対象も別物です。
既刊iBands(ボリンジャーバンド)との関係
iBandsは、内部でこの標準偏差を使って、
移動平均の上下にバンドを描いています。
・iBandsは「標準偏差を使ってバンドの位置を決める」関数
・iStdDevは「標準偏差の値そのもの」を返す関数
・iBandsだけではバンドの位置しか分からず
・散らばりの大きさを数値として直接取り出せない
バンドの位置ではなく、
散らばりの大きさそのものを数値として使いたいときは、
iStdDevを直接呼び出す必要があります。
iStdDev関数の引数と戻り値
公式リファレンス(MQL4 Reference: iStdDev)の内容を整理します。
7つの引数の意味
double iStdDev( string symbol, // 通貨ペア名(NULLで現在のチャート) int timeframe, // 時間足(0で現在の時間足) int ma_period, // 移動平均の期間 int ma_shift, // 移動平均のシフト int ma_method, // 移動平均の計算方法(MODE_SMA等) int applied_price, // 適用価格(PRICE_CLOSE等) int shift // 何本前のバーの値を取得するか );
iMAやiATRと同じ並び方で、
移動平均の計算方法と適用価格をそのまま引き継いでいる点が特徴です。
MQL5版との違い: 戻り値が直接の値かハンドルか
MQL4のiStdDevは、標準偏差の値をdoubleで直接返します。
一方、MQL5のiStdDev(MQL5 Reference: iStdDev)は、
値ではなくインジケーターのハンドル(int)を返します。
・MQL5のiStdDevはハンドルを返すだけで、値そのものは返さない
・実際の値はCopyBuffer()で別途取得する必要がある
・MQL4のコードをそのまま移植すると「ハンドルを値として使ってしまう」事故が起きやすい
既刊のMQL4→MQL5移行チェックリストと同じ、
テクニカル指標のハンドル方式化という変化点がここにも当てはまります。
サンプルインジケーター: 標準偏差の「急な広がり」を検知する設計
単に値を表示するだけでなく、
「今は普段より散らばっているか」まで判定します。
直近N本の平均StdDevと比較する
double sumStdDev = 0; for(int j = i; j < i + InpAvgLookback; j++) sumStdDev += iStdDev(NULL, 0, InpStdDevPeriod, 0, MODE_SMA, PRICE_CLOSE, j); double avgStdDev = sumStdDev / InpAvgLookback;
直近InpAvgLookback本の平均StdDevを基準値にし、
現在値がその何倍かで「普段より広がっているか」を判定します。
ラインバッファと警告ラベルの2本立て
標準偏差の値そのものをラインで描画しつつ、
基準値の何倍かという情報は別にOBJ_LABELで文字表示します。
数値だけ見ても散らばりの大小は直感的に分かりにくいため、
「普段の何倍か」という相対的な表示を追加しています。
実際に動くコード全体
実際にMetaEditorでコンパイルできる、
標準偏差ラインと急変検知ラベルを表示するインジケーターです。
//+------------------------------------------------------------------+
//| StdDevSpikeIndicator.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_separate_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
input int InpStdDevPeriod = 20; //標準偏差の計算期間
input int InpAvgLookback = 100; //「普段」とみなす平均の参照本数
input double InpSpikeRatio = 1.5; //普段の何倍で「広がっている」と判定するか
double StdDevBuffer[];
#define LABEL_NAME "StdDevSpikeLabel"
int OnInit()
{
SetIndexBuffer(0, StdDevBuffer);
SetIndexStyle(0, DRAW_LINE);
SetIndexEmptyValue(0, EMPTY_VALUE);
IndicatorShortName("StdDev Spike Detector");
ObjectCreate(0, LABEL_NAME, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, LABEL_NAME, OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, LABEL_NAME, OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, LABEL_NAME, OBJPROP_YDISTANCE, 10);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
ObjectDelete(0, LABEL_NAME);
}
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 = InpStdDevPeriod + InpAvgLookback + 2;
if(rates_total < needed)
return(0);
int limit = (prev_calculated == 0) ? rates_total - InpAvgLookback - 1 : rates_total - prev_calculated + 1;
if(limit > rates_total - InpAvgLookback - 1)
limit = rates_total - InpAvgLookback - 1;
for(int i = limit; i >= 0; i--)
StdDevBuffer[i] = iStdDev(NULL, 0, InpStdDevPeriod, 0, MODE_SMA, PRICE_CLOSE, i);
double currentStdDev = iStdDev(NULL, 0, InpStdDevPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
double sumStdDev = 0;
for(int j = 1; j <= InpAvgLookback; j++)
sumStdDev += iStdDev(NULL, 0, InpStdDevPeriod, 0, MODE_SMA, PRICE_CLOSE, j);
double avgStdDev = sumStdDev / InpAvgLookback;
double ratio = (avgStdDev > 0) ? currentStdDev / avgStdDev : 0;
color labelColor = (ratio >= InpSpikeRatio) ? clrRed : clrSilver;
string text = StringFormat("StdDev: %.5f 普段の%.2f倍 %s",
currentStdDev, ratio,
(ratio >= InpSpikeRatio) ? "(広がっている)" : "");
ObjectSetText(LABEL_NAME, text, 10, "Arial", labelColor);
return(rates_total);
}
MetaEditorでのコンパイル・実行手順
実際にMT4で動かすまでの手順です。
- MetaEditorで新規インジケーター「StdDevSpikeIndicator」を作成し、上のコードを貼り付けてコンパイルする
- エラー・警告が0件であることを確認する
- サブウィンドウにラインが表示され、左上にラベルが出ることを確認する
- InpSpikeRatioを一時的に1.0程度まで下げ、ラベルが赤くなる条件が増えることを確認する
- InpStdDevPeriod・InpAvgLookbackを変えて、ラインの滑らかさと判定の感度が変わることを確認する
よくあるエラーと注意点
実装でつまずきやすいポイントをまとめます。
ma_shiftを0以外にすると結果がずれる
ma_shiftは移動平均そのものをずらす引数で、
shift(何本前のバーか)とは別の意味です。
この2つを混同すると、
意図しない本数分だけ計算対象がずれます。
applied_priceの指定ミス
PRICE_CLOSE以外の値(PRICE_TYPICAL等)を使うと、
既刊iBands記事のバンドと見た目が一致しなくなることがあります。
比較する記事同士では、
同じapplied_priceに揃えることをおすすめします。
MQL5へ移植する際にCopyBufferを忘れる
前述のとおり、MQL5版は値ではなくハンドルを返すため、
iStdDev()の戻り値をそのまま
doubleとして使おうとするとコンパイルエラーになります。
既刊のMQL4→MQL5移行チェックリストと合わせて確認してください。
既刊のボラティリティ系記事との使い分け
似た目的の記事が複数あるため、使い分けを整理します。
| 記事 | 測る対象 | 用途 |
|---|---|---|
| 本記事(iStdDev) | 移動平均からの終値の散らばり | 普段より価格が散らばっているかを検知 |
| ATRボラティリティ判定インジケーター(既刊) | 1本ごとの値幅の平均 | 今は値動きが大きい相場かを判定 |
| iBands記事(既刊) | 標準偏差を使ったバンドの位置 | 価格が帯のどこにあるかを可視化 |
よくある質問
iStdDevについて、よくある疑問に回答します。
iStdDevとiATRはどちらを使うべきですか?
目的によって使い分けます。
値幅そのもの(ギャップも含めた動きの大きさ)を見たいならiATR、
終値が移動平均からどれだけ散らばっているかを見たいならiStdDevが向いています。
このインジケーターをEAのフィルターに使えますか?
使えます。
本記事のratio(現在値が普段の何倍か)を計算する部分だけを関数化すれば、
既刊のATRボラティリティフィルターEAと同じ要領でエントリー条件に組み込めます。
InpAvgLookbackはどれくらいの値が適切ですか?
まずは既定値の100本から始め、
チャートを見ながら「普段」の感覚に合うように調整することをおすすめします。
本数を増やすほど基準値は安定しますが、
相場環境の変化への反応は遅くなります。
【MQL4】iStdDevで価格の「散らばり」を可視化し、ボラティリティの急変を検知するインジケーターの作り方:まとめ
iStdDevは、既刊iATR・既刊iBandsのどちらとも計算対象が異なる、
移動平均からの終値の散らばりを直接取得できる関数です。
直近の平均的な標準偏差と比較することで、
「今は普段より価格が散らばっているか」を数値で検知できます。
MQL5では戻り値がハンドルに変わる点に注意し、
CopyBuffer()での値取得とセットで覚えておくと移行時の事故を防げます。
コメント