regimelab 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. regimelab-0.1.0/.gitignore +17 -0
  2. regimelab-0.1.0/LICENSE +21 -0
  3. regimelab-0.1.0/PKG-INFO +254 -0
  4. regimelab-0.1.0/README.md +213 -0
  5. regimelab-0.1.0/pyproject.toml +179 -0
  6. regimelab-0.1.0/src/regimelab/__init__.py +24 -0
  7. regimelab-0.1.0/src/regimelab/__main__.py +8 -0
  8. regimelab-0.1.0/src/regimelab/backtest/__init__.py +37 -0
  9. regimelab-0.1.0/src/regimelab/backtest/engine.py +365 -0
  10. regimelab-0.1.0/src/regimelab/backtest/metrics.py +345 -0
  11. regimelab-0.1.0/src/regimelab/backtest/walkforward.py +273 -0
  12. regimelab-0.1.0/src/regimelab/cli.py +195 -0
  13. regimelab-0.1.0/src/regimelab/data/__init__.py +22 -0
  14. regimelab-0.1.0/src/regimelab/data/alignment.py +396 -0
  15. regimelab-0.1.0/src/regimelab/data/fetcher.py +289 -0
  16. regimelab-0.1.0/src/regimelab/data/providers/__init__.py +75 -0
  17. regimelab-0.1.0/src/regimelab/data/providers/base.py +227 -0
  18. regimelab-0.1.0/src/regimelab/data/providers/parquet.py +150 -0
  19. regimelab-0.1.0/src/regimelab/data/providers/synthetic.py +261 -0
  20. regimelab-0.1.0/src/regimelab/data/providers/yahoo.py +152 -0
  21. regimelab-0.1.0/src/regimelab/features/__init__.py +217 -0
  22. regimelab-0.1.0/src/regimelab/features/_rolling.py +227 -0
  23. regimelab-0.1.0/src/regimelab/features/absorption.py +248 -0
  24. regimelab-0.1.0/src/regimelab/features/breadth.py +189 -0
  25. regimelab-0.1.0/src/regimelab/features/correlation.py +222 -0
  26. regimelab-0.1.0/src/regimelab/features/volatility.py +275 -0
  27. regimelab-0.1.0/src/regimelab/models/__init__.py +66 -0
  28. regimelab-0.1.0/src/regimelab/models/base.py +512 -0
  29. regimelab-0.1.0/src/regimelab/models/filters.py +283 -0
  30. regimelab-0.1.0/src/regimelab/models/gmm.py +150 -0
  31. regimelab-0.1.0/src/regimelab/models/hamilton.py +255 -0
  32. regimelab-0.1.0/src/regimelab/models/hmm.py +208 -0
  33. regimelab-0.1.0/src/regimelab/models/labeling.py +354 -0
  34. regimelab-0.1.0/src/regimelab/models/registry.py +57 -0
  35. regimelab-0.1.0/src/regimelab/models/types.py +351 -0
  36. regimelab-0.1.0/src/regimelab/pipeline.py +250 -0
  37. regimelab-0.1.0/src/regimelab/py.typed +0 -0
  38. regimelab-0.1.0/src/regimelab/report/__init__.py +12 -0
  39. regimelab-0.1.0/src/regimelab/report/html.py +380 -0
  40. regimelab-0.1.0/src/regimelab/settings.py +345 -0
  41. regimelab-0.1.0/src/regimelab/store.py +264 -0
  42. regimelab-0.1.0/src/regimelab/tui/__init__.py +39 -0
  43. regimelab-0.1.0/src/regimelab/tui/app.py +105 -0
  44. regimelab-0.1.0/tests/__init__.py +1 -0
  45. regimelab-0.1.0/tests/conftest.py +56 -0
  46. regimelab-0.1.0/tests/test_backtest.py +118 -0
  47. regimelab-0.1.0/tests/test_causality.py +148 -0
@@ -0,0 +1,17 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+
12
+ # Runtime artifacts
13
+ .artifacts/
14
+ .test-artifacts/
15
+ *.html
16
+ scratch_*.py
17
+ regimelab_test.toml
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AlgorithmicMind
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,254 @@
1
+ Metadata-Version: 2.5
2
+ Name: regimelab
3
+ Version: 0.1.0
4
+ Summary: Institutional market-regime detection engine: HMM/Hamilton regime switching, PCA absorption ratio, VIX term structure, point-in-time backtesting and automated reporting.
5
+ Project-URL: Homepage, https://github.com/AlgorithmicMind/regimelab
6
+ Project-URL: Repository, https://github.com/AlgorithmicMind/regimelab
7
+ Project-URL: Issues, https://github.com/AlgorithmicMind/regimelab/issues
8
+ Author-email: AlgorithmicMind <tonidinero27@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: absorption-ratio,backtesting,hidden-markov-model,point-in-time,quantitative-finance,regime-detection,systemic-risk
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Financial and Insurance Industry
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Office/Business :: Financial :: Investment
21
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.12
24
+ Requires-Dist: hmmlearn>=0.3.3
25
+ Requires-Dist: numpy>=2.5.2
26
+ Requires-Dist: pandas>=3.0.5
27
+ Requires-Dist: platformdirs>=4.11.5
28
+ Requires-Dist: plotly>=6.0.0
29
+ Requires-Dist: pyarrow>=25.0.1
30
+ Requires-Dist: pydantic-settings>=2.15.0
31
+ Requires-Dist: pydantic>=2.13.5
32
+ Requires-Dist: rich>=15.0.0
33
+ Requires-Dist: scikit-learn>=1.9.0
34
+ Requires-Dist: scipy>=1.18.1
35
+ Requires-Dist: statsmodels>=0.15.0
36
+ Requires-Dist: typer>=0.27.2
37
+ Requires-Dist: yfinance>=1.7.0
38
+ Provides-Extra: tui
39
+ Requires-Dist: textual>=8.2.8; extra == 'tui'
40
+ Description-Content-Type: text/markdown
41
+
42
+ <div align="center">
43
+
44
+ # 🏛️ RegimeLab
45
+
46
+ **Institutional-grade market regime detection, systemic risk telemetry, and walk-forward asset allocation engine in Python.**
47
+
48
+ [![PyPI version](https://img.shields.io/pypi/v/regimelab.svg?color=blue)](https://pypi.org/project/regimelab/)
49
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
50
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
51
+ [![Type Checked with mypy](https://img.shields.io/badge/mypy-strict-blue)](https://mypy-lang.org/)
52
+ [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
53
+
54
+ </div>
55
+
56
+ ---
57
+
58
+ ## ⚡ Why RegimeLab?
59
+
60
+ Most open-source regime detection scripts fit a Hidden Markov Model (HMM) on the entire in-sample dataset and claim predictive power. In production quantitative finance, this fails due to three fatal flaws:
61
+
62
+ 1. **Look-Ahead Bias:** Training filters without strict point-in-time (`asof`) truncation leaks future distribution moments into past states.
63
+ 2. **Label Switching:** HMM/GMM state indices are mathematically interchangeable between refits. Without canonical sorting, "State 0" randomly alternates between Bull and Bear across rolling windows.
64
+ 3. **Calendar Desynchronization:** Multi-asset cross-sections suffer from holiday mismatches, halted assets, and survivorship bias.
65
+
66
+ **RegimeLab** solves these operational hurdles, providing a turnkey, causal quantitative engine for systematic asset allocation and macro risk monitoring.
67
+
68
+ ---
69
+
70
+ ### 📊 Feature Matrix: Raw Tooling vs. RegimeLab
71
+
72
+ | Challenge | Raw `hmmlearn` / `statsmodels` | RegimeLab Framework |
73
+ | :--- | :--- | :--- |
74
+ | **State Labeling** | Unordered integer states (permutes on refit) | **Deterministic Canonical Sorting** ($\frac{\mu}{\sigma}$ / conditional vol ordering) |
75
+ | **Temporal Clock** | In-sample full-sample fitting (Look-ahead) | **Strict Point-in-Time (`asof`) cursor** & expanding-window walk-forward |
76
+ | **Systemic Risk** | None | **Kritzman Absorption Ratio (PCA)**, VIX Term Spread & Sector Breadth |
77
+ | **Execution Reality** | Pure theoretical classification | **Walk-Forward Backtester** with transaction costs (bps) and confidence floors |
78
+ | **Data Ingestion** | Expects clean 2D NumPy array | **Multi-Asset PIT Alignment**, staleness budgets, synthetic & Parquet providers |
79
+ | **Reporting** | Matplotlib static plot | **Interactive Plotly HTML reports** + Textual TUI Terminal Dashboard |
80
+
81
+ ---
82
+
83
+ ## 🚀 Quickstart
84
+
85
+ ### 1. Installation
86
+
87
+ ```bash
88
+ # Install from PyPI
89
+ pip install regimelab
90
+
91
+ # Or install with interactive TUI support
92
+ pip install "regimelab[tui]"
93
+ ```
94
+
95
+ ### 2. Python API Usage
96
+
97
+ #### Current Market Regime Detection (3 lines)
98
+
99
+ ```python
100
+ from regimelab import Settings
101
+ from regimelab.pipeline import run_single_asof
102
+
103
+ # Run point-in-time regime inference for any historical or current date
104
+ settings = Settings(data={"provider": "yfinance"})
105
+ payload = run_single_asof(settings, asof="2024-12-31")
106
+
107
+ print(f"Detected Regime: {payload.regime.value}")
108
+ print(f"Confidence: {payload.probabilities.confidence:.2%}")
109
+ print(f"Target Allocation: {payload.target_weights.weights if payload.target_weights else {}}")
110
+ ```
111
+
112
+ #### Extract Causal Systemic Risk Features
113
+
114
+ ```python
115
+ from regimelab import Settings
116
+ from regimelab.data.fetcher import load_aligned_panel
117
+ from regimelab.features import build_feature_matrix
118
+
119
+ settings = Settings(data={"provider": "yfinance"})
120
+ panel = load_aligned_panel(settings)
121
+ features = build_feature_matrix(panel, settings)
122
+
123
+ # Inspect causal feature matrix
124
+ print(features[["absorption_ratio", "absorption_delta", "vix_term_spread", "breadth"]].tail())
125
+ ```
126
+
127
+ #### Walk-Forward Backtesting Engine
128
+
129
+ ```python
130
+ from regimelab import Settings
131
+ from regimelab.pipeline import run_pipeline
132
+
133
+ settings = Settings(
134
+ data={"provider": "synthetic"}, # Fully offline, reproducible dataset
135
+ model={"classifier": "hmm", "n_states": 4},
136
+ backtest={"transaction_cost_bps": 5.0, "confidence_floor": 0.5},
137
+ )
138
+
139
+ result = run_pipeline(settings, command="backtest_run")
140
+ metrics = result.backtest.metrics
141
+
142
+ print(f"Strategy CAGR: {metrics.cagr:.2%}")
143
+ print(f"Sharpe Ratio: {metrics.sharpe:.2f}")
144
+ print(f"Max Drawdown: {metrics.max_drawdown:.2%}")
145
+ ```
146
+
147
+ ### 3. CLI & Terminal Dashboard
148
+
149
+ RegimeLab ships with a powerful Typer CLI:
150
+
151
+ ```bash
152
+ # 1. Run full walk-forward pipeline and generate interactive HTML report
153
+ regimelab run --report market_report.html
154
+
155
+ # 2. Inspect point-in-time telemetry for a specific date (JSON output)
156
+ regimelab asof 2023-10-15
157
+
158
+ # 3. Launch the full interactive Textual Terminal Dashboard
159
+ regimelab tui
160
+ ```
161
+
162
+ Additional CLI commands include `regimelab report OUTPUT` for direct HTML generation and `regimelab asof YYYY-MM-DD --output telemetry.json` for persisted JSON payloads.
163
+
164
+ ---
165
+
166
+ ## 🧠 Core Methodology & Architecture
167
+
168
+ ```text
169
+ ┌──────────────────────────────────────────────┐
170
+ │ Data Layer (PIT Alignment & Caching) │
171
+ └──────────────────────┬───────────────────────┘
172
+
173
+ ┌──────────────────────▼───────────────────────┐
174
+ │ Causal Features (PCA Absorption, Spread) │
175
+ └──────────────────────┬───────────────────────┘
176
+
177
+ ┌──────────────────────▼───────────────────────┐
178
+ │ Models: Hamilton / HMM / GMM + Anti-Switch │
179
+ └──────────────────────┬───────────────────────┘
180
+
181
+ ┌──────────────────────────────┴──────────────────────────────┐
182
+ ▼ ▼
183
+ ┌─────────────────────────┐ ┌─────────────────────────┐
184
+ │ Walk-Forward Engine │ │ Telemetry, HTML & TUI │
185
+ │ (Dynamic Allocations) │ │ (Interactive Artifacts) │
186
+ └─────────────────────────┘ └─────────────────────────┘
187
+ ```
188
+
189
+ ### 1. Canonical State Labeling (`regimelab.models.labeling`)
190
+
191
+ To eliminate label switching, RegimeLab fits the underlying statistical model (Gaussian HMM, Hamilton Markov Switching, or GMM) and evaluates the conditional distribution parameters of each state. States are sorted by risk-adjusted return ($\frac{\mu}{\sigma}$) and mapped deterministically to:
192
+
193
+ - **BULL_TREND** (High return, low volatility)
194
+ - **NEUTRAL_TRANSITION** (Moderate return, mean-reverting)
195
+ - **HIGH_VOL_BEAR** (Negative drift, elevated variance)
196
+ - **RISK_OFF** (Severe drawdown regime)
197
+
198
+ ### 2. Kritzman Absorption Ratio (`regimelab.features.absorption`)
199
+
200
+ Quantifies market fragility via Principal Component Analysis (PCA) over rolling multi-asset return covariance matrices:
201
+
202
+ $$
203
+ \text{Absorption Ratio} = \frac{\sum_{i=1}^{k} \sigma^2_{PC_i}}{\sum_{j=1}^{N} \sigma^2_j}
204
+ $$
205
+
206
+ A rapid spike in the absorption ratio ($\Delta \text{AR} > 1.5$) indicates tightening cross-asset coupling, signaling systemic vulnerability prior to market crashes.
207
+
208
+ ---
209
+
210
+ ## ⚙️ Configuration (`regimelab.toml`)
211
+
212
+ Customize execution parameters via `regimelab.toml`, environment variables (`REGIMELAB_DATA__PROVIDER=yfinance`), or Python kwargs:
213
+
214
+ ```toml
215
+ [data]
216
+ provider = "yfinance" # "yfinance", "synthetic", or "parquet"
217
+ start = "2005-01-01"
218
+ benchmark = "SPY"
219
+ calendar_anchor = "SPY"
220
+
221
+ [model]
222
+ classifier = "hmm" # "hmm", "gmm", or "hamilton"
223
+ n_states = 4
224
+ covariance_type = "diag"
225
+ min_train_observations = 756
226
+
227
+ [backtest]
228
+ transaction_cost_bps = 5.0
229
+ confidence_floor = 0.5
230
+ refit_frequency_days = 63
231
+ ```
232
+
233
+ ---
234
+
235
+ ## 🧪 Testing & Formal Verification
236
+
237
+ RegimeLab is built with property-based testing (hypothesis) to mathematically guarantee absence of look-ahead leakage:
238
+
239
+ ```bash
240
+ # Run test suite with causality property tests
241
+ uv run pytest -q
242
+
243
+ # Run strict mypy type checking
244
+ uv run mypy src/regimelab
245
+
246
+ # Lint with ruff
247
+ uv run ruff check .
248
+ ```
249
+
250
+ ---
251
+
252
+ ## 📄 License
253
+
254
+ MIT License. Developed for quantitative researchers, portfolio managers, and systematic trading engineers.
@@ -0,0 +1,213 @@
1
+ <div align="center">
2
+
3
+ # 🏛️ RegimeLab
4
+
5
+ **Institutional-grade market regime detection, systemic risk telemetry, and walk-forward asset allocation engine in Python.**
6
+
7
+ [![PyPI version](https://img.shields.io/pypi/v/regimelab.svg?color=blue)](https://pypi.org/project/regimelab/)
8
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
+ [![Type Checked with mypy](https://img.shields.io/badge/mypy-strict-blue)](https://mypy-lang.org/)
11
+ [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
12
+
13
+ </div>
14
+
15
+ ---
16
+
17
+ ## ⚡ Why RegimeLab?
18
+
19
+ Most open-source regime detection scripts fit a Hidden Markov Model (HMM) on the entire in-sample dataset and claim predictive power. In production quantitative finance, this fails due to three fatal flaws:
20
+
21
+ 1. **Look-Ahead Bias:** Training filters without strict point-in-time (`asof`) truncation leaks future distribution moments into past states.
22
+ 2. **Label Switching:** HMM/GMM state indices are mathematically interchangeable between refits. Without canonical sorting, "State 0" randomly alternates between Bull and Bear across rolling windows.
23
+ 3. **Calendar Desynchronization:** Multi-asset cross-sections suffer from holiday mismatches, halted assets, and survivorship bias.
24
+
25
+ **RegimeLab** solves these operational hurdles, providing a turnkey, causal quantitative engine for systematic asset allocation and macro risk monitoring.
26
+
27
+ ---
28
+
29
+ ### 📊 Feature Matrix: Raw Tooling vs. RegimeLab
30
+
31
+ | Challenge | Raw `hmmlearn` / `statsmodels` | RegimeLab Framework |
32
+ | :--- | :--- | :--- |
33
+ | **State Labeling** | Unordered integer states (permutes on refit) | **Deterministic Canonical Sorting** ($\frac{\mu}{\sigma}$ / conditional vol ordering) |
34
+ | **Temporal Clock** | In-sample full-sample fitting (Look-ahead) | **Strict Point-in-Time (`asof`) cursor** & expanding-window walk-forward |
35
+ | **Systemic Risk** | None | **Kritzman Absorption Ratio (PCA)**, VIX Term Spread & Sector Breadth |
36
+ | **Execution Reality** | Pure theoretical classification | **Walk-Forward Backtester** with transaction costs (bps) and confidence floors |
37
+ | **Data Ingestion** | Expects clean 2D NumPy array | **Multi-Asset PIT Alignment**, staleness budgets, synthetic & Parquet providers |
38
+ | **Reporting** | Matplotlib static plot | **Interactive Plotly HTML reports** + Textual TUI Terminal Dashboard |
39
+
40
+ ---
41
+
42
+ ## 🚀 Quickstart
43
+
44
+ ### 1. Installation
45
+
46
+ ```bash
47
+ # Install from PyPI
48
+ pip install regimelab
49
+
50
+ # Or install with interactive TUI support
51
+ pip install "regimelab[tui]"
52
+ ```
53
+
54
+ ### 2. Python API Usage
55
+
56
+ #### Current Market Regime Detection (3 lines)
57
+
58
+ ```python
59
+ from regimelab import Settings
60
+ from regimelab.pipeline import run_single_asof
61
+
62
+ # Run point-in-time regime inference for any historical or current date
63
+ settings = Settings(data={"provider": "yfinance"})
64
+ payload = run_single_asof(settings, asof="2024-12-31")
65
+
66
+ print(f"Detected Regime: {payload.regime.value}")
67
+ print(f"Confidence: {payload.probabilities.confidence:.2%}")
68
+ print(f"Target Allocation: {payload.target_weights.weights if payload.target_weights else {}}")
69
+ ```
70
+
71
+ #### Extract Causal Systemic Risk Features
72
+
73
+ ```python
74
+ from regimelab import Settings
75
+ from regimelab.data.fetcher import load_aligned_panel
76
+ from regimelab.features import build_feature_matrix
77
+
78
+ settings = Settings(data={"provider": "yfinance"})
79
+ panel = load_aligned_panel(settings)
80
+ features = build_feature_matrix(panel, settings)
81
+
82
+ # Inspect causal feature matrix
83
+ print(features[["absorption_ratio", "absorption_delta", "vix_term_spread", "breadth"]].tail())
84
+ ```
85
+
86
+ #### Walk-Forward Backtesting Engine
87
+
88
+ ```python
89
+ from regimelab import Settings
90
+ from regimelab.pipeline import run_pipeline
91
+
92
+ settings = Settings(
93
+ data={"provider": "synthetic"}, # Fully offline, reproducible dataset
94
+ model={"classifier": "hmm", "n_states": 4},
95
+ backtest={"transaction_cost_bps": 5.0, "confidence_floor": 0.5},
96
+ )
97
+
98
+ result = run_pipeline(settings, command="backtest_run")
99
+ metrics = result.backtest.metrics
100
+
101
+ print(f"Strategy CAGR: {metrics.cagr:.2%}")
102
+ print(f"Sharpe Ratio: {metrics.sharpe:.2f}")
103
+ print(f"Max Drawdown: {metrics.max_drawdown:.2%}")
104
+ ```
105
+
106
+ ### 3. CLI & Terminal Dashboard
107
+
108
+ RegimeLab ships with a powerful Typer CLI:
109
+
110
+ ```bash
111
+ # 1. Run full walk-forward pipeline and generate interactive HTML report
112
+ regimelab run --report market_report.html
113
+
114
+ # 2. Inspect point-in-time telemetry for a specific date (JSON output)
115
+ regimelab asof 2023-10-15
116
+
117
+ # 3. Launch the full interactive Textual Terminal Dashboard
118
+ regimelab tui
119
+ ```
120
+
121
+ Additional CLI commands include `regimelab report OUTPUT` for direct HTML generation and `regimelab asof YYYY-MM-DD --output telemetry.json` for persisted JSON payloads.
122
+
123
+ ---
124
+
125
+ ## 🧠 Core Methodology & Architecture
126
+
127
+ ```text
128
+ ┌──────────────────────────────────────────────┐
129
+ │ Data Layer (PIT Alignment & Caching) │
130
+ └──────────────────────┬───────────────────────┘
131
+
132
+ ┌──────────────────────▼───────────────────────┐
133
+ │ Causal Features (PCA Absorption, Spread) │
134
+ └──────────────────────┬───────────────────────┘
135
+
136
+ ┌──────────────────────▼───────────────────────┐
137
+ │ Models: Hamilton / HMM / GMM + Anti-Switch │
138
+ └──────────────────────┬───────────────────────┘
139
+
140
+ ┌──────────────────────────────┴──────────────────────────────┐
141
+ ▼ ▼
142
+ ┌─────────────────────────┐ ┌─────────────────────────┐
143
+ │ Walk-Forward Engine │ │ Telemetry, HTML & TUI │
144
+ │ (Dynamic Allocations) │ │ (Interactive Artifacts) │
145
+ └─────────────────────────┘ └─────────────────────────┘
146
+ ```
147
+
148
+ ### 1. Canonical State Labeling (`regimelab.models.labeling`)
149
+
150
+ To eliminate label switching, RegimeLab fits the underlying statistical model (Gaussian HMM, Hamilton Markov Switching, or GMM) and evaluates the conditional distribution parameters of each state. States are sorted by risk-adjusted return ($\frac{\mu}{\sigma}$) and mapped deterministically to:
151
+
152
+ - **BULL_TREND** (High return, low volatility)
153
+ - **NEUTRAL_TRANSITION** (Moderate return, mean-reverting)
154
+ - **HIGH_VOL_BEAR** (Negative drift, elevated variance)
155
+ - **RISK_OFF** (Severe drawdown regime)
156
+
157
+ ### 2. Kritzman Absorption Ratio (`regimelab.features.absorption`)
158
+
159
+ Quantifies market fragility via Principal Component Analysis (PCA) over rolling multi-asset return covariance matrices:
160
+
161
+ $$
162
+ \text{Absorption Ratio} = \frac{\sum_{i=1}^{k} \sigma^2_{PC_i}}{\sum_{j=1}^{N} \sigma^2_j}
163
+ $$
164
+
165
+ A rapid spike in the absorption ratio ($\Delta \text{AR} > 1.5$) indicates tightening cross-asset coupling, signaling systemic vulnerability prior to market crashes.
166
+
167
+ ---
168
+
169
+ ## ⚙️ Configuration (`regimelab.toml`)
170
+
171
+ Customize execution parameters via `regimelab.toml`, environment variables (`REGIMELAB_DATA__PROVIDER=yfinance`), or Python kwargs:
172
+
173
+ ```toml
174
+ [data]
175
+ provider = "yfinance" # "yfinance", "synthetic", or "parquet"
176
+ start = "2005-01-01"
177
+ benchmark = "SPY"
178
+ calendar_anchor = "SPY"
179
+
180
+ [model]
181
+ classifier = "hmm" # "hmm", "gmm", or "hamilton"
182
+ n_states = 4
183
+ covariance_type = "diag"
184
+ min_train_observations = 756
185
+
186
+ [backtest]
187
+ transaction_cost_bps = 5.0
188
+ confidence_floor = 0.5
189
+ refit_frequency_days = 63
190
+ ```
191
+
192
+ ---
193
+
194
+ ## 🧪 Testing & Formal Verification
195
+
196
+ RegimeLab is built with property-based testing (hypothesis) to mathematically guarantee absence of look-ahead leakage:
197
+
198
+ ```bash
199
+ # Run test suite with causality property tests
200
+ uv run pytest -q
201
+
202
+ # Run strict mypy type checking
203
+ uv run mypy src/regimelab
204
+
205
+ # Lint with ruff
206
+ uv run ruff check .
207
+ ```
208
+
209
+ ---
210
+
211
+ ## 📄 License
212
+
213
+ MIT License. Developed for quantitative researchers, portfolio managers, and systematic trading engineers.
@@ -0,0 +1,179 @@
1
+ [project]
2
+ name = "regimelab"
3
+ version = "0.1.0"
4
+ description = "Institutional market-regime detection engine: HMM/Hamilton regime switching, PCA absorption ratio, VIX term structure, point-in-time backtesting and automated reporting."
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ authors = [
9
+ { name = "AlgorithmicMind", email = "tonidinero27@gmail.com" }
10
+ ]
11
+ keywords = [
12
+ "quantitative-finance",
13
+ "regime-detection",
14
+ "hidden-markov-model",
15
+ "systemic-risk",
16
+ "backtesting",
17
+ "point-in-time",
18
+ "absorption-ratio",
19
+ ]
20
+ classifiers = [
21
+ "Development Status :: 3 - Alpha",
22
+ "Intended Audience :: Financial and Insurance Industry",
23
+ "Intended Audience :: Science/Research",
24
+ "License :: OSI Approved :: MIT License",
25
+ "Operating System :: OS Independent",
26
+ "Programming Language :: Python :: 3 :: Only",
27
+ "Programming Language :: Python :: 3.12",
28
+ "Programming Language :: Python :: 3.13",
29
+ "Topic :: Office/Business :: Financial :: Investment",
30
+ "Topic :: Scientific/Engineering :: Information Analysis",
31
+ "Typing :: Typed",
32
+ ]
33
+ requires-python = ">=3.12"
34
+ dependencies = [
35
+ "hmmlearn>=0.3.3",
36
+ "numpy>=2.5.2",
37
+ "pandas>=3.0.5",
38
+ "platformdirs>=4.11.5",
39
+ "plotly>=6.0.0",
40
+ "pyarrow>=25.0.1",
41
+ "pydantic>=2.13.5",
42
+ "pydantic-settings>=2.15.0",
43
+ "rich>=15.0.0",
44
+ "scikit-learn>=1.9.0",
45
+ "scipy>=1.18.1",
46
+ "statsmodels>=0.15.0",
47
+ "typer>=0.27.2",
48
+ "yfinance>=1.7.0",
49
+ ]
50
+
51
+ [project.urls]
52
+ Homepage = "https://github.com/AlgorithmicMind/regimelab"
53
+ Repository = "https://github.com/AlgorithmicMind/regimelab"
54
+ Issues = "https://github.com/AlgorithmicMind/regimelab/issues"
55
+
56
+ [project.scripts]
57
+ regimelab = "regimelab.cli:app"
58
+
59
+ [project.optional-dependencies]
60
+ tui = [
61
+ "textual>=8.2.8",
62
+ ]
63
+
64
+ [build-system]
65
+ requires = ["hatchling>=1.27"]
66
+ build-backend = "hatchling.build"
67
+
68
+ [tool.hatch.build.targets.wheel]
69
+ packages = ["src/regimelab"]
70
+
71
+ [tool.hatch.build.targets.sdist]
72
+ include = ["src/regimelab", "tests", "README.md", "LICENSE"]
73
+
74
+ [tool.ruff]
75
+ line-length = 100
76
+ target-version = "py312"
77
+ src = ["src", "tests"]
78
+
79
+ [tool.ruff.lint]
80
+ select = [
81
+ "E", "W", # pycodestyle
82
+ "F", # pyflakes
83
+ "I", # isort
84
+ "N", # pep8-naming
85
+ "UP", # pyupgrade
86
+ "B", # flake8-bugbear
87
+ "A", # flake8-builtins
88
+ "C4", # flake8-comprehensions
89
+ "DTZ", # flake8-datetimez
90
+ "ISC", # implicit-str-concat
91
+ "PIE", # flake8-pie
92
+ "PT", # flake8-pytest-style
93
+ "RET", # flake8-return
94
+ "SIM", # flake8-simplify
95
+ "ARG", # flake8-unused-arguments
96
+ "PD", # pandas-vet
97
+ "PL", # pylint
98
+ "NPY", # numpy-specific
99
+ "PERF", # perflint
100
+ "RUF", # ruff-specific
101
+ ]
102
+ ignore = [
103
+ "PLR0913", # quant functions legitimately take many parameters
104
+ "PLR2004", # magic values are readable in numerical code
105
+ "ISC001", # conflicts with the formatter
106
+ ]
107
+
108
+ [tool.ruff.lint.per-file-ignores]
109
+ "tests/**" = ["ARG", "PLR2004"]
110
+
111
+ [tool.ruff.lint.pydocstyle]
112
+ convention = "numpy"
113
+
114
+ [tool.mypy]
115
+ python_version = "3.12"
116
+ strict = true
117
+ warn_unreachable = true
118
+ warn_no_return = true
119
+ disallow_any_generics = true
120
+ no_implicit_reexport = true
121
+ show_error_codes = true
122
+ pretty = true
123
+ files = ["src", "tests"]
124
+
125
+ [[tool.mypy.overrides]]
126
+ module = [
127
+ "yfinance.*",
128
+ "hmmlearn.*",
129
+ "statsmodels.*",
130
+ "sklearn.*",
131
+ "scipy.*",
132
+ "plotly.*",
133
+ "textual.*",
134
+ ]
135
+ ignore_missing_imports = true
136
+
137
+ [tool.pytest.ini_options]
138
+ minversion = "8.0"
139
+ testpaths = ["tests"]
140
+ addopts = [
141
+ "-ra",
142
+ "--strict-markers",
143
+ "--strict-config",
144
+ "--import-mode=importlib",
145
+ ]
146
+ filterwarnings = [
147
+ "error",
148
+ "ignore::DeprecationWarning:hmmlearn.*",
149
+ "ignore::DeprecationWarning:statsmodels.*",
150
+ ]
151
+ markers = [
152
+ "network: test requires live network access (deselect with '-m \"not network\"')",
153
+ "slow: test is slow (deselect with '-m \"not slow\"')",
154
+ ]
155
+
156
+ [tool.coverage.run]
157
+ source = ["src/regimelab"]
158
+ branch = true
159
+ parallel = true
160
+
161
+ [tool.coverage.report]
162
+ precision = 1
163
+ show_missing = true
164
+ exclude_also = [
165
+ "if TYPE_CHECKING:",
166
+ "raise NotImplementedError",
167
+ "@(abc\\.)?abstractmethod",
168
+ "if __name__ == .__main__.:",
169
+ ]
170
+
171
+ [dependency-groups]
172
+ dev = [
173
+ "hypothesis>=6.167.1",
174
+ "mypy>=2.3.1",
175
+ "pandas-stubs>=3.0.5.260730",
176
+ "pytest>=9.1.1",
177
+ "pytest-cov>=7.1.0",
178
+ "ruff>=0.16.5",
179
+ ]