OBV is a great “first cumulative indicator” in MQL5 — each bar just adds or subtracts from the previous value. See the explainer for the rule.
What you’ll need
- MetaTrader 5 with MetaEditor
- Save as
AlgoGen.OBV.mq5underMQL5/Indicators/
The source
//+------------------------------------------------------------------+
//| AlgoGen.OBV.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_buffers 1
#property indicator_plots 1
#property indicator_label1 "OBV"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrMediumSeaGreen
#property indicator_width1 2
input bool InpUseRealVolume = false; // Use real volume (else tick volume)
double OBVBuffer[];
int OnInit()
{
SetIndexBuffer(0, OBVBuffer, INDICATOR_DATA);
IndicatorSetString(INDICATOR_SHORTNAME, "AlgoGen OBV");
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[])
{
if(rates_total < 2)
return(0);
int start;
if(prev_calculated == 0)
{
OBVBuffer[0] = 0.0;
start = 1;
}
else
start = prev_calculated - 1;
for(int i = start; i < rates_total; i++)
{
double vol = InpUseRealVolume ? (double)volume[i] : (double)tick_volume[i];
if(close[i] > close[i - 1])
OBVBuffer[i] = OBVBuffer[i - 1] + vol;
else if(close[i] < close[i - 1])
OBVBuffer[i] = OBVBuffer[i - 1] - vol;
else
OBVBuffer[i] = OBVBuffer[i - 1];
}
return(rates_total);
}
//+------------------------------------------------------------------+
Install & compile
- Drop it in
MQL5/Indicators/, press F7. - Drag onto a chart — a separate window shows the cumulative OBV line, matching the output chart.
Gotchas
- Tick volume vs real volume. Most retail forex feeds only provide tick
volume (number of price changes), not true traded volume. The
InpUseRealVolumeswitch lets you choose; on FX you’ll usually be stuck with tick volume, which is a proxy, not the real thing — interpret accordingly. - Incremental recompute. Restarting at
prev_calculated - 1re-runs only the latest bar each tick; the cumulative nature means you must never recompute from the wrong start or the whole line shifts. - MQL4? Same logic; MQL4 also has a built-in
iOBV. The custom version makes the volume-source choice explicit. - Add a signal line. OBV’s raw level is arbitrary, so in an Expert Advisor
you’ll usually compare it to a moving average of itself. Add a second buffer and
fill it with
iMAOnArray(OBVBuffer, ...)(or a manual SMA loop) to get a crossover trigger rather than trading the bare line. - Chart scale. Because OBV grows without bound, MT5 auto-scales the sub-window; don’t be alarmed by huge axis numbers — only the shape matters.
Reading the plotted line
Drop an SMA of the OBV buffer on top and watch two things: whether OBV is trending the same direction as price (confirmation), and whether it’s diverging (OBV sliding while price holds up, or vice versa). Those are the two reads that make OBV worth the sub-window it occupies.
Same indicator elsewhere: Python, Pine Script, EasyLanguage, NinjaScript. Then test an OBV filter 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
- New Key to Stock Market Profits (Google Books)
- Technical indicator functions (MetaQuotes)
