fix(trader): vnpy 桥接(am/trading/cancel_all/__getattr__兜底) + create 异步回放
This commit is contained in:
@@ -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))
|
||||
|
||||
@@ -67,6 +67,15 @@ class PaperCtaEngine:
|
||||
else:
|
||||
self._cancel_one(vt_orderid)
|
||||
|
||||
def cancel_all(self, vt_symbol: str | None = None) -> None:
|
||||
"""撤销所有挂单(纸面:清 pending;CtaTemplate.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
|
||||
|
||||
Reference in New Issue
Block a user