feat(backtest): 补全第5图VolatilityChart—metrics加rolling波动率时序+risk-series端点+前端接入(凑齐聚宽5图全套)
This commit is contained in:
@@ -156,6 +156,8 @@ export interface RiskSeriesData {
|
||||
alpha: number[]
|
||||
beta: number[]
|
||||
drawdown: number[]
|
||||
strategy_vol?: number[]
|
||||
benchmark_vol?: number[]
|
||||
}
|
||||
|
||||
export async function getRelativeMetrics(taskId: string): Promise<RelativeMetrics> {
|
||||
|
||||
@@ -13,6 +13,7 @@ import BenchmarkCurve from '@/components/backtest/BenchmarkCurve.vue'
|
||||
import AlphaChart from '@/components/backtest/AlphaChart.vue'
|
||||
import BetaChart from '@/components/backtest/BetaChart.vue'
|
||||
import DrawdownChart from '@/components/backtest/DrawdownChart.vue'
|
||||
import VolatilityChart from '@/components/backtest/VolatilityChart.vue'
|
||||
|
||||
const route = useRoute()
|
||||
const taskId = String(route.params.id)
|
||||
@@ -194,6 +195,13 @@ onMounted(async () => {
|
||||
:drawdown="filteredRiskSeries.drawdown"
|
||||
/>
|
||||
</el-card>
|
||||
<el-card>
|
||||
<VolatilityChart
|
||||
:dates="filteredRiskSeries.dates"
|
||||
:strategy="filteredRiskSeries.strategy_vol ?? []"
|
||||
:benchmark="filteredRiskSeries.benchmark_vol ?? []"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
|
||||
@@ -387,12 +387,16 @@ def risk_series(task_id: str):
|
||||
alpha = series.get("alpha", {})
|
||||
beta = series.get("beta", {})
|
||||
drawdown = series.get("drawdown", {})
|
||||
vol_s = series.get("volatility_strategy", {})
|
||||
vol_b = series.get("volatility_benchmark", {})
|
||||
|
||||
return {
|
||||
"dates": alpha.get("dates", []),
|
||||
"alpha": alpha.get("values", []),
|
||||
"beta": beta.get("values", []),
|
||||
"drawdown": drawdown.get("values", [])
|
||||
"drawdown": drawdown.get("values", []),
|
||||
"strategy_vol": vol_s.get("values", []),
|
||||
"benchmark_vol": vol_b.get("values", [])
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -64,11 +64,22 @@ def compute_metrics(
|
||||
cummax = equity.cummax()
|
||||
drawdown = (equity - cummax) / cummax
|
||||
|
||||
# Rolling annualized volatility (quarterly window) for the volatility chart
|
||||
_vol_window = min(63, len(s))
|
||||
if _vol_window >= 2:
|
||||
vol_strategy = s.rolling(_vol_window, min_periods=2).std() * np.sqrt(period)
|
||||
vol_benchmark = b.rolling(_vol_window, min_periods=2).std() * np.sqrt(period)
|
||||
else:
|
||||
vol_strategy = pd.Series([np.nan] * len(s), index=s.index)
|
||||
vol_benchmark = pd.Series([np.nan] * len(s), index=s.index)
|
||||
|
||||
series = {
|
||||
"equity_curve": equity,
|
||||
"benchmark_curve": bench_curve,
|
||||
"alpha": roll_alpha,
|
||||
"beta": roll_beta,
|
||||
"drawdown": drawdown,
|
||||
"volatility_strategy": vol_strategy,
|
||||
"volatility_benchmark": vol_benchmark,
|
||||
}
|
||||
return MetricsResult(scalars=scalars, series=series)
|
||||
|
||||
Reference in New Issue
Block a user