Files
sanguo_vnpy_v2/sanguo_trader/strategy_runner.py
T
claude_dev 42877213ae feat(trader): PaperEngine 主循环(逐bar重放/next_open缓冲/current_close/双层记账/持久化)
- run(): T+1解冻→撮合上根pending(用当前bar)→喂策略收单→current_close当根/next_open缓冲→盯市入库
- 双层记账一致性(总账=分户之和), checkpoint续跑字段
- StrategyRunner +symbol 字段 3 tests passed.
2026-07-07 12:01:37 +08:00

54 lines
2.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""模拟盘分户账:每策略持仓 + 已实现盈亏归因(spec §7 双层记账分户层)。
与 Account 共享同一笔 tradeAccount 记合并总账,StrategyRunner 记该策略归因。
"""
from .models import OrderSide, PaperTrade
from .position_ledger import PositionLedger
class StrategyRunner:
def __init__(self, strategy_id: str, strategy=None, paper_cta_engine=None,
symbol: str = "") -> None:
self.strategy_id: str = strategy_id
self.strategy = strategy
self.paper_cta_engine = paper_cta_engine
self.symbol: str = symbol
self.positions: dict[str, PositionLedger] = {}
self.realized_pnl: float = 0.0
self.commission_paid: float = 0.0
def _position(self, symbol: str) -> PositionLedger:
if symbol not in self.positions:
self.positions[symbol] = PositionLedger(symbol)
return self.positions[symbol]
def apply_trade(self, trade: PaperTrade) -> None:
pos = self._position(trade.symbol)
if trade.side == OrderSide.BUY:
pos.apply_buy(trade.price, trade.volume)
self.commission_paid += trade.commission + trade.transfer_fee
else:
avg = pos.avg_price
realized = (
(trade.price - avg) * trade.volume
- trade.commission - trade.stamp_duty - trade.transfer_fee
)
self.realized_pnl += realized
self.commission_paid += (
trade.commission + trade.stamp_duty + trade.transfer_fee
)
pos.apply_sell(trade.price, trade.volume)
def unfreeze_all(self) -> None:
"""每日开盘前:T+1 解冻分户持仓(与 Account.unfreeze_all 对称)。"""
for p in self.positions.values():
p.unfreeze()
def unrealized_pnl(self, bars_raw: dict[str, float]) -> float:
"""按 raw 收盘价算浮动盈亏(未实现)。"""
total = 0.0
for sym, p in self.positions.items():
if p.volume > 0:
total += (bars_raw.get(sym, p.avg_price) - p.avg_price) * p.volume
return total