安装所需的库
最后两个库为计算绩效评估指标的常用库:
pip install pandas numpy qstock pywencai empyrical quantstats
数据准备
这里假设我们从2010年第一个交易日开始持有贵州茅台600519,并以沪深300指数000300作为基准,进行绩效评估:
import qstock as qs
import pandas as pd
import empyrical as ep
import quantstats as qts
# 使用qstock拉取茅台和沪深300指数 2010 年至今的数据,fqt=2 表示后复权
data = qs.get_data(['000300','600519'], start='20100101', end='20240202', fqt=2)
# qstock获取多个数据是纵向堆叠的,这里我们拆分一下,并按时间对齐
# 拆分数据
bm_close = data.query("code=='000300'")[['close']].rename(columns={'close':'bm_close'})
close = data.query("code=='600519'")[['close']]
# 对齐
price = close.join(bm_close).ffill()
# 求收益率,就是每天的涨跌幅
ret = pd.DataFrame({i:price[i].pct_change() for i in price.columns}).fillna(0)s
累计收益率:
累计收益率即投资组合或策略在持有时间段的总体收益率。
总收益率 = (投资结束时的资产价值 / 投资初始时的资产价值 - 1) * 100%
ep.cum_returns_final(ret)*100
输出:
close 1263.338360 表示茅台总收益率 1263.34%
bm_close -10.058751 表示沪深300总收益率 -10.06%
dtype: float64
使用pandas计算,结果的最后一行就是总收益率:
(ret+1).cumprod()-1
年化收益率:
年化收益率是为了将不同投资组合或量化策略的收益结果统一为相同标准,方便进行评估和对比。
计算公式:年化收益率 =(策略当前净值 / 策略初始净值)^(年交易日天数 / 回测期间总天数)-1
其中年交易日天数是指市场一年的交易日天数。由于节假日原因,每年的交易天数不同,可以简单处理为242天。
ep.annual_return(ret)*100
输出
close 21.234668 表示茅台年化收益率 21.23%
bm_close -0.778336 表示沪深300年化收益率 -0.78%
dtype: float64
最大回撤:
最大回撤表示投资组合或策略在某一时间段内最大的损失。用来衡量组合或策略最极端情况下亏损的百分比。
计算公式:最大回撤=min(账户当日净值 / 当日之前账户最高净值 - 1)。
ep.max_drawdown(ret)*100
输出
0 -50.288834 表示茅台最大回撤-50.29%
1 -46.696054 表示沪深300最大回撤-46.70%
dtype: float64
Alpha(阿尔法)系数:
Alpha系数表示投资组合或策略相对于市场的超额收益,衡量了投资组合或策略的独立性和能力,以及承担的非系统性风险。
计算公式:alpha =(账户年化收益-无风险收益)- beta *(基准年化收益-无风险收益)
ep.alpha(ret.close, ret.bm_close)
Beta(贝塔)系数:
根据资本资产定价理论(CAPM模型),Beta系数衡量策略的回报率对市场变动的敏感程度,代表了该策略的结构性和系统性风险,代表组合或策略相对于市场基准的相关性。即组合或收益相对于基准收益的波动性,或者说承担市场风险带来的投资收益。
计算公式:beta = 日收益与基准日收益的协方差 / 基准日收益的方差。
比如策略对标的基准为沪深300指数,计算得到的beta如下:
- beta=1,说明策略和沪深300指数的收益变化一致。
- beta=1.1,说明沪深300指数上涨10%时,策略上涨11%;沪深300指数下跌10%时,策略下跌11%。
- beta=0.9,说沪深300指数上涨10%时,策略上涨9%;沪深300指数跌10%时,策略下跌9%。
ep.beta(ret.close, ret.bm_close)
夏普比率(Sharpe Ratio):
夏普比率表示投资组合或策略的风险调整后的收益率,衡量每单位风险所产生的收益,即表示每承受一单位风险,会产生多少的超额回报。
计算公式:夏普比率=(策略年化收益率-无风险利率)/ 策略收益波动率。
其中的无风险利率通常采用10年期国债收益率。
由于夏普比率代表单位风险所获得的超额回报率。该比率越高,策略承担单位风险得到的超额回报率越高,所以说夏普比率是越高越好。
ep.sharpe_ratio(ret.close)
卡玛(Calmar)比率
卡玛比率类似夏普比率,也是一种用于评估风险调整后收益率的指标。
计算公式:Calmar Ratio = 年化收益率 / 最大回撤率
这个比值越高,代表投资组合在承担相同的风险下获得的收益越高,或者在相同的收益水平下承担的风险更低。
ep.calmar_ratio(ret.close)
索提诺(Sortino)比率:
索提诺比率类似于夏普比率,但是只考虑下行风险,即负收益的波动性。
ep.sortino_ratio(ret.close)
信息比率(Information Ratio):
投资组合或策略的超额收益率与基准的波动率之比,用于衡量超额收益的风险。
计算公式:(策略收益率 - 基准收益率)/ 策略风险。
qts.stats.information_ratio(ret.close, ret.bm_close)
最大连续上涨和下跌天数
这些指标如字面含义,也代表了交易中各种最极端的情况,提醒投资者对这些情况做好心理准备。
up = (ret['close'] > 0).astype(int)
down = (ret['close'] < 0).astype(int)
up_streak = up * (up.groupby((up.diff() != 0).cumsum()).cumcount() + 1)
down_streak = down * (down.groupby((down.diff() != 0).cumsum()).cumcount() + 1)
max_up_streak = up_streak.max()
max_down_streak = down_streak.max()
print('最大连续上涨天数: ', max_up_streak)
print('最大连续下跌天数: ', max_down_streak)