ml4t-diagnostic 0.1.0a1__py3-none-any.whl
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.
- ml4t/diagnostic/AGENT.md +25 -0
- ml4t/diagnostic/__init__.py +166 -0
- ml4t/diagnostic/backends/__init__.py +10 -0
- ml4t/diagnostic/backends/adapter.py +192 -0
- ml4t/diagnostic/backends/polars_backend.py +899 -0
- ml4t/diagnostic/caching/__init__.py +40 -0
- ml4t/diagnostic/caching/cache.py +331 -0
- ml4t/diagnostic/caching/decorators.py +131 -0
- ml4t/diagnostic/caching/smart_cache.py +339 -0
- ml4t/diagnostic/config/AGENT.md +24 -0
- ml4t/diagnostic/config/README.md +267 -0
- ml4t/diagnostic/config/__init__.py +219 -0
- ml4t/diagnostic/config/barrier_config.py +277 -0
- ml4t/diagnostic/config/base.py +301 -0
- ml4t/diagnostic/config/event_config.py +148 -0
- ml4t/diagnostic/config/feature_config.py +404 -0
- ml4t/diagnostic/config/multi_signal_config.py +55 -0
- ml4t/diagnostic/config/portfolio_config.py +215 -0
- ml4t/diagnostic/config/report_config.py +391 -0
- ml4t/diagnostic/config/sharpe_config.py +202 -0
- ml4t/diagnostic/config/signal_config.py +206 -0
- ml4t/diagnostic/config/trade_analysis_config.py +310 -0
- ml4t/diagnostic/config/validation.py +279 -0
- ml4t/diagnostic/core/__init__.py +29 -0
- ml4t/diagnostic/core/numba_utils.py +315 -0
- ml4t/diagnostic/core/purging.py +372 -0
- ml4t/diagnostic/core/sampling.py +471 -0
- ml4t/diagnostic/errors/__init__.py +205 -0
- ml4t/diagnostic/evaluation/AGENT.md +26 -0
- ml4t/diagnostic/evaluation/__init__.py +437 -0
- ml4t/diagnostic/evaluation/autocorrelation.py +531 -0
- ml4t/diagnostic/evaluation/barrier_analysis.py +1050 -0
- ml4t/diagnostic/evaluation/binary_metrics.py +910 -0
- ml4t/diagnostic/evaluation/dashboard.py +715 -0
- ml4t/diagnostic/evaluation/diagnostic_plots.py +1037 -0
- ml4t/diagnostic/evaluation/distribution/__init__.py +499 -0
- ml4t/diagnostic/evaluation/distribution/moments.py +299 -0
- ml4t/diagnostic/evaluation/distribution/tails.py +777 -0
- ml4t/diagnostic/evaluation/distribution/tests.py +470 -0
- ml4t/diagnostic/evaluation/drift/__init__.py +139 -0
- ml4t/diagnostic/evaluation/drift/analysis.py +432 -0
- ml4t/diagnostic/evaluation/drift/domain_classifier.py +517 -0
- ml4t/diagnostic/evaluation/drift/population_stability_index.py +310 -0
- ml4t/diagnostic/evaluation/drift/wasserstein.py +388 -0
- ml4t/diagnostic/evaluation/event_analysis.py +647 -0
- ml4t/diagnostic/evaluation/excursion.py +390 -0
- ml4t/diagnostic/evaluation/feature_diagnostics.py +873 -0
- ml4t/diagnostic/evaluation/feature_outcome.py +666 -0
- ml4t/diagnostic/evaluation/framework.py +935 -0
- ml4t/diagnostic/evaluation/metric_registry.py +255 -0
- ml4t/diagnostic/evaluation/metrics/AGENT.md +23 -0
- ml4t/diagnostic/evaluation/metrics/__init__.py +133 -0
- ml4t/diagnostic/evaluation/metrics/basic.py +160 -0
- ml4t/diagnostic/evaluation/metrics/conditional_ic.py +469 -0
- ml4t/diagnostic/evaluation/metrics/feature_outcome.py +475 -0
- ml4t/diagnostic/evaluation/metrics/ic_statistics.py +446 -0
- ml4t/diagnostic/evaluation/metrics/importance_analysis.py +338 -0
- ml4t/diagnostic/evaluation/metrics/importance_classical.py +375 -0
- ml4t/diagnostic/evaluation/metrics/importance_mda.py +371 -0
- ml4t/diagnostic/evaluation/metrics/importance_shap.py +715 -0
- ml4t/diagnostic/evaluation/metrics/information_coefficient.py +527 -0
- ml4t/diagnostic/evaluation/metrics/interactions.py +772 -0
- ml4t/diagnostic/evaluation/metrics/monotonicity.py +226 -0
- ml4t/diagnostic/evaluation/metrics/risk_adjusted.py +324 -0
- ml4t/diagnostic/evaluation/multi_signal.py +550 -0
- ml4t/diagnostic/evaluation/portfolio_analysis/__init__.py +83 -0
- ml4t/diagnostic/evaluation/portfolio_analysis/analysis.py +734 -0
- ml4t/diagnostic/evaluation/portfolio_analysis/metrics.py +589 -0
- ml4t/diagnostic/evaluation/portfolio_analysis/results.py +334 -0
- ml4t/diagnostic/evaluation/report_generation.py +824 -0
- ml4t/diagnostic/evaluation/signal_selector.py +452 -0
- ml4t/diagnostic/evaluation/stat_registry.py +139 -0
- ml4t/diagnostic/evaluation/stationarity/__init__.py +97 -0
- ml4t/diagnostic/evaluation/stationarity/analysis.py +518 -0
- ml4t/diagnostic/evaluation/stationarity/augmented_dickey_fuller.py +296 -0
- ml4t/diagnostic/evaluation/stationarity/kpss_test.py +308 -0
- ml4t/diagnostic/evaluation/stationarity/phillips_perron.py +365 -0
- ml4t/diagnostic/evaluation/stats/AGENT.md +43 -0
- ml4t/diagnostic/evaluation/stats/__init__.py +191 -0
- ml4t/diagnostic/evaluation/stats/backtest_overfitting.py +219 -0
- ml4t/diagnostic/evaluation/stats/bootstrap.py +228 -0
- ml4t/diagnostic/evaluation/stats/deflated_sharpe_ratio.py +591 -0
- ml4t/diagnostic/evaluation/stats/false_discovery_rate.py +295 -0
- ml4t/diagnostic/evaluation/stats/hac_standard_errors.py +108 -0
- ml4t/diagnostic/evaluation/stats/minimum_track_record.py +408 -0
- ml4t/diagnostic/evaluation/stats/moments.py +164 -0
- ml4t/diagnostic/evaluation/stats/rademacher_adjustment.py +436 -0
- ml4t/diagnostic/evaluation/stats/reality_check.py +155 -0
- ml4t/diagnostic/evaluation/stats/sharpe_inference.py +219 -0
- ml4t/diagnostic/evaluation/themes.py +330 -0
- ml4t/diagnostic/evaluation/threshold_analysis.py +957 -0
- ml4t/diagnostic/evaluation/trade_analysis.py +1136 -0
- ml4t/diagnostic/evaluation/trade_dashboard/__init__.py +32 -0
- ml4t/diagnostic/evaluation/trade_dashboard/app.py +315 -0
- ml4t/diagnostic/evaluation/trade_dashboard/export/__init__.py +18 -0
- ml4t/diagnostic/evaluation/trade_dashboard/export/csv.py +82 -0
- ml4t/diagnostic/evaluation/trade_dashboard/export/html.py +276 -0
- ml4t/diagnostic/evaluation/trade_dashboard/io.py +166 -0
- ml4t/diagnostic/evaluation/trade_dashboard/normalize.py +304 -0
- ml4t/diagnostic/evaluation/trade_dashboard/stats.py +386 -0
- ml4t/diagnostic/evaluation/trade_dashboard/style.py +79 -0
- ml4t/diagnostic/evaluation/trade_dashboard/tabs/__init__.py +21 -0
- ml4t/diagnostic/evaluation/trade_dashboard/tabs/patterns.py +354 -0
- ml4t/diagnostic/evaluation/trade_dashboard/tabs/shap_analysis.py +280 -0
- ml4t/diagnostic/evaluation/trade_dashboard/tabs/stat_validation.py +186 -0
- ml4t/diagnostic/evaluation/trade_dashboard/tabs/worst_trades.py +236 -0
- ml4t/diagnostic/evaluation/trade_dashboard/types.py +129 -0
- ml4t/diagnostic/evaluation/trade_shap/__init__.py +102 -0
- ml4t/diagnostic/evaluation/trade_shap/alignment.py +188 -0
- ml4t/diagnostic/evaluation/trade_shap/characterize.py +413 -0
- ml4t/diagnostic/evaluation/trade_shap/cluster.py +302 -0
- ml4t/diagnostic/evaluation/trade_shap/explain.py +208 -0
- ml4t/diagnostic/evaluation/trade_shap/hypotheses/__init__.py +23 -0
- ml4t/diagnostic/evaluation/trade_shap/hypotheses/generator.py +290 -0
- ml4t/diagnostic/evaluation/trade_shap/hypotheses/matcher.py +251 -0
- ml4t/diagnostic/evaluation/trade_shap/hypotheses/templates.yaml +467 -0
- ml4t/diagnostic/evaluation/trade_shap/models.py +386 -0
- ml4t/diagnostic/evaluation/trade_shap/normalize.py +116 -0
- ml4t/diagnostic/evaluation/trade_shap/pipeline.py +263 -0
- ml4t/diagnostic/evaluation/trade_shap_dashboard.py +283 -0
- ml4t/diagnostic/evaluation/trade_shap_diagnostics.py +588 -0
- ml4t/diagnostic/evaluation/validated_cv.py +535 -0
- ml4t/diagnostic/evaluation/visualization.py +1050 -0
- ml4t/diagnostic/evaluation/volatility/__init__.py +45 -0
- ml4t/diagnostic/evaluation/volatility/analysis.py +351 -0
- ml4t/diagnostic/evaluation/volatility/arch.py +258 -0
- ml4t/diagnostic/evaluation/volatility/garch.py +460 -0
- ml4t/diagnostic/integration/__init__.py +48 -0
- ml4t/diagnostic/integration/backtest_contract.py +671 -0
- ml4t/diagnostic/integration/data_contract.py +316 -0
- ml4t/diagnostic/integration/engineer_contract.py +226 -0
- ml4t/diagnostic/logging/__init__.py +77 -0
- ml4t/diagnostic/logging/logger.py +245 -0
- ml4t/diagnostic/logging/performance.py +234 -0
- ml4t/diagnostic/logging/progress.py +234 -0
- ml4t/diagnostic/logging/wandb.py +412 -0
- ml4t/diagnostic/metrics/__init__.py +9 -0
- ml4t/diagnostic/metrics/percentiles.py +128 -0
- ml4t/diagnostic/py.typed +1 -0
- ml4t/diagnostic/reporting/__init__.py +43 -0
- ml4t/diagnostic/reporting/base.py +130 -0
- ml4t/diagnostic/reporting/html_renderer.py +275 -0
- ml4t/diagnostic/reporting/json_renderer.py +51 -0
- ml4t/diagnostic/reporting/markdown_renderer.py +117 -0
- ml4t/diagnostic/results/AGENT.md +24 -0
- ml4t/diagnostic/results/__init__.py +105 -0
- ml4t/diagnostic/results/barrier_results/__init__.py +36 -0
- ml4t/diagnostic/results/barrier_results/hit_rate.py +304 -0
- ml4t/diagnostic/results/barrier_results/precision_recall.py +266 -0
- ml4t/diagnostic/results/barrier_results/profit_factor.py +297 -0
- ml4t/diagnostic/results/barrier_results/tearsheet.py +397 -0
- ml4t/diagnostic/results/barrier_results/time_to_target.py +305 -0
- ml4t/diagnostic/results/barrier_results/validation.py +38 -0
- ml4t/diagnostic/results/base.py +177 -0
- ml4t/diagnostic/results/event_results.py +349 -0
- ml4t/diagnostic/results/feature_results.py +787 -0
- ml4t/diagnostic/results/multi_signal_results.py +431 -0
- ml4t/diagnostic/results/portfolio_results.py +281 -0
- ml4t/diagnostic/results/sharpe_results.py +448 -0
- ml4t/diagnostic/results/signal_results/__init__.py +74 -0
- ml4t/diagnostic/results/signal_results/ic.py +581 -0
- ml4t/diagnostic/results/signal_results/irtc.py +110 -0
- ml4t/diagnostic/results/signal_results/quantile.py +392 -0
- ml4t/diagnostic/results/signal_results/tearsheet.py +456 -0
- ml4t/diagnostic/results/signal_results/turnover.py +213 -0
- ml4t/diagnostic/results/signal_results/validation.py +147 -0
- ml4t/diagnostic/signal/AGENT.md +17 -0
- ml4t/diagnostic/signal/__init__.py +69 -0
- ml4t/diagnostic/signal/_report.py +152 -0
- ml4t/diagnostic/signal/_utils.py +261 -0
- ml4t/diagnostic/signal/core.py +275 -0
- ml4t/diagnostic/signal/quantile.py +148 -0
- ml4t/diagnostic/signal/result.py +214 -0
- ml4t/diagnostic/signal/signal_ic.py +129 -0
- ml4t/diagnostic/signal/turnover.py +182 -0
- ml4t/diagnostic/splitters/AGENT.md +19 -0
- ml4t/diagnostic/splitters/__init__.py +36 -0
- ml4t/diagnostic/splitters/base.py +501 -0
- ml4t/diagnostic/splitters/calendar.py +421 -0
- ml4t/diagnostic/splitters/calendar_config.py +91 -0
- ml4t/diagnostic/splitters/combinatorial.py +1064 -0
- ml4t/diagnostic/splitters/config.py +322 -0
- ml4t/diagnostic/splitters/cpcv/__init__.py +57 -0
- ml4t/diagnostic/splitters/cpcv/combinations.py +119 -0
- ml4t/diagnostic/splitters/cpcv/partitioning.py +263 -0
- ml4t/diagnostic/splitters/cpcv/purge_engine.py +379 -0
- ml4t/diagnostic/splitters/cpcv/windows.py +190 -0
- ml4t/diagnostic/splitters/group_isolation.py +329 -0
- ml4t/diagnostic/splitters/persistence.py +316 -0
- ml4t/diagnostic/splitters/utils.py +207 -0
- ml4t/diagnostic/splitters/walk_forward.py +757 -0
- ml4t/diagnostic/utils/__init__.py +42 -0
- ml4t/diagnostic/utils/config.py +542 -0
- ml4t/diagnostic/utils/dependencies.py +318 -0
- ml4t/diagnostic/utils/sessions.py +127 -0
- ml4t/diagnostic/validation/__init__.py +54 -0
- ml4t/diagnostic/validation/dataframe.py +274 -0
- ml4t/diagnostic/validation/returns.py +280 -0
- ml4t/diagnostic/validation/timeseries.py +299 -0
- ml4t/diagnostic/visualization/AGENT.md +19 -0
- ml4t/diagnostic/visualization/__init__.py +223 -0
- ml4t/diagnostic/visualization/backtest/__init__.py +98 -0
- ml4t/diagnostic/visualization/backtest/cost_attribution.py +762 -0
- ml4t/diagnostic/visualization/backtest/executive_summary.py +895 -0
- ml4t/diagnostic/visualization/backtest/interactive_controls.py +673 -0
- ml4t/diagnostic/visualization/backtest/statistical_validity.py +874 -0
- ml4t/diagnostic/visualization/backtest/tearsheet.py +565 -0
- ml4t/diagnostic/visualization/backtest/template_system.py +373 -0
- ml4t/diagnostic/visualization/backtest/trade_plots.py +1172 -0
- ml4t/diagnostic/visualization/barrier_plots.py +782 -0
- ml4t/diagnostic/visualization/core.py +1060 -0
- ml4t/diagnostic/visualization/dashboards/__init__.py +36 -0
- ml4t/diagnostic/visualization/dashboards/base.py +582 -0
- ml4t/diagnostic/visualization/dashboards/importance.py +801 -0
- ml4t/diagnostic/visualization/dashboards/interaction.py +263 -0
- ml4t/diagnostic/visualization/dashboards.py +43 -0
- ml4t/diagnostic/visualization/data_extraction/__init__.py +48 -0
- ml4t/diagnostic/visualization/data_extraction/importance.py +649 -0
- ml4t/diagnostic/visualization/data_extraction/interaction.py +504 -0
- ml4t/diagnostic/visualization/data_extraction/types.py +113 -0
- ml4t/diagnostic/visualization/data_extraction/validation.py +66 -0
- ml4t/diagnostic/visualization/feature_plots.py +888 -0
- ml4t/diagnostic/visualization/interaction_plots.py +618 -0
- ml4t/diagnostic/visualization/portfolio/__init__.py +41 -0
- ml4t/diagnostic/visualization/portfolio/dashboard.py +514 -0
- ml4t/diagnostic/visualization/portfolio/drawdown_plots.py +341 -0
- ml4t/diagnostic/visualization/portfolio/returns_plots.py +487 -0
- ml4t/diagnostic/visualization/portfolio/risk_plots.py +301 -0
- ml4t/diagnostic/visualization/report_generation.py +1343 -0
- ml4t/diagnostic/visualization/signal/__init__.py +103 -0
- ml4t/diagnostic/visualization/signal/dashboard.py +911 -0
- ml4t/diagnostic/visualization/signal/event_plots.py +514 -0
- ml4t/diagnostic/visualization/signal/ic_plots.py +635 -0
- ml4t/diagnostic/visualization/signal/multi_signal_dashboard.py +974 -0
- ml4t/diagnostic/visualization/signal/multi_signal_plots.py +603 -0
- ml4t/diagnostic/visualization/signal/quantile_plots.py +625 -0
- ml4t/diagnostic/visualization/signal/turnover_plots.py +400 -0
- ml4t/diagnostic/visualization/trade_shap/__init__.py +90 -0
- ml4t_diagnostic-0.1.0a1.dist-info/METADATA +1044 -0
- ml4t_diagnostic-0.1.0a1.dist-info/RECORD +242 -0
- ml4t_diagnostic-0.1.0a1.dist-info/WHEEL +4 -0
- ml4t_diagnostic-0.1.0a1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
"""Template system for backtest tearsheets.
|
|
2
|
+
|
|
3
|
+
Provides persona-based templates that customize the tearsheet content
|
|
4
|
+
for different user types:
|
|
5
|
+
- quant_trader: Trade-level analysis, MFE/MAE, exit optimization
|
|
6
|
+
- hedge_fund: Risk-adjusted returns, cost attribution, drawdowns
|
|
7
|
+
- risk_manager: Statistical validity, DSR, confidence intervals
|
|
8
|
+
- full: Everything included
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from dataclasses import dataclass, field
|
|
14
|
+
from typing import TYPE_CHECKING, Literal
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class TearsheetSection:
|
|
22
|
+
"""Definition of a tearsheet section."""
|
|
23
|
+
|
|
24
|
+
name: str
|
|
25
|
+
title: str
|
|
26
|
+
enabled: bool = True
|
|
27
|
+
priority: int = 0 # Lower = higher priority (shown first)
|
|
28
|
+
description: str = ""
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass
|
|
32
|
+
class TearsheetTemplate:
|
|
33
|
+
"""Template configuration for a tearsheet."""
|
|
34
|
+
|
|
35
|
+
name: str
|
|
36
|
+
description: str
|
|
37
|
+
sections: list[TearsheetSection] = field(default_factory=list)
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def quant_trader(cls) -> TearsheetTemplate:
|
|
41
|
+
"""Template focused on trade-level analysis for quantitative traders.
|
|
42
|
+
|
|
43
|
+
Emphasizes:
|
|
44
|
+
- Trade execution efficiency (MFE/MAE)
|
|
45
|
+
- Exit reason analysis
|
|
46
|
+
- Trade-by-trade waterfall
|
|
47
|
+
- Duration and timing analysis
|
|
48
|
+
"""
|
|
49
|
+
return cls(
|
|
50
|
+
name="quant_trader",
|
|
51
|
+
description="Trade-level deep dive for strategy optimization",
|
|
52
|
+
sections=[
|
|
53
|
+
TearsheetSection("executive_summary", "Executive Summary", priority=0),
|
|
54
|
+
TearsheetSection("key_insights", "Key Insights", priority=1),
|
|
55
|
+
TearsheetSection("mfe_mae", "Exit Efficiency (MFE/MAE)", priority=2),
|
|
56
|
+
TearsheetSection("exit_reasons", "Exit Reason Breakdown", priority=3),
|
|
57
|
+
TearsheetSection("trade_waterfall", "Trade-by-Trade PnL", priority=4),
|
|
58
|
+
TearsheetSection("duration", "Trade Duration Analysis", priority=5),
|
|
59
|
+
TearsheetSection("consecutive", "Win/Loss Streaks", priority=6),
|
|
60
|
+
TearsheetSection("size_return", "Position Size Analysis", priority=7),
|
|
61
|
+
TearsheetSection("shap_errors", "SHAP Error Patterns", priority=8, enabled=False),
|
|
62
|
+
# Disabled by default
|
|
63
|
+
TearsheetSection("equity_curve", "Equity Curve", priority=10, enabled=False),
|
|
64
|
+
TearsheetSection("drawdowns", "Drawdowns", priority=11, enabled=False),
|
|
65
|
+
TearsheetSection("dsr", "Statistical Validity", priority=12, enabled=False),
|
|
66
|
+
],
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
@classmethod
|
|
70
|
+
def hedge_fund(cls) -> TearsheetTemplate:
|
|
71
|
+
"""Template focused on risk-adjusted returns for hedge fund managers.
|
|
72
|
+
|
|
73
|
+
Emphasizes:
|
|
74
|
+
- Portfolio performance metrics
|
|
75
|
+
- Drawdown analysis
|
|
76
|
+
- Cost attribution
|
|
77
|
+
- Risk metrics
|
|
78
|
+
"""
|
|
79
|
+
return cls(
|
|
80
|
+
name="hedge_fund",
|
|
81
|
+
description="Risk-adjusted performance for portfolio managers",
|
|
82
|
+
sections=[
|
|
83
|
+
TearsheetSection("executive_summary", "Executive Summary", priority=0),
|
|
84
|
+
TearsheetSection("key_insights", "Key Insights", priority=1),
|
|
85
|
+
TearsheetSection("equity_curve", "Equity Curve", priority=2),
|
|
86
|
+
TearsheetSection("drawdowns", "Drawdown Analysis", priority=3),
|
|
87
|
+
TearsheetSection("cost_waterfall", "Cost Attribution", priority=4),
|
|
88
|
+
TearsheetSection("cost_sensitivity", "Cost Sensitivity", priority=5),
|
|
89
|
+
TearsheetSection("rolling_metrics", "Rolling Performance", priority=6),
|
|
90
|
+
TearsheetSection("monthly_returns", "Monthly Returns Heatmap", priority=7),
|
|
91
|
+
TearsheetSection("annual_returns", "Annual Returns", priority=8),
|
|
92
|
+
# Disabled by default
|
|
93
|
+
TearsheetSection("mfe_mae", "Exit Efficiency", priority=10, enabled=False),
|
|
94
|
+
TearsheetSection("trade_waterfall", "Trade Details", priority=11, enabled=False),
|
|
95
|
+
TearsheetSection("dsr", "Statistical Tests", priority=12, enabled=False),
|
|
96
|
+
],
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
@classmethod
|
|
100
|
+
def risk_manager(cls) -> TearsheetTemplate:
|
|
101
|
+
"""Template focused on statistical validity for risk managers.
|
|
102
|
+
|
|
103
|
+
Emphasizes:
|
|
104
|
+
- Deflated Sharpe Ratio
|
|
105
|
+
- Confidence intervals
|
|
106
|
+
- Minimum track record length
|
|
107
|
+
- Tail risk metrics
|
|
108
|
+
"""
|
|
109
|
+
return cls(
|
|
110
|
+
name="risk_manager",
|
|
111
|
+
description="Statistical rigor for risk oversight",
|
|
112
|
+
sections=[
|
|
113
|
+
TearsheetSection("executive_summary", "Executive Summary", priority=0),
|
|
114
|
+
TearsheetSection(
|
|
115
|
+
"statistical_summary", "Statistical Validity Overview", priority=1
|
|
116
|
+
),
|
|
117
|
+
TearsheetSection("dsr_gauge", "Deflated Sharpe Ratio", priority=2),
|
|
118
|
+
TearsheetSection("confidence_intervals", "Metric Confidence Intervals", priority=3),
|
|
119
|
+
TearsheetSection("min_trl", "Minimum Track Record", priority=4),
|
|
120
|
+
TearsheetSection(
|
|
121
|
+
"ras_analysis", "RAS Overfitting Check", priority=5, enabled=False
|
|
122
|
+
),
|
|
123
|
+
TearsheetSection("drawdowns", "Drawdown Analysis", priority=6),
|
|
124
|
+
TearsheetSection("tail_risk", "Tail Risk (VaR/CVaR)", priority=7),
|
|
125
|
+
TearsheetSection("distribution", "Returns Distribution", priority=8),
|
|
126
|
+
# Disabled by default
|
|
127
|
+
TearsheetSection("mfe_mae", "Exit Efficiency", priority=10, enabled=False),
|
|
128
|
+
TearsheetSection("cost_waterfall", "Cost Attribution", priority=11, enabled=False),
|
|
129
|
+
],
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
@classmethod
|
|
133
|
+
def full(cls) -> TearsheetTemplate:
|
|
134
|
+
"""Complete template with all available sections."""
|
|
135
|
+
return cls(
|
|
136
|
+
name="full",
|
|
137
|
+
description="Comprehensive analysis with all available visualizations",
|
|
138
|
+
sections=[
|
|
139
|
+
# Executive
|
|
140
|
+
TearsheetSection("executive_summary", "Executive Summary", priority=0),
|
|
141
|
+
TearsheetSection("key_insights", "Key Insights", priority=1),
|
|
142
|
+
# Performance
|
|
143
|
+
TearsheetSection("equity_curve", "Equity Curve", priority=10),
|
|
144
|
+
TearsheetSection("drawdowns", "Drawdown Analysis", priority=11),
|
|
145
|
+
TearsheetSection("monthly_returns", "Monthly Returns", priority=12),
|
|
146
|
+
TearsheetSection("annual_returns", "Annual Returns", priority=13),
|
|
147
|
+
TearsheetSection("rolling_metrics", "Rolling Performance", priority=14),
|
|
148
|
+
# Trade Analysis
|
|
149
|
+
TearsheetSection("mfe_mae", "Exit Efficiency (MFE/MAE)", priority=20),
|
|
150
|
+
TearsheetSection("exit_reasons", "Exit Reason Breakdown", priority=21),
|
|
151
|
+
TearsheetSection("trade_waterfall", "Trade-by-Trade PnL", priority=22),
|
|
152
|
+
TearsheetSection("duration", "Trade Duration Analysis", priority=23),
|
|
153
|
+
TearsheetSection("consecutive", "Win/Loss Streaks", priority=24),
|
|
154
|
+
TearsheetSection("size_return", "Position Size Analysis", priority=25),
|
|
155
|
+
# Cost Attribution
|
|
156
|
+
TearsheetSection("cost_waterfall", "Cost Attribution", priority=30),
|
|
157
|
+
TearsheetSection("cost_sensitivity", "Cost Sensitivity", priority=31),
|
|
158
|
+
TearsheetSection("cost_by_asset", "Costs by Asset", priority=32),
|
|
159
|
+
# Statistical Validity
|
|
160
|
+
TearsheetSection("statistical_summary", "Statistical Validity", priority=40),
|
|
161
|
+
TearsheetSection("dsr_gauge", "Deflated Sharpe Ratio", priority=41),
|
|
162
|
+
TearsheetSection("confidence_intervals", "Confidence Intervals", priority=42),
|
|
163
|
+
TearsheetSection("min_trl", "Minimum Track Record", priority=43),
|
|
164
|
+
TearsheetSection("ras_analysis", "RAS Analysis", priority=44, enabled=False),
|
|
165
|
+
# Distribution & Risk
|
|
166
|
+
TearsheetSection("distribution", "Returns Distribution", priority=50),
|
|
167
|
+
TearsheetSection("tail_risk", "Tail Risk", priority=51),
|
|
168
|
+
# SHAP (optional, requires model)
|
|
169
|
+
TearsheetSection("shap_errors", "SHAP Error Patterns", priority=60, enabled=False),
|
|
170
|
+
],
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
def get_enabled_sections(self) -> list[TearsheetSection]:
|
|
174
|
+
"""Return only enabled sections, sorted by priority."""
|
|
175
|
+
return sorted(
|
|
176
|
+
[s for s in self.sections if s.enabled],
|
|
177
|
+
key=lambda s: s.priority,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
def enable_section(self, name: str) -> None:
|
|
181
|
+
"""Enable a section by name."""
|
|
182
|
+
for section in self.sections:
|
|
183
|
+
if section.name == name:
|
|
184
|
+
section.enabled = True
|
|
185
|
+
return
|
|
186
|
+
raise ValueError(f"Section '{name}' not found in template")
|
|
187
|
+
|
|
188
|
+
def disable_section(self, name: str) -> None:
|
|
189
|
+
"""Disable a section by name."""
|
|
190
|
+
for section in self.sections:
|
|
191
|
+
if section.name == name:
|
|
192
|
+
section.enabled = False
|
|
193
|
+
return
|
|
194
|
+
raise ValueError(f"Section '{name}' not found in template")
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def get_template(
|
|
198
|
+
name: Literal["quant_trader", "hedge_fund", "risk_manager", "full"] = "full",
|
|
199
|
+
) -> TearsheetTemplate:
|
|
200
|
+
"""Get a tearsheet template by name.
|
|
201
|
+
|
|
202
|
+
Parameters
|
|
203
|
+
----------
|
|
204
|
+
name : {"quant_trader", "hedge_fund", "risk_manager", "full"}
|
|
205
|
+
Template name
|
|
206
|
+
|
|
207
|
+
Returns
|
|
208
|
+
-------
|
|
209
|
+
TearsheetTemplate
|
|
210
|
+
The requested template
|
|
211
|
+
|
|
212
|
+
Examples
|
|
213
|
+
--------
|
|
214
|
+
>>> template = get_template("quant_trader")
|
|
215
|
+
>>> for section in template.get_enabled_sections():
|
|
216
|
+
... print(section.title)
|
|
217
|
+
"""
|
|
218
|
+
templates = {
|
|
219
|
+
"quant_trader": TearsheetTemplate.quant_trader,
|
|
220
|
+
"hedge_fund": TearsheetTemplate.hedge_fund,
|
|
221
|
+
"risk_manager": TearsheetTemplate.risk_manager,
|
|
222
|
+
"full": TearsheetTemplate.full,
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if name not in templates:
|
|
226
|
+
raise ValueError(f"Unknown template: {name}. Available: {list(templates.keys())}")
|
|
227
|
+
|
|
228
|
+
return templates[name]()
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
# CSS styles for HTML tearsheet
|
|
232
|
+
TEARSHEET_CSS = """
|
|
233
|
+
<style>
|
|
234
|
+
:root {
|
|
235
|
+
--primary-color: #636EFA;
|
|
236
|
+
--success-color: #00CC96;
|
|
237
|
+
--warning-color: #FECB52;
|
|
238
|
+
--danger-color: #EF553B;
|
|
239
|
+
--text-color: #2E2E2E;
|
|
240
|
+
--bg-color: #FFFFFF;
|
|
241
|
+
--card-bg: #F8F9FA;
|
|
242
|
+
--border-color: #DEE2E6;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
[data-theme="dark"] {
|
|
246
|
+
--primary-color: #636EFA;
|
|
247
|
+
--success-color: #00CC96;
|
|
248
|
+
--warning-color: #FECB52;
|
|
249
|
+
--danger-color: #EF553B;
|
|
250
|
+
--text-color: #E0E0E0;
|
|
251
|
+
--bg-color: #1E1E1E;
|
|
252
|
+
--card-bg: #2D2D2D;
|
|
253
|
+
--border-color: #404040;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
body {
|
|
257
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
|
|
258
|
+
color: var(--text-color);
|
|
259
|
+
background-color: var(--bg-color);
|
|
260
|
+
margin: 0;
|
|
261
|
+
padding: 20px;
|
|
262
|
+
line-height: 1.6;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.tearsheet-container {
|
|
266
|
+
max-width: 1400px;
|
|
267
|
+
margin: 0 auto;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.tearsheet-header {
|
|
271
|
+
text-align: center;
|
|
272
|
+
margin-bottom: 30px;
|
|
273
|
+
padding-bottom: 20px;
|
|
274
|
+
border-bottom: 2px solid var(--border-color);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.tearsheet-header h1 {
|
|
278
|
+
margin: 0 0 10px 0;
|
|
279
|
+
font-size: 2em;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.tearsheet-header .subtitle {
|
|
283
|
+
color: #666;
|
|
284
|
+
font-size: 1.1em;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.section {
|
|
288
|
+
margin-bottom: 40px;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.section-title {
|
|
292
|
+
font-size: 1.4em;
|
|
293
|
+
font-weight: 600;
|
|
294
|
+
margin-bottom: 20px;
|
|
295
|
+
padding-bottom: 10px;
|
|
296
|
+
border-bottom: 1px solid var(--border-color);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.chart-container {
|
|
300
|
+
background: var(--card-bg);
|
|
301
|
+
border-radius: 8px;
|
|
302
|
+
padding: 15px;
|
|
303
|
+
margin-bottom: 20px;
|
|
304
|
+
border: 1px solid var(--border-color);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.row {
|
|
308
|
+
display: flex;
|
|
309
|
+
flex-wrap: wrap;
|
|
310
|
+
margin: -10px;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.col-6 {
|
|
314
|
+
flex: 0 0 50%;
|
|
315
|
+
padding: 10px;
|
|
316
|
+
box-sizing: border-box;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.col-12 {
|
|
320
|
+
flex: 0 0 100%;
|
|
321
|
+
padding: 10px;
|
|
322
|
+
box-sizing: border-box;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
@media (max-width: 900px) {
|
|
326
|
+
.col-6 {
|
|
327
|
+
flex: 0 0 100%;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.footer {
|
|
332
|
+
text-align: center;
|
|
333
|
+
margin-top: 40px;
|
|
334
|
+
padding-top: 20px;
|
|
335
|
+
border-top: 1px solid var(--border-color);
|
|
336
|
+
color: #666;
|
|
337
|
+
font-size: 0.9em;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.timestamp {
|
|
341
|
+
font-size: 0.85em;
|
|
342
|
+
color: #888;
|
|
343
|
+
}
|
|
344
|
+
</style>
|
|
345
|
+
"""
|
|
346
|
+
|
|
347
|
+
HTML_TEMPLATE = """
|
|
348
|
+
<!DOCTYPE html>
|
|
349
|
+
<html lang="en" data-theme="{theme}">
|
|
350
|
+
<head>
|
|
351
|
+
<meta charset="UTF-8">
|
|
352
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
353
|
+
<title>{title}</title>
|
|
354
|
+
{css}
|
|
355
|
+
<script src="https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
|
|
356
|
+
</head>
|
|
357
|
+
<body>
|
|
358
|
+
<div class="tearsheet-container">
|
|
359
|
+
<header class="tearsheet-header">
|
|
360
|
+
<h1>{title}</h1>
|
|
361
|
+
<p class="subtitle">{subtitle}</p>
|
|
362
|
+
<p class="timestamp">Generated: {timestamp}</p>
|
|
363
|
+
</header>
|
|
364
|
+
|
|
365
|
+
{sections_html}
|
|
366
|
+
|
|
367
|
+
<footer class="footer">
|
|
368
|
+
<p>Generated by ml4t-diagnostic | State-of-the-art backtest analysis</p>
|
|
369
|
+
</footer>
|
|
370
|
+
</div>
|
|
371
|
+
</body>
|
|
372
|
+
</html>
|
|
373
|
+
"""
|