fix(portfolio): run_backtest_json透传factor_topn四参——矩阵三跑全空仓总根因:CLI --json走本函数手工拼Namespace漏factor_dir(缺省空串→策略「未配置」直接空仓16秒假快),进程内诊断路径完整掩盖此bug;main --json分支params与Namespace双侧补齐+mock截获Namespace回归测试,全量1207绿 [vps]
This commit is contained in:
@@ -494,6 +494,13 @@ def run_backtest_json(params: Dict[str, Any]) -> Dict[str, Any]:
|
||||
stamp_duty_rate=float(params.get("stamp_duty_rate", 0.001)),
|
||||
min_commission=float(params.get("min_commission", 5.0)),
|
||||
slippage=float(params.get("slippage", 0.0)),
|
||||
# factor_topn 四参数(2026-09-12:漏透传=矩阵三跑全空仓的根因——
|
||||
# CLI --json 走本函数手工拼 Namespace,factor_dir 缺省空串使策略
|
||||
# 「factor_dir 未配置」直接空仓跑完)
|
||||
factor_name=params.get("factor_name", "composite_quant12_v2a"),
|
||||
factor_dir=params.get("factor_dir", ""),
|
||||
top_n=int(params.get("top_n", 100)),
|
||||
rebalance_days=int(params.get("rebalance_days", 21)),
|
||||
initial_positions=json.dumps(params["initial_positions"])
|
||||
if params.get("initial_positions") else "",
|
||||
)
|
||||
@@ -829,6 +836,10 @@ def main() -> None:
|
||||
"stamp_duty_rate": args.stamp_duty_rate,
|
||||
"min_commission": args.min_commission,
|
||||
"slippage": args.slippage,
|
||||
"factor_name": getattr(args, "factor_name", ""),
|
||||
"factor_dir": getattr(args, "factor_dir", ""),
|
||||
"top_n": getattr(args, "top_n", 100),
|
||||
"rebalance_days": getattr(args, "rebalance_days", 21),
|
||||
})
|
||||
print(json.dumps(result, ensure_ascii=False, default=str))
|
||||
else:
|
||||
|
||||
@@ -170,3 +170,27 @@ def test_initialize_registers_daily_schedule(factor_dir):
|
||||
st.broker.run_daily = lambda fn, t: calls.append((fn, t))
|
||||
st.initialize(_ctx("2024-10-08"))
|
||||
assert calls == [(st.rebalance, "9:30")]
|
||||
|
||||
|
||||
def test_run_backtest_json_passes_factor_topn_params(monkeypatch):
|
||||
"""CLI --json 路径(run_backtest_json 手工拼 Namespace)必须透传 factor 四参——
|
||||
2026-09-12 矩阵三跑全空仓根因: 漏透传→factor_dir=""→策略「未配置」直接空仓,
|
||||
而进程内 run_backtest(parse_args()) 路径完整(诊断一直成交掩盖此 bug)."""
|
||||
from sanguo_portfolio import runner_backtest
|
||||
captured: dict = {}
|
||||
|
||||
def _fake_run_backtest(args):
|
||||
captured.update({
|
||||
k: getattr(args, k, "<MISSING>")
|
||||
for k in ("factor_name", "factor_dir", "top_n", "rebalance_days")
|
||||
})
|
||||
return {}
|
||||
|
||||
monkeypatch.setattr(runner_backtest, "run_backtest", _fake_run_backtest)
|
||||
runner_backtest.run_backtest_json({
|
||||
"strategy": "factor_topn",
|
||||
"factor_name": "composite_test", "factor_dir": "/x/y",
|
||||
"top_n": 50, "rebalance_days": 10,
|
||||
})
|
||||
assert captured == {"factor_name": "composite_test", "factor_dir": "/x/y",
|
||||
"top_n": 50, "rebalance_days": 10}
|
||||
|
||||
Reference in New Issue
Block a user