最近做亚洲市场量化的朋友越来越多日本股市是绕不开的一个——东证一部TSE Prime有2000多家上市公司日均成交额排全球前三。跟美股、港股比起来日本市场的代码体系和交易规则都不太一样接数据的时候容易踩坑。这篇记录一下接入日本股票行情的全过程重点讲日本市场的代码体系和跟其他市场的差异。日本市场的基本情况日本主要的交易所是东京证券交易所TSE现在分三个板块Prime主板、Standard标准、Growth成长。我们平时说的日经225指数和东证股价指数TOPIX都是从Prime板块里选的。跟其他市场比起来日本市场有几个特点第一代码是4位数字。跟美股的字母代码AAPL、港股的5位数字代码00700都不一样日本股票代码是4位数字比如7203是丰田、9984是软银、6758是索尼。第二交易时间是日本标准时间JST。比北京时间早1小时开盘时间是东京时间9:00-11:30午盘前和12:30-15:00午盘后。做实时监控的时候要注意时区转换。第三region代码是JP。不是US、HK那种日本市场传JP。日本股票代码速查先整理一下日本常见大盘股的代码接数据的时候直接用代码公司名行业7203丰田汽车汽车9984软银集团综合商社6758索尼集团电子8306三菱UFJ金融集团银行6861基恩士工业自动化6098Recruit Holdings人力资源7974任天堂游戏4063信越化学化工这些都是日经225指数的成分股流动性好数据也稳定。REST拉取日本股票报价先从REST开始确认数据格式。importrequests API_BASEhttps://api.itick.orgTOKENyour_token_hereheaders{accept:application/json,token:TOKEN}# 拉日本股票的实时报价defget_jp_stock_quote(code):resprequests.get(f{API_BASE}/stock/quote,headersheaders,params{region:JP,code:code})returnresp.json()[data]# 拉几只日本大盘股stocks[7203,9984,6758]forcodeinstocks:qget_jp_stock_quote(code)signifq[chp]0elseprint(f{code}:{q[ld]}({sign}{q[chp]}%))返回字段跟其他市场基本一致ld最新价、chp涨跌幅、o/h/l开高低、v成交量。做行情看板这些字段够用了。注意日本股票代码是4位数字传参数的时候要传字符串形式“7203”不要传数字。WebSocket订阅日本股票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:7203$JP,9984$JP,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]}%))跟印度市场不一样——日本是两个参数7203$JP不是三个参数。因为日本主要就是东证一个交易所不需要像印度那样指定NSE/BSE。K线数据获取K线接口跟其他市场一样只是region传JP。defget_jp_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:JP,code:code,kType:k_type,limit:limit})returnresp.json()[data]# 拉丰田汽车近100根日Kdailyget_jp_kline(7203,k_type8,limit100)closes[bar[c]forbarindaily]# 算20日均线ma20sum(closes[-20:])/20print(f7203最新收盘:{closes[-1]}, 20日均线:{ma20:.2f})K线返回标准OHLCVt时间戳、o/h/l/c开高低收、v成交量。做技术分析直接用这些字段。日本市场接入的注意事项代码是4位数字。日本股票代码是4位数字7203、9984跟港股的5位数字00700、美股的字母代码AAPL都不一样。一开始我传了07203带前导零结果返回空数据。交易时间跟国内差1小时。日本标准时间JST比北京时间早1小时。东证开盘时间是东京时间9:00-11:30和12:30-15:00对应北京时间8:00-10:30和11:30-14:00。做实时监控的时候要注意时区。午间休市。日本股市中午有1小时休市东京时间11:30-12:30这个时间段没有成交数据。做策略回测的时候要注意别把午休时间当成流动性枯竭。订阅格式是两个参数。日本跟美股一样是两个参数7203$JP不是印度那种三个参数。因为日本主要就是东证一个交易所。时间戳是毫秒。所有返回的时间戳都是毫秒直接当秒数处理会得到一个很远的未来时间记得除以1000。完整脚本日本股票行情监控把前面几块拼起来最终的完整脚本importjson,time,threading,requests,websocket API_BASEhttps://api.itick.orgWS_URLwss://api.itick.org/stockTOKENyour_token_hereheaders{accept:application/json,token:TOKEN}# 日本股票监控列表watchlist[7203,9984,6758]# 启动时拉快照print( 日本股票快照 )forcodeinwatchlist:rrequests.get(f{API_BASE}/stock/quote,headersheaders,params{region:JP,code:code}).json()[data]signifr[chp]0elseprint(f{code}:{r[ld]}({sign}{r[chp]}%))# WebSocket实时推送authenticatedFalsedefon_message(ws,message):globalauthenticated payloadjson.loads(message)ifpayload.get(resAc)authandpayload.get(code)1andnotauthenticated:authenticatedTrueparams,.join(f{c}$JPforcinwatchlist)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()这个脚本跑起来之后开盘前先看到一组日本股票的快照盘中实时更新价格和涨跌幅。小结接日本股票数据的技术框架跟美股差不多——REST做快照和历史数据WebSocket做实时推送。主要区别在代码体系4位数字、交易时间比国内早1小时和午间休市。这些细节不踩一遍坑很容易忽略。参考文档https://docs.itick.org/websocket/stocksGitHubhttps://github.com/itick-org/