This repository implements a high-frequency statistical arbitrage strategy tailored for the Old School RuneScape (OSRS) Grand Exchange. It focuses on the cointegrated relationship between Ranarr Weed (raw material) and Prayer Potion(3) (finished product).
The strategy utilizes a Kalman Filter to dynamically estimate hedge ratios and a Regularized Rolling Optimizer to solve for the optimal entry threshold that maximizes expected PnL in the presence of significant transaction costs (1% tax).
(Figure 1: Net Equity Curve demonstrating strategy performance after transaction costs)
In OSRS, "Herblore" is a production skill where players process raw herbs into potions. The price relationship between Ranarr Weed (
- Production Chain: Weed is the primary input for Potion.
- No Arbitrage Bounds: If the spread diverges significantly (e.g., Potion becomes too expensive relative to Weed), players will process more herbs, increasing supply and forcing mean reversion. Conversely, if Potions are too cheap, production halts, restricting supply.
-
Cointegration: While individual prices follow random walks, their linear combination (the spread) is stationary:
$$\ln(P_{weed, t}) - \gamma_t \ln(P_{pot, t}) \sim \mathcal{N}(0, \sigma^2)$$
We treat the hedge ratio
-
State:
$x_t = [\mu_t, \gamma_t, \dot{\gamma}_t]^T$ -
Observation:
$y_t = \ln(P_{weed, t}) - (\mu_t + \gamma_t \ln(P_{pot, t}))$
A critical challenge in OSRS is the 1% tax on sell orders, resulting in a significant round-trip cost (
This project implements a Regularized Profit Maximization algorithm. At each step, we solve for the threshold
Step A: Empirical Crossing Rate
We define a grid of candidate Z-score thresholds
This counts how often the spread crosses the threshold
Step B: Tikhonov Regularization
Raw crossing counts
Where
Step C: Objective Function
We select the optimal threshold
If
(Figure 2: Visualizing entry/exit points relative to the dynamic cost-adjusted bands)
Data is sourced from the OSRS Wiki Realtime API. The src/data_collection.py module handles:
- Rate Limiting: Respects API etiquette.
- Alignment: Synchronizes disparate 5-minute buckets for both assets.
- Forward Filling: Implements strict forward-filling for prices (last known price) while zero-filling volume to preserve market reality.