Standard Deviation in MetaTrader (MQL5) — Full Indicator Source

The built-in iStdDev and a from-scratch version

Standard Deviation in MetaTrader MQL5
Standard Deviation in MetaTrader MQL5

MetaTrader 5 ships a Standard Deviation indicator, and MQL5 exposes it through iStdDev, so the canonical version is a handle and a copy. The from-scratch version shows the population-std math. See the explainer.

What you’ll need

  • MetaTrader 5 and the MetaEditor
  • A new Custom Indicator, plotted in a separate window.

The built-in

int stddevHandle;

int OnInit()
{
    // period, shift, MA method, applied price
    stddevHandle = iStdDev(_Symbol, _Period, 20, 0, MODE_SMA, PRICE_CLOSE);
    return(stddevHandle == INVALID_HANDLE ? INIT_FAILED : INIT_SUCCEEDED);
}

Then copy the buffer in OnCalculate with CopyBuffer(stddevHandle, 0, 0, rates_total, StdDevBuffer). MT5’s iStdDev uses the population formula (divide by N), matching Bollinger Bands.

From scratch

If you want the math in your own hands (and to prove what iStdDev does):

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_label1  "StdDev"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrOrange
#property indicator_width1  2

input int InpPeriod = 20;   // period

double StdDevBuffer[];

int OnInit()
{
    SetIndexBuffer(0, StdDevBuffer, INDICATOR_DATA);
    return(INIT_SUCCEEDED);
}

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
    if(rates_total < InpPeriod) return(0);

    int start = (prev_calculated > 0) ? prev_calculated - 1 : InpPeriod - 1;

    for(int i = start; i < rates_total; i++)
    {
        // 1. mean of the last N prices
        double sum = 0.0;
        for(int k = 0; k < InpPeriod; k++)
            sum += price[i - k];
        double mean = sum / InpPeriod;

        // 2. average squared deviation (population: divide by N)
        double sq = 0.0;
        for(int k = 0; k < InpPeriod; k++)
        {
            double d = price[i - k] - mean;
            sq += d * d;
        }
        StdDevBuffer[i] = MathSqrt(sq / InpPeriod);   // <-- N, not N-1
    }
    return(rates_total);
}

The inner loops compute the mean, then the average of the squared distances from it, then the square root — the same line the built-in draws.

Gotchas

  • Divide by N, not N−1. iStdDev and Bollinger Bands use the population formula. The from-scratch loop above divides sq by InpPeriod; don’t “fix” it to N-1.
  • applied price. The built-in defaults to PRICE_CLOSE; pass a different applied price if you want std of typical price, etc.
  • MODE_SMA. iStdDev lets you pick the averaging method for the mean; SMA is the standard, and what matches the textbook definition.
  • Separate window. Standard deviation is in price units but is a magnitude, not a price level — plot it below, not on the chart.

Same indicator elsewhere: Python, Pine Script, EasyLanguage, NinjaScript. Then test it in AlgoGen.


This post is educational, not financial advice. Indicators describe the past; they don’t predict the future. Backtest anything before you risk real money on it.

Sources and further reading

  1. Technical indicator functions (MetaQuotes)

Historical research from the Algogen archive. Not investment advice.

Blog

Have a strategy idea?

Describe it in plain English, preview where your rules fire, then decide whether the evidence is worth a backtest.

Keep me postedHow it works