python金融量化风险_【手把手教你】Python量化策略风险指标
如何衡量一個量化策略的好壞?一是比較穩定的收益,二是有嚴謹的回測,三是有清晰的邏輯。——劉富兵
引言
盡管過去不能代表未來,通過歷史回測來評估量化策略仍然是量化投資非常重要的一環。量化回測過程中常用到的指標有年化收益率、最大回撤、beta、alpha、夏普比率、信息比率等(見下圖)。目前很多量化網站都能提供Python的量化回測框架,如聚寬 、優礦、萬礦、Zipline 、vnpy 和pyalgotrade等,為我們評估量化策略提供了很好的交互平臺。畢竟平臺的使用有其局限性,如果不借助平臺, 如何使用python寫一個簡單的量化回測框架呢?本文將一步一步為你展示如何使用python計算量化策略風險指標。文中提及股票僅供學習示例,不構成投資建議。
(數據來源:優礦·通聯實驗室)
0
1
指標含義及公式
0
1
累計收益率與年化收益率
年化收益率是把當前收益率(日收益率、周收益率、月收益率)換算成年收益率來計算的,是一種理論收益率,并不是真正的已取得的收益率。因為年化收益率是變動的,所以年收益率不一定和年化收益率相同。
累計收益率:
其中,PT是期末賣出時的價格,Pt是期初買入時的價格。
年化收益率
:
其中,R是期間總收益率,m是與n(可以是天數、周數、月數)相對應的計算周期,根據計算慣例,m=250、52、12分別指代日、周、月向年化的轉換。
0
2
最大回撤
在選定周期內任一歷史時點往后推,于最低點時的收益率回撤幅度的最大值。最大回撤用來描述可能出現的最糟糕的情況。最大回撤是一個重要的風險指標,對于量化策略交易,該指標比波動率還重要。
P為某一天的凈值,i為某一天,j為i后的某一天,Pi為第i天的產品凈值,Pj則是Pi后面某一天的凈值
則該基金的
最大回撤
計算如下:
即通過對每一個凈值進行回撤率求值,然后找出最大的。
0
3
Beta和Alpha
Beta
:相當于業績評價基準收益的總體波動性,計算如下:
Pi和Pm分別指代個股(組合)、市場(如上證綜指)的收益率序列,beta值也常被用來衡量某一策略的系統性風險。
其含義可以簡單理解為:如果Beta為1,策略和市場(如滬深300指數)波動相同;如果Beta大于1,策略波動大于市場,如2,則市場上漲10%時,策略上漲20%;反之亦然。如果Beta小于1,則策略波動小于市場,如為0.8,市場上漲10%時,策略上漲8%;反之亦然。
Beta值如何看呢?這得具體問題具體分析,如果是牛市,個股、大盤狂漲,Beta值大的策略占優;如果是熊市,Beta值小的策略占優。
Alpha:
實際收益和按照Beta系數計算的期望收益之間的差額。代表策略多大程度上跑贏了預期的收益率。
可以使用資本資產定價模型(CAPM)來估計策略的beta和alpha的值:
E(ri)是股票i的預期收益率,rf是無風險利率,rm是市場指數收益率;beta系數在評估股市波動風險與投資機會的方法中,常用來衡量結構性與系統性風險,可以簡單理解為個股波動相對大盤波動的偏離程度。CAPM的計量模型可以表示為:
alpha可以理解為超額收益率,最后一項是隨機擾動,可以理解為個體風險。
0
4
夏普比率和信息比率
夏普比率
代表每多承擔一份風險,可以獲得幾份回報,即單位風險所獲得的超額回報,該比率越高,策略承擔單位風險得到的超額回報越高,所以夏普比率越高越好。
其中,Rp為策略年化收益率,Rf是無風險收益率,
為年化標準差。
信息比率
:含義與夏普比率類似,只不過其參照基準不是無風險收益率,而是策略的市場基準收益率。
其中,Rp為策略年化收益率,Rm為基準年化收益率(如滬深300指數),
為策略與基準每日收益率差值的年化標準差。
0
2
Python計算量化指標
使用tushare獲取交易數據,考慮最簡單的策略:買入持有!分別計算期間總收益率,年化收益率,最大回撤,beta、alpha系數,夏普比率和信息比率。
#先引入后面可能用到的包(package)
import?pandas?as?pd
import?numpy?as?np
import?matplotlib.pyplot?as?plt
%matplotlib?inline
#正常顯示畫圖時出現的中文和負號
from?pylab?import?mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
###?獲取數據:tushare開源庫(確認已安裝好:pip install tushare)
import?tushare?as?ts
#起始和結束日期可以自行輸入,否則使用默認
def?get_data(code,start_date="2009-01-01",?end_date="2019-01-18"):
df?=?ts.get_k_data(code,?start=start_date,?end=end_date)
df.index=pd.to_datetime(df.date)
return?df.close
#返回收盤價
#以上證綜指、貴州茅臺、工商銀行、中國平安為例
stocks={'sh':'上證綜指','600519':'貴州茅臺',
'601398':'工商銀行','601318':'中國平安'}
#獲取上述股票(指數)的每日前復權收盤價
df=pd.DataFrame()
for?code,name?in?stocks.items():
df[name]=get_data(code)
df.head()
#以第一交易日2009年1月5日收盤價為基點,計算凈值
df_new=df/df.iloc[0]
#將上述股票在回測期間內的凈值可視化
df_new.plot(figsize=(16,7))
#圖標題
plt.title('股價凈值走勢',fontsize=15)
#設置x軸坐標
my_ticks?=?pd.date_range('2008-01-01','2019-01-18',freq='Y')
plt.xticks(my_ticks,fontsize=12)
#去掉上、右圖的線
ax=plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
plt.show()
1
累計收益率和年化收益率
收益率可以根據上面公式計算,或使用對數收益率,下面直接根據上面的累計凈值來推出累計收益率(累計凈值-1)。
###?區間累計收益率(絕對收益率)
total_ret=df_new.iloc[-1]-1
TR=pd.DataFrame(total_ret.values,columns=['累計收益率'],index=total_ret.index)
TR
#定義成函數,減少重復工作
def?max_drawdown(df):
md=((df.cummax()-df)/df.cummax()).max()
return?round(md,4)
md={}
for?code,name?in?stocks.items():
md[name]=max_drawdown(df[name])
#最大回撤率結果:
MD=pd.DataFrame(md,index=['最大回撤']).T
MD
3
alpha和beta
#計算每日收益率
#收盤價缺失值(停牌),使用前值代替
rets=(df.fillna(method='pad')).apply(lambda?x:x/x.shift(1)-1)[1:]
rets.head()
#市場指數為x,個股收益率為y
from?scipy?import?stats
x=rets.iloc[:,0].values
y=rets.iloc[:,1:].values
AB=pd.DataFrame()
alpha=[]
beta=[]
for?i?in?range(3):
#使用scipy庫中的stats.linregress線性回歸
#python回歸有多種實現方式,
#如statsmodels.api的OLS,sklearn庫等等
b,a,r_value,p_value,std_err=stats.linregress(x,y[:,i])
#alpha轉化為年化
alpha.append(round(a*250,3))
beta.append(round(b,3))
AB['alpha']=alpha
AB['beta']=beta
AB.index=rets.columns[1:]
#輸出結果:
AB
#使用公式法直接計算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)}')
#輸出結果:
貴州茅臺beta:0.637
工商銀行beta:0.614
中國平安beta:1.071
#使用公式法直接計算beta值(見前文公式):
#annual_ret是前文計算出來的年化收益率
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)}')
#輸出結果:
貴州茅臺alpha:0.244
工商銀行alpha:0.077
中國平安alpha:0.138
4
夏普比率和信息比率
#超額收益率以無風險收益率為基準
#假設無風險收益率為年化3%
exReturn=rets-0.03/250
#計算夏普比率
sharperatio=np.sqrt(len(exReturn))*exReturn.mean()/exReturn.std()
#夏普比率的輸出結果
SHR=pd.DataFrame(sharperatio,columns=['夏普比率'])
SHR
###信息比率
#超額收益率以指數收益率或其他為基準
#這里以上證綜指為基準
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]a
#計算信息比率
information=np.sqrt(len(ex_return))*ex_return.mean()/ex_return.std()
#信息比率的輸出結果
INR=pd.DataFrame(information,columns=['信息比率'])
INR
將上述指標合并成一張表,不難看出,在回測期間內(2009年01月01日至2019月01月18日期間),貴州茅臺各項指標表現非常出色,其實貴州茅臺近幾年業績表現非常優秀,每股收益在整個A股中是最高的。但是,其最大回撤卻高達53.3%,意味著如果是在這期間的高點買入的,中間可能出現浮虧53.3%,要上漲114%才能回本,長期投資還真不是普通人心理能承受的。
indicators=pd.concat([TR,AR,MD,AB,SHR,INR],axis=1,
join='outer',sort='False')
#結果保留三位小數
indicators.round(3)
定義一個函數plot_max_drawdown(),對上述歷史回撤的收益和風險指標進行可視化,函數代碼相當于整合了上述計算過程,由于篇幅所限,此處省略。
#貴州茅臺買入持有策略回測可視化
plot_max_drawdown(df,'貴州茅臺')
#工商銀行買入持有策略回測可視化
plot_max_drawdown(df,'工商銀行')
#中國平安買入持有策略回測可視化
plot_max_drawdown(df,'中國平安')
總結
以上是生活随笔為你收集整理的python金融量化风险_【手把手教你】Python量化策略风险指标的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 幽默感七个技巧_如何通过三招,让自己成为
- 下一篇: 远程ykvm 插件移值java_Cent