from __future__ import annotations
import numpy as np
import pytest
from wbt import daily_performance
EXPECTED_KEYS = [
"绝对收益",
"年化",
"夏普",
"最大回撤",
"卡玛",
"日胜率",
"日盈亏比",
"日赢面",
"年化波动率",
"下行波动率",
"非零覆盖",
"盈亏平衡点",
"新高间隔",
"新高占比",
"回撤风险",
"回归年度回报率",
"长度调整平均最大回撤",
]
class TestDailyPerformance:
def test_known_values(self) -> None:
returns = np.array([0.01, -0.005, 0.02])
result = daily_performance(returns, yearly_days=252)
assert set(EXPECTED_KEYS) == set(result.keys())
assert result["绝对收益"] == pytest.approx(0.025)
assert result["年化"] == pytest.approx(2.1)
assert result["夏普"] == pytest.approx(10.0) assert result["最大回撤"] == pytest.approx(0.005)
assert result["卡玛"] == pytest.approx(20.0) assert result["日胜率"] == pytest.approx(0.6667, abs=1e-4)
assert result["日盈亏比"] == pytest.approx(3.0)
assert result["年化波动率"] == pytest.approx(0.1631, abs=1e-4)
assert result["非零覆盖"] == pytest.approx(1.0)
assert result["盈亏平衡点"] == pytest.approx(0.6667, abs=1e-4)
def test_all_zero(self) -> None:
returns = np.zeros(100)
result = daily_performance(returns)
assert result["绝对收益"] == pytest.approx(0.0)
assert result["年化"] == pytest.approx(0.0)
assert result["夏普"] == pytest.approx(0.0)
assert result["最大回撤"] == pytest.approx(0.0)
def test_empty_returns_default(self) -> None:
returns = np.array([], dtype=np.float64)
result = daily_performance(returns)
assert result["绝对收益"] == pytest.approx(0.0)
def test_yearly_days_proportional(self) -> None:
returns = np.array([0.002, -0.001] * 50)
r252 = daily_performance(returns, yearly_days=252)
r365 = daily_performance(returns, yearly_days=365)
assert r252["年化"] != 0.0
ratio = r365["年化"] / r252["年化"]
assert ratio == pytest.approx(365 / 252, rel=0.01)
def test_negative_returns_known(self) -> None:
returns = np.array([-0.01, -0.02, 0.005])
result = daily_performance(returns, yearly_days=252)
assert result["绝对收益"] == pytest.approx(-0.025)
assert result["日胜率"] == pytest.approx(0.3333, abs=1e-4) assert result["最大回撤"] == pytest.approx(0.02)
assert result["年化"] < 0