群益API Python 入門:從安裝到收到第一筆報價的 7 個步驟
看完觀念,知道群益API 是一組 COM 元件、資料是推播過來的,接下來卻不知道 Python 的第一行要寫什麼。網路上的範例東拼西湊,有的用 PumpEvents、有的設 MTA、有的什麼都沒做,跑起來事件沒進來,也不報錯。
群益API Python 入門有固定的先後順序。每一步都有一個「做對了會看到的訊號」,看不到訊號,就不要往下走。
本文是一張步驟地圖:每一步寫做什麼、做對了會看到什麼、卡住了去看哪一篇。COM 元件與事件推播的觀念,見〈群益API 是什麼〉。

目錄
群益API Python 入門前要準備什麼?
| 準備項目 | 用途 |
|---|---|
| Windows 電腦 | 群益API 是 Windows 的 COM 元件,無法跨平台 |
| Python 64 位元 | 位元數要和元件一致 |
群益提供的元件包(含 SKCOM.dll) | 所有功能都在這個元件裡 |
| 帳號、密碼、有效憑證 | 登入用;官方說明是「請在登入前,安裝使用者帳號ID有效憑證」 |
| 帳戶側的前置條件已完成 | 行情連線需要;未完成時,商品資料會拿不到 |
最後一項屬於帳戶設定範疇,不是程式能處理的。如果有遇到這類的問題可以先跟您的營業員反應。
步驟 1–3:確認位元數、註冊元件、安裝套件
步驟 1:確認 Python 是 64 位元。
python -c "import struct,sys; print(sys.version, struct.calcsize('P')*8, 'bit')"做對了會看到:輸出裡有 64 bit。64 位元的 Python 要搭配 64 位元(x64)的元件;位元數不一致時,元件無法使用。要注意,載入型別的 GetModule 不會因此失敗,問題會出在後面建立元件物件的那一步(依微軟文件推論),細節見〈群益API Python 環境檢查〉。
步驟 2:註冊元件。
把元件包放在固定的位置,之後不要搬動;進入對應位元的資料夾,以系統管理員身分執行註冊。
做對了會看到:執行過程沒有出現錯誤訊息。是否真的註冊成功,要到步驟 4 建立 COM 物件時沒有報錯才確認得到。卡住時:
- 出現「擷取元件 CLSID 失敗」這類註冊錯誤,見〈群益API 註冊失敗怎麼處理〉。
- 元件被系統擋下、無法載入,見〈群益API 元件無法載入〉。
步驟 3:安裝 Python 套件。
python -m pip install comtypes pywin32comtypes:載入元件的型別、建立 COM 物件、掛上事件。pywin32:本文用它的pythoncom.PumpWaitingMessages()抽送訊息(步驟 4)。
步驟 4:群益API 登入前,為什麼要先掛 OnReplyMessage?
這一步要照下面的順序做,其中第 2、4 點的先後有官方依據:
- 用
comtypes.client.GetModule載入元件的型別,再建立SKCenterLib、SKReplyLib、SKQuoteLib三個物件。 - 登入之前,先掛上
SKReplyLib的OnReplyMessage,並回傳-1。 - 掛上
SKQuoteLib的事件(OnConnection、OnNotifyQuoteLONG)。 - 呼叫
SKCenterLib_Login,回傳0才往下走。 - 等待事件的期間,一定要抽送訊息。
第 2 點的官方說明是「需在登入前先註冊此通知事件—OnReplyMessage,方可正確登入,不需先做回報連線。」沒有掛、或沒有回 -1,登入會回 2017:
| 代碼 | 常數 | 官方說明 |
|---|---|---|
2017 | SK_WARNING_REGISTER_REPLYLIB_ONREPLYMESSAGE_FIRST | 請(註冊)接收公告再登入 / 請參考單元3-2 |
這裡有一個跨語言的差異:官方宣告裡,OnReplyMessage 的第三個參數 sConfirmCode 是輸出參數。C# 透過輸出參數交回這個值;Python 的 comtypes 則把輸出參數變成回傳值,所以 Python 的方法只收前兩個參數,用 return -1 交回。
comtypes 的使用注意: GetEvents 回傳的連線物件與事件接收物件,都要存在變數裡;物件被回收後,就收不到事件。
抽送訊息有兩條路:
- STA+
pythoncom.PumpWaitingMessages():本文範例用這一條。 - 改成 MTA:做法見〈Python 接群益API 收不到事件〉。
不要只靠 comtypes 的 PumpEvents。 我們在 SKCOM 2.13.59 x64、Python 3.12、comtypes 1.4.16 的環境實測:STA 下只用 PumpEvents,收不到連線事件;改用 PumpWaitingMessages,或改成 MTA,都收得到。為什麼 PumpEvents 不行,我們沒有查明。
做對了會看到:登入回 0。登入失敗時,第一件事是看元件自己的 log,官方錯誤碼 1001 的說明就是「登入失敗,請由LOG查看失敗原因。」其他登入錯誤碼的判讀,見〈群益API 登入錯誤怎麼判讀〉。
步驟 5:群益API 什麼時候才能訂閱報價?
- 呼叫
SKQuoteLib_EnterMonitorLONG(),建立行情連線。 - 等
OnConnection收到3003,才訂閱。官方說明是「*請先SKQuoteLib_EnterMonitorLONG,須等OnConnection收到SK_SUBJECT_CONNECTION_STOCKS_READY後,方可進行訂閱商品報價。」 - 呼叫
SKQuoteLib_RequestStocks訂閱,例如台指期近月的商品代碼TX00。 - 收到
OnNotifyQuoteLONG(sMarketNo, nIndex)之後,用SKQuoteLib_GetStockByIndexLONG取出報價。官方說明是「透過以上兩個參數,可以再使用SKQuoteLib_GetStockByIndexLONG 取出報價的內容。」 - 價格是整數,要除以 10 的
sDecimal次方。
幾點補充:
RequestStocks在 Python 的回傳: 官方宣告第一個參數psPageNo是[in,out],comtypes 會把它一起放進回傳值,所以要拆開來看回傳碼。頁號照官方範例傳1。- 商品代碼: 訂閱用的是
TX00這類商品代碼,不是交易所的合約代碼。 - 要在交易時段內測試,才看得到報價變動。
做對了會看到:OnConnection 會收到 3001(連線)與 3003(報價商品載入完成);等到 3003 才訂閱,訂閱回 0,接著報價事件進來。卡住時:
3001與3003的差別,見〈群益API 連線狀態碼怎麼解讀〉。- 報價有哪兩層訂閱,見〈群益API 報價訂閱有哪兩層〉。
- 訂閱額度與相關錯誤碼,見〈群益API 訂閱額度有多少〉。
- 價格整數的換算,見〈群益API 報價價格為什麼是整數〉。
步驟 6:怎麼確認自己用的元件版本?
第一次跑通時,呼叫一次 SKCenterLib_GetSKAPIVersionAndBit。官方說明是「取得目前註冊SKAPI 版本及位元。」,回傳值是「目前註冊SKAPI版本及COM位元。(EX: 2.13.30_x64)」。官方沒有說明這個函式要在登入前還是登入後呼叫,本文範例放在登入之後,只是示意。我們實測在登入前呼叫也能取得結果,見〈群益API Python 環境檢查〉。
如果你用的是舊的元件包,登入可能直接回 9996:
| 代碼 | 常數 | 官方說明 |
|---|---|---|
9996 | SK_ERROR_UPDATE_API_REQUIRED | 此版本已無法登入,請更新版本。 |
這不是帳密或憑證的問題,要換新版元件。哪些版本、什麼時候會開始回這個錯誤碼,官方沒有公告。升級的做法見〈群益API 版本升級要注意什麼〉。
群益API Python 最小範例:只用 comtypes 與 pywin32 的完整程式
步驟 4 到步驟 6 合在一起,就是下面這段程式。所有群益API 函式的名稱與參數順序,都對照過官方元件說明文件:
# 群益API Python 最小範例:登入 → 行情連線 → 等 3003 → 訂閱 → 印第一筆報價
# 環境:Windows、Python 64 位元、已註冊 64 位元元件、pip install comtypes pywin32
import time
import pythoncom
import comtypes.client
DLL_PATH = r"C:\SKCOM\x64\SKCOM.dll" # 改成你註冊的元件路徑
USER_ID = "YOUR_LOGIN_ID"
PASSWORD = "YOUR_PASSWORD"
comtypes.client.GetModule(DLL_PATH)
import comtypes.gen.SKCOMLib as sk
center = comtypes.client.CreateObject(sk.SKCenterLib, interface=sk.ISKCenterLib)
reply = comtypes.client.CreateObject(sk.SKReplyLib, interface=sk.ISKReplyLib)
quote = comtypes.client.CreateObject(sk.SKQuoteLib, interface=sk.ISKQuoteLib)
state = {"ready": False, "got_quote": False}
class ReplyEvents:
def OnReplyMessage(self, bstrUserID, bstrMessage):
# 官方:登入前必須註冊此事件,sConfirmCode 回傳 VARIANT_TRUE(-1)
return -1
class QuoteEvents:
def OnConnection(self, nKind, nCode):
print("OnConnection", nKind, nCode)
if nKind == 3003: # SK_SUBJECT_CONNECTION_STOCKS_READY
state["ready"] = True
def OnNotifyQuoteLONG(self, sMarketNo, nIndex):
# comtypes 會把 [in,out] 參數和回傳碼一起回傳:(結構, 回傳碼)
stock, code = quote.SKQuoteLib_GetStockByIndexLONG(sMarketNo, nIndex, sk.SKSTOCKLONG())
if code == 0:
price = stock.nClose / (10 ** stock.sDecimal)
print(stock.bstrStockNo, stock.bstrStockName, price)
state["got_quote"] = True
# 事件連線物件一定要存在變數裡,被回收就收不到事件
reply_sink, quote_sink = ReplyEvents(), QuoteEvents()
reply_conn = comtypes.client.GetEvents(reply, reply_sink)
quote_conn = comtypes.client.GetEvents(quote, quote_sink)
def pump_until(cond, timeout):
end = time.time() + timeout
while not cond() and time.time() < end:
pythoncom.PumpWaitingMessages() # 不要只用 comtypes.client.PumpEvents
time.sleep(0.05)
return cond()
code = center.SKCenterLib_Login(USER_ID, PASSWORD)
print("Login", code, center.SKCenterLib_GetReturnCodeMessage(code))
if code != 0:
raise SystemExit("登入失敗,先看元件的 log")
print("版本", center.SKCenterLib_GetSKAPIVersionAndBit(USER_ID))
code = quote.SKQuoteLib_EnterMonitorLONG()
print("EnterMonitorLONG", code)
if not pump_until(lambda: state["ready"], 30):
raise SystemExit("沒有等到 3003,不能訂閱")
page_no, code = quote.SKQuoteLib_RequestStocks(1, "TX00") # comtypes 回傳(頁號, 回傳碼)
print("RequestStocks", code, center.SKCenterLib_GetReturnCodeMessage(code))
if code != 0:
raise SystemExit("訂閱失敗")
if not pump_until(lambda: state["got_quote"], 30):
print("30 秒內沒有報價變動;請在交易時段內測試")幾點說明:
- 帳號密碼:片段用佔位字串。實際使用時,不要把帳密寫死在程式裡,改從環境變數讀取。
SKCenterLib_GetReturnCodeMessage:把回傳碼轉成官方的說明文字,除錯時很實用。- 回傳形態:
GetStockByIndexLONG的第三個參數是[in,out],comtypes 會把它和回傳碼一起放進回傳值,順序是(結構, 回傳碼),所以直接拆成兩個變數。RequestStocks也一樣,回傳的是(頁號, 回傳碼)。 - 事件方法的參數名照官方宣告寫(
nKind, nCode、sMarketNo, nIndex),對照官方文件比較容易。這裡的OnConnection是國內報價SKQuoteLib的事件。 - 本文只收報價,所以片段沒有建立下單物件。
- 0.05 秒與 30 秒都是示意值,依你的程式調整。
- 回呼裡直接
print、直接取報價:在回呼內用GetStockByIndexLONG取報價是官方說明的用法;直接print則只是入門示意。正式的程式要遵守〈群益API 事件回呼跑在哪個執行緒〉的四條紀律,回呼裡只做最輕量的收集。
收到第一筆報價之後,下一步讀什麼?
| 你接下來想做 | 去看 |
|---|---|
| 準備下單 | 〈群益API 下單初始化有哪 7 步〉 |
| 弄清楚下單回傳 0 代表什麼 | 〈群益API 下單回傳值是 0 就成功了嗎〉 |
| 解析委託回報 | 〈群益API 委託回報怎麼解析〉 |
| 事件回呼裡能做什麼 | 〈群益API 事件回呼跑在哪個執行緒〉 |
| 弄清楚各個物件管什麼、初始化的完整順序 | 〈群益API 的六個 COM 物件各管什麼〉 |
| 斷線之後怎麼重連 | 〈群益API 斷線怎麼重連〉 |
| 弄清楚商品代碼怎麼填 | 〈群益API 商品代碼怎麼填〉 |
| 弄清楚回傳值為什麼是 list、參數要傳幾個 | 〈群益API Python 回傳值為什麼是 list〉 |
| 把行情、下單、回報接成一支程式 | 〈群益API Python 程式架構〉 |
下單之前要知道一件事:官方文件說明,下單函式回傳 0 只表示委託成功送至交易所,交易結果要由回報確認。
群益API Python 入門的 5 個誤解
- 誤解: 照網路範例呼叫
comtypes.client.PumpEvents就能收到事件。其實: 我們實測在 STA 下只靠它收不到,要改用pythoncom.PumpWaitingMessages()或改成 MTA。 - 誤解: 登入回
0之後就能立刻訂閱。其實: 要先呼叫EnterMonitorLONG,等OnConnection收到3003才可以。 - 誤解: 報價事件會直接把價格送進來。其實: 事件只給市場別和索引,要自己用
GetStockByIndexLONG取,價格還要除以 10 的sDecimal次方。 - 誤解: 登入失敗一定是密碼錯。其實:
2017(登入前沒掛公告事件)、9996(元件版本已無法登入)都跟密碼無關。 - 誤解: 範例程式裡的封裝類別是群益元件的功能。其實: 群益元件提供的是
SKCenterLib_*、SKQuoteLib_*這類函式,封裝是範例作者自己寫的。
常見問題
群益API 可以用 Python 寫嗎?需要裝什麼?
可以。在 Windows 上用 64 位元的 Python,安裝 comtypes 與 pywin32 兩個套件,再註冊 64 位元的元件,就能用 comtypes 呼叫群益API。
群益API Python 登入回 2017 是什麼意思?
登入之前沒有掛上 SKReplyLib 的 OnReplyMessage,或沒有回傳 -1。官方說明這個事件需在登入前先註冊,方可正確登入。
登入和訂閱都回 0,為什麼一筆報價都沒有?
先檢查等待事件的方式:在我們的實測裡,STA 下只用 PumpEvents 收不到事件,要改用 pythoncom.PumpWaitingMessages() 或改成 MTA。再確認是不是等到 3003 才訂閱,以及現在是不是交易時段。
網路上的範例用了一個封裝類別,那是群益API 的函式嗎?
不是。群益元件提供的是 SKCenterLib_*、SKQuoteLib_* 這類函式;範例裡的封裝類別是範例作者自己寫的。本文的範例只用 comtypes 與 pywin32,直接呼叫群益元件的函式。
風險揭露
期貨與選擇權屬高槓桿商品,價格波動可能造成超過原始保證金的損失,交易人須自負交易責任。本文為程式開發技術教學,說明用 Python 連線群益API 並收到報價的步驟,不構成投資建議,也不保證任何交易結果。程式化交易並不降低市場風險,程式錯誤可能造成非預期的委託行為,正式使用前請充分測試。
投資人教育資源
| 機構 | 資源 |
|---|---|
| 臺灣期貨交易所(TAIFEX) | 期貨及選擇權數位學習網 |
| 證券暨期貨市場發展基金會 | 證券期貨市場教育推廣 |
| 金融智慧網 | 金管會金融知識平台 |
| 中華民國期貨業商業同業公會 | 期貨業法規與宣導 |
| 證券投資人及期貨交易人保護中心 | 投資人保護與申訴 |
延伸閱讀
- 〈群益API 是什麼〉——開始寫程式前必須知道的 5 個前提。
- 〈Python 接群益API 收不到事件〉——抽送訊息的兩條路與 MTA 的設定順序。
- 〈群益API 連線狀態碼怎麼解讀〉——3001 與 3003 的差別與就緒判定。
參考資料
- 函式宣告、事件說明、錯誤碼
1001/2017/9996、SKSTOCKLONG欄位,以及登入前註冊OnReplyMessage、等3003才訂閱、用GetStockByIndexLONG取報價的說明,依群益官方元件說明文件。 - 下單函式回傳 0 的意義,依群益官方元件說明文件 2.13.58 的文件調整說明。
TX00為近月商品代碼,依群益官方元件說明文件(期、選智慧單委託物件的備註、錯誤代碼表)。- comtypes – PyPI
- pywin32 – PyPI
- STA 下
PumpEvents收不到事件、PumpWaitingMessages與 MTA 收得到:我們的實測(SKCOM 2.13.59 x64、Python 3.12、comtypes 1.4.16),非官方文件記載;機制未查明。
免責聲明
本文章僅作為群益API實作經驗分享,不構成投資建議,且策略及程式皆應自行撰寫。期貨及衍生性金融商品交易屬高風險投資,請謹慎評估自身風險承擔能力。







