feat: add unified weight backtest result facade
This commit is contained in:
@@ -34,8 +34,8 @@ print(result.summary())
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
from collections.abc import Mapping, Sequence
|
from collections.abc import Mapping, Sequence
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
@@ -46,6 +46,26 @@ from quant_engine.metrics import summary as metrics_summary
|
|||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True, slots=True, eq=False)
|
||||||
|
class BacktestResult:
|
||||||
|
"""一次权重回测的稳定结果快照。"""
|
||||||
|
|
||||||
|
nav: pd.Series
|
||||||
|
returns: pd.Series
|
||||||
|
weights: pd.DataFrame
|
||||||
|
benchmark_nav: pd.Series | None = None
|
||||||
|
|
||||||
|
def stats(self, rf: float = 0.0) -> Mapping[str, float]:
|
||||||
|
"""返回标准绩效指标。"""
|
||||||
|
return metrics_summary(self.returns, rf)
|
||||||
|
|
||||||
|
def benchmark_report(self, rf: float = 0.0) -> pd.DataFrame:
|
||||||
|
"""返回策略与基准的对比报告。"""
|
||||||
|
if self.benchmark_nav is None:
|
||||||
|
raise ValueError("benchmark_nav is required for benchmark comparison")
|
||||||
|
return compare_to_benchmark(self.nav, self.benchmark_nav, rf)
|
||||||
|
|
||||||
|
|
||||||
# ── 调仓表 → 净值 ──────────────────────────────────────
|
# ── 调仓表 → 净值 ──────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
@@ -113,6 +133,29 @@ def compute_returns_from_nav(nav: pd.Series) -> pd.Series:
|
|||||||
return nav.pct_change().fillna(0.0)
|
return nav.pct_change().fillna(0.0)
|
||||||
|
|
||||||
|
|
||||||
|
def run_weight_backtest(
|
||||||
|
weights: pd.DataFrame,
|
||||||
|
stock_returns: pd.DataFrame,
|
||||||
|
initial_capital: float = 1.0,
|
||||||
|
tc_rate: float = 0.0,
|
||||||
|
benchmark_nav: pd.Series | None = None,
|
||||||
|
) -> BacktestResult:
|
||||||
|
"""执行权重回测并返回隔离于调用方输入的结果快照。"""
|
||||||
|
weights_snapshot = weights.copy(deep=True)
|
||||||
|
nav = compute_nav_from_weights(
|
||||||
|
weights=weights_snapshot,
|
||||||
|
stock_returns=stock_returns,
|
||||||
|
initial_capital=initial_capital,
|
||||||
|
tc_rate=tc_rate,
|
||||||
|
)
|
||||||
|
return BacktestResult(
|
||||||
|
nav=nav,
|
||||||
|
returns=compute_returns_from_nav(nav),
|
||||||
|
weights=weights_snapshot,
|
||||||
|
benchmark_nav=None if benchmark_nav is None else benchmark_nav.copy(deep=True),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# ── 调仓工具 ──────────────────────────────────────
|
# ── 调仓工具 ──────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user