从2016年开始,接触了TB、文华财经之后,发现好多平台的夏普率计算结果不同。这次希望做一个总结,让自己完完全全搞明白夏普率是怎么计算的。教科书上的夏普率的计算方式很简单。年化的超额收益率/年化的标准差,代表着一单位风险获得的超额收益,然而,到了实际应用中,各个平台的计算方式有不小的差别。如下图,列举了几个平台的夏普率计算方式:
注:增加下聚宽的夏普率的具体算法:
接下来,首先用python生成随机的收益率来计算相应的夏普率
#夏普率的计算,首先,假设生成200个交易日的15分钟收益率,每个交易日96个15分钟(外汇) import pandas as pd import numpy as np import matplotlib.pyplot as plt #生成随机数200*96个 rate_minute=np.random.randn(200*96)/1000 rate_minute=pd.Series(rate_minute) #切割随机数,生成日收益率 rate_day=[] for i in range(200): day=rate_minute[i*96:(i+1)*96] # 有读者指出从分钟收益率合成日收益率的时候,不能简单想加求和 # 正常来说确实如此,对于简单收益率如果要计算累计收益率,需要计算复利 # 对于对数收益率,可以直接想加,计算夏普率的时候,更多的时候应该用简单收益率 # 所以,严格意义上,day.sum()是有问题的,这里暂时忽略这个小错误 rate_day.append(day.sum()) rate_day=pd.Series(rate_day) plt.plot(rate_minute.cumsum()) plt.title('15minute-cumsum rate') plt.show() plt.plot(rate_day.cumsum()) plt.title('day-cumsum rate') plt.show() #开始计算夏普率 #统一假定年化无风险收益率为3% rf=0.03 #交易日为N n=200 ########################米筐 day_sharp_rate=(rate_day-rf/252).mean()/(rate_day-rf/252).std() year_sharp_rate=day_sharp_rate*252**0.5 print('米筐的夏普率为',year_sharp_rate) ########################聚宽 sharp_rate=(rate_day.sum()*252/n-rf)/rate_day.std() print('聚宽的夏普率为',sharp_rate) ########################文华财经 sharp_rate_wenhua=(rate_day.sum()*252/n-rf)/rate_day.std()*(365/200)**0.5 print('文华财经的夏普率为',sharp_rate_wenhua) ################################对比--不带超额收益率 day_sharp_rate=(rate_day).mean()/(rate_day).std() year_sharp_rate_day_gap=day_sharp_rate*252**0.5 minute_sharp_rate=(rate_minute).mean()/(rate_minute).std() year_sharp_rate_minute_gap=minute_sharp_rate*(252*96)**0.5 print('日间隔的夏普率为:{},分钟间隔的夏普率为:{}'.format(year_sharp_rate_day_gap,year_sharp_rate_minute_gap)) ################################带超额收益率 ################################对比--不带超额收益率 day_sharp_rate=(rate_day-rf/252).mean()/(rate_day-rf/252).std() year_sharp_rate_day_gap=day_sharp_rate*252**0.5 minute_sharp_rate=(rate_minute-rf/(252*96)).mean()/(rate_minute-rf/(252*96)).std() year_sharp_rate_minute_gap=minute_sharp_rate*(252*96)**0.5 print('日间隔的夏普率为:{},分钟间隔的夏普率为:{}'.format(year_sharp_rate_day_gap,year_sharp_rate_minute_gap))