Stochastic Oscillator in MetaTrader 5 — MQL5 Source Code

A custom slow stochastic with %K and %D for MT5

Stochastic in MetaTrader 5
Stochastic in MetaTrader 5

Building your own stochastic in MQL5 is a good way to learn how MT5 handles range-based indicators — highest highs, lowest lows, and chained smoothing. See the explainer for what we’re drawing.

What you’ll need

  • MetaTrader 5 with MetaEditor
  • Save as AlgoGen.Stochastic.mq5 under MQL5/Indicators/

The source

We compute raw %K, smooth it into slow %K, then average that for %D.

//+------------------------------------------------------------------+
//|                                          AlgoGen.Stochastic.mq5  |
//|                                          Copyright 2026, AlgoGen |
//|                                           https://www.algogen.io |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, AlgoGen"
#property link      "https://www.algogen.io"
#property version   "1.00"
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 3
#property indicator_plots   2

#property indicator_label1  "%K"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_width1  2
#property indicator_label2  "%D"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrOrangeRed
#property indicator_width2  2
#property indicator_level1  20.0
#property indicator_level2  80.0

input int InpK      = 14; // %K length
input int InpSlow   = 3;  // %K smoothing (slow)
input int InpD      = 3;  // %D length

double KBuffer[], DBuffer[], RawK[];

int OnInit()
  {
   SetIndexBuffer(0, KBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, DBuffer, INDICATOR_DATA);
   SetIndexBuffer(2, RawK,    INDICATOR_CALCULATIONS);
   IndicatorSetString(INDICATOR_SHORTNAME,
      StringFormat("AlgoGen Stoch(%d,%d,%d)", InpK, InpSlow, InpD));
   return(INIT_SUCCEEDED);
  }

double SmaOf(const double &buf[], int i, int period)
  {
   double s = 0.0;
   for(int j = 0; j < period; j++) s += buf[i - j];
   return s / period;
  }

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[])
  {
   if(rates_total < InpK + InpSlow + InpD)
      return(0);

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

   // Raw %K.
   for(int i = start; i < rates_total; i++)
     {
      double hh = high[i], ll = low[i];
      for(int j = 1; j < InpK; j++)
        {
         if(high[i - j] > hh) hh = high[i - j];
         if(low[i - j]  < ll) ll = low[i - j];
        }
      double range = hh - ll;
      RawK[i] = (range == 0.0) ? 50.0 : 100.0 * (close[i] - ll) / range;
     }

   // Slow %K = SMA(rawK, InpSlow); %D = SMA(slowK, InpD).
   int s2 = MathMax(start, InpK - 1 + InpSlow - 1);
   for(int i = s2; i < rates_total; i++)
      KBuffer[i] = SmaOf(RawK, i, InpSlow);

   int s3 = MathMax(start, InpK - 1 + InpSlow - 1 + InpD - 1);
   for(int i = s3; i < rates_total; i++)
      DBuffer[i] = SmaOf(KBuffer, i, InpD);

   return(rates_total);
  }
//+------------------------------------------------------------------+

Install & compile

  1. Drop it in MQL5/Indicators/, press F7.
  2. Drag onto a chart — a separate window shows blue %K and orange %D with the 20/80 lines, matching the output chart.

Gotchas

  • Flat-range guard. (range == 0.0) ? 50.0 avoids dividing by zero on a perfectly flat window; 50 (mid-range) is a reasonable neutral fill.
  • Chained warm-up. Each smoothing stage needs its own extra bars, hence the s2/s3 start offsets — get these wrong and you smooth garbage at the left edge.
  • MQL4? Same math; MQL4 also has iStochastic, but rolling your own gives you the exact smoothing control.

Same indicator elsewhere: Python, Pine Script, EasyLanguage, NinjaScript. Then backtest 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. The Origins of the Stochastic Oscillator (CMT Association)
  2. 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