群益API 未平倉查詢四種呼叫方式的欄位差異示意圖

群益API 未平倉查詢怎麼選?四種查詢方式的欄位差異與陷阱

查未平倉部位,官方文件裡有四個名字很像的函式。隨便挑一個接上去,查到的部位跟你預期的不一樣:少了成本欄,或者價差部位根本沒出現。

群益API 未平倉查詢的四種呼叫方式,結果都從同一個事件回來,但每一種回來的欄位都不一樣。 選哪一種,決定了你拿得到什麼、拿不到什麼。

群益API 未平倉查詢四種呼叫方式的欄位差異示意圖

群益API 未平倉有哪幾種查法?四種呼叫方式、五種欄位格式

國內期貨的未平倉查詢有四種呼叫方式,結果都由 OnOpenInterest 事件回傳。依官方欄位表整理如下:

呼叫方式欄數含複式單買賣表示法成本一點價值
GetOpenInterest11 欄不含一個「買賣別」欄平均成本(三位小數)有
GetOpenInterestWithFormat(1:完整)10 欄含買方、賣方各一組欄位買方/賣方成交均價(二位小數)無
GetOpenInterestWithFormat(2:格式1)8 欄含買方、賣方各一組欄位無無
GetOpenInterestWithFormat(3:格式2-含損益)11 欄不含一個「買賣別」欄平均成本(三位小數)有
GetOpenInterestGW(格式 1)11 欄含一個「買賣別」欄平均成本(小數部分已處理)無

先決定你要什麼,再選查詢方式:

  • 要複式單(價差)部位:只有「完整」「格式1」與 GW 含複式單;GetOpenInterest 與「格式2」官方寫明不含。
  • 要成本:「格式1」沒有成本欄。
  • 要一點價值:只有 GetOpenInterest 與「格式2」有;GW 沒有。

官方把 GW 標成新版:事件說明寫「(新)期貨未平倉GW」,函式清單寫「(新)期貨未平倉查詢-GW」。

表中的欄數是依照官方欄位表列出的數字,但實際回傳的欄數可能因版本與回傳型態而不同——例如「格式2」的單口手續費、交易稅兩欄,官方註明「v2.13.53起暫不提供此欄位」。解析時不要寫死欄數,這跟〈群益API 委託回報怎麼解析〉是同一個原則。

我們為什麼選 GW?

我們自己的實作,查未平倉只用 GetOpenInterestGW 格式 1。理由是:

  • 它含複式單、有平均成本、有一個明確的買賣別欄。
  • 它是官方標「(新)」的版本。
  • 我們在舊的格式上遇過欄位語意跟預期不一致的情況,後來統一改用 GW。

這是我們的選擇,不是官方建議——官方只把 GW 標成「(新)」,並沒有說其他幾種不建議使用。GW 的代價是不含「一點價值」這個欄位,要另外處理,見〈群益API 價差部位怎麼讀〉。

群益API 未平倉的口數要看哪幾個欄位?

GW(以及 GetOpenInterest、「格式2」)把部位分成兩個欄位:「未平倉部位」與「當沖未平倉部位」。「完整」與「格式1」則是買方、賣方各有「未平倉」與「當沖未平倉」兩個欄位。

官方把這兩個欄位分開列出,但沒有說明兩者是否重疊。

我們的做法是兩者相加當成總口數。但要把兩個方向的風險都說清楚:

  • 如果兩者不重疊,只看「未平倉部位」一欄,會漏掉當沖的部位。
  • 如果兩者其實重疊,相加就會重複計算。

我們沒有拿實際部位對照過這一點的紀錄。請用你自己帳號的實際部位對一次,確認是哪一種情況。

複式單部位要注意什麼?

含複式單的格式裡,價差部位會以合成的商品代碼出現。複式部位的成本與買賣別怎麼讀,見〈群益API 價差部位怎麼讀〉。

這裡只提醒一件事:官方在含與不含複式單的格式旁邊,都註明了「市場別:TM」。所以不能用「市場別是不是 TM」來判斷一筆部位是不是複式單。

怎麼知道查完了、沒有部位、還是查詢失敗?

三種情況,官方各有說明:

查完了:官方備註是

當全部資料已經全部回傳完畢,將回傳一筆以「##」開頭的內容,表示查詢結束。

沒有部位:官方寫「若查無資料,則回傳001,查無資料,帳號」。

查詢失敗:官方另有一個狀態事件 OnOpenInterestGWStatus,說明是:

國內期貨未平倉GW的查詢狀態。透過呼叫 GetOpenInterestGW、GetOpenInterest、GetOpenInterestWithFormat 後,資訊由該事件回傳。

參數 nQueryStatus 的官方說明是「0:查詢成功;1查詢失敗」,bstrErrorMsg 成功時為空、失敗時為錯誤訊息。

掛上這個事件,才知道查詢是失敗了、還是還在等。 只靠 OnOpenInterest,查詢失敗的時候你可能只是一直等不到資料。

換版改了哪些欄位?

未平倉查詢的回傳欄位,官方在最近兩版都改過:

  • V2.13.58:官方版本說明是「新增內、外期未平倉查詢GetOpenInterest、GetOpenInterestGW、GetOpenInterestWithFormat、GetOverSeaFutureOpenInterest「查無庫存」時新增Account欄位」。解析「查無資料」的回傳,也不要寫死欄數。
  • V2.13.59:GetOpenInterestGW 新增第 11 欄「商品-下單代碼」。官方備註是:

