quantlite 1.0.2__tar.gz → 1.7.1__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.
- {quantlite-1.0.2/src/quantlite.egg-info → quantlite-1.7.1}/PKG-INFO +29 -1
- {quantlite-1.0.2 → quantlite-1.7.1}/README.md +18 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/pyproject.toml +12 -1
- quantlite-1.7.1/src/quantlite/__init__.py +167 -0
- quantlite-1.7.1/src/quantlite/alerts/__init__.py +415 -0
- quantlite-1.7.1/src/quantlite/benchmark/__init__.py +21 -0
- quantlite-1.7.1/src/quantlite/benchmark/compare.py +483 -0
- quantlite-1.7.1/src/quantlite/benchmark/runner.py +207 -0
- quantlite-1.7.1/src/quantlite/benchmark/speed.py +211 -0
- quantlite-1.7.1/src/quantlite/benchmark/tail_events.py +314 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/core/types.py +5 -9
- quantlite-1.7.1/src/quantlite/data/stream.py +410 -0
- quantlite-1.7.1/src/quantlite/explain/__init__.py +1 -0
- quantlite-1.7.1/src/quantlite/explain/attribution.py +368 -0
- quantlite-1.7.1/src/quantlite/explain/audit.py +325 -0
- quantlite-1.7.1/src/quantlite/explain/narratives.py +334 -0
- quantlite-1.7.1/src/quantlite/explain/whatif.py +308 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/metrics.py +5 -1
- quantlite-1.7.1/src/quantlite/portfolio/__init__.py +97 -0
- quantlite-1.7.1/src/quantlite/portfolio/dynamic_kelly.py +270 -0
- quantlite-1.7.1/src/quantlite/portfolio/ensemble.py +215 -0
- quantlite-1.7.1/src/quantlite/portfolio/regime_bl.py +278 -0
- quantlite-1.7.1/src/quantlite/portfolio/tail_risk_parity.py +336 -0
- quantlite-1.7.1/src/quantlite/portfolio/walkforward.py +288 -0
- quantlite-1.7.1/src/quantlite/regimes/online.py +273 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/risk/metrics.py +56 -8
- quantlite-1.7.1/src/quantlite/score/__init__.py +76 -0
- quantlite-1.7.1/src/quantlite/score/artifact.py +212 -0
- quantlite-1.7.1/src/quantlite/score/engine.py +496 -0
- quantlite-1.7.1/src/quantlite/score/integrity.py +240 -0
- quantlite-1.7.1/src/quantlite/score/monitoring.py +666 -0
- quantlite-1.7.1/src/quantlite/score/provenance.py +414 -0
- quantlite-1.7.1/src/quantlite/viz/alerts.py +173 -0
- quantlite-1.7.1/src/quantlite/viz/allocation.py +642 -0
- quantlite-1.7.1/src/quantlite/viz/benchmark.py +615 -0
- quantlite-1.7.1/src/quantlite/viz/explain.py +648 -0
- quantlite-1.7.1/src/quantlite/viz/online_regimes.py +211 -0
- quantlite-1.7.1/src/quantlite/viz/streaming.py +173 -0
- {quantlite-1.0.2 → quantlite-1.7.1/src/quantlite.egg-info}/PKG-INFO +29 -1
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite.egg-info/SOURCES.txt +39 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite.egg-info/requires.txt +12 -0
- quantlite-1.7.1/tests/test_alerts.py +160 -0
- quantlite-1.7.1/tests/test_allocation_engine.py +358 -0
- quantlite-1.7.1/tests/test_benchmarks.py +150 -0
- quantlite-1.7.1/tests/test_explainability.py +219 -0
- quantlite-1.7.1/tests/test_monitoring.py +179 -0
- quantlite-1.7.1/tests/test_online_regime.py +137 -0
- quantlite-1.7.1/tests/test_provenance.py +172 -0
- quantlite-1.7.1/tests/test_score.py +175 -0
- quantlite-1.7.1/tests/test_stream.py +159 -0
- quantlite-1.0.2/src/quantlite/__init__.py +0 -112
- quantlite-1.0.2/src/quantlite/portfolio/__init__.py +0 -35
- {quantlite-1.0.2 → quantlite-1.7.1}/LICENSE +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/setup.cfg +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/antifragile/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/backtesting/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/backtesting/analysis.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/backtesting/engine.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/backtesting/legacy.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/backtesting/signals.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/contagion/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/core/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/crypto/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/crypto/exchange.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/crypto/onchain.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/crypto/stablecoin.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/data/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/data/base.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/data/cache.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/data/crypto.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/data/fred.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/data/local.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/data/registry.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/data/yahoo.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/data_generation.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/dependency/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/dependency/clustering.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/dependency/copulas.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/dependency/correlation.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/distributions/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/distributions/fat_tails.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/diversification/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/ergodicity/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/factors/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/factors/classical.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/factors/custom.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/factors/tail_risk.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/forensics/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/instruments/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/instruments/bond_pricing.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/instruments/exotic_options.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/instruments/option_pricing.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/monte_carlo.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/network/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/overfit/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/pipeline.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/portfolio/optimisation.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/portfolio/rebalancing.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/regime_integration/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/regime_integration/portfolio.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/regime_integration/reporting.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/regime_integration/risk.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/regimes/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/regimes/changepoint.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/regimes/conditional.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/regimes/hmm.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/report/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/report/html_renderer.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/report/pdf_renderer.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/report/sections.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/report/tearsheet.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/resample/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/risk/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/risk/evt.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/scenarios/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/simulation/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/simulation/copula_mc.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/simulation/evt_simulation.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/simulation/regime_mc.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/visualisation.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/viz/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/viz/dependency.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/viz/plotly_backend/__init__.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/viz/plotly_backend/dependency.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/viz/plotly_backend/portfolio.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/viz/plotly_backend/regimes.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/viz/plotly_backend/risk.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/viz/plotly_backend/theme.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/viz/portfolio.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/viz/regimes.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/viz/risk.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite/viz/theme.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite.egg-info/dependency_links.txt +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/src/quantlite.egg-info/top_level.txt +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_analysis.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_antifragile.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_backtesting.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_changepoint.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_clustering.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_conditional.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_contagion.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_copulas.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_correlation.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_crypto_exchange.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_crypto_onchain.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_crypto_stablecoin.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_data_connectors.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_data_generation.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_diversification.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_engine.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_ergodicity.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_evt.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_factors_classical.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_factors_custom.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_factors_tail_risk.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_fat_tails.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_forensics.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_hmm.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_instruments.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_metrics.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_monte_carlo.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_network.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_optimisation.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_overfit.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_pipeline.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_plotly_viz.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_rebalancing.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_regime_integration.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_report.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_resample.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_risk_metrics.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_scenarios.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_signals.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_sim_copula.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_sim_evt.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_sim_regime.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_visualisation.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_viz.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_viz_dependency.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_viz_portfolio.py +0 -0
- {quantlite-1.0.2 → quantlite-1.7.1}/tests/test_viz_regimes.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: quantlite
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.1
|
|
4
4
|
Summary: A fat-tail-native quantitative finance toolkit: EVT, risk metrics, and honest modelling for markets that bite.
|
|
5
5
|
Author-email: Prasant Sudhakaran <code@prasant.net>
|
|
6
6
|
License: MIT License
|
|
@@ -54,6 +54,8 @@ Provides-Extra: yahoo
|
|
|
54
54
|
Requires-Dist: yfinance>=0.2; extra == "yahoo"
|
|
55
55
|
Provides-Extra: crypto
|
|
56
56
|
Requires-Dist: ccxt>=4.0; extra == "crypto"
|
|
57
|
+
Provides-Extra: stream
|
|
58
|
+
Requires-Dist: ccxt>=4.0; extra == "stream"
|
|
57
59
|
Provides-Extra: fred
|
|
58
60
|
Requires-Dist: fredapi>=0.5; extra == "fred"
|
|
59
61
|
Provides-Extra: plotly
|
|
@@ -72,11 +74,19 @@ Requires-Dist: plotly>=5.0; extra == "all"
|
|
|
72
74
|
Requires-Dist: kaleido>=0.2; extra == "all"
|
|
73
75
|
Requires-Dist: weasyprint>=60; extra == "all"
|
|
74
76
|
Requires-Dist: hmmlearn>=0.3; extra == "all"
|
|
77
|
+
Provides-Extra: docs
|
|
78
|
+
Requires-Dist: mkdocs>=1.5; extra == "docs"
|
|
79
|
+
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
|
|
80
|
+
Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
|
|
75
81
|
Provides-Extra: dev
|
|
76
82
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
83
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
77
84
|
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
78
85
|
Requires-Dist: mypy>=1.8; extra == "dev"
|
|
79
86
|
Requires-Dist: pandas-stubs; extra == "dev"
|
|
87
|
+
Requires-Dist: mkdocs>=1.5; extra == "dev"
|
|
88
|
+
Requires-Dist: mkdocs-material>=9.5; extra == "dev"
|
|
89
|
+
Requires-Dist: mkdocstrings[python]>=0.24; extra == "dev"
|
|
80
90
|
Dynamic: license-file
|
|
81
91
|
|
|
82
92
|
# QuantLite
|
|
@@ -114,6 +124,24 @@ Five lines. Fetch data, detect market regimes, build a regime-aware portfolio, b
|
|
|
114
124
|
|
|
115
125
|
---
|
|
116
126
|
|
|
127
|
+
## The QuantLite Score
|
|
128
|
+
|
|
129
|
+
An open, versioned, verifiable rating for trading track records. Raw Sharpe ratios are trivially gamed: test fifty variants and publish the winner, start the chart at the bottom of a drawdown, sell tail risk and post a 92% win rate. The QuantLite Score rates a track record on the statistics that are hard to game — deflated Sharpe, bootstrap robustness, tail risk, consistency — and flags the classic manipulation patterns.
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from quantlite.score import compute_score, verify_artifact
|
|
133
|
+
|
|
134
|
+
result = compute_score(returns, n_trials=20)
|
|
135
|
+
print(result.score, result.grade) # e.g. 72.4 B
|
|
136
|
+
|
|
137
|
+
payload = result.artifact.to_json() # publish or store this
|
|
138
|
+
assert verify_artifact(payload, returns) # anyone can reproduce it bit for bit
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Every score ships as a portable artifact with a SHA-256 content hash. Same returns, same parameters, same library version: same score, bit for bit. The methodology (QLS-1.0) is open and frozen per version — see [the specification](docs/score.md).
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
117
145
|
## Visual Showcase
|
|
118
146
|
|
|
119
147
|
### Fat Tails vs Gaussian
|
|
@@ -33,6 +33,24 @@ Five lines. Fetch data, detect market regimes, build a regime-aware portfolio, b
|
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
36
|
+
## The QuantLite Score
|
|
37
|
+
|
|
38
|
+
An open, versioned, verifiable rating for trading track records. Raw Sharpe ratios are trivially gamed: test fifty variants and publish the winner, start the chart at the bottom of a drawdown, sell tail risk and post a 92% win rate. The QuantLite Score rates a track record on the statistics that are hard to game — deflated Sharpe, bootstrap robustness, tail risk, consistency — and flags the classic manipulation patterns.
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from quantlite.score import compute_score, verify_artifact
|
|
42
|
+
|
|
43
|
+
result = compute_score(returns, n_trials=20)
|
|
44
|
+
print(result.score, result.grade) # e.g. 72.4 B
|
|
45
|
+
|
|
46
|
+
payload = result.artifact.to_json() # publish or store this
|
|
47
|
+
assert verify_artifact(payload, returns) # anyone can reproduce it bit for bit
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Every score ships as a portable artifact with a SHA-256 content hash. Same returns, same parameters, same library version: same score, bit for bit. The methodology (QLS-1.0) is open and frozen per version — see [the specification](docs/score.md).
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
36
54
|
## Visual Showcase
|
|
37
55
|
|
|
38
56
|
### Fat Tails vs Gaussian
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "quantlite"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.7.1"
|
|
8
8
|
description = "A fat-tail-native quantitative finance toolkit: EVT, risk metrics, and honest modelling for markets that bite."
|
|
9
9
|
requires-python = ">=3.9"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -48,16 +48,26 @@ dependencies = [
|
|
|
48
48
|
[project.optional-dependencies]
|
|
49
49
|
yahoo = ["yfinance>=0.2"]
|
|
50
50
|
crypto = ["ccxt>=4.0"]
|
|
51
|
+
stream = ["ccxt>=4.0"]
|
|
51
52
|
fred = ["fredapi>=0.5"]
|
|
52
53
|
plotly = ["plotly>=5.0", "kaleido>=0.2"]
|
|
53
54
|
report = ["plotly>=5.0", "kaleido>=0.2"]
|
|
54
55
|
pdf = ["weasyprint>=60"]
|
|
55
56
|
all = ["yfinance>=0.2", "ccxt>=4.0", "fredapi>=0.5", "plotly>=5.0", "kaleido>=0.2", "weasyprint>=60", "hmmlearn>=0.3"]
|
|
57
|
+
docs = [
|
|
58
|
+
"mkdocs>=1.5",
|
|
59
|
+
"mkdocs-material>=9.5",
|
|
60
|
+
"mkdocstrings[python]>=0.24",
|
|
61
|
+
]
|
|
56
62
|
dev = [
|
|
57
63
|
"pytest>=7.0",
|
|
64
|
+
"pytest-asyncio>=0.23",
|
|
58
65
|
"ruff>=0.4",
|
|
59
66
|
"mypy>=1.8",
|
|
60
67
|
"pandas-stubs",
|
|
68
|
+
"mkdocs>=1.5",
|
|
69
|
+
"mkdocs-material>=9.5",
|
|
70
|
+
"mkdocstrings[python]>=0.24",
|
|
61
71
|
]
|
|
62
72
|
|
|
63
73
|
[project.urls]
|
|
@@ -76,3 +86,4 @@ disallow_untyped_defs = false
|
|
|
76
86
|
|
|
77
87
|
[tool.pytest.ini_options]
|
|
78
88
|
testpaths = ["tests"]
|
|
89
|
+
asyncio_mode = "auto"
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"""QuantLite: a fat-tail-native quantitative finance toolkit.
|
|
2
|
+
|
|
3
|
+
Provides stochastic process generators, option and bond pricing,
|
|
4
|
+
risk metrics, extreme value theory, fat-tailed distributions,
|
|
5
|
+
portfolio optimisation, multi-asset backtesting, and
|
|
6
|
+
Stephen Few-inspired visualisation.
|
|
7
|
+
|
|
8
|
+
Submodules and public names are imported lazily (PEP 562): accessing
|
|
9
|
+
``quantlite.run_backtest`` or ``quantlite.score`` imports the backing module
|
|
10
|
+
on first use. This keeps light entry points light -- importing
|
|
11
|
+
``quantlite.score`` does not pull in pandas or matplotlib -- while preserving
|
|
12
|
+
the full ``from quantlite import X`` and ``quantlite.X`` public API.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import importlib
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
__version__ = "1.7.1"
|
|
21
|
+
|
|
22
|
+
# Public names mapped to the module that defines them, for lazy loading.
|
|
23
|
+
_ATTR_SOURCES = {
|
|
24
|
+
# Data generation
|
|
25
|
+
"geometric_brownian_motion": "quantlite.data_generation",
|
|
26
|
+
"correlated_gbm": "quantlite.data_generation",
|
|
27
|
+
"ornstein_uhlenbeck": "quantlite.data_generation",
|
|
28
|
+
"merton_jump_diffusion": "quantlite.data_generation",
|
|
29
|
+
# Instruments
|
|
30
|
+
"black_scholes_call": "quantlite.instruments.option_pricing",
|
|
31
|
+
"black_scholes_put": "quantlite.instruments.option_pricing",
|
|
32
|
+
"black_scholes_greeks": "quantlite.instruments.option_pricing",
|
|
33
|
+
"bond_price": "quantlite.instruments.bond_pricing",
|
|
34
|
+
"bond_yield_to_maturity": "quantlite.instruments.bond_pricing",
|
|
35
|
+
# Metrics
|
|
36
|
+
"annualised_return": "quantlite.metrics",
|
|
37
|
+
"annualised_volatility": "quantlite.metrics",
|
|
38
|
+
"sharpe_ratio": "quantlite.metrics",
|
|
39
|
+
"max_drawdown": "quantlite.metrics",
|
|
40
|
+
# Backtesting
|
|
41
|
+
"run_backtest": "quantlite.backtesting",
|
|
42
|
+
"BacktestConfig": "quantlite.backtesting",
|
|
43
|
+
"BacktestContext": "quantlite.backtesting",
|
|
44
|
+
"BacktestResult": "quantlite.backtesting",
|
|
45
|
+
"RiskLimits": "quantlite.backtesting",
|
|
46
|
+
"SlippageModel": "quantlite.backtesting",
|
|
47
|
+
# Visualisation
|
|
48
|
+
"plot_time_series": "quantlite.visualisation",
|
|
49
|
+
# Dream API (pipeline)
|
|
50
|
+
"fetch": "quantlite.pipeline",
|
|
51
|
+
"detect_regimes": "quantlite.pipeline",
|
|
52
|
+
"construct_portfolio": "quantlite.pipeline",
|
|
53
|
+
"backtest": "quantlite.pipeline",
|
|
54
|
+
"tearsheet": "quantlite.pipeline",
|
|
55
|
+
# Streaming & alerts (v1.1)
|
|
56
|
+
"AlertManager": "quantlite.alerts",
|
|
57
|
+
"AlertRule": "quantlite.alerts",
|
|
58
|
+
"Alert": "quantlite.alerts",
|
|
59
|
+
"PriceStream": "quantlite.data.stream",
|
|
60
|
+
"PriceTick": "quantlite.data.stream",
|
|
61
|
+
"create_stream": "quantlite.data.stream",
|
|
62
|
+
"stream": "quantlite.data.stream",
|
|
63
|
+
"OnlineRegimeDetector": "quantlite.regimes.online",
|
|
64
|
+
"RegimeUpdate": "quantlite.regimes.online",
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# Names whose attribute on the source module differs from the public name.
|
|
68
|
+
_ALIASES = {"stream": "create_stream"}
|
|
69
|
+
|
|
70
|
+
__all__ = [
|
|
71
|
+
# Data generation
|
|
72
|
+
"geometric_brownian_motion",
|
|
73
|
+
"correlated_gbm",
|
|
74
|
+
"ornstein_uhlenbeck",
|
|
75
|
+
"merton_jump_diffusion",
|
|
76
|
+
# Instruments
|
|
77
|
+
"black_scholes_call",
|
|
78
|
+
"black_scholes_put",
|
|
79
|
+
"black_scholes_greeks",
|
|
80
|
+
"bond_price",
|
|
81
|
+
"bond_yield_to_maturity",
|
|
82
|
+
# Metrics
|
|
83
|
+
"annualised_return",
|
|
84
|
+
"annualised_volatility",
|
|
85
|
+
"sharpe_ratio",
|
|
86
|
+
"max_drawdown",
|
|
87
|
+
# Backtesting
|
|
88
|
+
"run_backtest",
|
|
89
|
+
"BacktestConfig",
|
|
90
|
+
"BacktestContext",
|
|
91
|
+
"BacktestResult",
|
|
92
|
+
"RiskLimits",
|
|
93
|
+
"SlippageModel",
|
|
94
|
+
# Visualisation
|
|
95
|
+
"plot_time_series",
|
|
96
|
+
# Ergodicity economics
|
|
97
|
+
"ergodicity",
|
|
98
|
+
# Antifragility framework
|
|
99
|
+
"antifragile",
|
|
100
|
+
# Scenario engine
|
|
101
|
+
"scenarios",
|
|
102
|
+
# Strategy forensics
|
|
103
|
+
"forensics",
|
|
104
|
+
# Overfitting detection
|
|
105
|
+
"overfit",
|
|
106
|
+
# Resampled backtesting
|
|
107
|
+
"resample",
|
|
108
|
+
# Contagion metrics
|
|
109
|
+
"contagion",
|
|
110
|
+
# Network risk
|
|
111
|
+
"network",
|
|
112
|
+
# Diversification analysis
|
|
113
|
+
"diversification",
|
|
114
|
+
# Crypto-native risk
|
|
115
|
+
"crypto",
|
|
116
|
+
# Fat-tail Monte Carlo simulation
|
|
117
|
+
"simulation",
|
|
118
|
+
# Regime-aware integration
|
|
119
|
+
"regime_integration",
|
|
120
|
+
# Dream API (pipeline)
|
|
121
|
+
"fetch",
|
|
122
|
+
"detect_regimes",
|
|
123
|
+
"construct_portfolio",
|
|
124
|
+
"backtest",
|
|
125
|
+
"tearsheet",
|
|
126
|
+
# Streaming & alerts (v1.1)
|
|
127
|
+
"AlertManager",
|
|
128
|
+
"AlertRule",
|
|
129
|
+
"Alert",
|
|
130
|
+
"PriceStream",
|
|
131
|
+
"PriceTick",
|
|
132
|
+
"create_stream",
|
|
133
|
+
"stream",
|
|
134
|
+
"OnlineRegimeDetector",
|
|
135
|
+
"RegimeUpdate",
|
|
136
|
+
# Benchmarking (v1.5)
|
|
137
|
+
"benchmark",
|
|
138
|
+
# QuantLite Score (v1.6)
|
|
139
|
+
"score",
|
|
140
|
+
]
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def __getattr__(name: str) -> Any:
|
|
144
|
+
"""Lazily import a public name or submodule on first access (PEP 562).
|
|
145
|
+
|
|
146
|
+
Public names listed in ``__all__`` resolve to their defining module; any
|
|
147
|
+
other name is tried as a submodule, preserving the eager package's
|
|
148
|
+
behaviour of exposing ``quantlite.<submodule>`` without an explicit
|
|
149
|
+
import.
|
|
150
|
+
"""
|
|
151
|
+
source = _ATTR_SOURCES.get(name)
|
|
152
|
+
if source is not None:
|
|
153
|
+
module = importlib.import_module(source)
|
|
154
|
+
value = getattr(module, _ALIASES.get(name, name))
|
|
155
|
+
globals()[name] = value
|
|
156
|
+
return value
|
|
157
|
+
try:
|
|
158
|
+
module = importlib.import_module(f"{__name__}.{name}")
|
|
159
|
+
except ModuleNotFoundError:
|
|
160
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from None
|
|
161
|
+
globals()[name] = module
|
|
162
|
+
return module
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def __dir__() -> list[str]:
|
|
166
|
+
"""List the lazily exported names for tab completion and introspection."""
|
|
167
|
+
return sorted(__all__)
|