如何接入美股实时行情API

如果你是一名量化交易员,那么美股的实时行情接口你肯定非常熟悉了。无论是用来做市场分析,还是执行交易策略,实时行情数据都是必需的。市场行情的获取方式有很多种,其中实时接口和普通接口是最常见的两种,而它们之间最大的区别就在于延迟

普通接口通常有较长的延迟,通常会滞后 5 到 10 分钟左右。也就是说它返回的数据并不是市场的最新状态,更多的是用来进行复盘或者做历史数据研究。如果你只需要分析过去的市场走势、测试一些策略的表现,普通接口完全可以满足需求。

但当你进入实际交易的环节,尤其是做高频交易的,延迟慢个几秒钟都很难接受。实时行情接口则可以提供几乎即时的数据,延迟通常在毫秒级别,无论是交易还是监控市场都非常有用。

为什么是 WebSocket#

当然还是因为延迟。传统的 HTTP 请求每次都需要经过请求头、响应等一系列步骤,整体的延迟较高。而 WebSocket 在建立连接后几乎没有额外的延迟,一旦有交易发送会立刻接收到来自服务器的数据推送,而你只需要每隔一分钟向服务器发送心跳来保持连接不断开即可。

下面展示如何使用 infoway API 的 WebSocket 来获取美股的实时行情,各家行情接口的机制是大同小异的。

WebSocket 订阅苹果股票的实时 K 线数据#

import asyncio
import json
import websockets

# 美股行情的websocket订阅地址
WS_URL = "wss://data.infoway.io/ws?business=stock&apikey=yourApiKey"

# 请先在官网https://infoway.io 申请免费API key

async def connect_and_receive():
    async with websockets.connect(WS_URL) as websocket:
        # 发送初始化消息,这里订阅的是苹果股票的1分钟K线数据
        init_message = {
            "code": 10004,  # K线请求协议号
            "trace": "423afec425004bd8a5e02e1ba5f9b2b0",  # 可追溯ID(随机字符串)
            "data": {
                "arr": [
                    {
                        "type": 1,  # 1分钟K线
                        "codes": "AAPL"  # 订阅的股票代码
                    }
                ]
            }
        }
        await websocket.send(json.dumps(init_message))

        # 设置ping任务
        async def send_ping():
            while True:
                await asyncio.sleep(30)
                ping_message = {
                    "code": 10010,
                    "trace": "423afec425004bd8a5e02e1ba5f9b2b0"
                }
                await websocket.send(json.dumps(ping_message))

        # 启动ping任务协程
        ping_task = asyncio.create_task(send_ping())

        try:
            # 持续接收消息
            while True:
                message = await websocket.recv()
                print(f"Message received: {message}")
        except websockets.exceptions.ConnectionClosedOK:
            print("Connection closed normally")
        finally:
            # 取消ping任务
            ping_task.cancel()

# 运行主函数
asyncio.run(connect_and_receive())

当 WS 订阅成功后,每当苹果股票发生交易后,都会自动推送最新的 K 线行情,主要包含一分钟内的高开低收,也即所谓的 OHLC,返回结果示例:

{
    "c": "150.00",         // 当前价格
    "h": "150.20",         // 最高价
    "l": "149.80",         // 最低价
    "o": "149.90",         // 开盘价
    "pca": "0.00",         // 价格变化
    "pfr": "0.00%",        // 价格变化百分比
    "s": "AAPL",           // 股票代码
    "t": 1747550648097,    // 时间戳
    "ty": 1,               // K线类型:1 表示1分钟K线
    "v": "0.34716",        // 交易量
    "vw": "35923.5149678"  // 加权平均价格
}

WebSocket 订阅美股盘口数据#

Infoway 的美股行情接口支持 5 档盘口查询,我们需要在订阅时将协议号改成 10002 即可订阅盘口数据,我们尝试订阅苹果的盘口数据:

import asyncio
import json
import websockets

WS_URL = "wss://data.infoway.io/ws?business=stock&apikey=yourApiKey"

# 请先在官网https://infoway.io 申请免费API key

async def connect_and_receive():
    async with websockets.connect(WS_URL) as websocket:
        # 发送初始化消息,订阅的是苹果股票的盘口数据
        init_message = {
            "code": 10002,  # 盘口订阅的请求协议号
            "trace": "423afec425004bd8a5e02e1ba5f9b2b0",  # 可追溯ID(随机字符串)
            "data": {
                "codes": "AAPL"  # 订阅的股票代码,这里是苹果股票AAPL
            }
        }
        await websocket.send(json.dumps(init_message))

        # 设置ping任务
        async def send_ping():
            while True:
                await asyncio.sleep(30)
                ping_message = {
                    "code": 10010,
                    "trace": "423afec425004bd8a5e02e1ba5f9b2b0"
                }
                await websocket.send(json.dumps(ping_message))

        # 启动ping任务协程
        ping_task = asyncio.create_task(send_ping())

        try:
            # 持续接收消息
            while True:
                message = await websocket.recv()
                print(f"Message received: {message}")
        except websockets.exceptions.ConnectionClosedOK:
            print("Connection closed normally")
        finally:
            # 取消ping任务
            ping_task.cancel()

# 运行主函数
asyncio.run(connect_and_receive())

盘口返回示例:

{
    "a": [
        [
            "150.00",    // 卖盘价格1
            "150.10",    // 卖盘价格2
            "150.20",    // 卖盘价格3
            "150.30",    // 卖盘价格4
            "150.40"     // 卖盘价格5
        ],
        [
            "10.0000",   // 卖盘数量1
            "5.0000",    // 卖盘数量2
            "3.0000",    // 卖盘数量3
            "1.0000",    // 卖盘数量4
            "2.0000"     // 卖盘数量5
        ]
    ],
    "b": [
        [
            "149.90",    // 买盘价格1
            "149.80",    // 买盘价格2
            "149.70",    // 买盘价格3
            "149.60",    // 买盘价格4
            "149.50"     // 买盘价格5
        ],
        [
            "8.0000",    // 买盘数量1
            "4.0000",    // 买盘数量2
            "2.5000",    // 买盘数量3
            "1.5000",    // 买盘数量4
            "3.0000"     // 买盘数量5
        ]
    ],
    "s": "AAPL",           // 股票代码
    "t": 1747553102161     // 时间戳
}
``````json
{
    "a": [
        [
            "150.00",    // 卖盘价格1
            "150.10",    // 卖盘价格2
            "150.20",    // 卖盘价格3
            "150.30",    // 卖盘价格4
            "150.40"     // 卖盘价格5
        ],
        [
            "10.0000",   // 卖盘数量1
            "5.0000",    // 卖盘数量2
            "3.0000",    // 卖盘数量3
            "1.0000",    // 卖盘数量4
            "2.0000"     // 卖盘数量5
        ]
    ],
    "b": [
        [
            "149.90",    // 买盘价格1
            "149.80",    // 买盘价格2
            "149.70",    // 买盘价格3
            "149.60",    // 买盘价格4
            "149.50"     // 买盘价格5
        ],
        [
            "8.0000",    // 买盘数量1
            "4.0000",    // 买盘数量2
            "2.5000",    // 买盘数量3
            "1.5000",    // 买盘数量4
            "3.0000"     // 买盘数量5
        ]
    ],
    "s": "AAPL",           // 股票代码
    "t": 1747553102161     // 时间戳
}
本作品采用《CC 协议》,转载必须注明作者和本文链接