荷兰股票 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,开始构建荷兰股市量化策略!


延伸阅读: