This commit is contained in:
2026-09-07 00:27:33 +08:00
parent fdcbdc7869
commit d37f9edefc
11 changed files with 839 additions and 384 deletions

View File

@@ -67,64 +67,52 @@ class OrderItem:
@dataclass(slots=True)
class DealItem:
"""由 QMT Deal 成交对象解析得到的标准成交记录。"""
"""Execution data from the API's fixed order-detail fields."""
id: str
order_id: str
code: str
side: str
remark: str
traded_at: datetime | None
volume: int
price: float
amount: float
sys_order_id: str = ""
local_order_id: str = ""
order_ref: str = ""
code: str = ""
instrument_id: str = ""
exchange_id: str = ""
name: str = ""
account_id: str = ""
commission: float = 0.0
trade_date: str = ""
trade_time: str = ""
offset_flag: str = ""
side: str = ""
status: str = ""
remaining_volume: int = 0
traded_volume: int = 0
order_time: int = 0
insert_date: str = ""
insert_time: str = ""
remark: str = ""
price: float = 0.0
trade_price: float = 0.0
trade_amount: float = 0.0
@classmethod
def from_trade_detail(cls, data: dict[str, Any]) -> "DealItem":
"""从 TradeDetailData 的 QMT Deal 原始字段创建成交记录。"""
instrument_id = str(data.get("m_strInstrumentID") or "")
exchange_id = str(data.get("m_strExchangeID") or "")
code = (
f"{instrument_id}.{exchange_id}"
if instrument_id and exchange_id
else instrument_id
)
remark = str(data.get("m_strRemark") or "")
trade_date = str(data.get("m_strTradeDate") or "")
trade_time = str(data.get("m_strTradeTime") or "")
offset_flag = str(data.get("m_nOffsetFlag") or "")
return cls(
id=str(data.get("m_strTradeID") or ""),
order_id=str(data.get("m_strOrderSysID") or ""),
code=code,
side={"23": "BUY", "24": "SELL", "48": "BUY", "49": "SELL"}.get(
str(data.get("m_nOffsetFlag")), ""
),
remark=remark,
traded_at=_parse_datetime(trade_date, trade_time),
volume=_number(data.get("m_nVolume"), int),
price=_number(data.get("m_dPrice")),
amount=_number(data.get("m_dTradeAmount")),
sys_order_id=str(data.get("m_strOrderSysID") or ""),
local_order_id=remark.split("|", 1)[0] if remark else "",
order_ref=str(data.get("m_strOrderRef") or ""),
code=f"{instrument_id}.{exchange_id}" if instrument_id and exchange_id else instrument_id,
instrument_id=instrument_id,
exchange_id=exchange_id,
name=str(data.get("m_strInstrumentName") or ""),
account_id=str(data.get("m_strAccountID") or ""),
commission=_number(
data.get(
"m_dCommission",
data.get("m_dComission", data.get("m_dComssion")),
)
),
trade_date=trade_date,
trade_time=trade_time,
offset_flag=offset_flag,
side={"23": "BUY", "24": "SELL", "48": "BUY", "49": "SELL"}.get(offset_flag, ""),
status=str(data.get("m_nOrderStatus") or ""),
remaining_volume=_number(data.get("m_nVolumeTotal"), int),
traded_volume=_number(data.get("m_nVolumeTraded"), int),
order_time=_number(data.get("m_nOrderTime"), int),
insert_date=str(data.get("m_strInsertDate") or ""),
insert_time=str(data.get("m_strInsertTime") or ""),
remark=remark,
price=_number(data.get("m_dPrice")),
trade_price=_number(data.get("m_dTradePrice")),
trade_amount=_number(data.get("m_dTradeAmount")),
)

View File

@@ -42,8 +42,8 @@ class PortfolioMixin:
return [OrderItem.from_trade_detail(row) for row in data]
def deals(self) -> list[DealItem]:
"""查询原始 Deal 成交对象并转换为标准成交记录。"""
return [DealItem.from_trade_detail(row) for row in self.org("deal")]
data = self._get_json("/api/portfolio/deal") or []
return [DealItem.from_trade_detail(row) for row in data]
def trade_detail_data(self, datatype: str) -> Any:
datatype = str(datatype).strip().lower()