fix(trader): vnpy 桥接(am/trading/cancel_all/__getattr__兜底) + create 异步回放

This commit is contained in:
2026-07-07 15:03:57 +08:00
parent eb6aa34b82
commit 17a4801450
2 changed files with 28 additions and 9 deletions
+19 -9
View File
@@ -55,20 +55,23 @@ class PaperCreateRequest(BaseModel):
@router.post("/paper/create", dependencies=[Depends(verify_token)])
def create_paper(req: PaperCreateRequest):
from sanguo_trader.persistence import init_db, save_account, update_account_status
from sanguo_trader.persistence import init_db, save_account
import threading
db = _db_path["path"] or ":memory:"
init_db(db)
aid = save_account(db, req.model_dump())
status = "created"
if req.mode == "replay": # 回放模式:建 account 后同步跑 engine.run
try:
_run_replay(db, aid, req)
status = "done"
update_account_status(db, aid, "done")
except Exception as e: # noqa: BLE001 — 回放失败不阻塞 create,状态记 failed
update_account_status(db, aid, "failed", str(e))
status = "failed"
if req.mode == "replay": # 回放后台线程跑,create 立即返回(避免阻塞 worker 502)
def _bg():
from sanguo_trader.persistence import update_account_status
try:
_run_replay(db, aid, req)
update_account_status(db, aid, "done")
except Exception as e: # noqa: BLE001
update_account_status(db, aid, "failed", str(e))
threading.Thread(target=_bg, daemon=True).start()
status = "running"
return {"account_id": aid, "status": status}
@@ -146,6 +149,13 @@ def _run_replay(db, aid, req: PaperCreateRequest):
listing_days=s.listing_days)
vt_symbol = f"{s.symbol}.{guess_exchange(s.symbol).value}"
strat = cls(cta, s.name, vt_symbol, s.params) # CtaTemplate(cta_engine, name, vt_symbol, setting)
strat.trading = True # 允许 send_order(等价 on_start
try:
from vnpy.trader.utility import ArrayManager
if not hasattr(strat, "am"):
strat.am = ArrayManager(100)
except Exception:
pass
cta.set_strategy(strat)
runners.append(StrategyRunner(s.name, strategy=strat, paper_cta_engine=cta,
symbol=s.symbol))
+9
View File
@@ -67,6 +67,15 @@ class PaperCtaEngine:
else:
self._cancel_one(vt_orderid)
def cancel_all(self, vt_symbol: str | None = None) -> None:
"""撤销所有挂单(纸面:清 pendingCtaTemplate.on_bar 开头常调)。"""
self.pending_orders = []
def __getattr__(self, name: str):
"""兜底未实现的 cta_engine 方法(load_bar/put_event/write_log/send_email
/get_data/load_tick 等)返回 no-op,避免 CtaTemplate 调用时 AttributeError。"""
return lambda *a, **kw: None
def _cancel_one(self, vt_orderid: str) -> None:
try:
idx = int(vt_orderid.rsplit(".", 1)[-1]) - 1