project

Bayesian Market Filters

resultOut of sample Sharpe near 0.7 after fees.

Estimating hidden state in noisy market data, then testing whether that estimate survives fees and a clean split.

status: completeresult: out of samplescope: single asset and one pairconfidence: medium

Problem

Estimating hidden state, fair value, regime, and volatility in noisy market data, and testing whether it produces a tradeable edge without fooling myself.

Approach

Adaptive Kalman filter with Robbins Monro online noise estimation; a 2 state HMM regime detector via Baum Welch; a stochastic volatility particle filter with SIR resampling; and a cointegration Kalman filter for BTC versus ETH pairs.

Verified against synthetic OU ground truth with 12 unit tests. Evaluated on one year of hourly data with a strict 50/50 in sample and out of sample split and realistic 1.5 bps maker fees. Data is frozen and committed for exact reproducibility.

What I tried that failed

An early version reported an implausibly high Sharpe. I traced it to methodology artifacts and corrected it, which is why the reported number is modest.

Separately, the BTC versus ETH pairs strategy is cointegrated, confirmed by Augmented Dickey Fuller tests, but loses money out of sample because the spread is too tight and fee drag exceeds the edge.

I diagnosed the cause, a hardcoded noise scale that suppressed the z score, and fixed the filter with adaptive estimation. It still loses money, and I report that rather than tuning until it looks green.

Finding

The alpha threshold execution strategy held a positive out of sample Sharpe near 0.71 after fees; the pairs extension is a documented negative result.

The point of the project is a believable number, not a large one.

How to reproduce

Data is frozen and committed in the repository. The README gives the exact split and fee assumptions.