从零实现量化回测引擎:风险平价、动量策略对比

继承完善我们的引擎,昨天我们完成了引擎主体,就是一个account.py。

01 引擎框架

图片

def run(self, algo_list):
self.algo_list = algo_list
for index, date in enumerate(self.dates):
self.curr_date = date
self.step(index, date)

def step(self, index, date):
return_se = self._get_curr_return_se(date)
self.acc.update_bar(date, return_se)
self.algo_processor()

def algo_processor(self):
context = {'engine': self, 'acc': self.acc}
for algo in self.algo_list:
if algo(context) is True: # 如果algo返回True,直接不运行,本次不调仓
return None

def get_results_df(self):
df = pd.DataFrame({'date': self.acc.cache_dates, 'portfolio': self.acc.cache_portfolio_mv})
df['rate'] = df['portfolio'].pct_change()
df['equity'] = (df['rate'] + 1).cumprod()
df.set_index('date', inplace=True)
df.dropna(inplace=True) return df

回测的结果通过get_results_df返回回来,交给分析器。

02 分析器

我这个分析器天然就可以添加N个基准,quantstats只能添加一个。

class Analyzer:
    def __init__(self, df_results, benchmarks=['000300.SH']):
        self.df_results = df_results
        self.benchmarks = benchmarks

    def show_results(self):
        returns = self.df_results['rate']
        import empyrical

        print('累计收益:', round(empyrical.cum_returns_final(returns), 3))
        print('年化收益:', round(empyrical.annual_return(returns), 3))
        print('最大回撤:', round(empyrical.max_drawdown(returns), 3))
        print('夏普比', round(empyrical.sharpe_ratio(returns), 3))
        print('卡玛比', round(empyrical.calmar_ratio(returns), 3))
        print('omega', round(empyrical.omega_ratio(returns)), 3)

    def plot(self):
        returns = []
        for s in self.benchmarks:
            df_bench = DataUtils.load_returns([s])
            se = df_bench['return']
            se.name = s
            returns.append(se)

        se_port = self.df_results['rate']
        se_port.name = 'strategy'
        returns.append(se_port)
        all_returns = pd.concat(returns, axis=1)
        all_returns.dropna(inplace=True)
        all_equity = (1 + all_returns).cumprod()

        import matplotlib.pyplot as plt
        all_equity.plot()
        plt.show()

03 等权-买入并持有

symbols = ['N225', '000300.SH', 'ADX', '000905.SH', '399673.SZ', 'HSI', 'GDAXI']
from engine.algo.algos import *

e = Engine(symbols)

print('初始总市值', e.acc.get_total_mv())
e.run(algo_list=[
    RunOnce(),
    SelectAll(),
    WeightEqually()
])
print('最终总市值', e.acc.get_total_mv())
e.show_results(benckmarks=['000300.SH'])

图片

图片

04 等权-周度再平衡

年化由5.6%提升到6.1%,回撤由44%下降到33%。

图片

大家可以前往星球下载代码自己试,换一行代码即可。目前测试的结果——不考虑手续费的话,周频的效果最好。但考虑到成本,一般季度再平衡即可。

05 风险平价——原生

收益率上升至6.2,夏普提升至0.5。风险平价可以提升夏普比

图片

图片

06 风险平价-PCA主成份分解

加上主成分分解后,收益提升较多,夏普比提升到0.678。

图片

图片

07 20日动量-策略

图片

图片

20日-斜率动量,仅排序

图片

图片

总结一下:

A股,美股,港股,欧洲,日本 主要指数,等权是基准,年化不到6%,风险平价可以有效提升夏普比,pca更进一步提升不少收益率。动量策略肯定有效,但不确保回撤。我们需要把动量等因子,RSRS择时等,融入的风险平价里。

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/104195
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 2024 年 7 月 29 日
下一篇 2024 年 7 月 29 日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注