Files
sanguo_vnpy_v2/tests/portfolio/test_runner_curves.py
T

67 lines
2.0 KiB
Python

"""runner_backtest 基准对齐/回撤/扩展指标 纯函数单测(B1)。"""
import pytest
from sanguo_portfolio.runner_backtest import (
_align_benchmark,
_compute_extended_metrics,
_extract_drawdown,
)
EQ = [
{"date": "2024-01-01", "equity": 100.0},
{"date": "2024-01-02", "equity": 110.0},
{"date": "2024-01-03", "equity": 99.0},
{"date": "2024-01-04", "equity": 120.0},
{"date": "2024-01-05", "equity": 90.0},
]
BD = [
{"date": "2024-01-01", "close": 200.0},
{"date": "2024-01-02", "close": 220.0},
{"date": "2024-01-03", "close": 210.0},
{"date": "2024-01-04", "close": 260.0},
{"date": "2024-01-05", "close": 208.0},
]
def test_drawdown_series():
dd = _extract_drawdown(EQ)
vals = [p["drawdown"] for p in dd]
assert vals[0] == 0.0 and vals[1] == 0.0 and vals[3] == 0.0
assert vals[2] == pytest.approx(-10.0)
assert vals[4] == pytest.approx(-25.0)
def test_align_benchmark_normalizes_and_matches_length():
bench = _align_benchmark(BD, EQ)
assert len(bench) == len(EQ)
assert bench[0]["benchmark"] == pytest.approx(1.0)
assert bench[4]["benchmark"] == pytest.approx(1.04)
def test_align_benchmark_ffill_missing_dates():
bench = _align_benchmark(BD[:2], EQ)
# 后 3 天无基准数据 → 前向填充 1.1
assert [p["benchmark"] for p in bench] == [1.0, 1.1, 1.1, 1.1, 1.1]
def test_align_benchmark_empty_inputs():
assert _align_benchmark([], EQ) == []
assert _align_benchmark(BD, []) == []
def test_extended_metrics_values():
bench = _align_benchmark(BD, EQ)
m = _compute_extended_metrics(EQ, bench)
assert m["benchmark_return"] == pytest.approx(4.0)
assert m["excess_return"] == pytest.approx(-14.0) # -10% 策略 - +4% 基准
assert m["beta"] == pytest.approx(1.0874, abs=1e-3)
assert "annual_volatility" in m
assert "sortino" in m
assert "calmar" in m
def test_extended_metrics_short_series():
assert _compute_extended_metrics([{"date": "d", "equity": 1.0}], []) == {}
assert _compute_extended_metrics([], []) == {}