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,130 @@
|
|
|
1
|
+
"""Base report generation functionality."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from ml4t.diagnostic.results.base import BaseResult
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ReportFormat(str, Enum):
|
|
14
|
+
"""Supported report formats."""
|
|
15
|
+
|
|
16
|
+
HTML = "html"
|
|
17
|
+
JSON = "json"
|
|
18
|
+
MARKDOWN = "markdown"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ReportGenerator(ABC):
|
|
22
|
+
"""Base class for report generators.
|
|
23
|
+
|
|
24
|
+
Provides abstract interface for rendering evaluation results
|
|
25
|
+
into different formats (HTML, JSON, Markdown).
|
|
26
|
+
|
|
27
|
+
Subclasses must implement render() method.
|
|
28
|
+
|
|
29
|
+
Examples:
|
|
30
|
+
>>> generator = HTMLReportGenerator()
|
|
31
|
+
>>> report = generator.render(result)
|
|
32
|
+
>>> generator.save(report, "output.html")
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
@abstractmethod
|
|
36
|
+
def render(self, result: BaseResult, **options: Any) -> str:
|
|
37
|
+
"""Render result to string format.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
result: Evaluation result to render
|
|
41
|
+
**options: Format-specific rendering options
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Rendered report as string
|
|
45
|
+
"""
|
|
46
|
+
...
|
|
47
|
+
|
|
48
|
+
def save(self, content: str, filepath: str | Path) -> None:
|
|
49
|
+
"""Save rendered report to file.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
content: Rendered report content
|
|
53
|
+
filepath: Output file path
|
|
54
|
+
"""
|
|
55
|
+
path = Path(filepath)
|
|
56
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
57
|
+
path.write_text(content, encoding="utf-8")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class ReportFactory:
|
|
61
|
+
"""Factory for creating report generators.
|
|
62
|
+
|
|
63
|
+
Provides convenient access to all report generators via format enum.
|
|
64
|
+
|
|
65
|
+
Examples:
|
|
66
|
+
>>> generator = ReportFactory.create(ReportFormat.HTML)
|
|
67
|
+
>>> report = generator.render(result)
|
|
68
|
+
|
|
69
|
+
>>> # Or use convenience method
|
|
70
|
+
>>> report = ReportFactory.render(result, ReportFormat.MARKDOWN)
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
_generators: dict[ReportFormat, type[ReportGenerator]] = {}
|
|
74
|
+
|
|
75
|
+
@classmethod
|
|
76
|
+
def register(cls, format: ReportFormat, generator_class: type[ReportGenerator]) -> None:
|
|
77
|
+
"""Register a report generator for a format.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
format: Report format enum
|
|
81
|
+
generator_class: Generator class to register
|
|
82
|
+
"""
|
|
83
|
+
cls._generators[format] = generator_class
|
|
84
|
+
|
|
85
|
+
@classmethod
|
|
86
|
+
def create(cls, format: ReportFormat) -> ReportGenerator:
|
|
87
|
+
"""Create report generator for format.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
format: Desired report format
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
Report generator instance
|
|
94
|
+
|
|
95
|
+
Raises:
|
|
96
|
+
ValueError: If format not registered
|
|
97
|
+
"""
|
|
98
|
+
if format not in cls._generators:
|
|
99
|
+
raise ValueError(
|
|
100
|
+
f"No generator registered for format: {format}. Available: {list(cls._generators.keys())}"
|
|
101
|
+
)
|
|
102
|
+
return cls._generators[format]()
|
|
103
|
+
|
|
104
|
+
@classmethod
|
|
105
|
+
def render(cls, result: BaseResult, format: ReportFormat, **options: Any) -> str:
|
|
106
|
+
"""Convenience method to create generator and render in one call.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
result: Evaluation result to render
|
|
110
|
+
format: Desired report format
|
|
111
|
+
**options: Format-specific rendering options
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
Rendered report as string
|
|
115
|
+
|
|
116
|
+
Examples:
|
|
117
|
+
>>> report = ReportFactory.render(result, ReportFormat.HTML)
|
|
118
|
+
>>> report = ReportFactory.render(result, ReportFormat.JSON, indent=4)
|
|
119
|
+
"""
|
|
120
|
+
generator = cls.create(format)
|
|
121
|
+
return generator.render(result, **options)
|
|
122
|
+
|
|
123
|
+
@classmethod
|
|
124
|
+
def available_formats(cls) -> list[ReportFormat]:
|
|
125
|
+
"""List all registered report formats.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
List of available formats
|
|
129
|
+
"""
|
|
130
|
+
return list(cls._generators.keys())
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"""HTML report renderer with template support."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from ml4t.diagnostic.reporting.base import ReportFormat, ReportGenerator
|
|
8
|
+
from ml4t.diagnostic.results.base import BaseResult
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class HTMLReportGenerator(ReportGenerator):
|
|
12
|
+
"""Generate HTML reports from evaluation results.
|
|
13
|
+
|
|
14
|
+
Supports custom templates and styling.
|
|
15
|
+
|
|
16
|
+
Examples:
|
|
17
|
+
>>> generator = HTMLReportGenerator()
|
|
18
|
+
>>> report = generator.render(result, template="default")
|
|
19
|
+
>>> generator.save(report, "report.html")
|
|
20
|
+
|
|
21
|
+
>>> # Custom template
|
|
22
|
+
>>> custom_template = '''
|
|
23
|
+
... <html><body>
|
|
24
|
+
... <h1>{analysis_type}</h1>
|
|
25
|
+
... {content}
|
|
26
|
+
... </body></html>
|
|
27
|
+
... '''
|
|
28
|
+
>>> report = generator.render(result, custom_template=custom_template)
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
DEFAULT_TEMPLATE = """<!DOCTYPE html>
|
|
32
|
+
<html lang="en">
|
|
33
|
+
<head>
|
|
34
|
+
<meta charset="UTF-8">
|
|
35
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
36
|
+
<title>{title}</title>
|
|
37
|
+
<style>
|
|
38
|
+
body {{
|
|
39
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
40
|
+
max-width: 1200px;
|
|
41
|
+
margin: 0 auto;
|
|
42
|
+
padding: 20px;
|
|
43
|
+
background-color: #f5f5f5;
|
|
44
|
+
}}
|
|
45
|
+
.container {{
|
|
46
|
+
background-color: white;
|
|
47
|
+
padding: 30px;
|
|
48
|
+
border-radius: 8px;
|
|
49
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
50
|
+
}}
|
|
51
|
+
h1 {{
|
|
52
|
+
color: #2c3e50;
|
|
53
|
+
border-bottom: 2px solid #3498db;
|
|
54
|
+
padding-bottom: 10px;
|
|
55
|
+
}}
|
|
56
|
+
h2 {{
|
|
57
|
+
color: #34495e;
|
|
58
|
+
margin-top: 30px;
|
|
59
|
+
}}
|
|
60
|
+
.metadata {{
|
|
61
|
+
background-color: #ecf0f1;
|
|
62
|
+
padding: 15px;
|
|
63
|
+
border-radius: 4px;
|
|
64
|
+
margin-bottom: 20px;
|
|
65
|
+
}}
|
|
66
|
+
.metadata-item {{
|
|
67
|
+
margin: 5px 0;
|
|
68
|
+
}}
|
|
69
|
+
.summary {{
|
|
70
|
+
background-color: #fff9e6;
|
|
71
|
+
border-left: 4px solid #f39c12;
|
|
72
|
+
padding: 15px;
|
|
73
|
+
margin: 20px 0;
|
|
74
|
+
}}
|
|
75
|
+
table {{
|
|
76
|
+
width: 100%;
|
|
77
|
+
border-collapse: collapse;
|
|
78
|
+
margin: 20px 0;
|
|
79
|
+
}}
|
|
80
|
+
th {{
|
|
81
|
+
background-color: #3498db;
|
|
82
|
+
color: white;
|
|
83
|
+
padding: 12px;
|
|
84
|
+
text-align: left;
|
|
85
|
+
}}
|
|
86
|
+
td {{
|
|
87
|
+
padding: 10px;
|
|
88
|
+
border-bottom: 1px solid #ddd;
|
|
89
|
+
}}
|
|
90
|
+
tr:hover {{
|
|
91
|
+
background-color: #f5f5f5;
|
|
92
|
+
}}
|
|
93
|
+
.footer {{
|
|
94
|
+
margin-top: 40px;
|
|
95
|
+
padding-top: 20px;
|
|
96
|
+
border-top: 1px solid #ddd;
|
|
97
|
+
color: #7f8c8d;
|
|
98
|
+
font-size: 0.9em;
|
|
99
|
+
}}
|
|
100
|
+
</style>
|
|
101
|
+
</head>
|
|
102
|
+
<body>
|
|
103
|
+
<div class="container">
|
|
104
|
+
<h1>{title}</h1>
|
|
105
|
+
{metadata}
|
|
106
|
+
{summary}
|
|
107
|
+
{dataframes}
|
|
108
|
+
<div class="footer">
|
|
109
|
+
Generated by ML4T Diagnostic {version}
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
</body>
|
|
113
|
+
</html>"""
|
|
114
|
+
|
|
115
|
+
def render(self, result: BaseResult, **options: Any) -> str:
|
|
116
|
+
"""Render result to HTML format.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
result: Evaluation result to render
|
|
120
|
+
**options: HTML rendering options
|
|
121
|
+
- template: Template name or "default" (default: "default")
|
|
122
|
+
- custom_template: Custom HTML template string
|
|
123
|
+
- include_metadata: Include metadata section (default: True)
|
|
124
|
+
- include_dataframes: Include DataFrame tables (default: True)
|
|
125
|
+
- max_rows: Max rows to show in DataFrame tables (default: 50)
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
HTML string
|
|
129
|
+
"""
|
|
130
|
+
template = options.get("custom_template") or self.DEFAULT_TEMPLATE
|
|
131
|
+
include_metadata = options.get("include_metadata", True)
|
|
132
|
+
include_dataframes = options.get("include_dataframes", True)
|
|
133
|
+
max_rows = options.get("max_rows", 50)
|
|
134
|
+
|
|
135
|
+
# Build template variables
|
|
136
|
+
analysis_type = result.analysis_type.replace("_", " ").title()
|
|
137
|
+
title = f"{analysis_type} Report"
|
|
138
|
+
|
|
139
|
+
# Metadata section
|
|
140
|
+
metadata_html = ""
|
|
141
|
+
if include_metadata:
|
|
142
|
+
metadata_html = f"""
|
|
143
|
+
<div class="metadata">
|
|
144
|
+
<h2>Metadata</h2>
|
|
145
|
+
<div class="metadata-item"><strong>Analysis Type:</strong> {result.analysis_type}</div>
|
|
146
|
+
<div class="metadata-item"><strong>Created:</strong> {result.created_at}</div>
|
|
147
|
+
<div class="metadata-item"><strong>ML4T Diagnostic Version:</strong> {result.version}</div>
|
|
148
|
+
</div>
|
|
149
|
+
"""
|
|
150
|
+
|
|
151
|
+
# Summary section
|
|
152
|
+
summary_html = f"""
|
|
153
|
+
<div class="summary">
|
|
154
|
+
<h2>Summary</h2>
|
|
155
|
+
<pre>{self._escape_html(result.summary())}</pre>
|
|
156
|
+
</div>
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
# DataFrame sections
|
|
160
|
+
dataframes_html = ""
|
|
161
|
+
if include_dataframes:
|
|
162
|
+
try:
|
|
163
|
+
available_dfs = result.list_available_dataframes()
|
|
164
|
+
if available_dfs:
|
|
165
|
+
df_sections = []
|
|
166
|
+
for df_name in available_dfs:
|
|
167
|
+
df = result.get_dataframe(df_name)
|
|
168
|
+
|
|
169
|
+
# Limit rows if needed
|
|
170
|
+
if len(df) > max_rows:
|
|
171
|
+
display_df = df.head(max_rows)
|
|
172
|
+
caption = f"Showing first {max_rows} of {len(df)} rows"
|
|
173
|
+
else:
|
|
174
|
+
display_df = df
|
|
175
|
+
caption = ""
|
|
176
|
+
|
|
177
|
+
table_html = self._dataframe_to_html(
|
|
178
|
+
display_df, title=df_name.replace("_", " ").title(), caption=caption
|
|
179
|
+
)
|
|
180
|
+
df_sections.append(table_html)
|
|
181
|
+
|
|
182
|
+
dataframes_html = "\n".join(df_sections)
|
|
183
|
+
except (NotImplementedError, ValueError):
|
|
184
|
+
# Some results may not have DataFrames
|
|
185
|
+
pass
|
|
186
|
+
|
|
187
|
+
# Fill template
|
|
188
|
+
html = template.format(
|
|
189
|
+
title=title,
|
|
190
|
+
analysis_type=analysis_type,
|
|
191
|
+
metadata=metadata_html,
|
|
192
|
+
summary=summary_html,
|
|
193
|
+
dataframes=dataframes_html,
|
|
194
|
+
version=result.version,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
return html
|
|
198
|
+
|
|
199
|
+
def _dataframe_to_html(self, df, title: str = "", caption: str = "") -> str:
|
|
200
|
+
"""Convert Polars DataFrame to HTML table.
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
df: Polars DataFrame
|
|
204
|
+
title: Table title
|
|
205
|
+
caption: Optional caption
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
HTML table string
|
|
209
|
+
"""
|
|
210
|
+
html_parts = []
|
|
211
|
+
|
|
212
|
+
if title:
|
|
213
|
+
html_parts.append(f"<h2>{title}</h2>")
|
|
214
|
+
|
|
215
|
+
if caption:
|
|
216
|
+
html_parts.append(f"<p><em>{caption}</em></p>")
|
|
217
|
+
|
|
218
|
+
# Table header
|
|
219
|
+
html_parts.append("<table>")
|
|
220
|
+
html_parts.append("<thead><tr>")
|
|
221
|
+
for col in df.columns:
|
|
222
|
+
html_parts.append(f"<th>{self._escape_html(col)}</th>")
|
|
223
|
+
html_parts.append("</tr></thead>")
|
|
224
|
+
|
|
225
|
+
# Table body
|
|
226
|
+
html_parts.append("<tbody>")
|
|
227
|
+
for row in df.iter_rows():
|
|
228
|
+
html_parts.append("<tr>")
|
|
229
|
+
for val in row:
|
|
230
|
+
formatted = self._format_cell(val)
|
|
231
|
+
html_parts.append(f"<td>{formatted}</td>")
|
|
232
|
+
html_parts.append("</tr>")
|
|
233
|
+
html_parts.append("</tbody>")
|
|
234
|
+
html_parts.append("</table>")
|
|
235
|
+
|
|
236
|
+
return "\n".join(html_parts)
|
|
237
|
+
|
|
238
|
+
def _format_cell(self, value: Any) -> str:
|
|
239
|
+
"""Format cell value for HTML display.
|
|
240
|
+
|
|
241
|
+
Args:
|
|
242
|
+
value: Cell value
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
Formatted HTML string
|
|
246
|
+
"""
|
|
247
|
+
if value is None:
|
|
248
|
+
return "<em>null</em>"
|
|
249
|
+
elif isinstance(value, float):
|
|
250
|
+
return f"{value:.4f}"
|
|
251
|
+
else:
|
|
252
|
+
return self._escape_html(str(value))
|
|
253
|
+
|
|
254
|
+
def _escape_html(self, text: str) -> str:
|
|
255
|
+
"""Escape HTML special characters.
|
|
256
|
+
|
|
257
|
+
Args:
|
|
258
|
+
text: Text to escape
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
Escaped text
|
|
262
|
+
"""
|
|
263
|
+
return (
|
|
264
|
+
text.replace("&", "&")
|
|
265
|
+
.replace("<", "<")
|
|
266
|
+
.replace(">", ">")
|
|
267
|
+
.replace('"', """)
|
|
268
|
+
.replace("'", "'")
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
# Register with factory
|
|
273
|
+
from ml4t.diagnostic.reporting.base import ReportFactory # noqa: E402
|
|
274
|
+
|
|
275
|
+
ReportFactory.register(ReportFormat.HTML, HTMLReportGenerator)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""JSON report renderer."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from ml4t.diagnostic.reporting.base import ReportFormat, ReportGenerator
|
|
8
|
+
from ml4t.diagnostic.results.base import BaseResult
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class JSONReportGenerator(ReportGenerator):
|
|
12
|
+
"""Generate JSON reports from evaluation results.
|
|
13
|
+
|
|
14
|
+
Leverages BaseResult's built-in JSON serialization.
|
|
15
|
+
|
|
16
|
+
Examples:
|
|
17
|
+
>>> generator = JSONReportGenerator()
|
|
18
|
+
>>> report = generator.render(result, indent=2)
|
|
19
|
+
>>> generator.save(report, "report.json")
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def render(self, result: BaseResult, **options: Any) -> str:
|
|
23
|
+
"""Render result to JSON format.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
result: Evaluation result to render
|
|
27
|
+
**options: JSON rendering options
|
|
28
|
+
- indent: Indentation level (default: 2)
|
|
29
|
+
- exclude_none: Exclude None values (default: False)
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
JSON string
|
|
33
|
+
"""
|
|
34
|
+
indent = options.get("indent", 2)
|
|
35
|
+
exclude_none = options.get("exclude_none", False)
|
|
36
|
+
|
|
37
|
+
# Use BaseResult's built-in JSON export
|
|
38
|
+
if exclude_none:
|
|
39
|
+
# Get dict first, then convert to JSON
|
|
40
|
+
data = result.to_dict(exclude_none=True)
|
|
41
|
+
import json
|
|
42
|
+
|
|
43
|
+
return json.dumps(data, indent=indent)
|
|
44
|
+
else:
|
|
45
|
+
return result.to_json_string(indent=indent)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# Register with factory
|
|
49
|
+
from ml4t.diagnostic.reporting.base import ReportFactory # noqa: E402
|
|
50
|
+
|
|
51
|
+
ReportFactory.register(ReportFormat.JSON, JSONReportGenerator)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""Markdown report renderer."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from ml4t.diagnostic.reporting.base import ReportFormat, ReportGenerator
|
|
8
|
+
from ml4t.diagnostic.results.base import BaseResult
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MarkdownReportGenerator(ReportGenerator):
|
|
12
|
+
"""Generate Markdown reports from evaluation results.
|
|
13
|
+
|
|
14
|
+
Creates human-readable Markdown documentation from results.
|
|
15
|
+
|
|
16
|
+
Examples:
|
|
17
|
+
>>> generator = MarkdownReportGenerator()
|
|
18
|
+
>>> report = generator.render(result, include_metadata=True)
|
|
19
|
+
>>> generator.save(report, "report.md")
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def render(self, result: BaseResult, **options: Any) -> str:
|
|
23
|
+
"""Render result to Markdown format.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
result: Evaluation result to render
|
|
27
|
+
**options: Markdown rendering options
|
|
28
|
+
- include_metadata: Include metadata section (default: True)
|
|
29
|
+
- include_dataframes: Include DataFrame tables (default: True)
|
|
30
|
+
- max_rows: Max rows to show in DataFrame tables (default: 10)
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Markdown string
|
|
34
|
+
"""
|
|
35
|
+
include_metadata = options.get("include_metadata", True)
|
|
36
|
+
include_dataframes = options.get("include_dataframes", True)
|
|
37
|
+
max_rows = options.get("max_rows", 10)
|
|
38
|
+
|
|
39
|
+
sections = []
|
|
40
|
+
|
|
41
|
+
# Title
|
|
42
|
+
analysis_type = result.analysis_type.replace("_", " ").title()
|
|
43
|
+
sections.append(f"# {analysis_type} Report\n")
|
|
44
|
+
|
|
45
|
+
# Metadata section
|
|
46
|
+
if include_metadata:
|
|
47
|
+
sections.append("## Metadata\n")
|
|
48
|
+
sections.append(f"- **Analysis Type**: {result.analysis_type}")
|
|
49
|
+
sections.append(f"- **Created**: {result.created_at}")
|
|
50
|
+
sections.append(f"- **ML4T Diagnostic Version**: {result.version}\n")
|
|
51
|
+
|
|
52
|
+
# Summary section (all results have summary())
|
|
53
|
+
sections.append("## Summary\n")
|
|
54
|
+
sections.append(f"```\n{result.summary()}\n```\n")
|
|
55
|
+
|
|
56
|
+
# DataFrame sections (if available)
|
|
57
|
+
if include_dataframes:
|
|
58
|
+
try:
|
|
59
|
+
available_dfs = result.list_available_dataframes()
|
|
60
|
+
if available_dfs:
|
|
61
|
+
sections.append("## Data Tables\n")
|
|
62
|
+
for df_name in available_dfs:
|
|
63
|
+
df = result.get_dataframe(df_name)
|
|
64
|
+
sections.append(f"### {df_name.replace('_', ' ').title()}\n")
|
|
65
|
+
|
|
66
|
+
# Limit rows if needed
|
|
67
|
+
if len(df) > max_rows:
|
|
68
|
+
display_df = df.head(max_rows)
|
|
69
|
+
sections.append(f"*Showing first {max_rows} of {len(df)} rows*\n")
|
|
70
|
+
else:
|
|
71
|
+
display_df = df
|
|
72
|
+
|
|
73
|
+
# Convert to markdown table (basic implementation)
|
|
74
|
+
sections.append(self._dataframe_to_markdown(display_df))
|
|
75
|
+
sections.append("")
|
|
76
|
+
except (NotImplementedError, ValueError):
|
|
77
|
+
# Some results may not have DataFrames
|
|
78
|
+
pass
|
|
79
|
+
|
|
80
|
+
return "\n".join(sections)
|
|
81
|
+
|
|
82
|
+
def _dataframe_to_markdown(self, df) -> str:
|
|
83
|
+
"""Convert Polars DataFrame to Markdown table.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
df: Polars DataFrame
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Markdown table string
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
# Get column names
|
|
93
|
+
cols = df.columns
|
|
94
|
+
|
|
95
|
+
# Header
|
|
96
|
+
header = "| " + " | ".join(cols) + " |"
|
|
97
|
+
separator = "| " + " | ".join(["---"] * len(cols)) + " |"
|
|
98
|
+
|
|
99
|
+
# Rows
|
|
100
|
+
rows = []
|
|
101
|
+
for row in df.iter_rows():
|
|
102
|
+
formatted = []
|
|
103
|
+
for val in row:
|
|
104
|
+
# Format values
|
|
105
|
+
if isinstance(val, float):
|
|
106
|
+
formatted.append(f"{val:.4f}")
|
|
107
|
+
else:
|
|
108
|
+
formatted.append(str(val))
|
|
109
|
+
rows.append("| " + " | ".join(formatted) + " |")
|
|
110
|
+
|
|
111
|
+
return "\n".join([header, separator] + rows)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
# Register with factory
|
|
115
|
+
from ml4t.diagnostic.reporting.base import ReportFactory # noqa: E402
|
|
116
|
+
|
|
117
|
+
ReportFactory.register(ReportFormat.MARKDOWN, MarkdownReportGenerator)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# results/ - Result Dataclasses
|
|
2
|
+
|
|
3
|
+
Immutable results with `.to_dict()`, `.summary()`, `.get_dataframe()`.
|
|
4
|
+
|
|
5
|
+
## Modules
|
|
6
|
+
|
|
7
|
+
| File | Purpose |
|
|
8
|
+
|------|---------|
|
|
9
|
+
| base.py | `BaseResult` abstract |
|
|
10
|
+
| feature_results.py | Feature diagnostics |
|
|
11
|
+
| sharpe_results.py | DSR, PSR results |
|
|
12
|
+
| event_results.py | Event study results |
|
|
13
|
+
| portfolio_results.py | Portfolio analysis |
|
|
14
|
+
|
|
15
|
+
## Subdirectories
|
|
16
|
+
|
|
17
|
+
| Directory | Purpose |
|
|
18
|
+
|-----------|---------|
|
|
19
|
+
| signal_results/ | Signal analysis results (7 modules) |
|
|
20
|
+
| barrier_results/ | Barrier analysis results (6 modules) |
|
|
21
|
+
|
|
22
|
+
## Key Classes
|
|
23
|
+
|
|
24
|
+
`SignalResult`, `BarrierTearSheet`, `DSRResult`, `FeatureDiagnosticsResult`, `EventStudyResult`
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""Type-safe Pydantic result schemas for all evaluation outputs.
|
|
2
|
+
|
|
3
|
+
This module provides structured result schemas for:
|
|
4
|
+
- Feature diagnostics (Module A)
|
|
5
|
+
- Cross-feature analysis (Module B)
|
|
6
|
+
- Feature-outcome relationships (Module C)
|
|
7
|
+
- Portfolio evaluation (Module D)
|
|
8
|
+
- Sharpe framework analysis
|
|
9
|
+
|
|
10
|
+
All results support:
|
|
11
|
+
- JSON serialization
|
|
12
|
+
- DataFrame conversion
|
|
13
|
+
- Human-readable summaries
|
|
14
|
+
- Type-safe access via Pydantic validation
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from ml4t.diagnostic.results.barrier_results import (
|
|
18
|
+
BarrierTearSheet,
|
|
19
|
+
HitRateResult,
|
|
20
|
+
PrecisionRecallResult,
|
|
21
|
+
ProfitFactorResult,
|
|
22
|
+
TimeToTargetResult,
|
|
23
|
+
)
|
|
24
|
+
from ml4t.diagnostic.results.base import BaseResult
|
|
25
|
+
from ml4t.diagnostic.results.event_results import (
|
|
26
|
+
AbnormalReturnResult,
|
|
27
|
+
EventStudyResult,
|
|
28
|
+
)
|
|
29
|
+
from ml4t.diagnostic.results.feature_results import (
|
|
30
|
+
ACFResult,
|
|
31
|
+
CrossFeatureResult,
|
|
32
|
+
FeatureDiagnosticsResult,
|
|
33
|
+
FeatureOutcomeResult,
|
|
34
|
+
ICAnalysisResult,
|
|
35
|
+
StationarityTestResult,
|
|
36
|
+
ThresholdAnalysisResult,
|
|
37
|
+
)
|
|
38
|
+
from ml4t.diagnostic.results.multi_signal_results import (
|
|
39
|
+
ComparisonResult,
|
|
40
|
+
MultiSignalSummary,
|
|
41
|
+
)
|
|
42
|
+
from ml4t.diagnostic.results.portfolio_results import (
|
|
43
|
+
BayesianComparisonResult,
|
|
44
|
+
PortfolioEvaluationResult,
|
|
45
|
+
PortfolioMetrics,
|
|
46
|
+
)
|
|
47
|
+
from ml4t.diagnostic.results.sharpe_results import (
|
|
48
|
+
DSRResult,
|
|
49
|
+
FDRResult,
|
|
50
|
+
MinTRLResult,
|
|
51
|
+
PSRResult,
|
|
52
|
+
SharpeFrameworkResult,
|
|
53
|
+
)
|
|
54
|
+
from ml4t.diagnostic.results.signal_results import (
|
|
55
|
+
IRtcResult,
|
|
56
|
+
QuantileAnalysisResult,
|
|
57
|
+
RASICResult,
|
|
58
|
+
SignalICResult,
|
|
59
|
+
SignalTearSheet,
|
|
60
|
+
TurnoverAnalysisResult,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
__all__ = [
|
|
64
|
+
# Base
|
|
65
|
+
"BaseResult",
|
|
66
|
+
# Feature diagnostics (Module A)
|
|
67
|
+
"StationarityTestResult",
|
|
68
|
+
"ACFResult",
|
|
69
|
+
"FeatureDiagnosticsResult",
|
|
70
|
+
# Cross-feature (Module B)
|
|
71
|
+
"CrossFeatureResult",
|
|
72
|
+
# Feature-outcome (Module C)
|
|
73
|
+
"ICAnalysisResult",
|
|
74
|
+
"ThresholdAnalysisResult",
|
|
75
|
+
"FeatureOutcomeResult",
|
|
76
|
+
# Portfolio (Module D)
|
|
77
|
+
"PortfolioMetrics",
|
|
78
|
+
"BayesianComparisonResult",
|
|
79
|
+
"PortfolioEvaluationResult",
|
|
80
|
+
# Sharpe framework
|
|
81
|
+
"PSRResult",
|
|
82
|
+
"MinTRLResult",
|
|
83
|
+
"DSRResult",
|
|
84
|
+
"FDRResult",
|
|
85
|
+
"SharpeFrameworkResult",
|
|
86
|
+
# Signal analysis
|
|
87
|
+
"SignalICResult",
|
|
88
|
+
"RASICResult",
|
|
89
|
+
"QuantileAnalysisResult",
|
|
90
|
+
"TurnoverAnalysisResult",
|
|
91
|
+
"IRtcResult",
|
|
92
|
+
"SignalTearSheet",
|
|
93
|
+
# Event study
|
|
94
|
+
"AbnormalReturnResult",
|
|
95
|
+
"EventStudyResult",
|
|
96
|
+
# Multi-signal analysis
|
|
97
|
+
"MultiSignalSummary",
|
|
98
|
+
"ComparisonResult",
|
|
99
|
+
# Barrier analysis
|
|
100
|
+
"HitRateResult",
|
|
101
|
+
"ProfitFactorResult",
|
|
102
|
+
"PrecisionRecallResult",
|
|
103
|
+
"TimeToTargetResult",
|
|
104
|
+
"BarrierTearSheet",
|
|
105
|
+
]
|