群益API 委託回報 OnNewData 欄位與 Type 判讀的示意圖

群益API 委託回報怎麼解析?OnNewData 欄位的 5 個判讀重點

判斷買賣方向時,拿回報裡的 BuySell 欄跟 "B" 比,永遠比不到。把每一筆回報的數量加起來當成交量,結果比實際多。

群益API 委託回報是一串逗號分隔的欄位,而同一個欄位,在不同回報裡的意思不一樣。 光知道欄位在第幾個位置,還讀不懂一筆回報。

本文只談「讀懂一筆回報」。怎麼用回報去更新自己的掛單簿、怎麼對帳,見〈群益API 委託回報怎麼對帳〉。

群益API 委託回報 OnNewData 欄位與 Type 判讀的示意圖

群益API 委託回報長什麼樣?一串逗號分隔的欄位

委託回報由 OnNewData(string bstrUserID, string bstrData) 事件送來。官方對 bstrData 的說明是「每一筆資料以「,」分隔每一個欄位」,欄位依固定順序排列,用索引取值。

下面是本文會用到的重點欄位。索引依官方欄位表的順序,從 0 起算:

索引欄位說明
0KeyNo原始 13 碼委託序號(國內期選成交單沒有,見下文)
1MarketType市場別,例如 TF 期貨、TO 選擇權
2Type這筆是什麼回報
3OrderErrY 失敗、T 逾時、N 正常
6BuySell複合欄位,要逐字元讀
8ComId商品代碼
11Price價格,意思隨 Type 改變
20Qty數量,意思隨 Type 改變
23Date交易日期
24Time交易時間,含冒號的字串(例 01:02:03)
38ExecutionNo成交序號
44ErrorMsgOrderErr 為 Y 時的委託單錯誤訊息
47SeqNo13 碼序號
49Timefff國內期選的下單時間到毫秒(V2.13.59 新增)

完整的欄位表請見官方元件說明文件。

注意第 24 欄 Time:它是含冒號的字串,跟報價那邊的整數時間編碼不同(見〈群益API 報價價格為什麼是整數〉),解析方式要分開寫。

先看 Type:這筆是什麼回報?

讀一筆回報,第一步是看第 2 欄 Type。官方的定義是:

N:委託 C:取消 U:改量 P:改價D:成交 B:改價改量S:動態退單

再看第 3 欄 OrderErr:Y 是失敗、T 是逾時、N 是正常。OrderErr 為 Y 時,第 44 欄 ErrorMsg 是委託單錯誤訊息。

還要知道一件事:一筆委託會產生好幾筆回報。 官方備註舉的例子是(節錄):

被「動態退單」的委託,會收到委託回報、取消回報與動態退單回報,若有成交部位還會有成交回報。

群益API 委託回報的數量為什麼不能直接加總?

因為同一個欄位,意思會隨 Type 改變。官方欄位表是這樣寫的:

欄位Type = N(委託)Type = D(成交)Type = U(改量)Type = C(取消)
Price(第 11 欄)委託價成交價——
Qty(第 20 欄)委託量成交量減量數原委託剩量

把每一筆的 Qty 加總當成交量,會把改量的「減量數」和取消的「原委託剩量」也算進去。 成交量只能累加 Type = D 的 Qty。

累加成交量時,還有一件事要注意:〈群益API 下單初始化有哪 7 步〉講過,回報連線之後會先回補,OnComplete 到了才表示回補完成。回補送來的舊成交回報,Type 也是 D。 累加之前要把這一點考慮進去;同一筆成交怎麼去重,見〈群益API 委託回報怎麼對帳〉。

另外,官方對 Price 的說明是「價格,代表已經處理的價格」——回報裡的價格已經處理過小數,不需要像報價那樣除以 10 的 sDecimal 次方。複式單成交時,第 14 欄 Price1 是第一腳成交價、第 17 欄 Price2 是第二腳成交價。

BuySell 為什麼跟 “B” 比不到?要逐字元讀

因為官方把 BuySell 定義成複合欄位,每一個字元的位置代表不同的意思,而且不同市場別的定義也不一樣。國內期貨、選擇權的定義是:

位置意思
[0]B: 買 S: 賣
[1]Y: 當沖 N: 新倉 O: 平倉 7: 代沖銷
[2]I: IOC R: ROD F: FOK
[3]1: 市價 2: 限價 3: 範圍市價 4: 停損限價 5: 收市
[4]N/A

所以整欄跟 "B" 比對永遠不會相等。判斷買賣只取第 0 個字元。

證券、海期海選、複委託的 BuySell 每一位意思都不一樣,要依第 1 欄 MarketType 查官方表。這跟〈群益API 下單價格為什麼是字串〉講的 M 與時效代碼是同一個教訓:特殊值的意思要逐個查。

官方另有一個註記:刪單失敗單(例如預約單已被取消又再刪單)的 [0] 會顯示 0,不是 B 或 S。這條註記在官方表裡列在證券那一段。

國內期選的成交為什麼對不上原始委託序號?

因為國內期選的成交回報沒有這一欄。官方對第 0 欄 KeyNo 的說明是(節錄):

國內期選、海外市場:成交單無此欄 可使用新增的SeqNo 比對

所以用第 0 欄追國內期選的成交,會對不上。要用第 47 欄 SeqNo,官方說明是「13碼序號(成交單含IOC/FOK產生取消單)」。SeqNo 怎麼跟委託配對,見〈群益API 委託回報怎麼對帳〉。

其他幾個欄位也不是每筆都有:BeforeQty、AfterQty 僅提供證券、複委託市場;TradeDate 僅提供海外委託;PreOrder 與 Reserved(盤別)僅國內期、選委託。

欄位數為什麼不能寫死?

V2.13.59 在欄位表最尾端新增了 Timefff(國內期選的下單時間到毫秒),而官方對這個欄位的註記是(節錄):

預約單跟錯誤回報無提供

也就是說,同一個事件,不同回報型態的欄位數不一樣,換版也會增加。 前面所有欄位的位置沒有變。

用固定索引取前面的欄位;不要檢查「欄位數必須等於 N」,也不要用「取最後一欄」的方式取值。 索引超出範圍時,當成空字串處理。

先看第 0 欄是不是 980

官方範例程式會先判斷第 0 欄是否為 980,範例的註解寫「980(後台問題)」;是的話,整筆原樣顯示,不照欄位表解析。

在官方文件裡,980 只出現在這類事件資料字串的開頭,下單函式的回傳值說明裡沒有它。解析前先判斷第 0 欄;是 980 時整筆記錄下來,不要套欄位表。

群益API 委託回報的 7 條解析原則+程式碼

  1. 按索引解析,所有欄位走同一個解析入口,不要在程式各處各自寫索引。
  2. 先判斷第 0 欄是不是 980。
  3. 先看 Type,再讀其他欄位;OrderErr 為 Y 時看 ErrorMsg。
  4. 成交量只累加 Type = D 的 Qty,並注意回報回補送來的舊成交。
  5. 買賣方向只取 BuySell 的第 0 個字元;其他位置依市場別查官方表。
  6. 國內期選的成交用 SeqNo 比對,不要用 KeyNo。
  7. 不要檢查欄位數等於 N;索引超出範圍當空字串。
void OnNewData(string bstrUserID, string bstrData)
{
    string[] v = bstrData.Split(',');
    if (v[0] == "980") { LogRaw(bstrData); return; }       // 官方範例:980 開頭不套欄位表

    string F(int i) => i < v.Length ? v[i] : "";           // 欄位數不寫死:超出範圍當空字串

    string type     = F(2);                                 // N 委託 C 取消 U 改量 P 改價 D 成交 B 改價改量 S 動態退單
    string orderErr = F(3);                                 // Y 失敗 T 逾時 N 正常
    char   side     = F(6).Length > 0 ? F(6)[0] : ' ';      // BuySell 是複合欄位,買賣只看第 0 個字元
    string qty      = F(20);                                // 意思隨 Type 改變
    string seqNo    = F(47);                                // 國內期選成交用這個比對

    if (orderErr == "Y") { ShowError(F(44)); return; }      // ErrorMsg
    if (type == "D") AddFilledQty(side, qty);               // 成交量只累加成交回報(注意回報回補)
}

幾點補充:

  • string F(int i) => ... 用的是 C# 7 的區域函式,改寫成一般方法意思也一樣。
  • 解析本身很輕量,但之後要更新畫面或狀態時,照〈群益API 事件回呼跑在哪個執行緒〉的紀律,回呼裡只做收集。

常見問題

群益API 委託回報怎麼判斷買還是賣?

取 BuySell(第 6 欄)的第 0 個字元。官方把這一欄定義成複合欄位,國內期選的第 0 位是 B 買、S 賣,其他位置分別是新平倉、時效、價格類型,所以整欄跟 “B” 比對不會相等。

成交量要怎麼算?

只累加 Type = D(成交)的 Qty。依官方欄位表,Qty 在改量時是減量數、在取消時是原委託剩量。另外要注意,回報連線後回補送來的舊成交,Type 也是 D。

國內期選的成交回報要用哪一個序號比對?

用第 47 欄 SeqNo。官方寫明國內期選的成交單沒有第 0 欄 KeyNo,可使用 SeqNo 比對。

回報的欄位數為什麼跟文件不一樣?

不同回報型態的欄位數不同,換版也會增加。例如 V2.13.59 新增的 Timefff,官方註記預約單跟錯誤回報不提供。用固定索引取值,不要檢查欄位數。

風險揭露

期貨與選擇權屬高槓桿商品,價格波動可能造成超過原始保證金的損失,交易人須自負交易責任。本文為程式開發技術教學,說明委託回報欄位的判讀方式,不構成投資建議,也不保證任何交易結果。程式化交易並不降低市場風險,回報解析錯誤——例如把取消的剩量算成成交、或把買賣方向判斷錯——都可能讓程式對自己的部位產生錯誤認知並繼續下單。

投資人教育資源

機構資源
臺灣期貨交易所(TAIFEX)期貨及選擇權數位學習網
證券暨期貨市場發展基金會證券期貨市場教育推廣
金融智慧網金管會金融知識平台
中華民國期貨業商業同業公會期貨業法規與宣導
證券投資人及期貨交易人保護中心投資人保護與申訴

延伸閱讀

參考資料

  • OnNewData 的宣告、參數說明與備註,依群益官方元件說明文件「回報」章節;欄位表(含 Type、OrderErr、Price、Qty、BuySell、KeyNo、SeqNo 等欄位說明)依官方元件說明文件 V2.13.59 主手冊;Timefff 依 V2.13.59 版本說明。
  • 980 的判斷依官方範例程式。
  • 回報回補依官方 OnComplete 說明。

免責聲明

本文章僅作為群益API實作經驗分享,不構成投資建議,且策略及程式皆應自行撰寫。期貨及衍生性金融商品交易屬高風險投資,請謹慎評估自身風險承擔能力。

延伸閱讀|相關文章

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *