DEV Community

Cover image for 2026 Australian Securities Exchange (ASX) API Integration and Python Quantitative Strategies
San Si wu
San Si wu

Posted on

2026 Australian Securities Exchange (ASX) API Integration and Python Quantitative Strategies

As a developer in the global financial industry, when turning my attention to the Australian stock market in recent years, the first challenge encountered is "data acquisition." To conduct real-time market analysis and build quantitative strategies, a reliable real-time quote API integration is essential—otherwise, everything remains theoretical. After navigating numerous pitfalls, I've developed a comprehensive workflow from API integration and real-time data retrieval to implementing simple quantitative strategies. Today, I'm sharing these practical insights with fellow enthusiasts.

Core Aspects of ASX API

Unlike Hong Kong, U.S., or A-share markets, the Australian Securities Exchange (ASX) has its unique trading rules and data structures. Before integrating an API, clarify these key points:

  1. Data Types: Our primary focus is on real-time trade prices, bid-ask spreads, trading volumes, and percentage changes. A high-quality API provides millisecond-level real-time pushes rather than delayed snapshots.
  2. Integration Methods: Most ASX APIs support RESTful endpoints (for on-demand pulls) and WebSocket (for real-time pushes). The former suits targeted queries, while the latter is ideal for continuous market monitoring.
  3. Permissions and Costs: Individual developers typically start with free or low-cost plans to validate functionality before upgrading. Pay attention to API rate limits and data coverage (e.g., full-market stocks versus top-tier symbols only).

II. Retrieving Real-Time Market Data

First, prerequisites: Register on the iTick official website to obtain an API Key (typically generated in the developer dashboard) and ensure your account has real-time quote access permissions.

1. Environment Setup

Install the necessary Python libraries: requests for REST API calls, websocket-client for real-time pushes, and pandas for data manipulation:

pip install requests websocket-client pandas
Enter fullscreen mode Exit fullscreen mode

2. Fetching Real-Time Quotes for a Single Stock

Start with the simplest REST endpoint to retrieve real-time data for an Australian stock (e.g., CBA, Commonwealth Bank of Australia):

import requests

url = "https://api.itick.org/stock/quote?region=AU&code=CBA"

headers = {
"accept": "application/json",
"token": "your_token"
}

response = requests.get(url, headers=headers)

print(response.text)
Enter fullscreen mode Exit fullscreen mode

Running this code yields real-time data in the following format (example):

{
  "code": 0,
  "msg": null,
  "data": {
    "s": "CBA",
    "ld": 115.25,
    "o": 114.8,
    "h": 115.5,
    "l": 114.5,
    "t": 1765526889000,
    "v": 452000,
    "tu": 52000000,
    "ts": 0,
    "ch": 0.45,
    "chp": 0.39
  }
}
Enter fullscreen mode Exit fullscreen mode

3. WebSocket for Real-Time Quote Streaming

For continuous monitoring (e.g., generating real-time trading signals), REST polling is inefficient. Use WebSocket for push-based updates:

import websocket
import json
import threading
import time

# WebSocket connection URL and token
WS_URL = "wss://api.itick.org/stock"
API_TOKEN = "your_token"

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

    # Handle successful connection
    if data.get("code") == 1 and data.get("msg") == "Connected Successfully":
        print("Connected successfully, waiting for authentication...")

    # Handle authentication result
    elif data.get("resAc") == "auth":
        if data.get("code") == 1:
            print("Authentication successful")
            # Subscribe after successful authentication
            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("Subscription failed:", data.get("msg"))

    # Handle market data
    elif data.get("data"):
        # Print real-time quote data
        market_data = data["data"]
        data_type = market_data.get("type")
        symbol = market_data.get("s")
        print(f"{data_type.upper()} data for {symbol}:", market_data)

def on_error(ws, error):
    """Handle errors"""
    print("Error:", error)

def on_close(ws, close_status_code, close_msg):
    """Connection close callback"""
    print("Connection closed")

def on_open(ws):
    """Connection open callback"""
    print("WebSocket connection opened")

def subscribe(ws):
    """Subscribe to market data"""
    subscribe_msg = {
        "ac": "subscribe",
        "params": "CBA$AU",
        "types": "tick,quote,depth"
    }
    ws.send(json.dumps(subscribe_msg))
    print("Subscribe message sent")

def send_ping(ws):
    """Send periodic heartbeats"""
    while True:
        time.sleep(30)  # Send heartbeat every 30 seconds
        ping_msg = {
            "ac": "ping",
            "params": str(int(time.time() * 1000))
        }
        ws.send(json.dumps(ping_msg))
        print("Ping sent")

