群益API 初始化順序:六個 COM 物件各管什麼

群益API 的六個 COM 物件各管什麼?初始化順序一次看懂

範例程式一次建了好幾個物件,你只想收報價,不確定哪些可以省。登入回 2017,不知道跟「建物件」有什麼關係。登入成功了,接下來該先做下單初始化、回報連線,還是行情連線?

群益API 初始化順序可以用一句話記:登入前一段,登入後三條線。 每條線有自己的順序和就緒訊號,線與線之間官方沒有規定先後。

〈群益API 是什麼〉介紹過實務上用到的四個物件;本文補上完整的物件清單、每個物件管什麼,以及從建立物件到三條線就緒的順序。

群益API 初始化順序示意圖:登入前一段,登入後分成下單、回報、行情三條線

群益API 的六個物件各管什麼?

用 Python 的 comtypes.client.GetModule 載入元件後,產生的 comtypes.gen.SKCOMLib 裡有六個物件類別。做國內報價與下單用得到的是其中四個:

物件用途(官方說明)官方函式表上看得到的功能(舉例)本系列哪篇講過
SKCenterLib登入&環境設定。設定 log 路徑、登入、錯誤碼轉文字、版本查詢〈群益API Python 入門〉
SKOrderLib下單物件。初始化、讀憑證、取得交易帳號、各種下單與查詢〈群益API 下單初始化有哪 7 步〉
SKReplyLib回報物件。回報連線、公告事件 OnReplyMessage、委託回報 OnNewData〈群益API 委託回報怎麼解析〉
SKQuoteLib國內報價物件。報價連線、訂閱報價、K 線〈群益API 報價訂閱有哪兩層〉

另外兩個是海期報價物件 SKOSQuoteLib 與海選報價物件 SKOOQuoteLib,本文不展開。

幾點補充:

  • Python 的介面名是類別名前面加 I,例如 ISKCenterLib;本系列的範例建立物件時,都會用 interface 參數一起指定介面名。
  • C# 透過 Interop 用的類別名會多一個 Class 後綴;Python 用的是不帶後綴的名字。
  • 部分函式要帶 SKSTOCKLONG 這類結構物件當參數,〈群益API Python 入門〉的範例就用過。

只做報價,哪些物件可以不建?

原則是依任務決定要建的物件,但 SKReplyLib 不管做什麼都要建。

官方說明文件的「註冊公告(必要項目)」一節寫道(節錄):「請於登入(SKCenterLib_Login或SKCenterLib_LoginSetQuote)前先註冊公告,建立SKReplyLib 物件及事件SKReplyLib_OnReplyMessage4-3-e 並在事件處理函式中,回傳指定參數,參數值為-1。」

官方在這一節還特別附了 Python 範例的說明:「註冊事件SKReplyLib_OnReplyMessage並在事件處理函式(OnReplyMessage)中,回傳指定參數,參數值為-1。」

也就是說,SKReplyLib 是登入的前提,不是「要收回報才建」。登入前只要掛上事件,不必先做回報連線,官方的說明是「需在登入前先註冊此通知事件—OnReplyMessage,方可正確登入,不需先做回報連線。」沒有先註冊這個事件,登入會回 2017:

代碼常數官方說明
2017SK_WARNING_REGISTER_REPLYLIB_ONREPLYMESSAGE_FIRST請(註冊)接收公告再登入 / 請參考單元3-2

其他物件就依任務決定:

任務要建的物件
只收國內報價SKCenterLib、SKReplyLib、SKQuoteLib
要下單再加 SKOrderLib

〈群益API Python 入門〉的範例只收報價,就只建了 SKCenterLib、SKReplyLib、SKQuoteLib 三個物件。

群益API 初始化順序:登入前一段,登入後三條線

【登入前】
  GetModule → CreateObject(用到的物件)→ GetEvents 掛事件(保留回傳值)
  SKCenterLib_SetLogPath(路徑)        ← 要改 log 路徑時,最先呼叫
  SKReplyLib 的 OnReplyMessage 已掛上、回 -1
  SKCenterLib_Login(帳號, 密碼)        ← 回 0 才往下

