refactor QMT client and optimize API
This commit is contained in:
@@ -15,6 +15,9 @@ from sdk import Position
|
||||
STATUS_NONE = ""
|
||||
STATUS_ING = "ING"
|
||||
STATUS_OK = "OK"
|
||||
STATUS_FAILED = "FAILED"
|
||||
STATUS_CANCELED = "CANCELED"
|
||||
STATUS_UNKNOWN = "UNKNOWN"
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
@@ -110,6 +113,33 @@ class State:
|
||||
|
||||
self.save()
|
||||
|
||||
def reconcile(
|
||||
self,
|
||||
positions: Iterable[Position],
|
||||
orders: list[dict[str, str]],
|
||||
deals: list[dict[str, str]],
|
||||
) -> None:
|
||||
"""用真实持仓、委托和成交恢复本地状态,不增加持久化字段。"""
|
||||
position_list = list(positions)
|
||||
self.sync_positions(position_list)
|
||||
active_codes = {
|
||||
item.stock_code for item in position_list if item.volume > 0
|
||||
}
|
||||
for code in list(self.codes):
|
||||
if code not in active_codes:
|
||||
self.delete(code)
|
||||
|
||||
for code in list(self.codes):
|
||||
item = self.get(code)
|
||||
item.base_status = _reconcile_leg(
|
||||
item.base_order_id, item.base_status, orders, deals
|
||||
)
|
||||
item.added_status = _reconcile_leg(
|
||||
item.added_order_id, item.added_status, orders, deals
|
||||
)
|
||||
self.set(item)
|
||||
self.save()
|
||||
|
||||
def save(self) -> None:
|
||||
"""将内存状态格式化写入 JSON,并原子替换正式文件。"""
|
||||
with self.lock:
|
||||
@@ -144,3 +174,40 @@ class State:
|
||||
}
|
||||
except (TypeError, ValueError) as exc:
|
||||
raise ValueError(f"[状态] 状态字段无效: {exc}") from exc
|
||||
|
||||
|
||||
def _reconcile_leg(
|
||||
local_order_id: str,
|
||||
current_status: str,
|
||||
orders: list[dict[str, str]],
|
||||
deals: list[dict[str, str]],
|
||||
) -> str:
|
||||
if current_status != STATUS_ING or not local_order_id:
|
||||
return current_status
|
||||
if any(local_order_id in row.get("m_strRemark", "") for row in deals):
|
||||
return STATUS_OK
|
||||
order = next(
|
||||
(
|
||||
row for row in orders
|
||||
if local_order_id in row.get("m_strRemark", "")
|
||||
),
|
||||
None,
|
||||
)
|
||||
if order is None:
|
||||
return STATUS_UNKNOWN
|
||||
traded = _as_int(order.get("m_nVolumeTraded"))
|
||||
status = str(order.get("m_nOrderStatus", ""))
|
||||
if traded > 0 and status not in {"48", "49", "50", "51", "52", "55"}:
|
||||
return STATUS_OK
|
||||
if status in {"54", "56"}:
|
||||
return STATUS_CANCELED
|
||||
if status in {"57", "58"}:
|
||||
return STATUS_FAILED
|
||||
return STATUS_ING
|
||||
|
||||
|
||||
def _as_int(value: object) -> int:
|
||||
try:
|
||||
return int(value or 0)
|
||||
except (TypeError, ValueError):
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user