这里介绍使用免费开源Pytdx接口方式获取实时行情数据,并实时存入数据库中(mongodb/myslq)。
Pytdx 是一款纯Python语言开发的类似TradeX的行情数据接口的实现。它提供各种股票/期货/期权等等实时行情数据。
提供数据种类包括:
market category name short_name
0 1 1 临时股 TP
1 4 12 郑州商品期权 OZ
2 5 12 大连商品期权 OD
3 6 12 上海商品期权 OS
4 7 12 中金所期权 OJ
5 8 12 上海个股期权 QQ
6 9 12 深圳个股期权 SQ
7 10 4 基本汇率 FE
8 11 4 交叉汇率 FX
9 12 5 国际指数 WI
10 13 3 国际贵金属 GO
11 14 3 伦敦金属 LM
12 15 3 伦敦石油 IP
13 16 3 纽约商品 CO
14 17 3 纽约石油 NY
15 18 3 芝加哥谷 CB
16 19 3 东京工业品 TO
17 20 3 纽约期货 NB
18 27 5 香港指数 FH
19 28 3 郑州商品 QZ
20 29 3 大连商品 QD
21 30 3 上海期货 QS
22 31 2 香港主板 KH
23 33 8 开放式基金 FU
24 34 9 货币型基金 FB
25 35 8 券商理财产品 LC
26 36 9 券商货币产品 LB
27 37 11 全球指数(静态) FW
28 38 10 宏观指标 HG
29 39 3 马来期货 ML
30 40 11 中国概念股 CH
31 41 11 美股知名公司 MG
32 43 1 B股转H股 HB
33 44 1 股转系统 SB
34 46 11 上海黄金 SG
35 47 3 中金所期货 CZ
36 48 2 香港创业板 KG
37 49 2 香港基金 KT
38 50 3 渤海商品 BH
39 56 8 阳光私募基金 TA
40 57 8 券商集合理财 TB
41 58 9 券商货币理财 TC
42 60 3 主力期货合约 MA
43 62 5 中证指数 ZZ
44 70 5 扩展板块指数 UZ
45 71 2 港股通 GH
46 102 5 国证指数 GZ
支持python2、python3编程语言。
首先需要引入
from pytdx.exhq import *
from pytdx.hq import *
一、标准行情api方法列表
from pytdx.hq import *
1 : 获取股票行情
可以获取多只股票的行情信息
需要传入一个列表,每个列表由一个市场代码, 一个股票代码构成的元祖构成 [ (市场代码1, 股票代码1),(市场代码2, 股票代码2) … (市场代码n, 股票代码n) ]
如:api.get_security_quotes([(0, ‘000001’), (1, ‘600300’)])
2 : 获取k线
K线种类: 0 5分钟K线 1 15分钟K线 2 30分钟K线 3 1小时K线 4 日K线 5 周K线 6 月K线 7 1分钟 81分钟K线 9 日K线 10 季K线 11 年K线
api.get_security_bars(9,0, ‘000001’, 4, 3)
3 : 获取市场股票数量
api.get_security_count(0)
4 : 获取股票列表
api.get_security_list(1, 0)
5 : 获取指数k线
api.get_index_bars(9,1, ‘000001’, 1, 2)
6 : 查询分时行情
api.get_minute_time_data(1, ‘600300’)
7 : 查询历史分时行情
api.get_history_minute_time_data(TDXParams.MARKET_SH, ‘600300’, 20161209)
8 : 查询分笔成交
api.get_transaction_data(TDXParams.MARKET_SZ, ‘000001’, 0, 30)
9 : 查询历史分笔成交
api.get_history_transaction_data(TDXParams.MARKET_SZ, ‘000001’, 0, 10, 20170209)
10 : 查询公司信息目录
api.get_company_info_category(TDXParams.MARKET_SZ, ‘000001’)
11 : 读取公司信息详情
api.get_company_info_content(0, ‘000001’, ‘000001.txt’, 0, 100)
12 : 读取除权除息信息
api.get_xdxr_info(1, ‘600300’)
13 : 读取财务信息
api.get_finance_info(0, ‘000001’)
14 : 读取k线信息
get_k_data(‘000001’,‘2017-07-03’,‘2017-07-10’)
15 :读取板块信息
api.get_and_parse_block_info(TDXParams.BLOCK_SZ)
二、扩展行情接口API
from pytdx.exhq import *
1: 获取市场代码
api.get_markets()
2: 查询代码列表
api.get_instrument_info(0, 100)
3: 查询市场中商品数量
api.get_instrument_count()
4: 查询五档行情
api.get_instrument_quote(47, “IF1709”)
5: 查询分时行情
api.get_minute_time_data(47, “IF1709”)
6: 查询历史分时行情
api.get_history_minute_time_data(31, “00020”, 20170811)
7: 查询k线数据
api.get_instrument_bars(TDXParams.KLINE_TYPE_DAILY, 8, “10000843”, 0, 100)
8: 查询分笔成交
api.get_transaction_data(31, “00020”)
api.get_history_transaction_data(47, “IFL0”, 20170810, start=1800)
9: 查询历史分笔成交
api.get_history_transaction_data(31, “00020”, 20170810)
三、其他功能
多线程支持、心跳包、抛出异常、重连机制,以及读取读取通达信的日K线、历史专业财务数据,以及交易相关(如创建订单、撤销订单等),请参阅参考 https://github.com/rainx/pytdx/issues/5
四、应用案例源码
下面是实时获取股票/50ETF/300ETF 及其 股票期权实时行情的python 方法:
def fetcHQRisk(self, isSaveSTkRealtime=False, isSaveOptRealtime=False):
optList= self.contraManager.contrOptIdList
riskM=RISKMAN.RiskMan()
rate=4.
hv=20. #default
if self.db=='mysql':
try:
sql='select * from %s \
where tradeDate in (select max(tradeDate) from %s);'%(C.OPT_HV,C.OPT_HV)
res=dbcom.select_tuple_dict(sql)
hvDf=pd.DataFrame(list(res))
hv=(hvDf[hvDf['xmode']=='yz'][C.HVX]).values[0]
hv=round(hv*100.,1)
except Exception,e:
print (e)
elif self.db=='mongo':
hv=mdbcom.find(C.STK_HV,sortListOfTuple=[('date',-1)])
if hv is not None and len(hv)>0:
hv=hv[0][C.HVX]
hv=round(hv*100.,1)
api_hq=None
api_exhq=None
try:
api_hq = TdxHq_API()
with self.isConnected(api_hq,type='hq',verbose=True) as api_hq:
quote_hq=api_hq.get_security_quotes([(self.market_good, self.good[:-5])])
spotPrice=quote_hq[0]['price']/10.
#add on 2019-04-17
#daily 50etf info:today's cummulative info. cummulative!!!
#*********************************
etf_open=quote_hq[0]['open']/10.
etf_high=quote_hq[0]['high']/10.
etf_low=quote_hq[0]['low']/10.
etf_last_close=quote_hq[0]['last_close']/10.
#today's cummulative info
etf_vol=quote_hq[0]['vol']
etf_amount=quote_hq[0]['amount']
#*********************************
print(spotPrice)
if quote_hq is not None or spotPrice>0.000001:
if isSaveSTkRealtime:
'''
category->
K线种类
0 5分钟K线
1 15分钟K线
2 30分钟K线
3 1小时K线
4 日K线
5 周K线
6 月K线
7 1分钟
8 1分钟K线
9 日K线
10 季K线
11 年K线
market -> 市场代码 0:深圳,1:上海
stockcode -> 证券代码;
start -> 指定的范围开始位置;
count -> 用户要请求的 K 线数目,最大值为 800
'''
stk_1min_K=api_hq.get_security_bars(8, 1, self.good[:-5], 0, 10)
nowTime=xtool.nowTime()
stk_1min_K_df=pd.DataFrame(stk_1min_K)
stk_1min_K_df['xtime']=nowTime
hr_min=[t[-5:] for t in stk_1min_K_df['datetime']]
stk_1min_K_df['_id']=hr_min
record=stk_1min_K_df.to_dict(orient='record')
mdbcom.saveBatch(C.STK_MINS,record)
stk_1min_K_df['_id']=stk_1min_K_df['datetime']
stk_1min_K_df["tradeTime"]= stk_1min_K_df['datetime']
stk_1min_K_df["tradeMins"]= hr_min
stk_1min_K_df["tradeDate"]= [t[:10] for t in stk_1min_K_df['datetime']]
stk_1min_K_df["volume"]= stk_1min_K_df["vol"]
stk_1min_K_df=stk_1min_K_df[[
"_id" ,
"tradeMins" ,
"volume" ,
"tradeDate",
"high" ,
"amount",
"tradeTime" ,
"low",
"close" ,
"open"
]]
# 1-min K fig, vol NOT cummulative
mdbcom.saveBatch('etf50_date_mins',stk_1min_K_df.to_dict(orient='record'))
api_exhq = TdxExHq_API()
with self.isConnected(api_exhq, type='exhq', verbose=True) as api_exhq:
for optID in optList:
try:
quote_exhq=api_exhq.get_instrument_quote(self.market_opt, optID)
settlePrice=quote_exhq[0]['price']
settlePrice_high=settlePrice
settlePrice_low=settlePrice
settlePrice_open=settlePrice
if self.all_settlePrice_high.has_key(optID):
if settlePrice>self.all_settlePrice_high[optID]:
self.all_settlePrice_high[optID]=settlePrice
else:
settlePrice_high=self.all_settlePrice_high[optID]
else:
self.all_settlePrice_high[optID]=settlePrice
if self.all_settlePrice_low.has_key(optID):
if settlePrice<self.all_settlePrice_low[optID]:
self.all_settlePrice_low[optID]=settlePrice
else:
settlePrice_low=self.all_settlePrice_low[optID]
else:
self.all_settlePrice_low[optID]=settlePrice
if self.all_settlePrice_open.has_key(optID):
pass
else:
self.all_settlePrice_open[optID]=settlePrice_open
chicang=quote_exhq[0]['chicang']
if quote_exhq is None:
xlog.info('no settlePrice')
else:
if isSaveOptRealtime:
save=quote_exhq[0]
save['_id']=optID
save['xtime']=xtool.nowTime()
mdbcom.saveOne(C.OPT_QUOTE,save)
contractType=self.contraManager.contrDict['contractType'][optID]
contractStatus=self.contraManager.contrDict['contractStatus'][optID]
strikePrice=self.contraManager.contrDict['strikePrice'][optID]
dayToExpire=self.contraManager.contrDict['dayToExpire'][optID]
expDate=self.contraManager.contrDict['expDate'][optID]
tickerSymbol=self.contraManager.contrDict['tickerSymbol'][optID]
settlePrice_chg=0.
iv=0.
theoryPrice=0.
delta=0.
gamma=0.
theta=0.
vega=0.
rho=0.
if dayToExpire>0.5 and contractStatus=='L':
chg_symbol=""
pre_settlePrice=quote_exhq[0]['pre_close']
if pre_settlePrice >0.000001:
settlePrice_chg =(settlePrice/pre_settlePrice-1.00)*100.
if settlePrice_chg>0.000001:
chg_symbol='#fa9e66',# #ee5734'
elif settlePrice_chg<-0.000001:
chg_symbol='#b6f050'
else:
chg_symbol='#666666'
suffix_CP=None
if contractType=='C':
suffix_CP='x'
elif contractType=='P':
suffix_CP='y'
if spotPrice*settlePrice<0.000001 or contractType is None or contractType=='None':
xlog.info('no data')
else:
res=None
res=riskM.calu_mibian(contractType,
spotPrice,
strikePrice,
settlePrice,
rate,
dayToExpire,
hv)
if res is not None:
iv=round(res['iv'],1)
theoryPrice=round(res['theoryPrice'],4)
delta=round(res['delta'],4)
gamma=round(res['gamma'],4)
theta=round(res['theta'],4)
vega=round(res['vega'],4)
rho=round(res['rho'],4)
realtimeMsg={
optID+'_settlePrice_chg_'+suffix_CP:round(settlePrice_chg,1),
optID+'_settlePrice_'+suffix_CP:round(settlePrice,4),
optID+'_iv_'+suffix_CP:iv,
optID+'_theoryPrice_'+suffix_CP:theoryPrice,
optID+'_delta_'+suffix_CP:delta,
optID+'_gamma_'+suffix_CP:gamma,
optID+'_theta_'+suffix_CP:theta,
optID+'_vega_'+suffix_CP:vega,
optID+'_rho_'+suffix_CP:rho
}
keyList=realtimeMsg.keys()
xtime=xtool.nowTime()
xmins=xtime[:16]
saveMongoDBMsg={
'_id': optID,
'optID': optID,
'tickerSymbol':tickerSymbol,
'contractType':contractType,
'contractStatus':contractStatus,
'strikePrice':strikePrice,
'dayToExpire':dayToExpire,
'expDate':expDate,
'spotPrice':spotPrice,
'settlePrice_chg':round(settlePrice_chg,1),
'settlePrice':round(settlePrice,4),
'chicang':chicang,
'pre_settlePrice':round(pre_settlePrice,4),
'iv':iv,
'theoryMargin':round(theoryPrice-settlePrice,4),
'theoryPrice':round(theoryPrice,4),
'delta':round(delta,4),
'gamma':round(gamma,4),
'theta':round(theta,4),
'vega':round(vega,4),
'rho':round(rho,4),
'etf_open':etf_open,
'etf_high':etf_high,
'etf_low':etf_low,
'etf_last_close':etf_last_close,
'etf_vol':etf_vol,
'etf_amount':etf_amount,
'settlePrice_high':settlePrice_high,
'settlePrice_low':settlePrice_low,
'settlePrice_open':settlePrice_open,
'xtime':xtime,
'xmins':xmins
}
mdbcom.saveOne(C.OPT_RISK,saveMongoDBMsg)
saveMongoDBMsg_mins=saveMongoDBMsg.copy()
saveMongoDBMsg_mins['_id']='%s_%s'%(xtime[11:16].replace(":",""),optID)
mdbcom.saveOne(C.OPT_RISK_MINS,saveMongoDBMsg_mins)
#change _id, and save to OPT_RISK_DATE_MINS
saveMongoDBMsg_mins['_id']='%s_%s'%(xtime[:16].replace(" ","_"),optID)
mdbcom.saveOne(C.OPT_RISK_DATE_MINS,saveMongoDBMsg_mins)
if C.isDebug:
saveMongoDBMsg['_id']= xtool.nowDate()+'_'+optID
saveMongoDBMsg['tradeDate']=xtool.nowDate()
saveMongoDBMsg['remark']=C.HVX+'r=4,mibian'
mdbcom.saveOne(C.OPT_RISK_DAILY,saveMongoDBMsg)
else:
if xtool.nowOnlyTime()>='14:45:00':
saveMongoDBMsg['_id']= xtool.nowDate()+'_'+optID
saveMongoDBMsg['tradeDate']=xtool.nowDate()
saveMongoDBMsg['remark']=C.HVX+'r=4,mibian'
mdbcom.saveOne(C.OPT_RISK_DAILY,saveMongoDBMsg)
xlog.info('%s fetch/sent/saved'%(optID))
time.sleep(interval)
except Exception,e:
xlog.error(e)
time.sleep(interval)
xlog.info('****************************************************************************')
except Exception,e:
xlog.error(e)
self.sendEmail('hqserv fetcHQRisk load', e)
finally:
if api_hq is not None:
api_hq.disconnect()
if api_exhq is not None:
api_exhq.disconnect()