feat: expose platform-neutral ledger projection
This commit is contained in:
@@ -422,6 +422,50 @@ class ExecutionSimulationResult:
|
|||||||
]
|
]
|
||||||
return pd.DataFrame(rows, columns=columns)
|
return pd.DataFrame(rows, columns=columns)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ledger_frame(self) -> pd.DataFrame:
|
||||||
|
"""返回稳定的日频 Ledger 投影,不附加运行元数据或写数据库。"""
|
||||||
|
columns = [
|
||||||
|
"trade_date",
|
||||||
|
"portfolio_value",
|
||||||
|
"nav",
|
||||||
|
"pnl",
|
||||||
|
"pnl_pct",
|
||||||
|
"position_value",
|
||||||
|
"cash",
|
||||||
|
"turnover",
|
||||||
|
]
|
||||||
|
previous_value = self.initial_cash
|
||||||
|
rows: list[dict[str, float | str]] = []
|
||||||
|
daily_returns = self.daily_returns
|
||||||
|
for index, (position, daily) in enumerate(
|
||||||
|
zip(self.positions, self.daily_executions, strict=True)
|
||||||
|
):
|
||||||
|
daily_turnover = sum(
|
||||||
|
execution.executed_value
|
||||||
|
for execution in daily.executions
|
||||||
|
if execution.quantity > 0
|
||||||
|
)
|
||||||
|
turnover_rate = daily_turnover / daily.nav_before if daily.nav_before > 0 else 0.0
|
||||||
|
rows.append(
|
||||||
|
{
|
||||||
|
"trade_date": position.date,
|
||||||
|
"portfolio_value": position.portfolio_value,
|
||||||
|
"nav": (
|
||||||
|
position.portfolio_value / self.initial_cash
|
||||||
|
if self.initial_cash != 0
|
||||||
|
else 0.0
|
||||||
|
),
|
||||||
|
"pnl": position.portfolio_value - previous_value,
|
||||||
|
"pnl_pct": float(daily_returns.iloc[index]),
|
||||||
|
"position_value": position.portfolio_value - position.cash,
|
||||||
|
"cash": position.cash,
|
||||||
|
"turnover": turnover_rate,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
previous_value = position.portfolio_value
|
||||||
|
return pd.DataFrame(rows, columns=columns)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def total_costs(self) -> float:
|
def total_costs(self) -> float:
|
||||||
"""汇总实际成交产生的成本。"""
|
"""汇总实际成交产生的成本。"""
|
||||||
|
|||||||
Reference in New Issue
Block a user