Skip to content
← All work

03 · Volatility forecasting · Quant

SA Bank Quantile Volatility

Distributional forecasts of 5-day realized volatility for six JSE banking groups. A band, not a point, scored with pinball loss and coverage.

JSE banks: SBK, FSR, ABG, NED, CPI, INL
6
Quantiles forecast
q10 · q50 · q90
Horizon, annualized RV
5d
Target interval coverage
80%

Pinball loss, the scoring rule behind every forecast

Drag τ. This is the loss function from the repo's methodology, plotted exactly. No model output.

Lτ(y, q) = max(τ(y − q), (τ − 1)(y − q)). At τ = 0.90, under-forecasting volatility costs 9.0x as much as over-forecasting by the same amount.

Problem

A risk team does not need to know whether Standard Bank goes up tomorrow. It needs the range of volatility it could face next week, and whether that range is honest. A single average forecast hides the tail.

Approach

  1. 01Target is the sample standard deviation of the next 5 daily log returns, times √252. Forward-looking, so the model learns from today's information only.
  2. 02Gradient boosting with loss="quantile" fits q0.10, q0.50 and q0.90 separately. A constant-quantile dummy is the baseline every model has to beat.
  3. 03Walk-forward expanding windows. No random splits, because random splits leak the future into a time series.
  4. 04Model v1 uses short lags and 5/10-day rolling vol. Model v2 adds lags 1 to 10, 21 and 63-day windows, absolute-return lags for volatility clustering, and a 5/63 vol ratio. The dashboard reports v2's lift over v1 in median pinball loss.

Results

A FastAPI service with /forecast, /evaluation, /series and /leaderboard endpoints, and a React dashboard that ranks the six banks by how much Model v2 beat Model v1.

Metrics are computed live from Yahoo data on each run, so the repo does not commit a fixed results table. I am not quoting a number here that you cannot reproduce from the code.

Next

Commit a dated evaluation snapshot, add a GARCH baseline next to the dummy, and test conformal calibration on the q10 to q90 band.