群益API 架構示意圖,說明 COM 元件與事件回呼的關係

群益API 是什麼?開始寫程式前必須知道的 5 個前提

想用程式自己讀報價、自己下單,第一步通常是找一份 API 文件,然後照著串。群益API 這一步會卡住——因為它根本不是架在網路上的服務,而是一組要安裝到你電腦裡、向 Windows 註冊之後才能用的元件。資料也不是你去要,而是它主動推給你。

很多人卡關不是程式寫錯,而是一開始就套錯了心智模型,於是每一步都在跟它的設計對抗。這篇整理動筆前該先知道的 5 個前提,每一條都會影響你的架構選擇。

群益API 架構示意圖,說明 COM 元件與事件回呼的關係

群益API 是什麼?先把定位講清楚

群益API 是群益期貨提供的 Windows 元件庫,用 COM(Component Object Model)技術封裝,供程式讀行情、送委託、收回報。它不是架在網路上的服務,而是安裝在你電腦裡、需要向作業系統註冊的二進位元件。

實務上會用到的物件主要有四個:

元件物件負責範圍常見進入點
SKCenterLib登入、錯誤碼文字查詢SKCenterLib_Login
SKQuoteLib行情連線、報價訂閱、K 線SKQuoteLib_RequestTicks
SKOrderLib憑證讀取、帳號查詢、送單SKOrderLib_Initialize
SKReplyLib委託與成交回報通道OnReplyMessage

這四個物件有先後依賴,不是四個可以各自初始化的獨立 SDK:登入成功才談得上行情連線,行情連線就緒才能訂閱,回報通道就緒才可以送單。

一個最容易被跳過的前置條件

依賴順序不只是建議,它會用錯誤碼擋你。登入之前必須先掛上 SKReplyLibOnReplyMessage 事件,並在處理常式裡把 sConfirmCode 設為 -1,否則 SKCenterLib_Login 不會回 0,而是回 2017SK_WARNING_REGISTER_REPLYLIB_ONREPLYMESSAGE_FIRST,官方說明:請註冊接收公告再登入)。

這裡要注意兩種語言的寫法不一樣:官方簽名中 sConfirmCode輸出參數而不是函式回傳值,所以 C# 是在處理常式裡寫 sConfirmCode = -1;;Python 的 comtypes 則以回傳值對應輸出參數,寫成 return -1

# 登入前必須先掛 OnReplyMessage,否則 Login 會回 2017
class SKReplyLibEvent:
    def OnReplyMessage(self, bstrUserID, bstrMessage):
        return -1  # comtypes 以回傳值對應輸出參數 sConfirmCode

reply_handler = comtypes.client.GetEvents(m_pSKReply, SKReplyLibEvent())
n_code = m_pSKCenter.SKCenterLib_Login("YOUR_ID", "YOUR_PASSWORD")
# n_code 為 0 才是登入成功;回 2017 代表事件沒掛成功

判斷事件有沒有掛成功,看的就是登入回 0 還是回 2017

先對齊幾個名詞

這個主題的術語密度偏高,而且多半來自 Windows 桌面開發的世界。先用一句話對齊,後面各篇都沿用同一套講法:

名詞一句話解釋
COMWindows 的元件技術,程式透過它呼叫別人寫好的二進位元件
註冊(register)把元件登記到作業系統,程式才找得到它
CLSID元件的識別碼;「擷取 CLSID 失敗」通常代表沒註冊成功
事件回呼(callback)元件主動呼叫你寫好的函式,把資料送回來
Interop 組件讓 .NET 程式能呼叫 COM 元件的轉接層
STA(單一執行緒 Apartment)COM 的執行緒歸屬規則;物件的方法只能由所屬那條執行緒直接呼叫

前提一:群益API 沒有 WebSocket 與 REST

這點最違反現代開發者的直覺。把官方規格文件整套翻過一遍,找不到任何 WebSocket 或 REST 端點;元件底層的訊息傳遞看得到 Solace 的痕跡,但它只以 COM 事件對外,沒有可以直接連線的網路位址。

這個前提直接決定三件事:

  • 語言選擇受限:程式必須能呼叫 COM。C# 走 Interop 組件最自然,Python 走 comtypes 也可行,但沒有「用 HTTP 客戶端接一接」的路徑。
  • 部署位置受限:元件在哪台機器,程式就得在哪台機器。想讓手機或雲端讀到報價,只能自己包一層橋接。
  • 橋接不會變出額度:橋接轉發的是你已經訂到的資料,沒有新增任何訂閱,所有下游共用同一份,多一跳還多一份延遲。額度的實際數字與確認方式見〈群益API 訂閱額度有多少〉。

把群益API 當成「本機函式庫」而不是「雲端服務」來設計,後面所有決策都會順很多。

前提二:資料是被推播的,不是你去查的

訂閱函式多半只回傳「有沒有受理」,真正的資料是稍後才來的:元件會主動呼叫你註冊的事件處理常式,把資料送回來。

更關鍵的是,有些事件只通知「哪一檔更新了」,不直接給內容。OnNotifyQuoteLONG 的參數就只有 sMarketNo(市場別)與 nStockIdx(商品索引)兩個數字;實務上的作法是在回呼內同步呼叫 SKQuoteLib_GetStockByIndexLONG,把那一刻的快照取出來:

// 報價通知只給市場別與索引,快照要在回呼內自己取
private void OnNotifyQuoteLONG(short sMarketNo, int nStockIdx)
{
    // 官方簽名第三個參數是 ref,變數必須先初始化
    SKSTOCKLONG stock = new SKSTOCKLONG();
    m_pSKQuote.SKQuoteLib_GetStockByIndexLONG(sMarketNo, nStockIdx, ref stock);

    // 回呼跑在元件自己的執行緒:只做最輕量的收集
    _quoteQueue.Enqueue(Snapshot.From(stock));
}

