群益API 報價訂閱的兩層管道示意圖,說明快照層與深度層的差別

群益API 報價訂閱有哪兩層?這 2 條管道決定你拿得到什麼資料

環境裝好了、登入過了、事件模型也搞懂了,接下來就是群益API 報價訂閱這一關——把報價接進來。然後你打開文件,看到 RequestStocksRequestTicks 兩個函式——名字都像是「訂報價」,但它們不是同一件事的兩種寫法。

它們是兩條獨立的管道:函式不同、事件不同、額度不同、訂閱語意也不同。 選錯了,你會拿到一堆不需要的資料,或者少掉你真正要的那一項。

群益API 報價訂閱的兩層管道示意圖,說明快照層與深度層的差別

群益API 報價訂閱有哪兩層?

快照層深度層
訂閱函式SKQuoteLib_RequestStocksSKQuoteLib_RequestTicks
一次可帶多檔,以半形逗號分隔,最多 100 檔一檔
拿得到什麼該商品的整體報價快照成交明細(逐筆 Tick)+五檔+當天 Tick 回補
主要事件OnNotifyQuoteLONGOnNotifyTicksLONGOnNotifyBest5LONGOnNotifyHistoryTicksLONG

群益API 報價訂閱選層的判準很單純:

  • 只要最新價、最佳一檔的快照層就夠了
  • 需要五檔的、需要逐筆成交明細 → 才用深度層。

不要因為「深度層資料比較多」就一律用它。 深度層的額度遠小於快照層,拿它來看「最新價」是把稀缺的額度花在便宜的需求上。額度的細節與成因是另一篇的主題,這裡只需要知道兩層各有各的額度,而且深度層少得多

群益API 報價訂閱之前:連上線和可以訂閱是兩件事

群益API 報價訂閱有一個共同的前置條件。官方規格對這兩個函式的備註寫了同一件事:必須先呼叫 SKQuoteLib_EnterMonitorLONG,並等 OnConnection 收到 SK_SUBJECT_CONNECTION_STOCKS_READY 之後,才能送訂閱。

「連上線」和「可以訂閱」是兩個不同的時間點。 太早送訂閱不會有結果——而且它不會告訴你太早了,你只會覺得訂閱沒反應。

(連線狀態碼的完整判讀是另一個主題,這裡只需要記得:等到就緒事件再訂。)

一個 Page 只能訂一檔——漏看這一行的代價

深度層的 bstrStockNo 參數,官方說明只有一句話:

商品代號,一個 Page 僅能索取一檔

psPageNo 的說明是「請從 0 開始」。

這一行字漏看的代價非常高,而且它正是群益API 報價訂閱最容易出事的地方。

如果你的訂閱程式把頁號寫死成同一個值——這是很自然會寫出來的第一版——那麼任何時刻只有最後訂閱的那一檔真的有深度流,其他檔會被靜默頂掉

而「靜默」的意思是:沒有錯誤碼、沒有例外、沒有任何事件告訴你被頂掉了。 你看到的畫面是五檔停在某個時間點不動、走勢圖凍結,其他一切正常。

這個症狀看起來就是「元件不穩定」,而且它曾經被這樣誤判了很長一段時間。 真正的根因只是頁號寫死。

由這個限制直接推導出來的做法

既然一個 Page 只能放一檔,那麼做群益API 報價訂閱時你必須自己維護一份「商品 ↔ 頁號」的對應:每一檔佔一個頁號,退訂的時候把頁號釋放回去。

這不是誰的設計偏好,是這個 API 限制直接逼出來的結果——任何人撞到「一頁一檔」都會得到同一個結論。至於這份對應表怎麼配置、放在程式的哪一層,那是你的架構自由。

這篇最值得帶走的一句話:規格文件裡的參數備註,要在第一次寫訂閱程式碼的時候就讀完。那些看起來像註腳的句子,可能就是你後面幾週卡關的原因。

psPageNo 是輸入,也是輸出

官方 IDL 對兩個函式的 psPageNo 都標示為 [in,out]——也就是說,元件可能回寫實際配置的頁號

所以呼叫之後要把值讀回來存好,不能假設它還是你帶進去的那個數字。否則你那份對應表會跟元件的實際狀態脫節,而脫節的後果就是上一節那個症狀:你以為某檔訂在 3 號頁,實際上不是。

// 快照層:一次可帶多檔,逗號分隔
short snapshotPage = 1;
m_pSKQuote.SKQuoteLib_RequestStocks(ref snapshotPage, "TXFL5,MXFL5");
// 呼叫後 snapshotPage 可能已被回寫,要以它現在的值為準

// 深度層:一個 Page 只能訂一檔,頁號從 0 開始
short depthPage = AllocateFreePage();   // 你自己的配頁機制
m_pSKQuote.SKQuoteLib_RequestTicks(ref depthPage, "TXFL5");
_pageOf["TXFL5"] = depthPage;           // 存回實際頁號,退訂時才釋放得掉

快照層的事件只給索引,內容要自己取

群益API 報價訂閱的快照層事件 OnNotifyQuoteLONG 只帶兩個數字:市場別與商品索引。它不給你報價內容。

實務上的作法是在回呼內同步呼叫 SKQuoteLib_GetStockByIndexLONG,用那兩個數字把 SKSTOCKLONG 結構取出來——這一步是實務歸納的作法,官方文件沒有明文規定要這樣做。

至於回呼裡能做什麼、不能做什麼,那四條紀律在〈群益API 事件回呼跑在哪個執行緒〉講過,這裡不重述。取完值就離開,其餘交給別的執行緒。

深度層訂閱會附帶當天回補,那不是即時成交

官方備註寫明:RequestTicks 含當天 Tick 回補,而回補走的是 OnNotifyHistoryTicksLONG 這個事件。

有兩件事要先知道:

  1. 訂閱的當下會先收到一批當天的歷史資料,數量可能不少。那些不是即時成交,不要當成新的成交事件去觸發你的邏輯。
  2. 重新訂閱同一檔會再回補一次。 如果你的程式會在斷線後重訂,同一批歷史資料就會再進來一次。

重複資料怎麼去重、對統計的影響,是後續篇章的主題。這裡只要你知道:那批資料會來,而且它跟即時 Tick 走不同的事件。

訂閱不存在的代碼不會報錯,只會永遠沒資料

群益API 報價訂閱最後一個容易踩的:訂閱一個不存在的商品代碼,不會得到錯誤碼。 它只是永遠沒有資料。

這又是一個沒有失敗訊號的狀況——你會以為是訂閱邏輯錯了、是額度問題、是連線沒好,然後查很久。

實務上的防呆是訂閱前先驗代碼:用 SKQuoteLib_GetStockByNoLONG 查一次,查不到就不要送訂閱,直接在自己的程式裡報錯。花一行程式碼,換掉一個無解的除錯情境。

常見問題

RequestStocks 和 RequestTicks 有什麼不同?

它們是兩條獨立的管道,不是同一件事的兩種寫法。前者是快照層,一次可帶多檔、最多 100 檔,拿的是整體報價快照;後者是深度層,一個 Page 只能訂一檔,拿的是逐筆成交明細、五檔與當天回補。

群益API 報價訂閱訂了好幾檔,為什麼只有一檔有五檔資料?

檢查頁號是不是寫死成同一個值。深度層一個 Page 只能索取一檔,後訂的會靜默頂掉先訂的——沒有錯誤、沒有事件,看起來就像元件壞了。每一檔要配自己的頁號。

群益API 報價訂閱我只想看最新價,該用哪一層?

快照層就夠了。深度層的額度遠小於快照層,用它來看最新價是把稀缺的額度花在便宜的需求上。

訂閱了一個代碼卻完全沒反應,是不是權限問題?

先確認兩件事:一是有沒有等到連線就緒事件才送訂閱,二是那個商品代碼存不存在。不存在的代碼會被靜默略過,不會回錯誤碼。

訂閱之後馬上收到一大批資料,那是即時成交嗎?

不是。深度層訂閱含當天 Tick 回補,那批資料走 OnNotifyHistoryTicksLONG,與即時 Tick 的事件不同。重新訂閱同一檔會再回補一次。

風險揭露

期貨與選擇權屬高槓桿商品,價格波動可能造成超過原始保證金的損失,交易人須自負交易責任。本文為程式開發技術教學,說明報價訂閱介面的行為與注意事項,不構成投資建議,也不保證任何交易結果。程式化交易並不降低市場風險,反而可能因程式錯誤造成非預期的委託行為——本文描述的靜默失敗正是這類風險的來源之一。

投資人教育資源

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

延伸閱讀

參考資料

  • 函式簽名、參數說明(一個 Page 僅能索取一檔、psPageNo 請從 0 開始、多筆以逗號分隔最多 100 檔)、事件對應與前置條件,均依官方元件說明文件。
  • 同頁新訂閱靜默頂掉先前訂閱、重新訂閱會再回補當天 Tick:實機測試結果。
  • 不存在代碼靜默略過、快照事件的取值方式:實作歸納,非官方文件記載。

免責聲明

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

延伸閱讀|相關文章

發佈留言

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