【登入後,三條線】
  下單線(SKOrderLib)
    SKOrderLib_Initialize → ReadCertByID → GetUserAccount(帳號由 OnAccount 事件回傳)
    (海外期貨、海外選擇權下單另有前置步驟)

  回報線(SKReplyLib)
    SKReplyLib_ConnectByID → 等 OnComplete

  行情線(SKQuoteLib)
    SKQuoteLib_EnterMonitorLONG → 等 OnConnection 收到 3003 → 訂閱

  等待事件期間:一定要抽送訊息

每一步的依據:

步驟官方說明文件
要改 log 路徑時,SetLogPath 最先呼叫「欲變更Log路徑此函式需最先呼叫。」
登入前掛 OnReplyMessage「註冊公告(必要項目)」一節(上一節已引)
Initialize 在下單函式之前「需先執行才可執行相關下單函式。」
Initialize 之後讀憑證「當元件初始化成功後即需要做讀取憑證的動作」
GetUserAccount 的結果走事件「取回目前可交易的所有帳號。資料由OnAccount事件回傳。」
ConnectByID 的通知事件回報主機連線,通知事件是 OnSolaceReplyConnection、OnComplete
EnterMonitorLONG 後等 3003「*請先SKQuoteLib_EnterMonitorLONG,須等OnConnection收到SK_SUBJECT_CONNECTION_STOCKS_READY後,方可進行訂閱商品報價。」

要注意,ReadCertByID 與 GetUserAccount 誰先誰後,官方沒有寫;上面的流程是依〈群益API 下單初始化有哪 7 步〉的順序排的。

各條線的細節:

三條線之間有沒有先後?

官方沒有規定三條線之間的先後。 官方說明文件對每一條線各自寫了「先做什麼、才能做什麼」,但沒有寫「下單線要在行情線之前」這類跨線的順序。

唯一要注意的是:送單要等回報線就緒,也就是等 OnComplete 到了才開放送單,原因見〈群益API 下單初始化有哪 7 步〉。

我們沒有針對跨線的順序做過實測,所以這裡只說「官方沒有規定」,不說「任何順序都可以」。

Python 端:每個物件一個事件類別

在 Python 裡,一個物件對應一個事件類別、一次 GetEvents:

物件事件方法寫在這個物件的事件類別裡(舉例)
SKReplyLibOnReplyMessage、OnNewData、OnComplete
SKQuoteLibOnConnection、OnNotifyQuoteLONG
SKOrderLibOnAccount

事件方法要放在對應物件的事件類別裡。 comtypes 依方法名稱對應事件,放到別的物件的事件類別裡,不會被呼叫。

另外兩件事:

  • GetEvents 的回傳值要存在變數裡,回傳值被垃圾回收就收不到事件,見〈群益API Python 入門〉。
  • 同名事件在不同物件上,參數可能不一樣。國內報價 SKQuoteLib 的連線事件是 OnConnection(nKind, nCode),參數對照見〈群益API 連線狀態碼怎麼解讀〉。

群益API 初始化骨架程式碼

下面是骨架,只建物件、掛事件,標出三條線的起點;沒有登入,也沒有等待迴圈,完整可跑的流程見〈群益API Python 入門〉:

# 群益API Python 骨架:國內報價與下單用得到的四個物件
import comtypes.client

DLL_PATH = r"C:\SKCOM\x64\SKCOM.dll"   # 改成你註冊的元件路徑;32 位元 Python 用 x86 資料夾

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)   # 行情線
order = comtypes.client.CreateObject(sk.SKOrderLib, interface=sk.ISKOrderLib)   # 下單線,只收報價可不建


class ReplyEvents:                       # SKReplyLib 的事件
    def OnReplyMessage(self, bstrUserID, bstrMessage):
        return -1                        # 官方:回傳指定參數,參數值為 -1

    def OnComplete(self, bstrUserID):
        print("回報回補完成", bstrUserID)


