写点什么

【量化投资入门】带你通过恒有数数据接口来实战量化指标

  • 2022 年 1 月 12 日
  • 本文字数:3071 字

    阅读完需:约 10 分钟

作者:2021_2011

来源:恒生LIGHT云社区

一、前言

恒有数是恒生电子公开的金融数据接口,具体链接为:https://udata.hs.net/subscribe,数据 API 接口:


https://udata.hs.net/datas/332/


截图如下:


4309


支持 python,matlab,HTTP 的接口,其中 Python 的主要调用接口如下:


from hs_udata import set_token,stock_quote_dailyset_token(token = 'xxxxx')
data = stock_quote_daily(en_prod_code ="600006.SH",adjust_way=1, trading_date="20210810")data
复制代码


返回的结果是:


4311


对于上述 hs_udata 的安装方法如下:


pip install hs_udata


选取一部分数据:["recently_trading_date","open_price","close_price","high_price","low_price","prod_code"]


调用过去 2020 一年的数据,数据预览如下:


def get_times():    times=[]    for m in range(1,13):        for d in range(1,28):            m1 = "0"+str(m) if m<10 else str(m)            d1 = "0"+str(d) if d<10 else str(d)            times.append("2020"+"-"+m1+"-"+d1)    return times
复制代码


import timedef get_data_based_on_date(en_prod_code):    data_values_1 = pd.DataFrame(dtype="float64")    start_end_times = ["2021-05-10", "2021-05-11","2021-05-12","2021-05-13","2021-05-14","2021-05-17","2021-05-18","2021-05-19"]    for trading_date in get_times():        data = stock_quote_daily(en_prod_code=en_prod_code, trading_date=trading_date, adjust_way = 1)  # 获取前复权收盘价,adjust_way=1        if data["open_price"][0] and data["close_price"][0] and data["high_price"][0]:            data_values_2 = data[["recently_trading_date","open_price","close_price","high_price","low_price","prod_code"]]            data_values_1 = pd.concat([data_values_1,data_values_2], axis=0, ignore_index=True)            time.sleep(1)    return data_values_1
复制代码


数据样例:


res = get_data_based_on_date("000002.SZ")
复制代码


res:


4312


继续添加一些需要抽取的股票数据:


code_name = {"浦发银行":"600000.SH",            "齐鲁石化":"600004.SH",            "平安银行":"000001.SZ",            "美丽生态":"000010.SZ"}
复制代码


names=[]data_df = pd.DataFrame(dtype="float64")for name_zh in code_name.keys():    names.append(name_zh)    res = get_data_based_on_date(code_name[name_zh])    res.index = pd.to_datetime(res.recently_trading_date)    close_price = res["close_price"]   # 获取    data_df[name_zh] = close_price  data_df = pd.DataFrame(data_df,dtype=np.float)
复制代码


预览部分数据:


4313


全部数据预览:


4314

二、量化指标

下面参考和学习https://mp.weixin.qq.com/s/n9YAcjdpFpAAI4SvR1aGtg的基础上,通过恒有数数据接口实践量化指标和熟悉恒有数接口数据。

1 首先绘制股票净值走势

import matplotlib.pyplot as plt%matplotlib inlinefrom pylab import mplmpl.rcParams['font.sans-serif']=['SimHei']mpl.rcParams['axes.unicode_minus']=Falsedf_new=data_df/data_df.iloc[0]df_new.plot(figsize=(10,4))plt.title('股价净值走势',fontsize=15)ax=plt.gca()ax.spines['right'].set_color('none')ax.spines['top'].set_color('none')plt.show()
复制代码


图片显示:


4315

2 累积收益率

计算公式 R = (P1-P2)/P2;P1 是期末卖出时的价格,P2 是期初买入时的价格。


代码实践:


total_ret=df_new.iloc[-1]-1TR=pd.DataFrame(total_ret.values,columns=['累计收益率'],index=total_ret.index)
复制代码


4316


计算序列累积最大值:


df = data_dfcode='浦发银行'n_d=((np.maximum.accumulate(df[code])-df[code])/np.maximum.accumulate(df[code])).max()#pandas使用cummax()计算序列累计最大值p_d=((df[code].cummax()-df[code])/df[code].cummax()).max()#打印结果print(f'numpy方法计算结果:{round(n_d*100,2)}%')print(f'pandas方法计算结果:{round(p_d*100,2)}%') 
复制代码

3 年化收益率

