feat: expose realized ledger position weights
This commit is contained in:
@@ -87,6 +87,47 @@ class FactorBacktestResult:
|
|||||||
name="returns",
|
name="returns",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def position_weights(self) -> pd.DataFrame:
|
||||||
|
"""按日末实际股数、收盘估值和账本 NAV 投影资产权重。"""
|
||||||
|
weights = pd.DataFrame(
|
||||||
|
0.0,
|
||||||
|
index=self.valuation_prices.index.copy(),
|
||||||
|
columns=self.valuation_prices.columns.copy(),
|
||||||
|
)
|
||||||
|
for date, position in zip(
|
||||||
|
self.valuation_prices.index,
|
||||||
|
self.execution.positions,
|
||||||
|
strict=True,
|
||||||
|
):
|
||||||
|
if position.portfolio_value <= 0:
|
||||||
|
raise ValueError(f"portfolio value must be positive on {date}")
|
||||||
|
for asset, shares in position.holdings.items():
|
||||||
|
weights.at[date, asset] = (
|
||||||
|
shares * float(self.valuation_prices.at[date, asset])
|
||||||
|
/ position.portfolio_value
|
||||||
|
)
|
||||||
|
return weights
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cash_weights(self) -> pd.Series:
|
||||||
|
"""返回与实际资产权重使用同一日末 NAV 分母的现金权重。"""
|
||||||
|
values = []
|
||||||
|
for date, position in zip(
|
||||||
|
self.valuation_prices.index,
|
||||||
|
self.execution.positions,
|
||||||
|
strict=True,
|
||||||
|
):
|
||||||
|
if position.portfolio_value <= 0:
|
||||||
|
raise ValueError(f"portfolio value must be positive on {date}")
|
||||||
|
values.append(position.cash / position.portfolio_value)
|
||||||
|
return pd.Series(
|
||||||
|
values,
|
||||||
|
index=self.valuation_prices.index.copy(),
|
||||||
|
dtype=float,
|
||||||
|
name="cash_weight",
|
||||||
|
)
|
||||||
|
|
||||||
def stats(self, rf: float = 0.0) -> Mapping[str, float]:
|
def stats(self, rf: float = 0.0) -> Mapping[str, float]:
|
||||||
"""复用标准绩效口径计算指标。"""
|
"""复用标准绩效口径计算指标。"""
|
||||||
return metrics_summary(self.returns, rf)
|
return metrics_summary(self.returns, rf)
|
||||||
|
|||||||
Reference in New Issue
Block a user