荷蘭股票 API 接入教學:即時行情與歷史 K 線資料完整實現

引言:世界第一間股份有限公司的故鄉
1602 年,世界第一間股份有限公司在阿姆斯特丹誕生——荷蘭東印度公司(VOC)。同年,阿姆斯特丹證券交易所成立,成為全球最古老的證券交易所之一。四個多世紀後的今天,阿姆斯特丹交易所作為泛歐交易所(Euronext)的重要組成部分,依然是歐洲資本市場的核心樞紐。 荷蘭股市匯聚了眾多全球知名企業:從消費品巨頭聯合利華(UNA)、全球半導體設備領導者 ASML(ASML),到國際保險與金融集團 ING(INGA)、全球支付巨頭 Adyen(ADYEN),荷蘭上市公司在多個行業中佔據領先地位。AEX 指數作為荷蘭股市旗艦指標,是歐洲投資者佈局西歐市場的重要參考。
荷蘭作為歐洲金融強國,其阿姆斯特丹交易所(Euronext Amsterdam)擁有超過 400 年歷史,是全球最古老的證券交易所之一。今天,這裡匯聚了 ASML、聯合利華、ING 集團等全球巨頭,AEX 指數成為歐洲投資者佈局西歐市場的重要參考。
對於量化開發者和金融科技團隊,接入荷蘭股票資料具有獨特的技術價值。本文將帶你使用 iTick API 快速接入荷蘭股市,獲取即時行情、歷史 K 線及 WebSocket 即時推送,從程式碼層面連接這個擁有 400 年歷史的資本市場。
一、環境準備
1.1 註冊並獲取 API Token
訪問 iTick 官網 註冊帳號,在控制台獲取你的專屬 Token。
1.2 安裝依賴
pip install requests websocket-client
二、即時行情接入:WebSocket 完整實現
即時行情通常通過 WebSocket 協議實現低延遲資料推送,支援成交(tick)、報價(quote)和盤口(depth)等資料類型。荷蘭市場代碼為NL,WebSocket 訂閱格式為code$NL。
2.1 WebSocket API 參數說明
連線位址:wss://api.itick.org/stock
認證方式:在 HTTP Header 中傳遞 token 參數
訂閱請求格式:
| 參數 | 描述 | 類型 | 必填 | 範例 |
|---|---|---|---|---|
| ac | 操作類型,固定為"subscribe" | String | 是 | subscribe |
| params | 標的代碼,多個用逗號分隔,格式:code$NL | String | 是 | UNA$NL,ASML$NL,INGA$NL |
| types | 訂閱類型:tick(成交)、quote(報價)、depth(盤口) | String | 是 | tick,quote,depth |
2.2 Python 完整實現:訂閱荷蘭主流股票
以下程式碼訂閱聯合利華(UNA)、ASML(ASML)和 ING 集團(INGA)的即時行情,包含自動重連和心跳機制:
import websocket
import json
import threading
import time
# WebSocket連線位址和token
WS_URL = "wss://api.itick.org/stock"
API_TOKEN = "your_token_here"
def on_message(ws, message):
"""處理接收到的訊息"""
data = json.loads(message)
# 處理連線成功訊息
if data.get("code") == 1 and data.get("msg") == "Connected Successfully":
print("✅ WebSocket連線成功,等待認證...")
# 處理認證結果
elif data.get("resAc") == "auth":
if data.get("code") == 1:
print("✅ 認證成功,開始訂閱...")
subscribe(ws)
else:
print("❌ 認證失敗")
ws.close()
# 處理訂閱結果
elif data.get("resAc") == "subscribe":
if data.get("code") == 1:
print("✅ 訂閱成功")
else:
print(f"❌ 訂閱失敗: {data.get('msg')}")
# 處理市場資料
elif data.get("data"):
market_data = data["data"]
data_type = market_data.get("type")
symbol = market_data.get("s")
if data_type == "quote":
print(f"[{symbol}] 最新價: {market_data.get('ld')} EUR | "
f"漲跌幅: {market_data.get('chp')}% | "
f"成交量: {market_data.get('v')}")
elif data_type == "tick":
print(f"[{symbol}] 成交: {market_data.get('ld')} EUR")
elif data_type == "depth":
bids = market_data.get("b", [])[:3]
asks = market_data.get("a", [])[:3]
print(f"[{symbol}] 買盤: {bids} | 賣盤: {asks}")
def on_error(ws, error):
print(f"❌ 錯誤: {error}")
def on_close(ws, close_status_code, close_msg):
print(f"🔌 連線關閉: {close_msg},5秒後重連...")
time.sleep(5)
connect()
def on_open(ws):
print("🌐 WebSocket連線已開啟")
def subscribe(ws):
"""訂閱荷蘭股票行情"""
subscribe_msg = {
"ac": "subscribe",
"params": "UNA$NL,ASML$NL,INGA$NL", # 聯合利華、ASML、ING集團
"types": "tick,quote,depth"
}
ws.send(json.dumps(subscribe_msg))
print(f"📤 訂閱請求已發送")
def send_ping(ws):
"""定期發送心跳包保持連線"""
while True:
time.sleep(30)
if ws and ws.sock and ws.sock.connected:
ping_msg = {
"ac": "ping",
"params": str(int(time.time() * 1000))
}
ws.send(json.dumps(ping_msg))
print("💓 心跳已發送")
def connect():
"""建立WebSocket連線"""
global ws
ws = websocket.WebSocketApp(
WS_URL,
header={"token": API_TOKEN},
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close
)
# 啟動心跳執行緒
ping_thread = threading.Thread(target=send_ping, args=(ws,), daemon=True)
ping_thread.start()
# 執行連線
ws.run_forever()
if __name__ == "__main__":
connect()
2.3 WebSocket 回應範例
報價(quote)回應:
{
"code": 1,
"data": {
"s": "UNA",
"r": "NL",
"ld": 54.32,
"o": 54.1,
"h": 54.45,
"l": 54.05,
"t": 1741680000000,
"v": 2345600,
"type": "quote"
}
}
盤口(depth)回應:
{
"code": 1,
"data": {
"s": "ASML",
"r": "NL",
"a": [{ "po": 1, "p": 865.2, "v": 1500 }],
"b": [{ "po": 1, "p": 865.0, "v": 1200 }],
"type": "depth"
}
}
三、歷史 K 線接入:REST API 完整實現
歷史資料是策略回測的基礎。iTick 提供超過 30 年的 K 線資料,支援從分鐘線到月線的多週期。
3.1 REST API 參數說明
請求 URL:GET https://api.itick.org/stock/kline
| 參數 | 描述 | 類型 | 必填 | 範例 |
|---|---|---|---|---|
| region | 市場代碼,荷蘭為"NL" | String | 是 | NL |
| code | 股票代碼 | String | 是 | ASML |
| kType | K 線類型:1-分鐘,2-5 分鐘,3-15 分鐘,4-30 分鐘,5-60 分鐘,8-日線,9-週線,10-月線 | Integer | 是 | 8 |
| limit | 獲取 K 線數量 | String | 是 | 100 |
| et | 截止時間戳(毫秒),可選 | String | 否 | 1741680000000 |
回應欄位:
t:時間戳(毫秒)o:開盤價h:最高價l:最低價c:收盤價v:成交量tu:成交額
3.2 Python 完整實現:獲取多週期 K 線
import requests
import pandas as pd
API_TOKEN = "your_token_here"
BASE_URL = "https://api.itick.org"
HEADERS = {"token": API_TOKEN, "accept": "application/json"}
def get_kline(symbol, ktype=8, limit=100):
"""
獲取荷蘭股票歷史K線資料
:param symbol: 股票代碼,如"ASML"
:param ktype: K線類型,8=日線
:param limit: 獲取數量
:return: K線資料列表
"""
url = f"{BASE_URL}/stock/kline"
params = {
"region": "NL",
"code": symbol,
"kType": ktype,
"limit": str(limit)
}
resp = requests.get(url, params=params, headers=HEADERS)
data = resp.json()
if data.get("code") == 0:
klines = data.get("data", [])
# 週期類型對應
ktype_map = {
1: "1分鐘", 2: "5分鐘", 3: "15分鐘", 4: "30分鐘", 5: "60分鐘",
8: "日線", 9: "週線", 10: "月線"
}
print(f"✅ 獲取到 {len(klines)} 條{ktype_map.get(ktype, '')}資料")
# 列印最近3條資料
for item in klines[-3:]:
print(f"時間:{item['t']} 開:{item['o']} 高:{item['h']} 低:{item['l']} 收:{item['c']} 量:{item['v']}")
return klines
else:
print(f"❌ 錯誤: {data.get('msg')}")
return []
# 範例1:獲取ASML日線資料
print("📊 ASML 日線資料:")
asml_daily = get_kline("ASML", ktype=8, limit=30)
# 範例2:獲取聯合利華週線資料
print("\n📊 聯合利華 週線資料:")
una_weekly = get_kline("UNA", ktype=9, limit=20)
# 範例3:獲取ING集團60分鐘線
print("\n📊 ING集團 60分鐘線:")
inga_hourly = get_kline("INGA", ktype=5, limit=50)
3.3 將 K 線資料轉換為 DataFrame(用於回測)
def kline_to_dataframe(klines):
"""將K線資料轉換為Pandas DataFrame"""
if not klines:
return None
df = pd.DataFrame(klines)
df['timestamp'] = pd.to_datetime(df['t'], unit='ms')
df.set_index('timestamp', inplace=True)
df.rename(columns={
'o': 'open', 'h': 'high', 'l': 'low',
'c': 'close', 'v': 'volume'
}, inplace=True)
# 轉換為數值類型
for col in ['open', 'high', 'low', 'close', 'volume']:
df[col] = pd.to_numeric(df[col])
return df[['open', 'high', 'low', 'close', 'volume']]
# 範例:獲取ASML資料並轉為DataFrame
klines = get_kline("ASML", ktype=8, limit=100)
if klines:
df = kline_to_dataframe(klines)
print("\n📈 DataFrame前5行:")
print(df.head())
# 簡單統計
print(f"\n📊 統計資訊:")
print(f"最新收盤價: {df['close'].iloc[-1]:.2f} EUR")
print(f"期間最高: {df['high'].max():.2f} EUR")
print(f"期間最低: {df['low'].min():.2f} EUR")
四、荷蘭市場速查表
| 項目 | 說明 |
|---|---|
| 市場代碼 | region=NL(REST)或 $NL(WebSocket) |
| 主流股票 | UNA(聯合利華)、ASML(ASML)、INGA(ING 集團)、ADYEN(Adyen)、PHIA(飛利浦) |
| 指數代碼 | AEX(AEX 指數) |
| 交易時間 | 阿姆斯特丹時間 9:00-17:30(夏令時台北時間 15:00-23:30) |
| 貨幣單位 | 歐元(EUR) |
主流荷蘭股票代碼參考
| 公司名稱 | 股票代碼 | 所屬板塊 | 業務簡介 |
|---|---|---|---|
| Unilever (聯合利華) | UNA | 消費品 | 全球消費品巨頭 |
| ASML | ASML | 半導體 | 全球光刻機霸主 |
| ING Group (ING 集團) | INGA | 金融 | 荷蘭最大金融服務集團 |
| Adyen | ADYEN | 金融科技 | 全球支付服務商 |
| Philips (飛利浦) | PHIA | 醫療科技 | 全球健康科技領導者 |
五、總結
透過本文,你已完整實現荷蘭股票資料的兩種核心接入方式:
- WebSocket 即時行情:低延遲訂閱聯合利華、ASML 等股票的 tick、quote、depth 資料,適用於高頻交易和即時監控
- REST API 歷史 K 線:獲取多週期 K 線資料,支援策略回測和趨勢分析,資料可無縫轉換為 Pandas DataFrame
iTick 為荷蘭市場提供完整的資料覆蓋,免費套餐即可滿足個人開發需求。立即訪問 iTick 官網 註冊,獲取你的 API Key,開始構建荷蘭股市量化策略!
延伸閱讀: