:我用Python接WebSocket获取美股实时tick数据,但消息体里没有一个字段告诉我这是盘前、盘中还是盘后。如果不区分阶段,策略会受到很大干扰。有什么稳健的判断方式吗?

:我来分享一下我的实战经验。当初做交易机器人时也卡在这个地方,后来总结了两套方案,可以覆盖绝大多数场景。

方案一:基于时间戳自行换算

美股行情api通常都会返回每条tick的时间戳。你只需要把时间戳转成美东时间,然后对照下表判断。

阶段美东时间数据特征
盘前04:00-09:30成交稀疏,跳动偏随机
盘中09:30-16:00成交密集,价格连续
盘后16:00-20:00波动受消息影响明显

具体实现可以参考这段代码:

from datetime import datetime
import pytz

# US Eastern timezone
et = pytz.timezone('US/Eastern')

def get_session(ts):
    t = datetime.fromtimestamp(ts, et)
    # Check pre-market hours
    if t.hour < 9 or (t.hour == 9 and t.minute < 30):
        return "pre"
    # Regular market
    if t.hour < 16:
        return "regular"
    # After-hours session
    return "after"

记得处理好夏令时,用pytzUS/Eastern就可以自动适应。

方案二:读取交易状态字段

如果你用的数据源比较完善,有些会在WebSocket消息里直接给出sessionType之类的字段。这样的话,就不需要自己转换时区。但我建议还是用几天的数据做一下边界验证,因为不同提供商对9:30:00这个节点的归属定义可能略有不同。

落地建议

我目前在用的实时流处理中,以AllTick的WebSocket数据作为输入,就是采用第一种方案。在on_message回调里对每条tick进行时段打标,然后再推给策略逻辑。

import websocket
import json
from datetime import datetime
import pytz

# US Eastern timezone
et = pytz.timezone('US/Eastern')

def session(ts):
    t = datetime.fromtimestamp(ts, et)
    if t.hour < 9 or (t.hour == 9 and t.minute < 30):
        return "pre"
    elif t.hour < 16:
        return "regular"
    else:
        return "after"

def on_message(ws, message):
    data = json.loads(message)
    s = session(data["timestamp"])
    print(f"{data['symbol']} | {s} | {data['price']} | {data['volume']}")

# Connect to WebSocket market stream
ws = websocket.WebSocketApp("wss://ws.alltick.co/stock", on_message=on_message)
ws.run_forever()

把时段标签作为基础字段沉淀下来,后续无论是做实时风控还是生成K线,都可以直接按标签过滤,避免盘前噪声和盘后情绪单误导策略。从维护成本上看,集中一处处理也比在每个策略里散落时区判断要高效得多。希望对你有所帮助。


EmilyLi
1 声望1 粉丝