Implementation of the Hausdorff-Adaptive Filter (HAF) algorithm from the paper:
"Robust Online Learning in Non-Stationary Markets: A Credal Set Approach with Uncertainty Quantification"
This implementation is publication-ready and reproduces key paper results:
# Reproduce Tables 1-3 with statistical validation
python reproduce_paper.py✅ Includes:
- All baseline methods (BOCPD, HMM, RMV, BOL)
- Bootstrap confidence intervals
- Statistical significance tests (p-values)
- Negative results (high-SNR environments)
See REPRODUCTION.md for detailed reproduction guide.
HAF is an online learning algorithm designed for regime detection and adaptive decision-making in non-stationary environments (especially financial markets). It uses credal sets (convex sets of probability distributions) to quantify epistemic uncertainty and detect regime changes through contraction ratio monitoring.
- Epistemic Uncertainty Quantification: Uses credal sets to distinguish between uncertainty due to lack of data vs. inherent randomness
- Automatic Regime Detection: Monitors Hausdorff contraction ratios to detect regime shifts without manual tuning
- Principled Risk Management: Automatically scales positions based on credal set diameter (epistemic uncertainty)
- Theoretical Guarantees: Geometric convergence in stable regimes, probabilistic regime detection bounds
In stable market regimes, credal sets contract geometrically toward a fixed point. When a regime shift occurs, this contractivity breaks down - the credal set expands rather than contracts, providing an early warning signal.
# Clone the repository
git clone https://github.com/yourusername/haf-implementation.git
cd haf-implementation
# Install dependencies
pip install -r requirements.txt
# Optional: For real data experiments
pip install yfinancefrom haf_core import HausdorffAdaptiveFilter
import numpy as np
# Initialize HAF
haf = HausdorffAdaptiveFilter(
n_assets=1,
rho_thresh=0.95, # Stable regime threshold
rho_reset=1.2, # Regime shift threshold
window=10 # Moving average window
)
# Online learning loop
for observation in market_data:
# Update with new observation
regime, position_scale = haf.update(observation)
# Get recommended action (portfolio weights)
action = haf.get_action()
# Scale position based on uncertainty
final_position = action * position_scale
# Get monitoring metrics
metrics = haf.get_metrics()
print(f"Regime: {regime}, Uncertainty: {metrics['diameter']:.4f}")# Run complete reproduction suite
python reproduce_paper.py
# Run basic demo
python demo.py
# Run tests
pytest tests/ -vhaf-implementation/
├── README.md # This file
├── REPRODUCTION.md # Paper reproduction guide (NEW)
├── requirements.txt # Dependencies
├── haf_core.py # Core HAF implementation
├── baselines.py # Baseline methods (BOCPD, HMM, RMV, BOL) (NEW)
├── statistical_utils.py # Bootstrap CI, p-values (NEW)
├── data_loader.py # Data loading utilities (NEW)
├── reproduce_paper.py # Paper reproduction script (NEW)
├── demo.py # Basic demo
├── tests/
│ └── test_haf.py # Unit tests
├── examples/
│ └── multi_asset_example.py # Multi-asset portfolio example
└── docs/
├── QUICK_START.md # Quick start guide
├── USAGE_EXAMPLES.md # Usage examples
├── PROJECT_STRUCTURE.md # Code organization
└── TEST_DOCUMENTATION.md # Test documentation
Represents a convex set of probability distributions through K extreme distributions (typically K=3):
- Bull regime: Positive mean, low volatility
- Bear regime: Negative mean, high volatility
- Neutral regime: Zero mean, medium volatility
credal_set = CredalSet([bull_dist, bear_dist, neutral_dist])
diameter = credal_set.diameter() # Epistemic uncertainty measureThe Hausdorff metric measures the "distance" between two credal sets:
d_H = credal_set_t.hausdorff_distance(credal_set_{t-1})The key signal for regime detection:
ρ_t = d_H(P_t, P_{t-1}) / d_H(P_{t-1}, P_{t-2})
- ρ < 1: Contracting (stable regime)
- ρ ≈ 1: Uncertain
- ρ > 1.2: Expanding (regime shift detected!)
Choose actions that maximize worst-case expected utility across all distributions in the credal set:
action = argmax_a min_{P ∈ credal_set} E_P[utility(a)]| Parameter | Default | Description |
|---|---|---|
rho_thresh |
0.95 | Threshold for identifying stable regimes |
rho_reset |
1.2 | Threshold for detecting regime shifts |
window |
10 | Moving average window for ρ smoothing |
safety_factor |
0.3 | Position scaling during detected regime shifts |
In stable regimes, credal sets converge geometrically:
E[d_H(P_t, P*)] ≤ d_H(P_0, P*) · τ^t
where τ < 1 is the contraction rate.
When a regime shift occurs with separation Δ:
P(ρ_t ≥ 1 + δ) ≥ 1 - exp(-c·n·Δ²/σ²)
Larger regime changes are detected with higher probability.
Cumulative regret is controlled by epistemic uncertainty:
R_T ≤ U_max · d_H(P_0, {P*}) · (1-τ^T)/(1-τ)
Recommended for:
- Non-stationary environments with regime shifts
- Need for interpretable uncertainty quantification
- Moderate transaction costs (< 10 basis points)
- Daily or lower frequency rebalancing
May not help when:
- Extended stable regimes with high signal-to-noise
- Very high transaction costs (> 20 bps)
- High-frequency trading requirements
The paper suggests several extensions:
- Decompose epistemic vs. aleatoric uncertainty formally
- Incorporate transaction costs into theoretical guarantees
- Scale to high dimensions via factor models
- Applications beyond finance: robotics, healthcare, recommendation systems
If you use this implementation, please cite:
MIT License - see LICENSE file for details
Contributions are welcome! Please feel free to submit a Pull Request.
For questions or issues, please open an GitHub issue or contact the maintainer.
Note: This is a research implementation for educational purposes. Not intended for production trading without proper risk management and validation.