群益API Python 回傳值為什麼是 list?[in,out]、[out] 參數與 comtypes 的回傳規則
回傳值印出來是 [1, 0] 這種 list,拿去跟 0 比,永遠不相等。官方宣告明明有三個參數,OnReplyMessage 的 Python 方法卻只收兩個、還要 return -1。對照官方文件的宣告,也看不出 Python 到底要傳幾個參數。
群益API Python 回傳值的規則可以用一句話講完:看每個參數的方向。[in] 要傳;[out] 不用傳,但會出現在回傳值;[in,out] 要傳,也會回來。回傳多個值時,直接拆成多個變數。
本文的實測環境是 SKCOM 2.13.59 x64、Python 3.12、comtypes 1.4.16,在未登入的狀態下進行。
![群益API Python 回傳值為什麼是 list?[in,out]、[out] 參數與 comtypes 的回傳規則 2 群益API Python 回傳值示意圖:依參數方向決定要不要傳、會不會回來](/wp-content/uploads/2026/10/capital-api-python-out-params.webp)
目錄
群益API Python 怎麼看參數方向?
官方元件說明文件的宣告裡,每個參數前面都標了方向。comtypes 照這個方向決定 Python 的呼叫方式與回傳值:
| 方向 | 呼叫時要傳嗎 | 會出現在回傳值嗎 | 例子 |
|---|---|---|---|
[in] | 要 | 不會 | RequestStocks 的 bstrStockNos |
[out] | 不用 | 會 | 回傳碼;SendFutureOrderCLR 的 bstrMessage |
[in,out] | 要 | 會 | RequestStocks 的 psPageNo;GetStockByIndexLONG 的 pSKStock |
回傳值的組成:
- 只有一個要回來的值(只有回傳碼):直接回那個值,例如
RequestStockList回傳一個整數。 - 兩個以上:回傳一組值,順序跟宣告裡的參數順序一樣,回傳碼在最後一個。
群益API Python 回傳值為什麼是 list,不是 tuple?
我們的實測(未登入,所以回傳碼都是 1000,也就是 SK_ERROR_LOGIN_FIRST):
| 呼叫 | 回傳 |
|---|---|
quote.SKQuoteLib_RequestStocks(1, "TX00") | [1, 1000](list) |
quote.SKQuoteLib_RequestTicks(0, "TX00") | [0, 1000](list) |
quote.SKQuoteLib_GetStockByNoLONG("TX00", sk.SKSTOCKLONG()) | [SKSTOCKLONG, 1000](list) |
quote.SKQuoteLib_GetStockByIndexLONG(2, 0, sk.SKSTOCKLONG()) | [SKSTOCKLONG, 1000](list) |
quote.SKQuoteLib_RequestStockList(2) | 1000(int) |
規則是:方法有 [in,out] 參數時,comtypes 回傳 list。 只有 [out] 參數的函式(例如下單的 SendFutureOrderCLR)回傳的是 tuple;這一點我們沒有實際呼叫下單函式驗證。
還有一個地方容易混淆:comtypes 產生的模組裡,型別提示寫的是 tuple。編輯器可能顯示 tuple,實際執行回傳的是 list,以實際執行為準。
所以,不需要記哪個是 list、哪個是 tuple,直接拆包就好,兩種都適用:
page_no, code = quote.SKQuoteLib_RequestStocks(1, "TX00")不要用 isinstance(r, tuple) 判斷。 有 [in,out] 參數的方法回傳的是 list,這個判斷會失敗,結果整個 list 被當成回傳碼,後面的判斷全部出錯。本系列〈群益API Python 入門〉的範例早期曾用這種寫法,已更正。
[in,out] 要傳值:psPageNo 的例子
官方對 RequestStocks 的宣告是:
Long SKQuoteLib_RequestStocks([in,out] SHORT* psPageNo, [in] BSTR bstrStockNos);comtypes 產生的模組裡,psPageNo 的方向也是 in、out 兩者都有,跟官方宣告一致。所以第一個參數就是頁號,要傳:
page_no, code = quote.SKQuoteLib_RequestStocks(1, "TX00")少傳頁號會怎樣?我們實測 RequestStocks("TX00"),會拋出 TypeError: 'str' object cannot be interpreted as an integer:comtypes 把 "TX00" 當成第一個位置的頁號,但它是字串,型別不符。
參數名稱以官方手冊為準;comtypes 產生的模組裡,有些參數名稱跟手冊不同,但位置與方向一致。
結構類的 [in,out] 可以省略
我們實測 GetStockByNoLONG 與 GetStockByIndexLONG 這兩個函式,不傳結構也可以呼叫,comtypes 會自動補一個空的結構:
stock, code = quote.SKQuoteLib_GetStockByNoLONG("TX00") # 不傳結構也可以傳一個新建的結構進去也可以,例如 sk.SKSTOCKLONG()。其他函式我們沒有逐一測過。
數值類的 [in,out](例如 psPageNo)不能省略:它在前面的位置,省了後面的參數就錯位。
純 [out] 不用傳:函式從回傳值拿,事件用 return 給
這是最值得對照的一組:
函式的 [out],從回傳值拿。 SendFutureOrderCLR 的宣告是:
Long SendFutureOrderCLR([in] BSTR bstrLogInID, [in] VARIANT_BOOL bAsyncOrder, [in] struct FUTUREORDER* pAsyncOrder,[out] BSTR* bstrMessage);Python 只傳前三個參數,bstrMessage 跟回傳碼一起回來:message, code = ...。訊息的判讀見〈群益API 下單回傳 980 怎麼讀〉。
事件的 [out],用 return 給。 OnReplyMessage 的宣告是:
void OnReplyMessage([in] BSTR bstrUserID , [in] BSTR bstrMessage,[out]SHORT* sConfirmCode);事件是元件呼叫你的程式,[out] 是你要交回去的值。所以 Python 的事件方法只收兩個 [in] 參數,用 return -1 交回 sConfirmCode,見〈群益API Python 入門〉的步驟 4。
怎麼查某個函式的參數方向?
有兩個地方可以查:
- 官方元件說明文件的宣告:每個參數都標了
[in]、[out]或[in,out]。 - comtypes 產生的模組:
GetModule之後,用import comtypes.gen.SKCOMLib as sk; print(sk.__file__)找到所在的資料夾。SKCOMLib.py只是轉介,真正的定義在同一個資料夾、以一串編號命名的那個檔案裡,每個方法都列了參數方向(['in']、['out']、['in', 'out'])。
第二種是元件型別的實際內容,跟〈群益API Python 環境檢查〉講的「以元件型別為準」是同一個原則。
群益API Python 回傳值判讀程式碼
下面的片段示範三種情況,未登入也能跑,回傳的形態一樣:
# 群益API Python 回傳值:依參數方向決定怎麼呼叫、怎麼接
# 前提:GetModule、CreateObject 完成;未登入也能看到回傳的形態
import comtypes.gen.SKCOMLib as sk
# 1. 只有回傳碼([in] 參數 + 回傳碼)→ 直接回一個整數
code = quote.SKQuoteLib_RequestStockList(2)
print(type(code).__name__, code)
# 2. 有 [in,out] 的數值參數(psPageNo)→ 要傳,會和回傳碼一起回來
page_no, code = quote.SKQuoteLib_RequestStocks(1, "TX00")
print(page_no, code)
# 3. 有 [in,out] 的結構參數 → 傳一個新建的結構,結構和回傳碼一起回來
stock, code = quote.SKQuoteLib_GetStockByNoLONG("TX00", sk.SKSTOCKLONG())
print(type(stock).__name__, code)
# 錯誤示範:判斷 tuple 會失敗,因為上面兩種回的是 list
result = quote.SKQuoteLib_RequestStocks(1, "TX00")
print(type(result).__name__) # list未登入時的輸出(1000 是 SK_ERROR_LOGIN_FIRST):
int 1000
1 1000
SKSTOCKLONG 1000
list第 3 段只印結構的型別名稱、不印欄位:未登入時結構裡沒有內容。
群益API Python 回傳值的 4 個誤解
- 誤解: comtypes 回傳多個值,一定是 tuple。其實: 有
[in,out]參數的方法回傳 list(我們在 comtypes 1.4.16 實測);直接拆包兩種都適用。 - 誤解:
psPageNo是輸出參數,不用傳。其實: 官方宣告是[in,out],要傳值,也會回來。 - 誤解: 官方宣告有幾個參數,Python 就傳幾個。其實:
[out]參數不用傳,它會出現在回傳值裡。 - 誤解:
OnReplyMessage的 Python 方法要收三個參數。其實: 事件的[out]參數由你用return交回,方法只收兩個[in]參數。
常見問題
群益API Python 的回傳值印出來是 [1, 0],回傳碼是哪一個?
最後一個。有 [in,out] 參數的方法,comtypes 會把參數和回傳碼一起放進 list 回傳,回傳碼在最後;直接寫 page_no, code = … 拆開來用。
為什麼不能用 isinstance(r, tuple) 判斷回傳值?
因為有 [in,out] 參數的方法回傳的是 list,不是 tuple,判斷會失敗。直接拆包對 list 和 tuple 都適用。
RequestStocks 少傳頁號會怎樣?
我們實測會拋出 TypeError: ‘str’ object cannot be interpreted as an integer。官方宣告的第一個參數 psPageNo 是 [in,out],要傳值。
OnReplyMessage 為什麼只收兩個參數、還要 return -1?
第三個參數 sConfirmCode 是 [out]。事件的 [out] 是你要交回給元件的值,在 Python 裡用 return 交回;官方說明要回傳 -1。
風險揭露
期貨與選擇權屬高槓桿商品,價格波動可能造成超過原始保證金的損失,交易人須自負交易責任。本文為程式開發技術教學,說明 Python 呼叫群益API 時參數與回傳值的處理方式,不構成投資建議,也不保證任何交易結果。程式化交易並不降低市場風險,回傳碼判讀錯誤可能讓程式誤判委託或訂閱的狀態,正式使用前請充分測試。
投資人教育資源
| 機構 | 資源 |
|---|---|
| 臺灣期貨交易所(TAIFEX) | 期貨及選擇權數位學習網 |
| 證券暨期貨市場發展基金會 | 證券期貨市場教育推廣 |
| 金融智慧網 | 金管會金融知識平台 |
| 中華民國期貨業商業同業公會 | 期貨業法規與宣導 |
| 證券投資人及期貨交易人保護中心 | 投資人保護與申訴 |
延伸閱讀
- 〈群益API Python 入門〉——從安裝到收到第一筆報價。
- 〈群益API Python 環境檢查〉——GetModule 與 CreateObject 各檢查什麼。
- 〈群益API 商品代碼怎麼填〉——RequestStockList 查商品清單。
- 〈群益API 下單回傳 980 怎麼讀〉——下單回傳值與訊息字串的判讀。
參考資料
SKQuoteLib_RequestStocks、SKQuoteLib_GetStockByIndexLONG、SendFutureOrderCLR、OnReplyMessage、SKQuoteLib_RequestStockList的宣告,依群益官方元件說明文件。- comtypes – PyPI
- 回傳形態(list、int)、少傳頁號的錯誤訊息、結構可省略:我們 2026-10-16 在 comtypes 1.4.16、未登入狀態的實測,非官方文件記載;其他 comtypes 版本沒有測過。
- 只有
[out]的函式回傳 tuple:依 Python 底層的行為,我們沒有實際呼叫下單函式驗證。
免責聲明
本文章僅作為群益API實作經驗分享,不構成投資建議,且策略及程式皆應自行撰寫。期貨及衍生性金融商品交易屬高風險投資,請謹慎評估自身風險承擔能力。

![群益API Python 回傳值為什麼是 list?[in,out]、[out] 參數與 comtypes 的回傳規則 1 群益API Python 回傳值:[in,out]、[out] 參數與 comtypes 的回傳規則](https://capfutures.com/wp-content/uploads/2026/10/capital-api-python-out-params.webp)





