Netherlands Stock API: Real-Time Quotes & Historical K-Line Data

  1. iTick
  2. Tutorial
Netherlands Stock API: Real-Time Quotes & Historical K-Line Data - iTick
Netherlands Stock API: Real-Time Quotes & Historical K-Line Data

Introduction: Birthplace of the World’s First Joint-Stock Company

In 1602, the world’s first joint-stock company — the Dutch East India Company (VOC) — was founded in Amsterdam. In the same year, the Amsterdam Stock Exchange was established, becoming one of the oldest securities exchanges in the world. More than four centuries later, Euronext Amsterdam remains a central hub of European capital markets as a key component of Euronext.

The Dutch equity market hosts many globally recognized companies: from consumer goods giant Unilever (UNA), world-leading semiconductor equipment manufacturer ASML (ASML), to financial services group ING (INGA) and global payments provider Adyen (ADYEN). Dutch listed companies hold leading positions across multiple sectors. The AEX Index, the flagship benchmark of the Dutch equity market, serves as a key reference for investors seeking exposure to Western Europe.

As one of Europe’s major financial centers, Euronext Amsterdam (with over 400 years of history) is one of the world’s oldest stock exchanges. Today it is home to global leaders such as ASML, Unilever, ING Group, and others. The AEX Index is an important benchmark for European investors allocating to Western European markets.

For quantitative developers and fintech teams, accessing Dutch equity market data offers unique technical value. This guide demonstrates how to quickly integrate iTick API to obtain real-time market data, historical K-lines, and WebSocket streaming — connecting programmatically to a capital market with over 400 years of history.

I. Environment Setup

1.1 Register and Obtain API Token

Visit the iTick official website to register an account and obtain your dedicated API Token from the developer console.

1.2 Install Dependencies

      pip install requests websocket-client

    

II. Real-Time Market Data Integration: Full WebSocket Implementation

Real-time market data is typically delivered via WebSocket for low-latency streaming, supporting trade (tick), quote, and order book (depth) updates. The market code for the Netherlands is NL. The WebSocket subscription format is code$NL.

2.1 WebSocket API Parameters

Connection URL: wss://api.itick.org/stock

Authentication: Pass the token in HTTP headers

Subscription Message Format:

ParameterDescriptionTypeRequiredExample
acAction type, fixed value "subscribe"StringYessubscribe
paramsInstrument codes (comma-separated), format: code$NLStringYesUNA$NL,ASML$NL,INGA$NL
typesData types: tick (trades), quote, depth (order book)StringYestick,quote,depth

2.2 Python Full Implementation: Subscribing to Major Dutch Stocks

The following code subscribes to real-time data for Unilever (UNA), ASML (ASML), and ING Group (INGA), including automatic reconnection and heartbeat mechanism:

      import websocket
import json
import threading
import time

# WebSocket endpoint and token
WS_URL = "wss://api.itick.org/stock"
API_TOKEN = "your_token_here"

def on_message(ws, message):
    """Handle incoming messages"""
    data = json.loads(message)

    # Handle successful connection
    if data.get("code") == 1 and data.get("msg") == "Connected Successfully":
        print("✅ WebSocket connected successfully, awaiting authentication...")

    # Handle authentication result
    elif data.get("resAc") == "auth":
        if data.get("code") == 1:
            print("✅ Authentication successful, starting subscription...")
            subscribe(ws)
        else:
            print("❌ Authentication failed")
            ws.close()

    # Handle subscription result
    elif data.get("resAc") == "subscribe":
        if data.get("code") == 1:
            print("✅ Subscription successful")
        else:
            print(f"❌ Subscription failed: {data.get('msg')}")

    # Handle market data
    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}] Last: {market_data.get('ld')} EUR | "
                  f"Change %: {market_data.get('chp')}% | "
                  f"Volume: {market_data.get('v')}")
        elif data_type == "tick":
            print(f"[{symbol}] Trade: {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: {bids} | Asks: {asks}")

def on_error(ws, error):
    print(f"❌ Error: {error}")

def on_close(ws, close_status_code, close_msg):
    print(f"🔌 Connection closed: {close_msg}, reconnecting in 5 seconds...")
    time.sleep(5)
    connect()

def on_open(ws):
    print("🌐 WebSocket connection opened")

def subscribe(ws):
    """Subscribe to Dutch equity real-time feeds"""
    subscribe_msg = {
        "ac": "subscribe",
        "params": "UNA$NL,ASML$NL,INGA$NL",  # Unilever, ASML, ING Group
        "types": "tick,quote,depth"
    }
    ws.send(json.dumps(subscribe_msg))
    print(f"📤 Subscription request sent")

def send_ping(ws):
    """Send heartbeat packets to maintain connection"""
    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("💓 Heartbeat sent")

def connect():
    """Establish WebSocket connection"""
    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
    )

    # Start heartbeat thread
    ping_thread = threading.Thread(target=send_ping, args=(ws,), daemon=True)
    ping_thread.start()

    # Run forever
    ws.run_forever()

if __name__ == "__main__":
    connect()

    

2.3 WebSocket Response Examples

Quote Response:

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

    

Order Book (Depth) Response:

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

    

III. Historical K-Line Integration: Full REST API Implementation

Historical data forms the foundation of strategy backtesting. iTick provides more than 30 years of K-line history, supporting multiple timeframes from 1-minute to monthly bars.

3.1 REST API Parameters

Endpoint: GET https://api.itick.org/stock/kline

ParameterDescriptionTypeRequiredExample
regionMarket code; Netherlands = "NL"StringYesNL
codeTicker symbolStringYesASML
kTypeK-line timeframe: 1=1min, 2=5min, 3=15min, 4=30min, 5=60min, 8=Daily, 9=Weekly, 10=MonthlyIntegerYes8
limitNumber of bars to returnStringYes100
etEnd timestamp (milliseconds), optionalStringNo1741680000000

Response Fields:

  • t: Timestamp (ms)
  • o: Open
  • h: High
  • l: Low
  • c: Close
  • v: Volume
  • tu: Turnover

3.2 Python Full Implementation: Multi-Timeframe K-Line Retrieval

      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):
    """
    Retrieve historical K-line data for Dutch stocks
    :param symbol: Ticker, e.g. "ASML"
    :param ktype: Bar type, 8 = daily
    :param limit: Number of bars
    :return: List of K-line records
    """
    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", [])

        # Timeframe mapping
        ktype_map = {
            1: "1 min", 2: "5 min", 3: "15 min", 4: "30 min", 5: "60 min",
            8: "Daily", 9: "Weekly", 10: "Monthly"
        }

        print(f"✅ Retrieved {len(klines)} {ktype_map.get(ktype, '')} bars")

        # Print last 3 bars
        for item in klines[-3:]:
            print(f"Time:{item['t']} O:{item['o']} H:{item['h']} L:{item['l']} C:{item['c']} Vol:{item['v']}")

        return klines
    else:
        print(f"❌ Error: {data.get('msg')}")
        return []

# Example 1: ASML daily bars
print("📊 ASML Daily Data:")
asml_daily = get_kline("ASML", ktype=8, limit=30)

# Example 2: Unilever weekly bars
print("\n📊 Unilever Weekly Data:")
una_weekly = get_kline("UNA", ktype=9, limit=20)

# Example 3: ING Group 60-min bars
print("\n📊 ING Group 60-min Data:")
inga_hourly = get_kline("INGA", ktype=5, limit=50)

    

3.3 Convert K-Line Data to Pandas DataFrame (for Backtesting)

      def kline_to_dataframe(klines):
    """Convert K-line list to 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)

    # Convert to numeric
    for col in ['open', 'high', 'low', 'close', 'volume']:
        df[col] = pd.to_numeric(df[col])

    return df[['open', 'high', 'low', 'close', 'volume']]

# Example: Retrieve ASML data and convert
klines = get_kline("ASML", ktype=8, limit=100)
if klines:
    df = kline_to_dataframe(klines)
    print("\n📈 DataFrame head:")
    print(df.head())

    # Basic statistics
    print(f"\n📊 Statistics:")
    print(f"Latest close: {df['close'].iloc[-1]:.2f} EUR")
    print(f"Period high: {df['high'].max():.2f} EUR")
    print(f"Period low: {df['low'].min():.2f} EUR")

    

IV. Netherlands Market Quick Reference

ItemDescription
Market Coderegion=NL (REST) or $NL (WebSocket)
Major StocksUNA (Unilever), ASML, INGA (ING Groep), ADYEN, PHIA (Koninklijke Philips)
Benchmark IndexAEX Index
Trading HoursAmsterdam local time 09:00–17:30 (CE(S)T)
CurrencyEuro (EUR)

Major Dutch Stock Ticker Reference

Company NameTickerSectorBusiness Overview
Unilever PLCUNAConsumer StaplesGlobal consumer goods leader
ASML Holding N.V.ASMLSemiconductorsGlobal leader in photolithography
ING Groep N.V.INGAFinancialsLeading Dutch universal banking group
Adyen N.V.ADYENFinancial TechnologyGlobal payment platform
Koninklijke Philips N.V.PHIAHealth TechnologyGlobal leader in health technology

V. Summary

This guide has demonstrated complete implementation of the two core data access methods for the Dutch equity market:

  1. WebSocket Real-Time Feeds — low-latency subscription to tick, quote, and depth data for names such as Unilever, ASML, etc.; ideal for high-frequency trading and live monitoring
  2. REST Historical K-Line API — multi-timeframe historical bars suitable for strategy backtesting and technical analysis; data can be seamlessly converted to Pandas DataFrame

iTick provides comprehensive coverage of the Dutch market, with the free tier sufficient for most individual development needs. Visit the iTick official website now to register, obtain your API key, and start building quantitative strategies for the Dutch equity market!


Further Reading: