券商適配層與集成

本章面向準備對接新券商(或未來 QMT)的用戶與開發者:模擬券商之上的一層「統一櫃臺接口」長什麼樣、如何擴展。

讀者說明:若您剛入門模擬實盤,讀完 :doc:2-configuration-and-run 與 :doc:3-risk-and-order-lifecycle 即可;本章可暫時跳過。當您需要接入真實櫃檯或自定義 Broker 時再回來閱讀。

親愛的用戶,在 qteasy 裏,Broker(券商) 負責「收單 → 告訴您是否受理 → 異步推送成交」。默認的 simulator 用 live 價模擬這一切;我們設計了統一適配層,以便日後換成 QMT 等真實櫃檯時,Trader 主體邏輯儘量不用改。

0. 适用场景

  • 您希望對接新的券商,並與現有 Trader 邏輯兼容

  • 您需要先打通「提交 → 受理結果 → 成交回報 → 狀態更新」最小閉環

1. 核心概念:分层结构

典型 live 調用鏈(由外到內):

Operator.run_live_trade()
  → Trader(日程、风控、账本)
       → BrokerFacade(券商适配外壳:统一 API)
            → SimulatorBroker / 您注册的 Broker

BrokerFacade(適配外殼):像給不同券商櫃檯套上的統一翻譯層——Trader 只跟 Facade 說「connect / submit / poll_fills」,不必關心底層是模擬還是 QMT。

要點:

  • Facade 對外提供 connect / disconnect / submit_with_ack / poll_fills / get_remote_*

  • CLI 中 broker status|connect|disconnect 反映 is_connected(simulator 上表示「適配層已準備好」,不是真實券商登錄)

  • Trader 主循環通過 poll_fills 消費成交回報,而不是直接掏內部隊列

2. 核心接口(用户/开发者向)

Broker 適配層是 Trader 與具體券商(simulator、未來的 QMT 等)之間的統一接口。無論底層是誰,Trader 都用同一套「連接 → 遞單 → 聽受理 → 輪詢成交 → 必要時查遠端賬本」流程。下表先給出接口名與日常類比,便於閱讀後文對照表與接入清單。

各列含義接口爲適配層方法名;做什麼爲在 live 鏈路中的職責;您可以理解爲爲幫助記憶的比喻。

如何使用:接入新券商時,按 §6 清單逐項實現;日常運維只需關心 connectsubmit_with_ackpoll_fills 與 CLI broker status

接口

做什麼

您可以理解爲

connect / disconnect

建立/斷開適配層會話

櫃檯窗口開/關

is_connected

是否已 connect

窗口是否開着

submit_with_ack

遞單並同步得到受理與否

遞單後立即聽「收/不收」

cancel

撤單

撤銷未成交委託

poll_fills

取異步成交回報

問「有沒有新成交」

get_remote_*

查遠端現金/持倉/訂單

與券商賬本對賬(simulator 多爲佔位)

2.1 接口職責對照

同一接口在 simulator真實 QMT 上行爲深度不同:前者用 live 價模擬,後者對接櫃檯。下表幫助您建立預期——避免把 simulator 上的 connect 當成真實登錄,也便於規劃 QMT 接入時要補的能力。

各列含義接口同 §2;語義爲抽象職責;simulator 上您會看到爲當前默認模擬行爲;真實 QMT(規劃中) 爲後續目標(非當前版本承諾)。

如何使用:排錯時先看 simulator 列是否已滿足「受理 + 回報」;規劃 QMT 時以最後一列爲目標能力勾選。

接口

語義

simulator 上您會看到

真實 QMT(規劃中)

connect / disconnect

會話

內部標誌置位;非真實登錄

真實登錄與重連

submit_with_ack

同步受理

返回 accepted、模擬 broker_order_id 等

柜台真实受理结果(见 :doc:4a-xtquant-broker-adapter-contract-v1

poll_fills

異步回報

模擬成交隊列

真實成交推送/輪詢

get_remote_*

遠端賬本

常爲空或 None

對賬、門禁、sync 的數據源

cancel

撤單

模擬實現

真實撤單號映射

建議按「最小閉環」理解優先級:

  1. 连接:connect / is_connected

  2. 交易:submit_with_ack / cancel

  3. 回报:poll_fills

  4. 查詢:get_remote_*(對接真實櫃檯後才具備完整業務意義)

3. submit_with_ack 与本地订单

與風控拒單不同:風控在更前面,不入訂單表(見 :doc:3-risk-and-order-lifecycle)。

submit_with_ack 同步返回券商是否受理委託。下表僅描述受理階段本地訂單與 broker_order_id 的對應關係;成交進度見 :doc:3-risk-and-order-lifecycle 狀態表。

各列含義受理結果爲 ACK 中的 accepted 語義;本地訂單爲訂單表狀態走向;broker_order_id 爲是否回寫券商委託號。

如何使用:訂單 rejected 且 broker 號爲空 → 查「accepted=False」行;有 broker 號但長期不成交 → 查狀態表與 poll_fills

受理結果

本地訂單

broker_order_id

accepted=True

繼續流轉

回寫券商號與名稱

accepted=False

常为 rejected

保持空

詳細對照見 :doc:6-trader-snapshot-gate

提交前訂單結構與回報字段均經契約校驗,格式不對時會盡早報錯,避免「髒數據進賬本」。

4. 扩展新 Broker 类型

XtQuant / MiniQMT:配置项 live_trade_broker_type='xtquant' 已在 2.5.2 白名单中;实现细节与禁止双重下单等规则见英文契约 :doc:4a-xtquant-broker-adapter-contract-v1(协作方 PR 评审基准)。

註冊工廠(示例):

from qteasy.broker import register_broker_factory

register_broker_factory('my_broker', MyBrokerFactory)
# qt.configure(live_trade_broker_type='my_broker')

独立扩展包(推荐用于 QMT):

import qteasy_xtquant

qteasy_xtquant.register()
# qt.configure(live_trade_broker_type='xtquant')

CLI sync(別名 pull-state:當前爲預留,執行會列印 [NOT_IMPLEMENTED] ...,表示真實「從券商拉狀態」尚未實現;對接 QMT 後將替換爲可用實現。

5. 边界行为(接入时请注意)

  • connectsubmit / poll_fills:應得到明確錯誤,而非靜默失敗

  • cancel 未知委託號:應穩定返回「未撤成」

  • poll_fills 超時:應返回空列表,而非髒數據

  • simulator 上 connect 不代表真實券商會話,僅表示適配層可受理

6. 最小接入清单

  1. 实现 connect / disconnect / is_connected

  2. 打通 submit_with_ackpoll_fills

  3. 回報字段滿足契約校驗

  4. 實現 cancel 與異常路徑

  5. (若需門禁/對賬/sync)實現 get_remote_*

  6. 在 CLI 下驗證:broker statusreconcile、訂單映射

7. 最小验收标准

  • connectis_connected=True,可 submit_with_ack

  • 受理成功:本地訂單含 broker_order_id

  • 受理拒單:rejected 且 broker 字段空

  • poll_fills 回報可校驗

  • 未連接 / 未知單 / 超時行爲穩定

  • CLI broker / reconcile 可觀測

8. 相关跳转

  • 生命週期與風控::doc:3-risk-and-order-lifecycle

  • 產物與排錯::doc:5-artifacts-and-troubleshooting

  • 快照/門禁::doc:6-trader-snapshot-gate

  • CLI 对照::doc:8-cli-trader-capability-matrix

  • 設計說明:design/10-live-trading-s1.3-architecture.md