1. 引言
量化回测是评估一个交易策略是否有效的关键步骤,通过历史数据对策略进行验证,可以帮助投资者预估策略在实际应用中的表现。本文将介绍量化回测的基本框架及其核心指标,包括收益、风险、最大回撤、夏普比率等常用的评估标准。我们将以沪深300指数、贵州茅台、工商银行、中国平安这几只股票为例,结合 Python 的代码展示如何完成一个完整的回测过程。
2. 获取数据
我们首先通过 Tushare API 获取贵州茅台、工商银行、中国平安的历史股价数据,并使用沪深300指数作为基准指数。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import tushare as ts
# 无视warning
import warnings
warnings.filterwarnings("ignore")
# 正常显示画图时出现的中文和负号
from pylab import mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
# 获取数据函数
def get_data(code, start_date, end_date):
my_token = '039660346bc8f4ad98c1b7b28fbbbb7750a6c6eea62573ff80a42593'
pro = ts.pro_api(my_token)
df = pro.daily(ts_code=code, start_date=start_date, end_date=end_date)
df.index = pd.to_datetime(df.trade_date)
return df.close
# 获取贵州茅台、工商银行、中国平安数据
stocks = {'600519.SH': '贵州茅台', '601398.SH': '工商银行', '601318.SH': '中国平安'}
df = pd.DataFrame()
for code, name in stocks.items():
df[name] = get_data(code, '20180101', '20221231')
# 本地读取沪深300指数数据
df_base = pd.read_csv('/Users/jin/Downloads/000300.XSHG_2018_2022.csv')
df_base.index = pd.to_datetime(df_base.trade_date)
df['沪深300'] = df_base['close']
# 日期排序
df = df.sort_index()
3. 绘制净值曲线
为了直观地展示不同股票的表现,我们将以2018年1月1日的收盘价为基准,计算股票的净值,并绘制出净值曲线。
# 计算净值并绘制净值曲线
df_worth = df / df.iloc[0]
df_worth.plot(figsize=(15,6))
plt.title('股价净值走势', fontsize=10)
plt.xticks(pd.date_range('20180101','20221231',freq='Y'), fontsize=10)
plt.show()
4. 计算核心指标
4.1 累计收益率和年化收益率
累计收益率表示区间内资产的涨幅,而年化收益率是对投资回报的年度化标准度量。计算公式如下:
# 计算累计收益率
total_return = df_worth.iloc[-1] - 1
total_return = pd.DataFrame(total_return.values, columns=['累计收益率'], index=total_return.index)
# 计算年化收益率
annual_return = pd.DataFrame((1 + total_return.values) ** (252 / 1826) - 1, columns=['年化收益率'], index=total_return.index)
4.2 波动率
波动率是衡量资产价格变化速度的指标,用于衡量风险。我们使用标准差来计算波动率:
df_return = df / df.shift(1) - 1
df_return = ((df_return.iloc[1:] - df_return.mean()) ** 2)
volatility = pd.DataFrame(np.sqrt(df_return.sum() * 252 / (1826 - 1)), columns=['波动率'], index=total_return.index)
4.3 最大回撤
最大回撤表示资产从高点到低点的最大跌幅,是衡量风险的重要指标。
def max_drawdown_cal(df):
md = ((df.cummax() - df) / df.cummax()).max()
return round(md, 4)
max_drawdown = {}
for code, name in stocks.items():
max_drawdown[name] = max_drawdown_cal(df[name])
max_drawdown = pd.DataFrame(max_drawdown, index=['最大回撤']).T
4.4 Alpha 和 Beta
Alpha 和 Beta 是经典的风险收益度量指标,表示个股相对于市场的表现。
from scipy import stats
rets = (df.iloc[:, :4].fillna(method='pad')).apply(lambda x: x / x.shift(1) - 1)[1:]
x = rets.iloc[:, 3].values
y = rets.iloc[:, :3].values
capm = 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))
capm['alpha'] = alpha
capm['beta'] = beta
capm.index = rets.columns[:3]
4.5 夏普比率
夏普比率用于衡量单位风险的超额回报。
# 超额收益率假设无风险收益率为年化3%
ex_return = rets - 0.03 / 250
sharpe_ratio = np.sqrt(len(ex_return)) * ex_return.mean() / ex_return.std()
sharpe_ratio = pd.DataFrame(sharpe_ratio, columns=['夏普比率'])
4.6 信息比率
信息比率衡量超额收益率与基准指数收益率的差异。
ex_return = pd.DataFrame()
ex_return['贵州茅台'] = rets.iloc[:, 0] - rets.iloc[:, 3]
ex_return['工商银行'] = rets.iloc[:, 1] - rets.iloc[:, 3]
ex_return['中国平安'] = rets.iloc[:, 2] - rets.iloc[:, 3]
information_ratio = np.sqrt(len(ex_return)) * ex_return.mean() / ex_return.std()
information_ratio = pd.DataFrame(information_ratio, columns=['信息比率'])
总结
本文通过量化回测评估了沪深300指数、贵州茅台、工商银行、中国平安在2018年至2022年期间的表现。通过净值曲线、累计收益、波动率、最大回撤、夏普比率等指标,我们全面分析了这些资产的风险和收益特性。在量化投资中,回测是不可或缺的步骤,通过历史数据的回测可以有效验证策略的有效性,帮助投资者做出更科学的决策。
如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!
欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。
谢谢大家的支持!