Skip to main content

開始使用

富果行情 WebSocket API 提供台股即時行情服務。透過 WebSocket API 可以滿足您想要接收即時行情的需求。

建立連線​

您可以透過以下位置向富果行情 WebSocket API server 建立連線:

wss://api.fugle.tw/marketdata/v1.0/stock/streaming

身份驗證​

建立 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 目前提供以下可訂閱頻道:

訂閱頻道​

要訂閱一個頻道,請將以下 JSON 格式訊息發送到 WebSocket Server:

{
"event": "subscribe",
"data": {
"channel": "<CHANNEL_NAME>",
"symbol": "<SYMBOL_ID>"
}
}

在 data 指定 "intradayOddLot": true 可訂閱盤中零股行情。

訂閱成功後,會收到以下事件回應:

{
"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>"
}
]
}

接收行情資料​

訂閱成功後,若該檔股票當日已有資料,會先收到一則 event 為 snapshot 的訊息,內容為該頻道最近一次的資料,之後有新資料時才會收到 event 為 data 的訊息。收盤後訂閱只會收到 snapshot;代碼錯誤時同樣會收到 subscribed,但不會收到任何行情訊息。

當日尚未有資料時(例如盤前試撮開始前)訂閱,trades、books、indices 不會收到 snapshot;aggregates 與 candles 仍會收到一則 snapshot,其中 aggregates 只有參考價與昨收、累計量為 0,candles 的 data 為空陣列。

除 candles 外,兩種訊息的 data 格式相同;candles 的 snapshot 以 data 陣列帶入當日已有的K線(另帶 timeframe),data 訊息則是單根K線。各頻道欄位請見各頻道頁:

{
"event": "snapshot",
"data": {
"symbol": "2330",
"type": "EQUITY",
"exchange": "TWSE",
"market": "TSE",
"price": 2420,
"size": 5574,
"bid": 2415,
"ask": 2420,
"volume": 22224,
"isClose": true,
"time": 1792560600000000,
"serial": 15057309
},
"id": "<CHANNEL_ID>",
"channel": "trades"
}

各頻道訊息的共通規則:

  • time 等時間欄位為 Unix 時間戳記,單位為微秒(例:1792560600000000 為 2026-10-21 13:30:00)。
  • 布林旗標(如 isTrial、isContinuous、isClose)只在值為 true 時出現,未出現即視為 false。
  • 數量單位:整股行情為交易單位,多數股票 1 張為 1,000 股;盤中零股行情為股。交易單位不是 1,000 股的標的,請以 Intraday Ticker 的 boardLot 換算。
  • 訂閱盤中零股("intradayOddLot": true)時,訊息的 type 為 ODDLOT,可用來區分同一檔股票的整股與零股行情。

取消訂閱​

要取消已訂閱頻道,請將以下 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"
}
}
codedata.message原因處理方式
1000Invalid authentication credentialsAPI Key 無效,伺服器隨即關閉連線,不帶 close code確認 API Key 正確且有效後再連線,不要原樣重試
1000Cannot switch user on an authenticated connection已完成身份驗證的連線改用其他帳號的 API Key 再次驗證,伺服器隨即關閉連線,不帶 close code一條連線只使用一個帳號的 API Key;要使用其他帳號時,請另外建立連線
1000Your plan does not support this product type目前方案不包含此商品的即時行情,隨後關閉連線(close code 1001)改用包含此商品的方案,不要原樣重試
1001Subscription limit exceeded訂閱數超過方案上限,連線不會中斷取消不需要的訂閱,或將訂閱分到另一條連線
1002Forbidden resource尚未完成身份驗證就送出訂閱、取消訂閱、查詢或 ping收到 authenticated 之後再送出
1003id should not be empty、symbol should not be empty、channel should not be empty指令缺少必要欄位補上缺少的欄位;取消訂閱請帶入 subscribed 回應中的 id
1003symbol 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 arraysymbol 與 symbols(或 id 與 ids)同時帶入,或 symbols、ids 不是陣列symbol 與陣列形式的 symbols 擇一帶入;取消訂閱的 id 與 ids 亦同
1003Maximum number of connections reached連線數已達方案上限,隨後關閉連線(close code 1013)先關閉其他連線再重新連線;持續重連只會一直被拒絕
1004No authentication request received連線後 60 秒內沒有送出身份驗證,隨後關閉連線(close code 1001)連線建立後立即送出身份驗證
1011Auth service unavailable、Internal server error身份驗證時伺服器暫時異常;連線後第一次驗證失敗時隨後關閉連線(close code 1011),已驗證的連線再次驗證失敗則不關閉間隔一段時間後重新連線並重新驗證

關閉代碼​

close codereason原因處理方式
1001No authentication request received連線後 60 秒內沒有送出身份驗證連線建立後立即送出身份驗證
1001Your plan does not support this product type目前方案不包含此商品的即時行情改用包含此商品的方案,不要原樣重試
1001Server maintenance - going down for restart服務更新間隔一段時間後重新連線並重新訂閱
1008Too many authentication attempts同一連線重複送出身份驗證的次數過多驗證成功後不需再送出身份驗證
1011Auth service unavailable、Internal server error連線後第一次身份驗證時伺服器暫時異常間隔一段時間後重新連線並重新驗證
1013Maximum 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連線網址的路徑或版本錯誤(台股僅支援 v1.0)確認連線網址與 建立連線 所列一致
握手回應 HTTP 502 或其他 5xx服務暫時無法連線間隔一段時間後重試,並逐次拉長間隔

快速開始​

以下是一個在瀏覽器環境下,建立 WebSocket 連線、身份驗證以及訂閱頻道接收即時行情的範例:

const socket = new WebSocket('wss://api.fugle.tw/marketdata/v1.0/stock/streaming');

socket.onopen = () => {
socket.send(
JSON.stringify({
event: 'auth',
data: {
apikey: '<API_KEY>',
},
}),
);

socket.onmessage = (message) => {
const data = JSON.parse(message.data);

if (data.event === 'authenticated') {
socket.send(
JSON.stringify({
event: 'subscribe',
data: {
channel: 'trades',
symbol: '2330',
},
}),
);
}

console.log(data);
};
};

使用 SDK​

富果行情 WebSocket API 提供 Python 與 Node.js SDK。

請先安裝 SDK:

pip install fugle-marketdata

安裝後可透過以下範例存取 WebSocket API:

from fugle_marketdata import WebSocketClient

def handle_message(message):
print(f'message: {message}')

def handle_connect():
print('connected')

def handle_disconnect(code, message):
print(f'disconnect: {code}, {message}')

def handle_error(error):
print(f'error: {error}')

def main():
client = WebSocketClient(api_key='YOUR_API_KEY')
stock = client.stock
stock.on("connect", handle_connect)
stock.on("message", handle_message)
stock.on("disconnect", handle_disconnect)
stock.on("error", handle_error)
stock.connect()
stock.subscribe({
"channel": 'trades',
"symbol": '2330'
})

if __name__ == "__main__":
main()