分享

backtrader下的轮动策略模板,附年化20.6%的策略源码。

 AI量化实验室 2024-11-05 发布于北京

原创内容第700篇,专注量化投资、个人成长与财富自由。

原创日更700天,回首向来萧瑟处,也无风雨也无晴。

但行好事,莫问前程,持续改1%,为社群的同学们提供价值。

今天我们实现backtrader下的轮动策略模板。

这个模板有通用,几乎所有的策略都可以在此基础上派生。

class StrategyRolling(StrategyBase):
# 参数定义
params = dict(
period=20, # 动量周期
topK=1,
dropN=0,
)

def __init__(self, show_info=False):
super(StrategyRolling, self).__init__(show_info)

# 多标的需要循环定义指标
self.sorters = {}
for data in self.datas:
self.sorters[data] = bt.indicators.ROC(data, period=self.p.period)

def next(self):
orderby = {}
for data, sorter in self.sorters.items():
orderby[data] = sorter[0]

sorted_datas = [data for data, value in sorted(orderby.items(), key=lambda x: x[1], reverse=True)]
selected = sorted_datas[self.p.dropN:self.p.topK]

# 当前持仓
holdings = self.get_current_holding_datas()
if holdings and len(holdings) > 0:
for h in holdings:
if h not in selected:
self.close(h)

if len(selected) > 0:
weight = 1 / len(selected)
for data in selected:
self.order_target_percent(data, weight * 0.99)

类定义和参数

  • StrategyRolling 类继承自 StrategyBase,这是一个交易策略的基类。

  • params 字典定义了策略的参数:

    • period:动量周期,默认为20,表示计算动量时使用过去20个交易日的数据。

    • topK:这个参数在代码中没有直接使用,通常用于选择动量排名前几的资产。

    • dropN:这个参数用于在排序后跳过前几个资产,可能是为了避免最近表现不佳的资产。

构造函数 __init__

  • 构造函数接受一个参数 show_info,用于控制是否显示额外的信息。

  • 调用父类的构造函数 super(StrategyRolling, self).__init__(show_info)

  • self.sorters 是一个字典,用于存储每个数据(资产)的动量指标。

  • 循环遍历 self.datas(这是一个包含所有资产数据的列表),为每个资产计算动量指标 ROC(Rate of Change,变化率指标),并将其存储在 self.sorters 字典中。

next 方法

  • next 方法是策略的核心,它在每个交易周期被调用。

  • orderby 字典用于存储每个资产及其动量值。

  • 循环遍历 self.sorters 字典,将每个资产的动量值存储在 orderby 字典中。

  • 使用列表推导式和排序函数对 orderby 字典的项进行排序,选择动量值最高的资产。

  • sorted_datas 是排序后的资产列表。

  • selected 是从 sorted_datas 中根据 dropN 和 topK 参数选择的资产列表。

交易逻辑

  • 获取当前持有的资产列表 holdings

  • 如果持有资产,检查这些资产是否在 selected 列表中。如果不在,则卖出这些资产。

  • 如果 selected 列表不为空,计算每个选中资产的购买权重,并将目标资产权重设置为总资产的 0.99 倍(可能是为了避免全仓操作)。

这个策略的基本思想是:在每个交易周期,计算所有资产的动量,选择动量最高的资产进行投资,同时卖出不在选择列表中的资产。这种策略假设动量高的资产在未来一段时间内会继续表现良好。

我们来调用这个模板:

from backtrader_extends.engine import Engine
from backtrader_extends.strategy import StrategyRolling

symbols = ['510300.SH',
'513500.SH', # 标普500
'159920.SZ', # 恒生ETF
'159915.SZ']
e = Engine(symbols=symbols)

if __name__ == '__main__':
e.run_strategy(StrategyRolling)
#e.optstrategy(StrategyRolling, period=range(6, 30, 2), topK=range(1, 3, 1), dropN=range(0, 3, 1))
e.show_result_empyrical()

年化20.6%,效果还可以。

代码在如下位置:

AI量化实验室 星球,已经运行三年多,1200+会员。

quantlab代码交付至6.X版本,含几十个策略源代码,因子表达式引擎、遗传算法(Deap)因子挖掘引等,支持backtrader和bt引擎,每周五迭代一次,代码和数据在星球全部开源。

作者:AI量化实验室(专注量化投资、个人成长与财富自由)

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多