做港股开发那段时间我碰到一个挺尴尬的问题——碎股行情。正常来说我们拿到的tick数据都是按每手交易来的但碎股不一样它成交零散流动性低很多接口干脆不推。一开始我没在意直到回测策略的时候发现数据对不上才意识到碎股这块被忽略了。碎股是什么简单说就是不足一手的买卖盘。港股市场上有些股票单价高投资者可能只买几十股这种成交不会出现在常规的行情推送里。如果做高频或者量化策略忽略碎股数据就不完整了。为什么碎股行情难抓我试过几个港股api发现碎股数据有几个特点推送不稳定不是每个成交都有推送频率低很多字段不统一有的接口单独给碎股字段有的直接不提供延迟较高碎股成交往往比整手交易晚几秒才出来用轮询方式基本抓不到因为碎股更新慢但不定时轮询间隔设短了浪费资源设长了容易漏。我后来换成WebSocket总算能稳定收到了。实际怎么获取碎股行情以AllTick API为例它的WebSocket接口会推送完整的tick数据里面包含了碎股成交记录。关键是要在订阅的时候明确指定需要哪些字段不然默认只返回整手数据。import websocket import json def on_message(ws, message): data json.loads(message) # 碎股成交会单独标识 for trade in data.get(trades, []): if trade.get(is_odd_lot): # 碎股标识 print(f碎股成交 {trade[symbol]} 价格:{trade[price]} 数量:{trade[volume]}) else: print(f整手成交 {trade[symbol]} 价格:{trade[price]} 数量:{trade[volume]}) def on_open(ws): # 订阅时需要开启碎股数据推送 subscribe_msg { action: subscribe, symbols: [00700.HK, 09988.HK], include_odd_lot: True # 这个参数很关键 } ws.send(json.dumps(subscribe_msg)) ws websocket.WebSocketApp( wss://api.alltick.co/ws/stock, on_openon_open, on_messageon_message ) ws.run_forever()代码里那个include_odd_lot参数是我翻文档才发现的。一开始没加死活收不到碎股数据加上之后立马就有了。处理碎股数据的几个小技巧拿到碎股数据后我通常这样处理场景处理方式实时展示碎股单独列一行和整手区分开策略计算把碎股合并到总成交量里但单独标记历史回测碎股数据存到另一张表需要时再关联碎股数据量不大但我会做一层缓存把最近五分钟的碎股成交暂存起来。因为有些策略需要判断碎股占比如果碎股突然变多可能是个信号。容易忽略的细节港股api返回的碎股数据里有个字段容易误解——trade_type。我一开始以为碎股就是类型为“ODD_LOT”结果发现有些接口用的是“ODD”有些直接写在备注里。最好先打印一条数据看看结构别直接写死判断逻辑。另外碎股的成交价格有时会和整手有偏差。我碰到过碎股比整手贵两档的情况后来才明白是投资者急着成交愿意出高价。做策略时别把碎股价格和整手混在一起算均价会偏。我的看法碎股行情看似边缘但在某些场景下挺有用。比如某只股票突然出现大量碎股买入可能是有散户提前动手这种细节有时候比整手数据还敏感。港股api里能稳定提供碎股推送的不多选接口时这块值得留意。数据完整度决定了策略的可靠性碎股虽然零碎但补齐了才安心。