開始使用
富果行情 WebSocket API 提供台股期權即時行情服務。透過 WebSocket API 可以滿足您想要接收即時行情的需求。
建立連線
富果期權行情 WebSocket API 提供 v1.1 與 v1.0 兩個版本:
wss://api.fugle.tw/marketdata/v1.1/futopt/streaming
wss://api.fugle.tw/marketdata/v1.0/futopt/streaming
兩個版本的唯一差異在 trades/books 頻道是否推送 試撮訊息:
- v1.0:恆不推送帶
isTrial: true的trades/books訊息(整則丟棄)。 - v1.1:試撮與正式行情一併推送,以逐筆訊息的
isTrial欄位區分。
aggregates/candles 頻道兩版本行為完全相同。請特別注意:aggregates 的試撮欄位(頂層 isTrial、lastTrial)在 v1.0 連線一樣會出現,且試撮期間的 lastPrice/change 也會反映試撮價。無論使用哪個版本,程式都應判斷 isTrial,詳見 aggregates。
v1.0 預計於 2026 年底退場,且不會回頭推送試撮訊息。新專案請直接使用 v1.1,既有整合請預留遷移時間。
身份驗證
建立 WebSocket 連線後,請使用 API 金鑰進行身份驗證,以獲得授權訂閱各項頻道:
{
"event": "auth",
"data": {
"apikey": "<API_KEY>"
}
}
當驗證成功後,會收到以下訊息:
{
"event": "authenticated",
"data": {
"message": "Authenticated successfully"
}
}
若驗證失敗,則會收到以下訊息:
{
"event": "error",
"code": 1000,
"data": {
"message": "Invalid authentication credentials"
}
}
其他錯誤訊息與關閉代碼請參考 錯誤與關閉代碼。
Heartbeat
每隔 30 秒 WebSocket server 會送出一個 heartbeat 訊息:
{
"event": "heartbeat",
"data": {
"time": "<Timestamp>"
}
}
Ping/Pong
將以下 JSON 格式訊息發送到 WebSocket Server(state 為可選):
{
"event": "ping",
"data": {
"state": "<ANY>"
}
}
WebSocket Server 會回應以下訊息(若 ping 未送 state 則不會有該欄位):
{
"event": "pong",
"data": {
"time": "<TIMESTAMP>",
"state": "<ANY>"
}
}
Channels
富果行情 WebSocket API 目前提供以下可訂閱頻道:
trades- 接收訂閱期權商品最新成交資訊candles- 接收訂閱期權商品最新分鐘Kbooks- 接收訂閱期權商品最新最佳五檔委買委賣資訊aggregates- 接收訂閱期權聚合數據的行情資訊
連續月別名
訂閱時的 symbol 除了具體合約代碼(如 TXFG6),也可使用連續月別名 {ROOT}1!/2!/3! 訂閱第 1/2/3 近月合約(如 TXF1! 為最近月臺股期貨)。系統會自動解析為當前對應的具體合約,回傳 data 中的 symbol 為解析後的具體合約代碼。詳見 REST API — 商品代碼與連續月別名。
連續月別名是在送出訂閱的當下解析成具體合約,之後該訂閱就固定綁在那個合約上。長時間保持的連線在跨過結算日之後不會自動重新解析——訂閱仍綁在已結算的舊合約,因而靜默地收不到任何資料。
跨結算日的長效連線請自行在換月後重新訂閱(unsubscribe 後再 subscribe),或改用具體合約代碼並自行控制轉倉。REST API 則不受影響,每次呼叫都會重新解析。
{
"event": "subscribe",
"data": {
"channel": "trades",
"symbol": "TXF1!"
}
}
價差契約訂閱
價差契約(如 TXFG6/H6)同樣以 symbol 欄位訂閱,代碼原樣放入即可。詳見 價差契約。
{
"event": "subscribe",
"data": {
"channel": "trades",
"symbol": "TXFG6/H6"
}
}
訂閱頻道
要訂閱一個頻道,請將以下 JSON 格式訊息發送到 WebSocket Server:
{
"event": "subscribe",
"data": {
"channel": "<CHANNEL_NAME>",
"symbol": "<SYMBOL_ID>"
}
}
訂閱成功後,會收到以下事件回應:
{
"event": "subscribed",
"data": {
"id": "<CHANNEL_ID>",
"channel": "<CHANNEL_NAME>",
"symbol": "<SYMBOL_ID>"
}
}
支援訂閱同頻道的多檔商品:
{
"event": "subscribe",
"data": {
"channel": "<CHANNEL_NAME>",
"symbols": ["<SYMBOL_ID_1>", "<SYMBOL_ID_2>"]
}
}
訂閱成功後,會 收到以下事件回應:
{
"event": "subscribed",
"data": [
{
"id": "<CHANNEL_ID>",
"channel": "<CHANNEL_NAME>",
"symbol": "<SYMBOL_ID_1>"
},
{
"id": "<CHANNEL_ID>",
"channel": "<CHANNEL_NAME>",
"symbol": "<SYMBOL_ID_2>"
}
]
}
取消訂閱
要取消已訂閱頻道,請將以下 JSON 格式訊息發送到 WebSocket Server:
{
"event": "unsubscribe",
"data": {
"id": "<CHANNEL_ID>"
}
}
取消訂閱成功後,會收到以下事件回應:
{
"event": "unsubscribed",
"data": {
"id": "<CHANNEL_ID>",
"channel": "<CHANNEL_NAME>",
"symbol": "<SYMBOL_ID>"
}
}
支援取消訂閱多個頻道:
{
"event": "unsubscribe",
"data": {
"ids": ["<CHANNEL_ID_1>", "<CHANNEL_ID_2>"]
}
}
取消訂閱成功後,會收到以下事件回應:
{
"event": "unsubscribed",
"data": [
{
"id": "<CHANNEL_ID_1>",
"channel": "<CHANNEL_NAME>",
"symbol": "<SYMBOL_ID_1>"
},
{
"id": "<CHANNEL_ID_2>",
"channel": "<CHANNEL_NAME>",
"symbol": "<SYMBOL_ID_2>"
}
]
}
訂閱資訊
要取得已訂閱的頻道,請將以下 JSON 格式訊息發送到 WebSocket Server:
{
"event": "subscriptions"
}
然後會收到以下事件回應:
{
"event": "subscriptions",
"data": [
{
"id": "<CHANNEL_ID>",
"channel": "<CHANNEL_NAME>",
"symbol": "<SYMBOL_ID>"
}
]
}
錯誤與關閉代碼
WebSocket 的錯誤有兩種形式:伺服器送出 event 為 error 的訊息(code 在訊息最外層),或直接關閉連線(以 close code 與 reason 表示)。同一個數字在兩種形式中代表不同意思,請依訊息形式與文字判斷。
錯誤訊息
{
"event": "error",
"code": 1002,
"data": {
"message": "Forbidden resource"
}
}
code | data.message | 原因 | 處理方式 |
|---|---|---|---|
1000 | Invalid authentication credentials | API Key 無效,伺服器隨即關閉連線,不帶 close code | 確認 API Key 正確且有效後再連線,不要原樣重試 |
1000 | Cannot switch user on an authenticated connection | 已完成身份驗證的連線改用其他帳號的 API Key 再次驗證,伺服器隨即關閉連線,不帶 close code | 一條連線只使用一個帳號的 API Key;要使用其他帳號時,請另外建立連線 |
1000 | Your plan does not support this product type | 目前方案不包含此商品的即時行情(例如基本用戶連線期權行情),隨後關閉連線(close code 1001) | 改用包含此商品的方案,不要原樣重試 |
1001 | Subscription limit exceeded | 訂閱數超過方案上限,連線不會中斷 | 取消不需要的訂閱,或將訂閱分到另一條連線 |
1002 | Forbidden resource | 尚未完成身份驗證就送出訂閱、取消訂閱、查詢或 ping | 收到 authenticated 之後再送出 |
1003 | id should not be empty、symbol should not be empty、channel should not be empty | 指令缺少必要欄位 | 補上缺少的欄位;取消訂閱請帶入 subscribed 回應中的 id |
1003 | symbol cannot exist alongside the following defined properties: symbols、id cannot exist alongside the following defined properties: ids、symbols must be an array、ids must be an array | symbol 與 symbols(或 id 與 ids)同時帶入,或 symbols、ids 不是陣列 | symbol 與陣列形式的 symbols 擇一帶入;取消訂閱的 id 與 ids 亦同 |
1003 | Maximum number of connections reached | 連線數已達方案上限,隨後關閉連線(close code 1013) | 先關閉其他連線再重新連線;持續重連只會一直被拒絕 |
1004 | No authentication request received | 連線後 60 秒內沒有送出身份驗證,隨後關閉連線(close code 1001) | 連線建立後立即送出身份驗證 |
1011 | Auth service unavailable、Internal server error | 身份驗證時伺服器暫時異常;連線後第一次驗證失敗時隨後關閉連線(close code 1011),已驗證的連線再次驗證失敗則不關閉 | 間隔一段時間後重新連線並重新驗證 |
關閉代碼
| close code | reason | 原因 | 處理方式 |
|---|---|---|---|
1001 | No authentication request received | 連線後 60 秒內沒有送出身份驗證 | 連線建立後立即送出身份驗證 |
1001 | Your plan does not support this product type | 目前方案不包含此商品的即時行情 | 改用包含此商品的方案,不要原樣重試 |
1001 | Server maintenance - going down for restart | 服務更新 | 間隔一段時間後重新連線並重新訂閱 |
1008 | Too many authentication attempts | 同一連線重複送出身份驗證的次數過多 | 驗證成功後不需再送出身份驗證 |
1011 | Auth service unavailable、Internal server error | 連線後第一次身份驗證時伺服器暫時異常 | 間隔一段時間後重新連線並重新驗證 |
1013 | Maximum number of connections reached | 連線數已達方案上限 | 先關閉其他連線再重新連線 |
收到錯誤訊息 1000(Invalid authentication credentials、Cannot switch user on an authenticated connection)後,伺服器關閉連線時不帶 close code,多數函式庫會回報為 close code 1005。
伺服器每 30 秒送出一次 WebSocket Ping,若 60 秒內沒有收到用戶端的任何訊框(包含回應 Ping 的 Pong),會直接中斷連線、不送出 close frame,多數函式庫會回報為 close code 1006。請使用會自動回應 Ping 的 WebSocket 函式庫,處理訊息時不要阻塞超過 60 秒;斷線後重新連線並重新訂閱。
建立連線失敗
| 狀況 | 原因 | 處理方式 |
|---|---|---|
握手回應 HTTP 404 | 連線網址的路徑或版本錯誤 | 確認連線網址與 建立連線 所列一致 |
握手回應 HTTP 502 或其他 5xx | 服務暫時無法連線 | 間隔一段時間後重試,並逐次拉長間隔 |
使用 SDK
富果行情 WebSocket API 提供 Python 與 Node.js SDK。
請先安裝 SDK:
- Python
- Node.js
pip install fugle-marketdata
npm install @fugle/marketdata
安裝後可透過以下方式存取 WebSocket API:
- Python
- Node.js
from fugle_marketdata import WebSocketClient
client = WebSocketClient(api_key = 'YOUR_API_KEY')
futopt = client.futopt
const { WebSocketClient } = require('@fugle/marketdata');
const client = new WebSocketClient({ apiKey: 'YOUR_API_KEY' });
const futopt = client.futopt;
指定連線版本
SDK 提供 version 選項指定期權要連線的 WebSocket 版本。期權(futopt)預設即為 v1.1,一般情況不需另行指定;若要維持既有的 v1.0 行為,請明確指定 v1.0。
- Python
- Node.js
from fugle_marketdata import WebSocketClient
# 期權預設連線 v1.1
client = WebSocketClient(api_key='YOUR_API_KEY')
# 明確指定版本
client = WebSocketClient(api_key='YOUR_API_KEY', version={'futopt': 'v1.1'})
# 維持既有 v1.0 行為(不接收 trades/books 試撮訊息)
client = WebSocketClient(api_key='YOUR_API_KEY', version={'futopt': 'v1.0'})
const { WebSocketClient } = require('@fugle/marketdata');
// 期權預設連線 v1.1
const client = new WebSocketClient({ apiKey: 'YOUR_API_KEY' });
// 明確指定版本
const clientV11 = new WebSocketClient({ apiKey: 'YOUR_API_KEY', version: { futopt: 'v1.1' } });
// 維持既有 v1.0 行為(不接收 trades/books 試撮訊息)
const clientV10 = new WebSocketClient({ apiKey: 'YOUR_API_KEY', version: { futopt: 'v1.0' } });
version 選項需要 Node.js @fugle/marketdata v1.5.0/Python fugle-marketdata 2.5.0 以上。台股(stock)目前僅支援 v1.0,指定其他版本會拋出錯誤。