How to Use iTick API for Italian Stock Data: Real-Time Quotes & Backtesting Examples

  1. iTick
  2. Tutorial
How to Use iTick API for Italian Stock Data: Real-Time Quotes & Backtesting Examples - iTick
How to Use iTick API for Italian Stock Data: Real-Time Quotes & Backtesting Examples

In 2026, with global asset allocation increasingly diversified, Italy — the eurozone’s third-largest economy — continues to gain relevance in institutional portfolios. The Milan Stock Exchange (Borsa Italiana) hosts globally recognized names across luxury (Ferrari), energy (Eni), banking (Intesa Sanpaolo, UniCredit), utilities (Enel), and industrials (Stellantis), making Italian equities an attractive universe for cross-border arbitrage, factor models, and European thematic strategies.

This guide provides a step-by-step walkthrough of accessing Borsa Italiana data through the iTick API, covering real-time Level 1 quotes, trade-by-trade updates, market depth, and multi-timeframe historical bars — complete with production-grade Python implementation examples.

I. Why iTick Is the Preferred Gateway to Italian Equities

After evaluating major financial data providers, iTick consistently ranks highest for developers and quant teams targeting European mid- and small-cap as well as large-cap names.

DimensioniTick APITraditional VendorsPublic / Free Endpoints
Italian Market CoverageFull Borsa Italiana universeUsually blue-chips onlyVery limited / none
Real-time Latency<50 ms (WebSocket)100–500 ms15-minute delayed
Historical Depth>15 years~10 years1–2 years
Protocol SupportREST + WebSocket + FIXMostly RESTREST only
Free TierUnlimited base quotes + WSNo free tierStrict rate limits
Multi-Asset CoverageEquities / FX / Futures / FundsUsually equities onlyEquities only

Key Strengths of iTick

  1. Complete Borsa Italiana coverage — from large-cap constituents to mid- and small-cap names — via a single, normalized interface.
  2. Developer-first experience — clean REST & WebSocket endpoints, concise documentation, multi-language samples.
  3. Ultra-low latency streaming — sub-50 ms WebSocket updates with tick, quote, and depth support.
  4. Rich data granularity — trade-level (tick), Level 1 (quote), Level 2 (depth) feeds available in one subscription.
  5. Generous free tier — sufficient for research, prototyping, backtesting, and light production usage.

II. Environment Setup

1. Obtain iTick API Token

Register at https://itick.org (~30 seconds, no credit card required). Retrieve your personal API token from the developer console.

2. Install Required Python Libraries

      pip install requests websocket-client pandas matplotlib

    

III. Real-Time Italian Equity Streaming via WebSocket

For latency-sensitive strategies, WebSocket provides true push-based updates with millisecond-level latency.

Endpoint: wss://api.itick.org/stock

Authentication: Pass token in HTTP headers

Subscription Format

FieldDescriptionExample
acAction type"subscribe"
paramsComma-separated symbols (format: TICKER$IT)"ENI$IT,FERR$IT,ISP$IT"
typesData types: tick, quote, depth"tick,quote,depth"

Python Example — Subscribing to Eni, Ferrari, and Intesa Sanpaolo

      import websocket
import json
import threading
import time

WS_URL = "wss://api.itick.org/stock"
API_TOKEN = "your_api_token_here"  # ← Replace with your token

def on_message(ws, message):
    data = json.loads(message)

    # Connection & auth handling
    if data.get("code") == 1 and data.get("msg") == "Connected Successfully":
        print("WebSocket connected successfully")
    elif data.get("resAc") == "auth":
        if data.get("code") == 1:
            print("Authentication successful → subscribing...")
            subscribe(ws)
        else:
            print(f"Authentication failed: {data.get('msg')}")
            ws.close()

    # Subscription confirmation
    elif data.get("resAc") == "subscribe":
        print("Subscription accepted" if data.get("code") == 1 else f"Subscription failed: {data.get('msg')}")

    # Market data
    elif "data" in data:
        payload = data["data"]
        symbol = payload.get("s")
        msg_type = payload.get("type")

        if msg_type == "quote":
            print(f"[{symbol}] Last: {payload.get('ld')} | Chg%: {payload.get('chp')}% | Vol: {payload.get('v')}")
        elif msg_type == "tick":
            ts = payload.get('t', 0) / 1000
            print(f"[{symbol}] Trade @ {payload.get('ld')} | {time.strftime('%H:%M:%S', time.localtime(ts))}")
        elif msg_type == "depth":
            bids = payload.get("b", [])[:3]
            asks = payload.get("a", [])[:3]
            print(f"[{symbol}] Bids: {bids} | Asks: {asks}")

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

def on_close(ws, code, reason):
    print(f"WebSocket closed: {reason}")

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

def subscribe(ws):
    sub = {
        "ac": "subscribe",
        "params": "ENI$IT,FERR$IT,ISP$IT",
        "types": "tick,quote,depth"
    }
    ws.send(json.dumps(sub))
    print(f"Sent subscription: {sub['params']}")

def heartbeat(ws):
    while True:
        time.sleep(30)
        ws.send(json.dumps({
            "ac": "ping",
            "params": str(int(time.time() * 1000))
        }))
        print("Heartbeat sent")

if __name__ == "__main__":
    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
    )

    threading.Thread(target=heartbeat, args=(ws,), daemon=True).start()

    print("Starting WebSocket client...")
    ws.run_forever()

    

IV. Historical OHLCV Bars via REST API

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

Key Parameters

ParamDescriptionExample
regionMarket codeIT
codeLocal tickerENI
kTypeBar resolution (8 = daily, 1 = 1-min, etc.)8
limitNumber of bars100

Python Example — Downloading & Visualizing Eni Daily Bars

      import requests
import pandas as pd
import matplotlib.pyplot as plt

def get_italian_kline(symbol: str, ktype: int = 8, limit: int = 100):
    url = "https://api.itick.org/stock/kline"
    params = {
        "region": "IT",
        "code": symbol,
        "kType": str(ktype),
        "limit": str(limit)
    }
    headers = {
        "accept": "application/json",
        "token": "your_api_token_here"
    }

    try:
        resp = requests.get(url, params=params, headers=headers)
        result = resp.json()

        if result.get("code") == 0:
            bars = result.get("data", [])
            if not bars:
                print(f"No data returned for {symbol}")
                return None

            df = pd.DataFrame(bars)
            df['datetime'] = pd.to_datetime(df['t'], unit='ms')
            df.set_index('datetime', inplace=True)

            df.rename(columns={
                'o': 'open', 'h': 'high', 'l': 'low',
                'c': 'close', 'v': 'volume', 'tu': 'turnover'
            }, inplace=True)

            for col in ['open','high','low','close','volume','turnover']:
                if col in df.columns:
                    df[col] = pd.to_numeric(df[col], errors='coerce')

            print(f"Retrieved {len(df)} bars | Range: {df.index[0]:%Y-%m-%d}{df.index[-1]:%Y-%m-%d}")
            print(df[['open','high','low','close','volume']].tail())

            return df

        else:
            print(f"API error: {result.get('msg')}")
            return None

    except Exception as e:
        print(f"Request failed: {e}")
        return None


def plot_price_with_ma(df, symbol):
    if df is None or df.empty:
        return

    plt.figure(figsize=(14,7))
    plt.plot(df.index, df['close'], label='Close', color='royalblue')
    df['MA20'] = df['close'].rolling(20).mean()
    plt.plot(df.index, df['MA20'], '--', label='20-day MA', color='darkred')

    plt.title(f"{symbol} – Daily Closing Price & 20-day MA")
    plt.xlabel("Date")
    plt.ylabel("Price (EUR)")
    plt.grid(True, alpha=0.3)
    plt.legend()
    plt.tight_layout()
    plt.gcf().autofmt_xdate()
    plt.show()


# Download & visualize
eni_df = get_italian_kline("ENI", ktype=8, limit=100)
if eni_df is not None:
    plot_price_with_ma(eni_df, "ENI")
    print("\nKey Statistics:")
    print(f"Latest Close:      {eni_df['close'].iloc[-1]:.3f} EUR")
    print(f"Period High:       {eni_df['high'].max():.3f} EUR")
    print(f"Period Low:        {eni_df['low'].min():.3f} EUR")
    print(f"Avg Daily Volume:  {eni_df['volume'].mean():,.0f} shares")
    print(f"Period Return:     {((eni_df['close'].iloc[-1]/eni_df['close'].iloc[0]-1)*100):+.2f}%")

    

V. Italy Market Quick Reference

Ticker Format
REST: region=IT + local ticker
WebSocket: TICKER$IT (e.g. ENI$IT, FERR$IT)

Major Italian Blue-Chips

CompanyTickerSectorISIN
EniENIEnergyIT0003132476
FerrariFERRAutomobilesNL0011585146
Intesa SanpaoloISPBankingIT0000072618
UniCreditUCGBankingIT0005239360
EnelENELUtilitiesIT0003128367
StellantisSTLAAutomobilesNL00150001Q9
GeneraliGInsuranceIT0000062072

Trading Hours (Milan local time)
09:00 – 17:30 CET
→ Summer (CEST): 15:00 – 23:30 Beijing Time
→ Winter (CET): 16:00 – 00:30 Beijing Time (next day)

VI. Summary

iTick provides one of the most developer-friendly, cost-effective, and comprehensive ways to access Borsa Italiana data in 2026:

  • Full universe coverage
  • Sub-50 ms real-time streaming (tick / quote / depth)
  • Multi-decade historical bars
  • Seamless REST + WebSocket integration
  • Generous free tier for research & early production

Start now: register at https://itick.org and refer to the official documentation.


Further Reading