文件内容
paper_trading/dto.py
"""Runtime DTOs — in-memory order / quote / matching result.
These are intentionally minimal for the MVP. Rule-based matching (round_to /
CommissionInfo) lives in rules.py.
"""
from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime
from typing import Literal, Optional
Side = Literal["BUY", "SELL"]
OrderType = Literal["MARKET", "LIMIT"]
@dataclass(frozen=True)
class Order:
order_id: str
account_id: str
symbol: str
side: Side
type: OrderType
qty: float
price: Optional[float] = None
client_order_id: Optional[str] = None
tif: str = "DAY"
notes: Optional[str] = None
expires_at: Optional[datetime] = None # LIMIT DAY → session close (UTC)
@dataclass(frozen=True)
class Quote:
"""One quote tick projected to engine-facing shape.
``tags`` carries upstream semantic tags like '涨停' / '跌停' / '曾涨停'. Engine
uses bid/ask None as the primary liquidity signal; tags are kept for
richer reject messages and downstream observability.
"""
symbol: str
last: float
bid: Optional[float] = None
ask: Optional[float] = None
source_tier: str = "realtime" # realtime / yesterday / daily
server_ts: Optional[str] = None
prev_close: Optional[float] = None # upstream pre_close; CN 涨跌停校验
tags: tuple[str, ...] = ()
@dataclass(frozen=True)
class Fill:
order_id: str
fill_price: float
qty: float
fee: float
@dataclass(frozen=True)
class Reject:
order_id: str
code: str
message: str
@dataclass(frozen=True)
class Pending:
order_id: str
MatchResult = Fill | Reject | Pending