feat(shadow-desk): P1-d 影子主管+通路策略增强(用户拍板): channel_test universe分6类资产各3只(宽基/行业/跨境商品ETF/主板蓝筹/中盘/创业板,个股只主板+创业板无科创北交铁律)hold 6只每日跨类型轮换;盘中4时点场景(9:35主调仓卖全买等权/10:45部分加减仓/13:45卖后买资金复用/14:30 T+1拒单探针)每天全场景,适配15m; shadow supervisor --auto轮询paper库自动拉起/停止/重启影子账户子进程(env映射SANGUO_LIVE_+SANGUO_SHADOW_契约); 11新测试 [vps]
CI/CD / test (push) Successful in 12s
CI/CD / nas-deploy (push) Successful in 32s
CI/CD / nas-verify (push) Successful in 15s

This commit is contained in:
2026-08-14 19:14:13 +08:00
parent 2ee6043592
commit f00730482f
5 changed files with 378 additions and 95 deletions
+64
View File
@@ -0,0 +1,64 @@
"""影子柜台主管(supervisor)纯逻辑测试:账户筛选 + env 映射。"""
from __future__ import annotations
import json
from sanguo_trader.persistence import init_db, save_account
from sanguo_trader.shadow.supervisor import account_env, load_shadow_accounts
def _mk_account(**kw) -> dict:
base = dict(
name="shadow-acc", mode="shadow", strategy_type="portfolio",
interval="15m", symbols=["hs300_subset"],
strategies=[{"name": "channel_test", "params": {"max_pool": 6,
"benchmark": "000905.XSHG"}}],
initial_capital=500_000, rate=0.00025, stamp_duty_rate=0.001,
min_commission=5, slippage=0.002,
start="2026-08-14", end="2026-12-31", engine="shadow",
)
base.update(kw)
return base
def test_load_shadow_accounts_filters(tmp_path):
db = str(tmp_path / "p.db")
init_db(db)
from sanguo_trader.persistence import update_account_status
a_shadow = save_account(db, _mk_account()) # 应选中
update_account_status(db, a_shadow, "running") # 创建后 API 置 running
a_stopped = save_account(db, _mk_account(name="stopped", strategies=[
{"name": "x", "params": {}}]))
update_account_status(db, a_stopped, "stopped") # 停止 → 不选
a_live = save_account(db, _mk_account(name="live", mode="live")) # 实走 → 不选
_ = a_live
accounts = load_shadow_accounts(db)
assert [a["id"] for a in accounts] == [a_shadow]
def test_account_env_mapping(tmp_path):
db = str(tmp_path / "p.db")
init_db(db)
aid = save_account(db, _mk_account())
from sanguo_trader.persistence import update_account_status
update_account_status(db, aid, "running")
acc = load_shadow_accounts(db)[0]
env = account_env(acc, db)
assert env["SANGUO_LIVE_STRATEGY"] == "channel_test"
assert env["SANGUO_LIVE_MAX_POOL"] == "6"
assert env["SANGUO_LIVE_BENCHMARK"] == "000905.XSHG"
assert env["SANGUO_LIVE_CASH"] == "500000"
assert env["SANGUO_SHADOW_DB"] == db
assert env["SANGUO_SHADOW_ACCOUNT_ID"] == str(aid)
assert env["SANGUO_SHADOW_COMMISSION"] == "0.00025"
assert env["SANGUO_SHADOW_SLIPPAGE"] == "0.002"
def test_account_env_defaults_on_sparse_row():
acc = {"id": 9, "strategies": json.dumps([]),
"initial_capital": None, "rate": None}
env = account_env(acc, "db")
assert env["SANGUO_LIVE_STRATEGY"] == "all_weather"
assert env["SANGUO_LIVE_CASH"] == "1000000"
assert env["SANGUO_SHADOW_ACCOUNT_ID"] == "9"