feat(trader): 影子账户 params 透传 factor 系 env——挑战者实例换因子通路(#69 影子A/B) [vps] [no-doc]

This commit is contained in:
2026-09-27 07:23:55 +08:00
parent 16641f0723
commit cc995faf00
2 changed files with 42 additions and 0 deletions
+11
View File
@@ -61,6 +61,17 @@ def account_env(acc: dict[str, Any], db_path: str) -> Dict[str, str]:
"SANGUO_SHADOW_MIN_COMM": _num(acc.get("min_commission") or 5),
"SANGUO_SHADOW_SLIPPAGE": repr(float(acc.get("slippage") or 0.001)),
})
# #69 影子A/B 挑战者换因子:params 因子五键存在则透传,缺键不设 env
# (不传时 live_strategy.py 代码内默认值兜底,在位者行为不变)
for key, env_key, conv in (
("factor_name", "SANGUO_LIVE_FACTOR_NAME", str),
("factor_dir", "SANGUO_LIVE_FACTOR_DIR", str),
("top_n", "SANGUO_LIVE_FACTOR_TOP_N", _num),
("reb_days", "SANGUO_LIVE_FACTOR_REB_DAYS", _num),
("band", "SANGUO_LIVE_FACTOR_BAND", _num),
):
if key in params:
env[env_key] = conv(params[key])
return env
+31
View File
@@ -62,3 +62,34 @@ def test_account_env_defaults_on_sparse_row():
assert env["SANGUO_LIVE_STRATEGY"] == "all_weather"
assert env["SANGUO_LIVE_CASH"] == "1000000"
assert env["SANGUO_SHADOW_ACCOUNT_ID"] == "9"
def test_account_env_factor_params_passthrough():
"""#69 影子A/B 挑战者:params factor 五键 → SANGUO_LIVE_FACTOR_* env 齐透传。"""
acc = {"id": 43, "strategies": json.dumps([{"name": "factor_topn", "params": {
"factor_name": "challenger_v1",
"factor_dir": r"C:\sanguo_vnpy_v2\data\factors\challenger",
"top_n": 200.0,
"reb_days": 21,
"band": 1.5,
}}]), "initial_capital": 1_000_000}
env = account_env(acc, "db")
assert env["SANGUO_LIVE_FACTOR_NAME"] == "challenger_v1"
# factor_dir 字符串原样透传
assert env["SANGUO_LIVE_FACTOR_DIR"] == r"C:\sanguo_vnpy_v2\data\factors\challenger"
assert env["SANGUO_LIVE_FACTOR_TOP_N"] == "200" # 整数不带小数点(200.0 → "200")
assert env["SANGUO_LIVE_FACTOR_REB_DAYS"] == "21"
assert env["SANGUO_LIVE_FACTOR_BAND"] == "1.5"
def test_account_env_factor_absent_not_set(monkeypatch):
"""params 无 factor 键:不设 SANGUO_LIVE_FACTOR_*(live_strategy 默认值兜底)。"""
for k in ("SANGUO_LIVE_FACTOR_NAME", "SANGUO_LIVE_FACTOR_DIR",
"SANGUO_LIVE_FACTOR_TOP_N", "SANGUO_LIVE_FACTOR_REB_DAYS",
"SANGUO_LIVE_FACTOR_BAND"):
monkeypatch.delenv(k, raising=False)
acc = {"id": 44, "strategies": json.dumps([{"name": "factor_topn",
"params": {"max_pool": 0}}]),
"initial_capital": None}
env = account_env(acc, "db")
assert not [k for k in env if k.startswith("SANGUO_LIVE_FACTOR_")]