Statistical Arbitrage Engine:
Decoding the JSE Banking Sector

This project is a statistical arbitrage engine designed to trade the relationship between two of South Africa’s largest financial institutions: Standard Bank and Nedbank. Rather than relying on simple price averages, this system uses advanced probabilistic modeling to understand market regimes, map extreme tail risks, and dynamically manage capital.

Category

Quantitative Finance /
Systematic Trading

Language

R

Start Date

May 30, 2026

Designer

Sbusiso Mdingi

Interactive Out-of-Sample Dashboard

This quantitative trading dashboard presents the real-world, out-of-sample performance of a complex pair-trading strategy. It tracks the dynamic relationship between Standard Bank (SBK.JO) and Nedbank (NED.JO).

The dashboard moves beyond standard financial charts. It provides a window into an algorithmic engine that continuously reads the market’s “temperature.” By isolating moments when the two banks structurally disconnect from each other, the system generates precise trading signals while automatically displaying risk-adjusted metrics like Maximum Drawdown, Calmar Ratio, and Hit Rate.

THE STORY

Traditional pairs trading is a well-known concept: find two stocks that usually move together, wait for them to drift apart, and bet that they’ll eventually reconnect. The problem? In the real world, standard correlation often breaks down exactly when you need it most—during market crashes or sudden volatility spikes. When the market panics, traditional models tend to blow up.

I wanted to build a statistical arbitrage framework for the South African market that doesn't just look at historical averages, but actually understands the environment it is trading in. My goal was to build a system that knows the difference between a temporary pricing anomaly and a fundamental market shift.

I developed a computationally heavy research environment to map this out using decades of JSE data. To make the results accessible, I extracted the core inference engine into this clean, interactive dashboard. It serves as a transparent look at how the strategy performs strictly out-of-sample, proving its resilience outside of the theoretical lab.

MY APPROACH

Building this engine required stripping away the traditional, overly simplistic ways of looking at market data.

  • Filtering the Noise: Raw market data is messy and carries a lot of echo. Before the system even looks for a trade, it passes the data through an econometric filter to strip away standard autocorrelations, leaving behind only the true, underlying volatility.
  • Reading the Market Weather: Markets behave differently in calm periods versus chaotic ones. Instead of treating all data equally, the engine uses Markov-Switching models to detect which "regime" the market is currently in, adjusting its expectations for volatility on the fly.
  • Mapping the Connection: To understand how the two banks interact, especially during extreme tail events, the system utilizes Bivariate Vine Copulas. This allows the engine to accurately measure the strength of the relationship even when standard correlation completely falls apart.
  • Knowing When to Step Away: The secret to surviving algorithmic trading isn't just knowing when to trade; it’s knowing when not to. I integrated a dynamic volatility filter that acts as the system's defense mechanism, flattening positions and preserving capital when market instability breaches critical thresholds.

The final piece of the puzzle was proving it works. A good strategy shouldn't just look flawless in hindsight. By firmly freezing the model's parameters and testing it strictly on unseen future data, the dashboard reflects honest, robust performance—demonstrating a system that successfully navigates the realities of the JSE.

TECHNICAL STACK

Econometric Modeling:
ARMA Pre-whitening, Markov-Switching GARCH (MS-GARCH), Bivariate Vine Copulas, Regime Detection.

Risk & Execution:
Walk-forward Backtesting, Hysteresis Logic, Dynamic Volatility Filtering.

R Ecosystem:
MSGARCH, VineCopula, rugarch, Shiny, quantmod.