GARCH Stochastic Volatility Forecaster for Scalping
Posted: Mon Aug 10, 2026 3:46 pm
Hey everyone,
If you are scalping the lower timeframes (M1, M5) using traditional volatility indicators like ATR or Bollinger Bands, you've probably noticed a glaring flaw: they are entirely backward-looking. By the time your standard deviation indicator tells you the market is volatile, the move has already happened, and you are buying the absolute top of a breakout before it whipsaws.Institutional quants don't just measure historical volatility; they forecast it. One of the most robust ways to do this is using a GARCH (Generalized Autoregressive Conditional Heteroskedasticity) model. I’ve built a lightweight MT4 indicator that brings this stochastic volatility forecasting to our charts. Here is a breakdown of how it works, how to trade it, and the open-source MQL4 code so you can compile it yourself.
The Core Concept: Why GARCH?
Financial markets exhibit a phenomenon called volatility clustering — calm periods tend to be followed by calm periods, and violent price swings tend to trigger more violent price swings. The GARCH(1,1) model captures this perfectly. Instead of just taking a simple average of the last 14 candles like an ATR, GARCH calculates the conditional variance of the current candle based on three distinct factors:$$GARCH(1,1): \sigma_t^2 = \omega + \alpha \epsilon_{t-1}^2 + \beta \sigma_{t-1}^2$$$\omega$ (Omega): The baseline, long-term variance floor. $\alpha$ (Alpha): The "shock" sensitivity. This dictates how aggressively the model reacts to yesterday's price spike.$\beta$ (Beta): The volatility persistence. This dictates how long the "echo" of a volatile event lasts in the market.(Note: For the math to stay stable, Alpha + Beta must be less than 1).
How to Apply It in Scalping
Because GARCH is highly responsive to recent shocks while remembering historical persistence, it’s an incredible filter for scalpers: Filtering the "Dead Zone": Don't take breakout trades when the GARCH line is flat and resting at its baseline (Omega). The market lacks the underlying energy to sustain a move.Catching the Expansion: The golden setup is when price compresses into a tight range, but your GARCH line begins to tick upward sharply. This indicates a "shock" has entered the order flow, and volatility is expanding.Dynamic Position Sizing: This is the real secret. When the GARCH value is high, reduce your lot size. When the GARCH value is low, increase your lot size. This targets a constant risk profile across all trades, preventing high-volatility chop from blowing your daily drawdown limit.
The MT4 Code (MQL4)
Here is the source code. Open your MetaEditor, create a new Custom Indicator, paste this in, and compile.
Parameter Tuning Tips
Out of the box, Alpha = 0.08 and Beta = 0.90 are highly standard parameters for equity and forex markets.
If you find the indicator is too noisy during M1 scalping, try increasing Beta (e.g., 0.94) and lowering Alpha (e.g., 0.04) to force the model to respect historical persistence more than sudden ticks.
If you want it to react lightning-fast to breakouts, do the reverse.
Drop it on your charts alongside your normal setup and watch how the curve anticipates the consolidation/expansion cycles. Let me know what you guys think or if you need help tweaking the logic!
If you are scalping the lower timeframes (M1, M5) using traditional volatility indicators like ATR or Bollinger Bands, you've probably noticed a glaring flaw: they are entirely backward-looking. By the time your standard deviation indicator tells you the market is volatile, the move has already happened, and you are buying the absolute top of a breakout before it whipsaws.Institutional quants don't just measure historical volatility; they forecast it. One of the most robust ways to do this is using a GARCH (Generalized Autoregressive Conditional Heteroskedasticity) model. I’ve built a lightweight MT4 indicator that brings this stochastic volatility forecasting to our charts. Here is a breakdown of how it works, how to trade it, and the open-source MQL4 code so you can compile it yourself.
The Core Concept: Why GARCH?
Financial markets exhibit a phenomenon called volatility clustering — calm periods tend to be followed by calm periods, and violent price swings tend to trigger more violent price swings. The GARCH(1,1) model captures this perfectly. Instead of just taking a simple average of the last 14 candles like an ATR, GARCH calculates the conditional variance of the current candle based on three distinct factors:$$GARCH(1,1): \sigma_t^2 = \omega + \alpha \epsilon_{t-1}^2 + \beta \sigma_{t-1}^2$$$\omega$ (Omega): The baseline, long-term variance floor. $\alpha$ (Alpha): The "shock" sensitivity. This dictates how aggressively the model reacts to yesterday's price spike.$\beta$ (Beta): The volatility persistence. This dictates how long the "echo" of a volatile event lasts in the market.(Note: For the math to stay stable, Alpha + Beta must be less than 1).
How to Apply It in Scalping
Because GARCH is highly responsive to recent shocks while remembering historical persistence, it’s an incredible filter for scalpers: Filtering the "Dead Zone": Don't take breakout trades when the GARCH line is flat and resting at its baseline (Omega). The market lacks the underlying energy to sustain a move.Catching the Expansion: The golden setup is when price compresses into a tight range, but your GARCH line begins to tick upward sharply. This indicates a "shock" has entered the order flow, and volatility is expanding.Dynamic Position Sizing: This is the real secret. When the GARCH value is high, reduce your lot size. When the GARCH value is low, increase your lot size. This targets a constant risk profile across all trades, preventing high-volatility chop from blowing your daily drawdown limit.
The MT4 Code (MQL4)
Here is the source code. Open your MetaEditor, create a new Custom Indicator, paste this in, and compile.
Code: Select all
//+------------------------------------------------------------------+
//| GARCH_Forecaster.mq4 |
//| |
//+------------------------------------------------------------------+
#property copyright "Open Source Trading Community"
#property link ""
#property version "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 clrDodgerBlue
#property indicator_width1 2
//--- Inputs for GARCH(1,1) parameters
input double InpOmega = 0.000005; // Baseline Volatility (Omega)
input double InpAlpha = 0.08; // Shock Reaction (Alpha)
input double InpBeta = 0.90; // Volatility Persistence (Beta)
//--- Indicator buffer
double GarchBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, GarchBuffer);
SetIndexStyle(0, DRAW_LINE);
IndicatorShortName("GARCH(1,1) ("+DoubleToStr(InpAlpha,2)+","+DoubleToStr(InpBeta,2)+")");
if(InpAlpha + InpBeta >= 1.0)
Print("Warning: Alpha + Beta should be < 1 for a stationary model.");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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 limit;
// Determine how many bars need to be calculated
if(prev_calculated == 0)
{
limit = rates_total - 2;
GarchBuffer[rates_total-1] = 0.0; // Seed the oldest bar
}
else
{
limit = rates_total - prev_calculated;
}
// Standard MT4 loop (calculating from oldest to newest bar)
for(int i = limit; i >= 0; i--)
{
// 1. Calculate the recent shock (percentage return)
double ret = (close[i] - close[i+1]) / close[i+1];
double shock2 = ret * ret; // epsilon squared
// 2. Fetch the previous variance
double prev_var = GarchBuffer[i+1] * GarchBuffer[i+1];
// 3. Apply the GARCH(1,1) formula
double current_var = InpOmega + (InpAlpha * shock2) + (InpBeta * prev_var);
// 4. Store standard deviation (volatility) in the buffer for plotting
GarchBuffer[i] = MathSqrt(current_var);
}
return(rates_total);
}
//+------------------------------------------------------------------+Out of the box, Alpha = 0.08 and Beta = 0.90 are highly standard parameters for equity and forex markets.
If you find the indicator is too noisy during M1 scalping, try increasing Beta (e.g., 0.94) and lowering Alpha (e.g., 0.04) to force the model to respect historical persistence more than sudden ticks.
If you want it to react lightning-fast to breakouts, do the reverse.
Drop it on your charts alongside your normal setup and watch how the curve anticipates the consolidation/expansion cycles. Let me know what you guys think or if you need help tweaking the logic!