class QuoteEvents:                       # SKQuoteLib 的事件
    def OnConnection(self, nKind, nCode):
        print("行情連線", nKind, nCode)


class OrderEvents:                       # SKOrderLib 的事件
    def OnAccount(self, bstrLogInID, bstrAccountData):
        print("帳號", bstrAccountData)


# 每個物件一個事件類別;回傳值一定要存起來
reply_conn = comtypes.client.GetEvents(reply, ReplyEvents())
quote_conn = comtypes.client.GetEvents(quote, QuoteEvents())
order_conn = comtypes.client.GetEvents(order, OrderEvents())

# 之後:SetLogPath(要改 log 路徑時)→ Login → 三條線
#   下單線:SKOrderLib_Initialize → ReadCertByID → GetUserAccount
#   回報線:SKReplyLib_ConnectByID → 等 OnComplete
#   行情線:SKQuoteLib_EnterMonitorLONG → 等 OnConnection 收到 3003

幾點說明:

群益API 初始化順序的 4 個誤解

  1. 誤解: 只收報價,就不用建回報物件。其實: 官方規定登入前要建 SKReplyLib、掛 OnReplyMessage,否則登入回 2017。
  2. 誤解: 元件裡的物件都要建。其實: 依任務建;只做國內報價,SKCenterLib、SKReplyLib、SKQuoteLib 三個就夠用了,〈群益API Python 入門〉的範例就是這樣。
  3. 誤解: 登入後要按固定順序,先做下單、再做回報、再做行情。其實: 三條線各自有順序,官方沒有規定線與線之間的先後;要注意的是送單要等回報線就緒。
  4. 誤解: 事件方法寫在哪個類別都可以。其實: 要寫在對應物件的事件類別裡,再用 GetEvents 綁到那個物件。

常見問題

群益API 只收報價,也要建 SKReplyLib 嗎?

要。官方規定登入前要建立 SKReplyLib、註冊 OnReplyMessage 並回傳 -1,否則登入會回 2017。登入前只要掛上事件,不必先做回報連線。

群益API 登入之後,下單、回報、行情要照什麼順序初始化?

每條線各自有順序:下單線是 SKOrderLib_Initialize、ReadCertByID、GetUserAccount;回報線是 SKReplyLib_ConnectByID 後等 OnComplete;行情線是 SKQuoteLib_EnterMonitorLONG 後等 3003。線與線之間,官方沒有規定先後,但送單要等回報線就緒。

SetLogPath 要在什麼時候呼叫?

要改 log 路徑時呼叫,而且官方說明這個函式需最先呼叫,也就是放在登入之前。

事件方法寫好了卻沒被呼叫,可能是什麼原因?

先確認方法寫在對應物件的事件類別裡,例如 OnAccount 要寫在 SKOrderLib 的事件類別;再確認 GetEvents 的回傳值有存在變數裡,以及等待事件時有抽送訊息。

風險揭露

期貨與選擇權屬高槓桿商品,價格波動可能造成超過原始保證金的損失,交易人須自負交易責任。本文為程式開發技術教學,說明群益API 元件物件的用途與初始化順序,不構成投資建議,也不保證任何交易結果。程式化交易並不降低市場風險,初始化未完成就送單可能造成非預期的結果,正式使用前請充分測試。

投資人教育資源

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

延伸閱讀

參考資料

  • 四個國內物件的用途、「註冊公告(必要項目)」一節、SetLogPath/SKOrderLib_Initialize/GetUserAccount/SKReplyLib_ConnectByID 的說明與備註、2017 錯誤碼、等 3003 才訂閱的說明,依群益官方元件說明文件。
  • 六個物件類別:依元件的型別資訊(Python GetModule 產生的模組,SKCOM 2.13.59)。
  • ReadCertByID 與 GetUserAccount 的先後、送單等 OnComplete:依本系列〈群益API 下單初始化有哪 7 步〉,非官方規定。

免責聲明

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

延伸閱讀|相關文章

發佈留言

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