Rp = -1+(1+R)^(m/n) 其中 R 是期间总收益率,m 是与 n(可以是天数、周数、月数)相对应的计算周期。


代码实践:


annual_ret=pow(1+total_ret,250/len(df_new))-1AR=pd.DataFrame(annual_ret.values,columns=['年化收益率'],index=annual_ret.index)AR
复制代码


4318

4 最大回撤

r = max(pi-pj)/pi


P 为某一天的净值,i 为某一天,j 为 i 后的某一天,Pi 为第 i 天的产品净值,Pj 则是 Pi 后面某一天的净值


代码实践:


def max_drawdown(df):    md=((df.cummax()-df)/df.cummax()).max()    return round(md,4)md={}for name,code in code_name.items():    md[name]=max_drawdown(df[name])#最大回撤率结果:MD=pd.DataFrame(md,index=['最大回撤']).TMD
复制代码


4319

5 alpha 和 beta 参数

rets=(df.fillna(method='pad')).apply(lambda x:x/x.shift(1)-1)[1:]rets.head()
#市场指数为x,个股收益率为yfrom scipy import statsx=rets.iloc[:,0].valuesy=rets.iloc[:,1:].valuesAB=pd.DataFrame()alpha=[]beta=[]for i in range(3):
b,a,r_value,p_value,std_err=stats.linregress(x,y[:,i]) alpha.append(round(a*250,3)) beta.append(round(b,3))AB['alpha']=alphaAB['beta']=betaAB.index=rets.columns[1:]
复制代码


4320


直接计算 beta 值:


beta1=rets[['浦发银行','齐鲁石化']].cov().iat[0,1]/rets['浦发银行'].var()beta2=rets[['浦发银行','平安银行']].cov().iat[0,1]/rets['浦发银行'].var()beta3=rets[['浦发银行','美丽生态']].cov().iat[0,1]/rets['浦发银行'].var()print(f'齐鲁石化beta:{round(beta1,3)}')print(f'平安银行beta:{round(beta2,3)}')print(f'美丽生态beta:{round(beta3,3)}')

alpha1=(annual_ret[1]-annual_ret[0]*beta1)alpha2=(annual_ret[2]-annual_ret[0]*beta2)alpha3=(annual_ret[3]-annual_ret[0]*beta3)print(f'齐鲁石化alpha:{round(alpha1,3)}')print(f'平安银行alpha:{round(alpha2,3)}')print(f'美丽生态alpha:{round(alpha3,3)}')
复制代码


5 夏普比例


ratio = (Rp-Rf)/年化标准差,其中 Rp 为策略年化收益率,Rf 是无风险收益率


exReturn=rets-0.03/250#计算夏普比率sharperatio=np.sqrt(len(exReturn))*exReturn.mean()/exReturn.std()#夏普比率的输出结果SHR=pd.DataFrame(sharperatio,columns=['夏普比率'])
复制代码


4322

6 信息比率

info_ratio = (Rp-Rm)/k, 其中 Rp 为策略年化收益率,Rm 为基准年化收益率,k 为策略与基准每日收益率差值的年化标准差。


ex_return=pd.DataFrame() ex_return['齐鲁石化']=rets.iloc[:,1]-rets.iloc[:,0]ex_return['平安银行']=rets.iloc[:,2]-rets.iloc[:,0]ex_return['美丽生态']=rets.iloc[:,3]-rets.iloc[:,0]
#计算信息比率information=np.sqrt(len(ex_return))*ex_return.mean()/ex_return.std()#信息比率的输出结果INR=pd.DataFrame(information,columns=['信息比率'])INR
复制代码


4323


整体指标展示:


indicators=pd.concat([TR,AR,MD,AB,SHR,INR],axis=1,    join='outer',sort='False')indicators.round(3)
复制代码


4324


以上就是基于参考文献的基础上,主要试用恒有数数据接口简单实现量化指标的过程。


参考文献:


https://mp.weixin.qq.com/s/n9YAcjdpFpAAI4SvR1aGtg




想向技术大佬们多多取经?开发中遇到的问题何处探讨?如何获取金融科技海量资源?


恒生LIGHT云社区,由恒生电子搭建的金融科技专业社区平台,分享实用技术干货、资源数据、金融科技行业趋势,拥抱所有金融开发者。


扫描下方小程序二维码,加入我们!



发布于: 刚刚阅读数: 2
用户头像

还未添加个人签名 2018.11.07 加入

还未添加个人简介

评论

发布
暂无评论
【量化投资入门】带你通过恒有数数据接口来实战量化指标