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

  1. iTick
  2. 教程
荷蘭股票 API 接入教學:即時行情與歷史 K 線資料完整實現 - iTick
荷蘭股票 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"Stringsubscribe
params標的代碼,多個用逗號分隔,格式:code$NLStringUNA$NL,ASML$NL,INGA$NL
types訂閱類型:tick(成交)、quote(報價)、depth(盤口)Stringtick,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 參數說明

請求 URLGET https://api.itick.org/stock/kline

參數描述類型必填範例
region市場代碼,荷蘭為"NL"StringNL
code股票代碼StringASML
kTypeK 線類型:1-分鐘,2-5 分鐘,3-15 分鐘,4-30 分鐘,5-60 分鐘,8-日線,9-週線,10-月線Integer8
limit獲取 K 線數量String100
et截止時間戳(毫秒),可選String1741680000000

回應欄位

  • 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消費品全球消費品巨頭
ASMLASML半導體全球光刻機霸主
ING Group (ING 集團)INGA金融荷蘭最大金融服務集團
AdyenADYEN金融科技全球支付服務商
Philips (飛利浦)PHIA醫療科技全球健康科技領導者

五、總結

透過本文,你已完整實現荷蘭股票資料的兩種核心接入方式:

  1. WebSocket 即時行情:低延遲訂閱聯合利華、ASML 等股票的 tick、quote、depth 資料,適用於高頻交易和即時監控
  2. REST API 歷史 K 線:獲取多週期 K 線資料,支援策略回測和趨勢分析,資料可無縫轉換為 Pandas DataFrame

iTick 為荷蘭市場提供完整的資料覆蓋,免費套餐即可滿足個人開發需求。立即訪問 iTick 官網 註冊,獲取你的 API Key,開始構建荷蘭股市量化策略!


延伸閱讀: