加拿大股票API对接:多伦多证券交易所(TSX/TSXV)实时行情与量化实践

引言:为什么是加拿大?为什么是现在?
在全球量化交易的版图中,多伦多证券交易所(TSX) 及其创业板(TSXV)长期处于一个微妙的位置:资源股丰富、分红稳定、波动性独特,但数据获取门槛却远高于美股和港股。
彭博终端太贵,免费源频遭封锁,主流API供应商对加拿大市场的覆盖要么延迟严重,要么只提供日线级别的“古董数据”。对于专注跨市场套利、能源板块轮动或加拿大分红策略的开发者而言,TSX实时行情的接入一直是“想做但不好做”的痛点。
iTick API 在2026年的版本更新中,已悄然完成对加拿大股票市场的全品种覆盖。本文将以多伦多交易所(TSX) 为核心,手写Python代码,演示如何通过iTick的REST与WebSocket接口,获取加拿大蓝筹股的实时报价、历史K线以及低延迟推送行情—— 全部示例均基于真实TSX证券代码,开箱可测。
一、iTick加拿大市场支持概况
根据iTick官方文档及近期技术更新,其股票API已支持包括 加拿大(TSX/TSXV) 在内的全球40+主要交易所。与美股(US)、港股(HK)类似,加拿大市场的region代码为“CA”,证券代码采用交易所原生代码的统一格式。
✅ 支持的数据类型:
- 实时报价(最新价、涨跌幅、成交量)
- 实时Tick(逐笔成交)
- 实时盘口(买卖盘)
- 历史K线(1分钟~月线,最长15年)
- WebSocket实时推送(毫秒级)
✅ 适用场景:
- 加拿大资源股(能源、矿产)的量化监控
- TSX成分股的高股息策略自动化
- 多市场套利系统的数据基建
二、快速开始:获取API Token
在开始代码之前,你需要完成两件事:
- 访问 iTick官网 注册账号
- 在控制台查看API Key(注册即可获取免费套餐,个人开发者足够使用)
iTick目前提供免费套餐,基本行情无限调用,这对加拿大市场的策略回测与实盘监控极具吸引力。
三、实战一:REST API获取TSX实时报价
我们以加拿大皇家银行(RY)——TSX市值最大的金融股为例,演示单次查询实时行情。
📌 代码示例:TSX股票实时报价
import requests
import json
# 配置区域
API_TOKEN = 'your_itick_token_here' # 替换为你的真实Token
BASE_URL = 'https://api.itick.org'
def get_tsx_quote(symbol):
"""
获取多伦多交易所(TSX)股票实时报价
:param symbol: TSX证券代码,如 RY, ENB, BNS
"""
headers = {
'accept': 'application/json',
'token': API_TOKEN
}
# 加拿大市场region固定为CA
url = f'{BASE_URL}/stock/quote?region=CA&code={symbol}'
try:
response = requests.get(url, headers=headers, timeout=10)
if response.status_code == 200:
data = response.json()
quote = data.get('data', {})
return quote
else:
print(f"请求失败 | 状态码: {response.status_code}")
print(f"错误详情: {response.text}")
return None
except Exception as e:
print(f"网络异常: {str(e)}")
return None
# 实战调用:加拿大皇家银行 RY
if __name__ == '__main__':
quote = get_tsx_quote('RY')
if quote:
print("=" * 60)
print(f"多伦多证券交易所 TSX - 实时行情")
print("=" * 60)
print(f"证券代码: {quote.get('s', 'N/A')}")
print(f"最新价: {quote.get('ld', 'N/A')} CAD")
print(f"涨跌额: {quote.get('ch', 'N/A')}")
print(f"涨跌幅: {quote.get('chp', 'N/A')}%")
print(f"成交量: {quote.get('v', 'N/A')}")
print(f"开盘: {quote.get('o', 'N/A')}")
print(f"最高: {quote.get('h', 'N/A')}")
print(f"最低: {quote.get('l', 'N/A')}")
print(f"时间戳: {quote.get('t', 'N/A')}")
else:
print("未获取到数据,请检查Token或网络")
🔍 响应字段解析(TSX专用)
| 字段 | 含义 | 示例 |
|---|---|---|
s | 证券代码 | RY |
ld | 最新价 | 168.32 |
ch | 涨跌 | 0.05 |
chp | 涨跌幅(百分比) | 0.45 |
o | 开盘价 | 168.05 |
h | 最高价 | 168.32 |
l | 最低价 | 167.95 |
v | 成交量 | 1000 |
t | 时间戳 | 1631234567000 |
小贴士:若你获取的是TSXV创业板股票(如高风险矿业股),代码格式一般为
ABC,region仍为CA,iTick会自动路由至对应交易所。
四、实战二:WebSocket实时推送:构建TSX监控流水线
REST API适合定时查询,但如果你想监控加拿大能源板块的毫秒级异动,或构建低延迟的算法交易信号,必须使用WebSocket。
📌 代码示例:订阅多只TSX股票的实时报价与Tick
import websocket
import json
import threading
import time
WS_URL = "wss://api.itick.org/stock"
API_TOKEN = 'your_itick_token_here'
class TSXMonitor:
def on_message(self, ws, message):
try:
data = json.loads(message)
if 'data' in data:
payload = data['data']
symbol = payload.get('s')
typ = payload.get('type')
if typ == 'quote':
print(f"[报价] {symbol}: 最新 {payload.get('ld')} | 量 {payload.get('v')}")
elif typ == 'tick':
print(f"[成交] {symbol}: 价 {payload.get('ld')} | 量 {payload.get('v')}")
except Exception as e:
print(f"解析错误: {e}")
def on_open(self, ws):
print("WebSocket 已连接,正在订阅 TSX 股票...")
sub_msg = {
"ac": "subscribe",
"params": "RY$CA,ENB$CA,ABX$CA",
"types": "quote,tick"
}
ws.send(json.dumps(sub_msg))
def on_error(self, ws, error):
print(f"错误: {error}")
def on_close(self, ws, code, msg):
print("连接关闭")
def start(self):
headers = {"token": API_TOKEN}
self.ws = websocket.WebSocketApp(
WS_URL, header=headers,
on_open=self.on_open, on_message=self.on_message,
on_error=self.on_error, on_close=self.on_close
)
def heartbeat():
while True:
time.sleep(30)
if self.ws.sock and self.ws.sock.connected:
self.ws.send(json.dumps({"ac": "ping", "params": str(int(time.time()*1000))}))
threading.Thread(target=heartbeat, daemon=True).start()
self.ws.run_forever()
if __name__ == '__main__':
monitor = TSXMonitor()
monitor.start()
⚙️ 技术要点说明
- 参数格式:
RY$CA——证券代码$市场代码,与美股AAPL$US完全一致 - 订阅类型:
quote(报价)、tick(成交)、depth(盘口),可自由组合 - 心跳机制:每30秒发送
ping,防止连接闲置断开 - 多标订阅:逗号分隔,单次订阅上限建议不超过50只
此代码跑通后,你可以在终端实时看到加拿大蓝筹股的每一笔报价变动——这是搭建TSX量化监控面板的第一块砖。
五、实战三:历史K线获取——回测必备
任何量化策略都离不开历史数据。iTick为加拿大股票提供长达15年的日线数据及完整的分钟级历史K线。
📌 代码示例:获取TSX股票最近20根日K线
import requests
import pandas as pd
from datetime import datetime
def get_tsx_kline(symbol, ktype=8, limit=20):
"""
获取TSX股票历史K线
:param symbol: 证券代码,如 RY
:param ktype: K线类型 1=1分钟, 2=5分钟, 3=15分钟, 4=30分钟, 5=1小时, 6=2小时, 7=4小时, 8=日线, 9=周线, 10=月线
:param limit: 返回K线根数
"""
headers = {
'accept': 'application/json',
'token': 'your_itick_token_here'
}
url = f"https://api.itick.org/stock/kline?region=CA&code={symbol}&kType={ktype}&limit={limit}"
resp = requests.get(url, headers=headers)
if resp.status_code == 200:
data = resp.json().get('data', [])
# 转换为DataFrame便于分析
df = pd.DataFrame(data)
if not df.empty:
df.rename(columns={
't': 'timestamp',
'o': 'open',
'h': 'high',
'l': 'low',
'c': 'close',
'v': 'volume'
}, inplace=True)
# 时间戳转换
df['datetime'] = pd.to_datetime(df['timestamp'], unit='ms')
return df[['datetime', 'open', 'high', 'low', 'close', 'volume']]
else:
print(f"K线获取失败: {resp.status_code}")
return None
# 示例:获取Enbridge(ENB)最近10个交易日数据
df = get_tsx_kline('ENB', ktype=8, limit=10)
if df is not None:
print(df.to_string(index=False))
你可以直接在此基础上封装双均线策略、RSI择时或波动率突破策略——数据源已就绪。
六、附录:iTick加拿大股票代码速查表(部分)
为了方便测试,这里提供一组流动性较好的TSX证券代码,均可通过上述代码直接拉取数据:
| 公司名称 | 代码 | 板块 |
|---|---|---|
| 加拿大皇家银行 | RY | 金融 |
| 多伦多道明银行 | TD | 金融 |
| 森科能源 | SU | 能源 |
| 加拿大自然资源 | CNQ | 能源 |
| 巴里克黄金 | ABX | 材料 |
| 惠顿贵金属 | WPM | 材料 |
| 加拿大国家铁路 | CNR | 工业 |
创业板(TSXV)示例:如
NGEX(矿产勘探),用法同上。
结语:加拿大市场不再是数据孤岛
长期以来,TSX在全球金融API生态中处于“被遗忘的角落”。iTick此次对加拿大市场的完整覆盖,填补了个人开发者与中小机构在加拿大股票实时数据接入上的空白。
官方文档:https://docs.itick.org
GitHub:https://github.com/itick-org