重點不在語法,而在註解那一行。群益API 的事件回呼跑在元件自己的執行緒上,不是你的主執行緒,因此回呼裡有四件事不能做:

  1. 不要直接更新畫面——先收集起來,再交給 UI 執行緒批次更新。
  2. 不要呼叫耗時的查詢函式——會拖慢事件流,後面的報價全部塞車。
  3. 不要阻塞等待——在回呼裡等結果,很容易把自己鎖死。
  4. 不要在回呼裡重入元件——部分函式在對應事件內同步呼叫時會靜默失效,回傳成功但事件整批不來。

這四條的成因、反例與正解,以及「為什麼把工作搬到背景不是通解」,在〈群益API 事件回呼跑在哪個執行緒〉整篇展開。

前提三:沒有模擬模式,每一次下單都是真單

群益API 沒有內建的模擬或紙上交易模式,所有下單呼叫都直連真實市場。這代表模擬功能必須由你自己在程式層做:送出前攔截、回一個假的委託序號、根本不呼叫下單函式。

還有一件事同樣重要:下單函式回傳 0,只代表委託送達交易所,不代表委託成立、更不代表成交。

你以為的意思實際的意思正確做法
回傳 0 = 下單成功只是送達交易所等回報事件確認
回傳 0 = 已經成交成交是另一類回報以成交回報為準
沒收到錯誤 = 一切正常有些失敗是靜默的主動比對委託狀態

測試階段請務必先把模擬開關做出來,再接上下單函式,這是整套介面裡代價最高的一個誤會。

前提四:環境綁死 Windows 64 位元與 COM 註冊

群益API 是 64 位元的 Windows COM 元件,需要 64 位元的 Windows 環境並安裝 .NET Framework 4.8 執行階段;32 位元系統與較舊的 Windows 版本載入不了。

註冊失敗時的錯誤訊息不會告訴你真正的原因。最典型的一條是登入跳「擷取元件 CLSID 失敗」,而根因可能在相依鏈的更深處:CTSecuritiesATL.dll 匯入了 VC++ 2010 的 mfc100.dll,而新電腦未必裝有 2010 那一版的執行階段,於是整條鏈從最底下斷掉。

看到的症狀實際發生的事
登入跳 CLSID 擷取失敗元件根本沒註冊成功
regsvr32 回 exit 3載入元件失敗,常見成因是相依項缺件
Win32 錯誤 126相依鏈中某個 DLL 找不到

診斷方向是固定的:逐一載入各個 DLL,找出回報 126 的那一個,再讀它的匯入表。完整排查流程另篇再談。

前提五:群益API 的行為會隨版本改變

欄位語意、回傳碼、事件觸發順序都相當細碎,而且版本之間會變動。最具代表性的一件事:新版新增了 9996SK_ERROR_UPDATE_API_REQUIRED,官方說明:此版本已無法登入,請更新版本),也就是說這套介面具備強制升版機制,仍在散布舊版元件的程式會在某個時點集體登入失敗。至於舊版何時真正被停用,官方並未公告時程。

版本相容性也容易誤解:舊的 Interop 組件搭配新的元件檔通常能跑,但只要用到新版才有的功能,就必須換新的 Interop 組件。「能跑」不等於「用得到新功能」。

因此有一條紀律值得從第一天就建立:任何函式語意、欄位位置、回傳碼一律先查官方文件,查不到就標「未確認」。憑記憶寫下的欄位索引,是這類整合專案裡最難追的一種錯。

群益API 與一般行情 API 的差別在哪?

把五個前提收斂成一張對照表:

面向一般雲端行情 API群益API
連線方式HTTP/WebSocket本機 COM 元件
取得資料主動請求事件回呼推播
開發語言幾乎不限需能呼叫 COM
部署位置任意主機綁 Windows 64 位元本機
模擬環境多半有沙箱沒有,需自行實作
版本升級多為向後相容需注意元件與 Interop 搭配

如果你熟悉的是雲端行情服務的開發節奏,右欄每一格都是要重新適應的地方。想先補足交易端的背景知識,可參考〈台指期是什麼〉與〈技術分析入門〉。

常見問題

群益API 可以用 Python 開發嗎?

可以,透過 COM 互通層(例如 comtypes)建立元件物件並掛事件。但執行緒模型有特定要求,設定不對時會出現「函式都回傳成功、事件卻一個都收不到」的無聲失敗——檢查點與解法見〈Python 接群益API 收不到事件〉。

沒有 WebSocket,可以自己包一層對外嗎?

技術上可行,把本機程式包成橋接服務即可。但連線數與訂閱數綁在帳號上,橋接不會讓額度變多。

群益API 可以跑在 Linux 或雲端主機上嗎?

不行。COM 是 Windows 的元件技術,需要 64 位元 Windows 環境並完成註冊。其他平台只能由一台 Windows 機器負責連線,再自行對外提供服務。

登入一直回 2017 是什麼意思?

代表 OnReplyMessage 事件還沒掛成功。這個事件必須在登入之前註冊,而且要在處理常式裡把 sConfirmCode 設為 -1(C# 寫 sConfirmCode = -1;,Python 的 comtypes 以 return -1 對應),登入才會回 0。

下單函式回傳 0,是不是代表成交了?

不是。回傳 0 只代表委託送達交易所,是否成立、是否成交都要以回報內容為準。

風險揭露

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

投資人教育資源

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

延伸閱讀

參考資料

免責聲明

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

延伸閱讀|相關文章

發佈留言

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