if __name__ == "__main__":
    # Create WebSocket connection with token in header
    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,))
    ping_thread.daemon = True
    ping_thread.start()

    # Run WebSocket connection
    ws.run_forever()
Enter fullscreen mode Exit fullscreen mode

Upon execution, you'll observe real-time pushed data, with updates for every price or order book change—this forms the foundation for quantitative strategies.

III. A Simple ASX Quantitative Strategy Example

With real-time data in hand, you can construct basic quantitative strategies. Here's a "breakout buy" strategy: Trigger a buy signal when the real-time price exceeds 1.01 times the 5-minute moving average, accompanied by volume surge.

import requests
import pandas as pd
import time

API_TOKEN = "your_token"
BASE_URL = "https://api.itick.org/stock/quote"

# Store recent 5-minute price data
price_history = {
    "CBA": []
}
AVG_WINDOW = 300  # 5 minutes (in seconds)
PRICE_RATIO = 1.01  # Breakout threshold

def get_realtime_price(symbol):
    """Fetch real-time price"""
    headers = {
        "accept": "application/json",
        "token": API_TOKEN
    }
    params = {
        "region": "AU",
        "code": symbol
    }
    try:
        response = requests.get(BASE_URL, headers=headers, params=params, timeout=5)
        data = response.json()
        if "data" in data:
            quote = data["data"]
            return quote["ld"], quote["v"], quote["t"]
    except Exception as e:
        print(f"Price fetch failed: {e}")
    return None, None, None

def check_breakout_strategy(symbol):
    """Check for breakout signals"""
    price, volume, ts = get_realtime_price(symbol)
    if price is None:
        return

    # Record price, retaining only recent 5-minute data
    current_time = ts / 1000  # Convert to seconds
    price_history[symbol].append({"price": price, "volume": volume, "time": current_time})
    # Filter out data older than 5 minutes
    price_history[symbol] = [x for x in price_history[symbol] if current_time - x["time"] <= AVG_WINDOW]

    # Require at least 10 data points for average calculation
    if len(price_history[symbol]) >= 10:
        prices = [x["price"] for x in price_history[symbol]]
        avg_price = pd.Series(prices).mean()
        # Check for volume surge (compared to previous point)
        volume_increase = volume > price_history[symbol][-2]["volume"] * 1.2 if len(price_history[symbol]) > 1 else False

        # Trigger breakout signal
        if price > avg_price * PRICE_RATIO and volume_increase:
            print(f"\n[Buy Signal] {symbol} - Real-time Price: {price} | 5-min Avg: {round(avg_price,2)} | Volume: {volume}")
        else:
            print(f"{symbol} - Real-time Price: {price} | 5-min Avg: {round(avg_price,2)} | No Signal", end="\r")

if __name__ == "__main__":
    # Continuously monitor for signals every 3 seconds
    while True:
        check_breakout_strategy("CBA")
        time.sleep(3)
Enter fullscreen mode Exit fullscreen mode

This strategy's logic is straightforward, ideal for beginners: Continuously collect real-time prices, compute short-term moving averages, and validate breakouts with volume to avoid false signals. In practice, adjust for ASX trading hours (Australian Eastern Time 9:15–16:00) and incorporate risk controls like stop-loss or take-profit.

IV. Key Considerations for ASX API Integration

  1. Time Zone Issues: Australia uses AEST/AEDT, 2–3 hours ahead of Beijing Time. Always convert timestamps to avoid data misalignment.
  2. API Rate Limiting: Free/basic plans often impose limits (e.g., 10 calls per second). Add delays for batch queries to prevent throttling.
  3. Data Validation: Real-time quotes may include outliers (e.g., price gaps). Implement data cleansing in strategies, such as filtering unreasonable fluctuations.
  4. Testing Environment: Validate strategies in a sandbox or with test APIs before live deployment, and familiarize yourself with ASX trading rules and fees.

Summary

  1. ASX API integration hinges on defining data needs (real-time/historical) and selecting appropriate interfaces (REST/WebSocket). The iTick API serves as a versatile example.
  2. Python API docking emphasizes authentication, error handling, and data formatting; WebSocket excels for real-time acquisition.
  3. Quantitative strategy implementation starts with simple logic, integrating real-time data for signal validation while addressing time zones, limits, and data integrity.

Reference Documentation: https://blog.itick.org/stock-api/2026-australian-stock-market-itick-api-guide

GitHub: https://github.com/itick-org/

Top comments (0)