做美股量化要踩的坑:WebSocket 断线重连后,行情为什么会悄悄断更?
展开
个人博客|实战笔记
做美股数据采集、跑量化策略的朋友应该都遇到过一种糟心情况:程序看着还在正常跑,进程没崩,WebSocket也显示重连成功了,但行情数据早就悄咪咪停掉了,等过了很久才发现少了一大段tick数据,回测、实盘信号全部受影响。
之前我写采集脚本的时候,一开始把精力都放在处理K线、指标计算、策略逻辑上面,想当然以为WebSocket连上之后,就会源源不断推送行情。真正挂起来长时间跑,才发现现实没这么简单。
网络波动、网络超时、接口侧的连接限制,都可能把长连接搞断。最坑的是静默断线,程序不会报错崩溃,表面一切正常,就是不更新行情。如果在跑实盘或者积累历史tick样本,数据缺口带来的麻烦挺大,回测对不上实盘,信号错乱,后面排查要花大量时间。
很多网上的示例只做了断线重连,这里有个很关键的误区:重连不等于恢复订阅。只是把网络接通,没有重新发送订阅指令,服务器就不会再给你推送股票的数据。连接状态看着ok,实际拿不到行情。想要恢复完整数据流,重建连接之后,必须把之前订阅过的标的重新订阅一遍。
完整的处理逻辑其实就4步:
时刻监控WebSocket连接是否正常;检测到断线,自动重新建立连接;读取之前保存好的股票代码、数据类型这些订阅参数,重新发起订阅;继续接收行情数据,供给策略和数据存储使用。小提醒:如果同时订阅多只美股,一定要把全部订阅清单存下来,不然重连之后,只会恢复部分股票的数据。
Python实操代码,可本地调试测试
下面这段基础代码,用来测试断线自动重连+恢复订阅逻辑。连接断掉之后会自动重试,连接建立成功就重新订阅标的,适合自己本地做原型测试。
import websocketimport jsonimport timedef subscribe(ws): data = { action : subscribe , symbol : AAPL , type : tick , source : alltick } ws.send(json.dumps(data))def on_open(ws): print( 连接成功 ) subscribe(ws)def on_message(ws, message): data = json.loads(message) print(data)def on_close(ws, code, msg): print( 连接关闭 )while True: try: ws = websocket.WebSocketApp( wss://api.alltick.co/ws , on_open=on_open, on_message=on_message, on_close=on_close ) ws.run_forever() except Exception as e: print( 异常: , e) time.sleep(5)
简单说下逻辑:连接断开之后,程序休眠几秒再尝试新建连接,连接打开触发回调,就再次执行订阅函数,把行情数据流拉回来。注意:这只是基础demo,不要不做修改直接丢去实盘跑。
实际跑策略,还要注意这几个现实问题
做好数据去重重连的时候,有可能收到重复的tick数据。建议拿时间戳或者成交编号做判断过滤,避免重复写入数据库,不然样本库被污染,回测结果就会失真。保管好全部订阅列表多股票策略,所有订阅标的要完整保存,防止断线恢复之后少部分股票行情丢失。控制重连的频率不要死循环疯狂重试连接,频繁请求会给接口造成压力,还会占用本机资源,影响策略本身运行,设置合理的等待间隔。建议自己加简单告警可以加一层简单判断,如果长时间没有收到新行情日志,就做提醒。防止出现极端情况,程序拿着过期数据继续跑策略。
个人一点实战感悟
做美股量化,大家都热衷于研究指标、选股逻辑、回测模型,但底层数据源的稳定性往往容易被轻视。回测结果靠不靠谱,实盘信号能不能用,前提就是行情数据完整可用。WebSocket断线自愈看着是底层小细节,但会直接影响整套数据的质量。写采集脚本的时候,就要把连接状态管理、订阅信息保存、数据校验这些考虑进去。做原型调试的时候,可以借助AllTick API验证这套断线恢复逻辑,把更多精力放在策略本身的打磨上。
帖子随笔:不知道各位股友在写行情采集脚本的时候,还踩过哪些奇奇怪怪的坑,欢迎评论区一起交流探讨。
做美股数据采集、跑量化策略的朋友应该都遇到过一种糟心情况:程序看着还在正常跑,进程没崩,WebSocket也显示重连成功了,但行情数据早就悄咪咪停掉了,等过了很久才发现少了一大段tick数据,回测、实盘信号全部受影响。
之前我写采集脚本的时候,一开始把精力都放在处理K线、指标计算、策略逻辑上面,想当然以为WebSocket连上之后,就会源源不断推送行情。真正挂起来长时间跑,才发现现实没这么简单。
网络波动、网络超时、接口侧的连接限制,都可能把长连接搞断。最坑的是静默断线,程序不会报错崩溃,表面一切正常,就是不更新行情。如果在跑实盘或者积累历史tick样本,数据缺口带来的麻烦挺大,回测对不上实盘,信号错乱,后面排查要花大量时间。
很多网上的示例只做了断线重连,这里有个很关键的误区:重连不等于恢复订阅。只是把网络接通,没有重新发送订阅指令,服务器就不会再给你推送股票的数据。连接状态看着ok,实际拿不到行情。想要恢复完整数据流,重建连接之后,必须把之前订阅过的标的重新订阅一遍。
完整的处理逻辑其实就4步:
时刻监控WebSocket连接是否正常;检测到断线,自动重新建立连接;读取之前保存好的股票代码、数据类型这些订阅参数,重新发起订阅;继续接收行情数据,供给策略和数据存储使用。小提醒:如果同时订阅多只美股,一定要把全部订阅清单存下来,不然重连之后,只会恢复部分股票的数据。
Python实操代码,可本地调试测试
下面这段基础代码,用来测试断线自动重连+恢复订阅逻辑。连接断掉之后会自动重试,连接建立成功就重新订阅标的,适合自己本地做原型测试。
import websocketimport jsonimport timedef subscribe(ws): data = { action : subscribe , symbol : AAPL , type : tick , source : alltick } ws.send(json.dumps(data))def on_open(ws): print( 连接成功 ) subscribe(ws)def on_message(ws, message): data = json.loads(message) print(data)def on_close(ws, code, msg): print( 连接关闭 )while True: try: ws = websocket.WebSocketApp( wss://api.alltick.co/ws , on_open=on_open, on_message=on_message, on_close=on_close ) ws.run_forever() except Exception as e: print( 异常: , e) time.sleep(5)
简单说下逻辑:连接断开之后,程序休眠几秒再尝试新建连接,连接打开触发回调,就再次执行订阅函数,把行情数据流拉回来。注意:这只是基础demo,不要不做修改直接丢去实盘跑。
实际跑策略,还要注意这几个现实问题
做好数据去重重连的时候,有可能收到重复的tick数据。建议拿时间戳或者成交编号做判断过滤,避免重复写入数据库,不然样本库被污染,回测结果就会失真。保管好全部订阅列表多股票策略,所有订阅标的要完整保存,防止断线恢复之后少部分股票行情丢失。控制重连的频率不要死循环疯狂重试连接,频繁请求会给接口造成压力,还会占用本机资源,影响策略本身运行,设置合理的等待间隔。建议自己加简单告警可以加一层简单判断,如果长时间没有收到新行情日志,就做提醒。防止出现极端情况,程序拿着过期数据继续跑策略。
个人一点实战感悟
做美股量化,大家都热衷于研究指标、选股逻辑、回测模型,但底层数据源的稳定性往往容易被轻视。回测结果靠不靠谱,实盘信号能不能用,前提就是行情数据完整可用。WebSocket断线自愈看着是底层小细节,但会直接影响整套数据的质量。写采集脚本的时候,就要把连接状态管理、订阅信息保存、数据校验这些考虑进去。做原型调试的时候,可以借助AllTick API验证这套断线恢复逻辑,把更多精力放在策略本身的打磨上。
帖子随笔:不知道各位股友在写行情采集脚本的时候,还踩过哪些奇奇怪怪的坑,欢迎评论区一起交流探讨。
话题与分类:
主题股票:
主题概念:
声明:遵守相关法律法规,所发内容承担法律责任,倡导理性交流,远离非法证券活动,共建和谐交流环境!
