test: define daily ledger projection contract

This commit is contained in:
ao gong
2026-08-21 22:02:58 +08:00
parent b794ab2e8f
commit 1b39c53f18
+41
View File
@@ -583,6 +583,47 @@ def test_daily_ledger_nav_is_rebuildable_and_trades_are_projectable() -> None:
assert (trades["qty"] > 0).all() assert (trades["qty"] > 0).all()
def test_daily_ledger_frame_matches_platform_projection_contract() -> None:
"""核心层输出稳定日频投影,但不携带 run_id 或执行数据库写入。"""
config = ExecutionConfig(
commission_bps=0,
stamp_tax_bps=0,
slippage_bps=0,
min_trade_amount=0,
)
result = simulate_daily_ledger_with_audit(
target_weights_history=[("d1", {"A": 1.0})],
execution_price_history=[("d1", {"A": 10.0})],
valuation_price_history=[
("d0", {"A": 9.0}),
("d1", {"A": 11.0}),
("d2", {"A": 12.0}),
],
initial_cash=1_000.0,
config=config,
)
ledger = result.ledger_frame
assert ledger.columns.tolist() == [
"trade_date",
"portfolio_value",
"nav",
"pnl",
"pnl_pct",
"position_value",
"cash",
"turnover",
]
assert ledger["trade_date"].tolist() == ["d0", "d1", "d2"]
assert ledger["nav"].tolist() == pytest.approx([1.0, 1.1, 1.2])
assert ledger["pnl"].tolist() == pytest.approx([0.0, 100.0, 100.0])
assert ledger["pnl_pct"].tolist() == pytest.approx([0.0, 0.1, 1.2 / 1.1 - 1.0])
assert ledger["position_value"].tolist() == pytest.approx([0.0, 1_100.0, 1_200.0])
assert ledger["cash"].tolist() == pytest.approx([1_000.0, 0.0, 0.0])
assert ledger["turnover"].tolist() == pytest.approx([0.0, 1.0, 0.0])
def test_daily_ledger_rejects_missing_close_for_held_asset() -> None: def test_daily_ledger_rejects_missing_close_for_held_asset() -> None:
"""已有持仓缺少收盘估值价时必须 fail closed。""" """已有持仓缺少收盘估值价时必须 fail closed。"""
with pytest.raises(ValueError, match="missing valuation price for held asset A"): with pytest.raises(ValueError, match="missing valuation price for held asset A"):