- research.PortfolioSpec(weighting=equal;max_position_pct/max_industry_weight_pct 预留) + ResearchSpec.portfolio;config_snapshot 自动记录组合配置 - quant/portfolio.py:equal_weight_budget(与既有等权回测语义一致,行为收敛到本模块)+ unimplemented_notes(设置约束即在结果中显式标注未建模,禁止假装支持) - TopKBacktestRunner 预算与 unimplemented 改用 portfolio 模块;默认配置数值不变 (一致性/quant 引擎回归通过);tests 补约束标注与 config_snapshot;全量 pytest 通过
32 lines
1.2 KiB
Python
32 lines
1.2 KiB
Python
"""Portfolio Engine(v2 §16)—— 组合构建模块(M8.2)。
|
||
|
||
MVP:等权资金拆分(与既有 TopK 回测等权语义一致,行为收敛到本模块);
|
||
单股/行业上限等约束为预留字段,未建模时由回测器写入 unimplemented
|
||
(禁止假装支持,AGENT.md §24)。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from app.domain.entities.research import PortfolioSpec
|
||
|
||
|
||
def equal_weight_budget(cash: float, target_count: int) -> float:
|
||
"""等权单标的预算:现金均分(target_count>0)。"""
|
||
if target_count <= 0:
|
||
return 0.0
|
||
return cash / target_count
|
||
|
||
|
||
def unimplemented_notes(portfolio: PortfolioSpec) -> list[str]:
|
||
"""组合层未建模项说明(默认空;设置约束即显式标注)。"""
|
||
notes: list[str] = []
|
||
if portfolio.max_position_pct is not None:
|
||
notes.append(
|
||
f"最大单股权重 {portfolio.max_position_pct:.0%} 约束未建模(Portfolio v1 仅等权)"
|
||
)
|
||
if portfolio.max_industry_weight_pct is not None:
|
||
notes.append(
|
||
f"最大行业权重 {portfolio.max_industry_weight_pct:.0%} 约束未建模(Portfolio v1 仅等权)"
|
||
)
|
||
return notes
|