當「商品-下單代碼」查詢發生異常時,「商品-下單代碼」欄位將回傳空值。請重新呼叫 GetOpenInterestGW 以重新取得資料。

也就是說,這個欄位可能是空的,程式要能處理空值;空值時,官方的建議是重新查詢。

另外,V2.13.58 起官方新增了 OnOpenInterestJson 事件,可以一次以 JSON 格式回傳所有庫存。我們沒有使用經驗,本文只提它的存在。

群益API 未平倉查詢的 7 條原則+程式碼

  1. 先決定要什麼資料,再選查詢方式:要複式單、要成本、要一點價值,對照上面的表。
  2. 我們的選擇是 GetOpenInterestGW 格式 1;它不含「一點價值」欄位,要另外處理。
  3. 口數看「未平倉部位」與「當沖未平倉部位」兩個欄位,兩者的關係請用實際部位確認。
  4. 以「##」判斷查完,以「001」判斷沒有部位;兩者的欄數都不要寫死。
  5. 掛上 OnOpenInterestGWStatus,才知道查詢成功還是失敗。
  6. GW 的「商品-下單代碼」可能是空值,空值時照官方建議重新查詢。
  7. 定期拿查詢結果跟本地部位對一次。
// 查詢:GW、格式 1(結果由 OnOpenInterest 回傳)
int nCode = m_pSKOrder.GetOpenInterestGW("YOUR_LOGIN_ID", "YOUR_ACCOUNT", 1);

void OnOpenInterest(string bstrData)
{
    if (bstrData.StartsWith("##")) { OnQueryDone(); return; }       // 查完
    string[] v = bstrData.Split(',');
    if (v[0] == "001") { OnNoPosition(); return; }                  // 查無資料(欄數不寫死)
    string F(int i) => i < v.Length ? v[i] : "";

    // GW 格式 1:市場別,帳號,商品,買賣別,未平倉部位,當沖未平倉部位,平均成本,單口手續費,交易稅,LOGIN_ID,商品-下單代碼
    string symbol   = F(2);
    string side     = F(3);
    int.TryParse(F(4), out int qty);
    int.TryParse(F(5), out int dayTradeQty);
    int total = qty + dayTradeQty;                                  // 我們的做法:兩欄相加(官方沒說明是否重疊,請自行確認)
    string orderCode = F(10);                                       // V2.13.59 新增,可能是空值
    AddPosition(F(0), symbol, side, total, F(6), orderCode);
}

void OnOpenInterestGWStatus(int nQueryStatus, string bstrErrorMsg)
{
    if (nQueryStatus == 1) OnQueryFailed(bstrErrorMsg);             // 1:查詢失敗
}

幾點補充:

  • 帳號與 LOGIN_ID 一律用佔位符。程式碼註解列的是官方 GW 格式 1 的欄位名,程式裡的索引從 0 起算,官方欄位表是從 1 起算。
  • 買賣別欄的值,官方 GW 欄位表沒有列出值域,上面的程式碼片段只把它原樣帶出。
  • 事件在元件自己的執行緒上觸發,部位資料實際使用時要做同步,見〈群益API 事件回呼跑在哪個執行緒〉。

查詢是對帳的另一半

〈群益API 委託回報怎麼對帳〉講過:回報是推過來的,中間可能漏、可能重複、可能還在回補。未平倉查詢是另一個獨立的來源,定期拿本地的部位跟查詢結果對一次。多久查一次、對不上時怎麼處理,屬於你自己的風控設計,本文不給規則。

常見問題

群益API 未平倉查詢有四種,要選哪一個?

先決定你要什麼資料。要複式單部位,選含複式單的格式(完整、格式1、GW);要成本,不要選格式1;要一點價值,只有 GetOpenInterest 與格式2 有。我們自己的實作用 GW 格式 1。

查到的口數跟預期不一樣,是什麼原因?

檢查是不是只看了「未平倉部位」一欄。官方另外列了「當沖未平倉部位」,但沒有說明兩者是否重疊;請用實際部位對一次,確認要不要相加。

怎麼知道是查詢失敗,還是沒有部位?

沒有部位時,官方會回傳「001,查無資料,帳號」。查詢失敗要看 OnOpenInterestGWStatus 事件,nQueryStatus 為 1 代表失敗。

換版之後未平倉的解析失敗了,可能是什麼原因?

官方在 V2.13.58 為「查無庫存」的回傳新增了帳號欄位,V2.13.59 為 GW 新增了「商品-下單代碼」欄位。解析時不要寫死欄數。

風險揭露

期貨與選擇權屬高槓桿商品,價格波動可能造成超過原始保證金的損失,交易人須自負交易責任。本文為程式開發技術教學,說明未平倉查詢的欄位差異與解析方式,不構成投資建議,也不保證任何交易結果。程式化交易並不降低市場風險,部位口數算錯或查詢失敗而程式未察覺,都可能讓程式對自己的部位產生錯誤認知並繼續下單。

投資人教育資源

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

延伸閱讀

參考資料

  • GetOpenInterestWithFormat、GetOpenInterestGW 的宣告與參數,OnOpenInterest 的三段欄位表與備註,OnOpenInterestGWStatus、OnOpenInterestJson 的說明,以及 V2.13.58、V2.13.59 版本說明,依群益官方元件說明文件 V2.13.59 主手冊。
  • 只用 GW、兩個口數欄相加:實作經驗,非官方文件記載。

免責聲明

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

延伸閱讀|相關文章

發佈留言

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