Python港股实时行情API接入:恒生股票数据获取与AH股溢价监控实战
做跨境量化或者港股通策略的开发者接港股数据是绕不开的。港股跟A股有个很特别的联动关系——同一家公司在A股和港股两地上市价格经常不一样这就是所谓的AH股溢价。这个价差不仅是金融从业者关心的套利机会也是技术开发者做跨市场数据监控的典型场景。这篇从AH股溢价监控这个实际场景出发讲一下怎么用Python接港股实时行情数据以及怎么同时拉A股和港股的价格做价差计算。为什么要接港股数据一开始我做A股量化的时候数据都是国内的接口用得挺顺手。后来想做AH股套利策略才发现需要同时拿A股和港股两边的实时价格。这时候问题就来了——用两个不同的接口拿两边的数据时间戳对不上延迟也不一样算出来的价差不准。后来找了一圈试了几个不同的金融数据接口最后留下来一直在用的是那种同时覆盖A股和港股的统一数据源——不用维护两套代码两边的数据时间戳一致性也靠谱很多。现在做跨市场监控一个key打通多个市场的接口选择其实挺关键的。港股市场的基本情况先理一下港股的基本情况这样看返回数据的时候才知道每个字段是什么意思。交易时间上午9:30-12:00下午13:00-16:00。比A股多半小时中午也有1小时休市。代码格式港股代码是5位数字比如00700是腾讯、09988是阿里、03690是美团。跟A股的6位数字不一样传参数的时候要注意位数。交易货币港币HKD。算AH股溢价的时候要注意汇率换算。region代码港股市场region传HKA股传CN。REST拉取港股报价先从REST开始确认数据格式。importrequests API_BASEhttps://api.itick.orgTOKENyour_token_hereheaders{accept:application/json,token:TOKEN}# 拉港股实时报价defget_hk_stock_quote(code):resprequests.get(f{API_BASE}/stock/quote,headersheaders,params{region:HK,code:code})returnresp.json()[data]# 拉几只港股大盘股stocks[00700,09988,03690]forcodeinstocks:qget_hk_stock_quote(code)signifq[chp]0elseprint(f{code}:{q[ld]}({sign}{q[chp]}%))返回字段跟其他市场基本一致ld最新价、chp涨跌幅、o/h/l开高低、v成交量。做行情看板这些字段够用了。注意港股代码是5位数字传参数的时候要传字符串形式“00700”不要传数字。一开始我传了700结果返回空数据——港股代码必须带前导零5位数字。WebSocket订阅港股做实时监控的时候轮询REST接口效率太低这时候就得用WebSocket实时推送了。importjsonimportthreadingimporttimeimportwebsocket WS_URLwss://api.itick.org/stockTOKENyour_token_hereauthenticatedFalsedefon_message(ws,message):globalauthenticated payloadjson.loads(message)# 先等鉴权成功ifpayload.get(resAc)authandpayload.get(code)1andnotauthenticated:authenticatedTrue# 港股订阅格式代码$市场ws.send(json.dumps({ac:subscribe,params:00700$HK,09988$HK,types:quote}))returnifpayload.get(resAc)pong:returndatapayload.get(data)or{}ifdata.get(type)quote:signifdata[chp]0elseprint(f{data[s]}:{data[ld]}({sign}{data[chp]}%))港股订阅是两个参数00700$HK跟美股、A股一样不是印度那种三个参数。AH股溢价监控实战这是港股数据最有技术含量的应用场景——同一家公司在A股和港股两地上市价格经常不一样。比如招商银行A股代码是600036港股代码是03968。两边的价格理论上应该差不多但实际上经常有5%-30%的溢价差。这个价差就是量化交易者关心的套利机会。# AH股溢价监控# 招商银行A股 600036港股 03968# 中国平安A股 601318港股 02318defget_ah_premium(a_code,h_code,hkd_cny_rate0.92): 计算AH股溢价率 a_code: A股代码 h_code: 港股代码 hkd_cny_rate: 港币兑人民币汇率 # 拉A股价格a_resprequests.get(f{API_BASE}/stock/quote,headersheaders,params{region:CN,code:a_code}).json()[data]# 拉港股价格h_resprequests.get(f{API_BASE}/stock/quote,headersheaders,params{region:HK,code:h_code}).json()[data]# 港股价格换算成人民币h_price_cnyh_resp[ld]*hkd_cny_rate# 计算溢价率premium(a_resp[ld]-h_price_cny)/h_price_cny*100return{a_code:a_code,a_price:a_resp[ld],h_code:h_code,h_price_hkd:h_resp[ld],h_price_cny:round(h_price_cny,2),premium_pct:round(premium,2)}# 监控几只AH股ah_pairs[(600036,03968),# 招商银行(601318,02318),# 中国平安(600900,00900),# 长江电力]fora_code,h_codeinah_pairs:resultget_ah_premium(a_code,h_code)print(f{result[a_code]}/{result[h_code]}: fA股{result[a_price]}元, 港股{result[h_price_hkd]}港币 f(≈{result[h_price_cny]}元), f溢价{result[premium_pct]}%)这个脚本跑起来之后就能看到每只AH股的溢价率了。溢价率过高或者过低的时候就是套利的机会。注意汇率是动态变化的做实时监控的时候要定期更新汇率不能写死。K线数据获取K线接口跟其他市场一样只是region传HK。defget_hk_kline(code,k_type8,limit100): k_type: 11分钟 25分钟 51小时 8日K 9周K 10月K resprequests.get(f{API_BASE}/stock/kline,headersheaders,params{region:HK,code:code,kType:k_type,limit:limit})returnresp.json()[data]# 拉腾讯近100根日Kdailyget_hk_kline(00700,k_type8,limit100)closes[bar[c]forbarindaily]# 算20日均线ma20sum(closes[-20:])/20print(f00700最新收盘:{closes[-1]}, 20日均线:{ma20:.2f})K线返回标准OHLCVt时间戳、o/h/l/c开高低收、v成交量。做技术分析直接用这些字段。港股特有的注意事项代码是5位数字带前导零。港股代码是5位数字00700、09988跟A股的6位数字600519不一样。一开始我传了700结果返回空数据——港股代码必须是5位前面补零。交易时间比A股长半小时。港股上午9:30-12:00下午13:00-16:00。比A股多半小时做跨市场监控的时候要注意两边的交易时间窗口。交易货币是港币。港股价格单位是港币HKD做AH股溢价计算的时候要换算成人民币。汇率是动态的不能写死。港股通标的有限。不是所有港股都能通过港股通买做策略的时候要注意标的范围。时间戳是毫秒。所有返回的时间戳都是毫秒直接当秒数处理会得到一个很远的未来时间记得除以1000。完整脚本港股AH股溢价监控把前面几块拼起来最终的完整脚本importjson,time,threading,requests,websocket API_BASEhttps://api.itick.orgWS_URLwss://api.itick.org/stockTOKENyour_token_hereheaders{accept:application/json,token:TOKEN}# 港股监控列表watchlist[00700,09988,03690]# 启动时拉快照print( 港股快照 )forcodeinwatchlist:rrequests.get(f{API_BASE}/stock/quote,headersheaders,params{region:HK,code:code}).json()[data]signifr[chp]0elseprint(f{code}:{r[ld]}({sign}{r[chp]}%))# AH股溢价快照print(\n AH股溢价 )ah_pairs[(600036,03968),(601318,02318)]fora_code,h_codeinah_pairs:arequests.get(f{API_BASE}/stock/quote,headersheaders,params{region:CN,code:a_code}).json()[data]hrequests.get(f{API_BASE}/stock/quote,headersheaders,params{region:HK,code:h_code}).json()[data]h_cnyh[ld]*0.92premium(a[ld]-h_cny)/h_cny*100print(f{a_code}/{h_code}: A股{a[ld]}元, 港股{h[ld]}港币 f(≈{h_cny:.2f}元), 溢价{premium:.1f}%)# WebSocket实时推送港股authenticatedFalsedefon_message(ws,message):globalauthenticated payloadjson.loads(message)ifpayload.get(resAc)authandpayload.get(code)1andnotauthenticated:authenticatedTrueparams,.join(f{c}$HKforcinwatchlist)ws.send(json.dumps({ac:subscribe,params:params,types:quote}))threading.Thread(targetheartbeat,args(ws,),daemonTrue).start()returnifpayload.get(resAc)pong:returndatapayload.get(data)or{}ifdata.get(type)quote:signifdata[chp]0elseprint(f[实时]{data[s]}:{data[ld]}({sign}{data[chp]}%))defheartbeat(ws):whileTrue:time.sleep(30)ws.send(json.dumps({ac:ping,params:str(int(time.time()*1000))}))wswebsocket.WebSocketApp(WS_URL,header[ftoken:{TOKEN}],on_messageon_message)ws.run_forever()这个脚本跑起来之后开盘前先看到一组港股的快照和AH股溢价率盘中实时更新港股价格。小结接港股数据的技术框架跟A股、美股差不多——REST做快照和历史数据WebSocket做实时推送。主要区别在代码格式5位数字带前导零、交易货币港币和交易时间比A股长半小时。最有技术含量的应用场景是AH股溢价监控——同时拉A股和港股两边的价格算跨市场价差。做港股量化策略或者AH股套利的话这套流程可以直接套。具体的参数细节和返回字段说明我一般都是边写代码边翻官方文档对照比自己猜参数靠谱多了。GitHubhttps://github.com/itick-org/