風控與訂單生命週期
本章幫您弄清兩件事:訂單爲什麼有時「沒出去」;出去之後爲什麼有時一直「部分成交」。重點區分風控拒單與櫃檯拒單——這是 live 排錯最常見的坑。
親愛的用戶,模擬實盤裏「沒成交」並不總意味着策略沒信號。可能是本地風控攔下了,也可能是模擬券商不收單。我們把兩條路徑分開講,您就不會誤把風控拒單當成「券商壞了」。
0. 适用场景
您已能運行 live,但需要判斷「未成交 / 拒單 / 撤單」到底發生了什麼
您想把界面提示、日誌與訂單狀態串成同一條可解釋鏈路
1. 核心概念:两条「拒单」路径
很多用戶第一次遇到拒單,會以爲「都是券商拒的」。在 qteasy 裏,請先分清:
┌─ 风控拒单:复核台打回,委托单未入库、未递柜台
策略信号 → 订单意图 ─┤
└─ 柜台受理拒单:已入库,券商同步回复「不收」,status=rejected
↓(若受理成功)
异步成交回报 → partial-filled → filled
在 live 子系統中,訂單從策略信號到最終成交須經過 RiskManager(可選)→ 本地建單 → Broker 受理 → 成交回報 幾站。下表歸納三種結局——排錯時請先對號入座「類型」列,再按「優先查哪裏」打開對應日誌。
各列含義:類型爲路徑名稱;您會看到什麼爲界面/返回值特徵;訂單表有記錄嗎指本地 sys_op_trade_orders 是否新增行;優先查哪裏爲建議的第一份證據。
如何使用:CLI 出現英文 Order rejected by risk rule → 選「風控拒單」行 → 查 risk_log;訂單列表裏有 rejected 且無 broker 號 → 選「櫃檯受理拒單」行。
類型 |
您會看到什麼 |
訂單表有記錄嗎 |
優先查哪裏 |
|---|---|---|---|
風控拒單 |
CLI 英文拒因;提交結果爲空 |
沒有新行 |
|
櫃檯受理拒單 |
有訂單行, |
有 |
訂單表、trace |
受理成功 |
|
有,且通常有 |
訂單表、trade_log |
完整對照表見 :doc:6-trader-snapshot-gate。
RiskManager(風控管理器) 像下單前的複覈臺:按您組裝的規則鏈(白名單、單筆上限、交易時段等)依次檢查 OrderIntent(訂單意圖) 與 AccountSnapshot(賬戶快照);任一規則不通過則產出 RiskDecision(風控決策)——拒絕,並帶英文 reason 與 rule_id。
若放行,qteasy 才繼續建單、校驗,並交給 Broker(券商) 的 submit_with_ack 聽櫃檯是否受理。
2. 风控如何工作(用户视角)
在 live 下單前,若您爲 Trader 配置了 RiskManager:
qteasy 根據當前賬本組裝賬戶快照
把「這一筆打算下的單」交給規則鏈評估
拒絕:不寫訂單表、不進券商隊列;英文拒因寫入系統日誌與
risk_log放行:與未配風控時一樣,繼續提交
若您沒有傳入 RiskManager,則跳過本地規則鏈,直接進入建單與提交——行爲與舊版更接近。
2.1 規則示例(便於理解閾值)
RiskManager 在 Trader 提交訂單之前評估規則鏈——像複覈臺按 checklist 逐項打勾。下表列舉常見規則類型及用戶可見結果,幫助您理解 rule_id 與拒因;不是內置規則全量列表(規則由您在 Python 中組裝)。
各列含義:場景爲業務情境;您設定的規則爲規則語義;會發生什麼爲 live 中的表現。
如何使用:對照 risk_log 或 CLI 英文拒因中的 rule_id(如 MAX_ORDER_QTY)反查類似場景,再調整閾值或白名單。
示例:拒因含 MAX_ORDER_QTY → 對應「單筆數量」行 → 減小委託數量或提高規則上限。
場景 |
您設定的規則 |
會發生什麼 |
|---|---|---|
白名單 |
只允許 |
對 |
單筆數量 |
最多 500 股 |
要買 501 股 → 拒絕;500 股且其他通過 → 放行 |
交易時段 |
僅 9:30–11:30、13:00–15:00 |
午休下單 → 拒絕 |
日成交額 |
當日累計 + 本筆超上限 |
拒絕;未超 → 放行 |
組裝方式:在創建 Trader 前用 Python 構造 RiskManager([規則1, 規則2, ...]) 並傳入;不傳則關閉本地規則鏈。詳見 :doc:2-configuration-and-run 與教程。
2.2 用戶可見英文拒因示例
CLI/TUI 會顯示類似:
Order rejected by risk rule [MAX_ORDER_QTY]: order quantity exceeds limit
含義:風控規則 MAX_ORDER_QTY 認爲數量超限。請到 risk_log 搜 <RISK REJECTED> 覈對細節。
3. 订单状态生命周期
受理成功後,訂單在 live 中會經歷典型狀態(您可在 CLI orders 或日誌裏看到):
submitted → partial-filled → filled
也可能:
submitted → canceled
受理成功後,訂單在 live 中會經歷若干狀態(CLI orders 或日誌可見)。這些狀態描述「委託在券商側進行到哪一步」,與風控拒單(根本沒有 submitted)不同。下表覆蓋最常見狀態;完整枚舉以運行中實際輸出爲準。
各列含義:狀態爲英文狀態名;含義爲投資語義;您該關注什麼爲排查或確認時的檢查點。
如何使用:長期停在某一狀態 → 查該行「您該關注什麼」→ 必要時到 :doc:5-artifacts-and-troubleshooting 劇本 D/E。
狀態 |
含義 |
您該關注什麼 |
|---|---|---|
submitted |
櫃檯已收單,尚未全部成交 |
是否有 |
partial-filled |
部分成交,累計量 < 委託量 |
累計成交量是否在增加 |
filled |
累計成交量達到委託量 |
持倉與現金是否已更新 |
canceled |
已撤單 |
收盤或手動撤單後的終態 |
rejected |
櫃檯受理階段拒絕 |
broker 號通常爲空;不是風控拒單 |
排查思路:
「根本沒有 submitted」→ 先查風控與提交前校驗(§1 表)
「一直是 partial-filled」→ 查成交回報是否在持續到達(§4)
4. 分批成交与全部成交
當一筆大單分多筆成交時,狀態會先停在 partial-filled,像「委託只成交了一部分」。 當累計成交量達到委託數量時,qteasy 會將狀態更新爲 filled。若您看到長期 partial-filled,請對照成交回報與目標數量——有時只是行情或模擬撮合尚未湊滿整單。
5. 收盘后未成交订单
收盤後,qteasy 會通過 post_close 任務統一收尾當日未決訂單:
submitted/partial-filled:視爲曾進入櫃檯,收盤撤餘量,終態爲canceled(可能有撤單成交記錄)。created:視爲未成功報單的本地草稿(如報單鏈路中斷或歷史遺留),收盤置爲rejected,不與盤中櫃檯拒單混淆,也不寫入撤單型成交結果。
對您而言:收盤後請關注 post_close 相關日誌與 reconcile 對賬輸出,確認在途單是否已按規則收尾,而不必記憶內部 API 名稱。
6. 遇到异常时建议顺序
CLI/TUI 即時英文提示(先記下
rule_id或訂單號)risk_log:是否有<RISK REJECTED>(風控路徑)訂單與成交記錄:狀態序列、
broker_order_id是否回寫
更系統的決策樹見 :doc:5-artifacts-and-troubleshooting §3。
7. 快速判定清单
這筆單是否進入提交鏈路(訂單表或日誌裏能否找到)
若未提交:能否在
risk_log或界面找到rule_id/reason若已提交:是否有對應成交回報、狀態是否與累計量一致
拒單類型是否分清:風控(無訂單行)vs 櫃檯(
rejected行)
8. 相关跳转
配置啓動::doc:
2-configuration-and-run排錯手冊::doc:
5-artifacts-and-troubleshooting拒單與門禁細節::doc:
6-trader-snapshot-gateCLI 命令::doc:
8-cli-trader-capability-matrix