十年长期年化30%,夏普比1.21的ETF轮动策略代码分享,附backtrader交易系统和通用策略模板
今天咱们来实现完整的策略,两种方式,一种是低代码,如何通过ailabx.com官网直接配置出来。首先打开ailabx.com网站,免费注册/登录,登录后点击“免费创建策略”。原创内容第961篇,专注量化投资,AGI和智能体落地、个人成长与财富自由。等,支持vnpy,qlib,backtrader和bt引擎,内置多个。,每周五迭代一次,代码和数据在星球全部开源。aitrader代码,因子表达式引擎、
原创内容第961篇,专注量化投资,AGI和智能体落地、个人成长与财富自由。
昨天的文章,咱们分享了trend_score因子在backtrader里的实现:
10年24倍!创业板+纳指+黄金+上证180,基于trend_score因子的排序轮动,附backtrader实现
今天咱们来实现完整的策略,两种方式,一种是低代码,如何通过ailabx.com官网直接配置出来。
首先打开ailabx.com网站,免费注册/登录,登录后点击“免费创建策略”。

在选股里选择如下四支ETF:

咱们只需要排序规则,买入和卖出留空即可:

排序规则,点击添加“斜率*拟合度”即可,其余保持默认:

点“运行策略”:

一个年化31%的策略就做好了:

有些同学想要策略代码,咱们使用backtrader来实现一下:
backtrader通用策略模板:
import backtrader as btimport numpy as npclass StrategyTemplate(bt.Strategy):params = (('lookback',25),)def log(self, txt, dt=None):dt = dt or self.datas[0].datetime.date(0)print(f"{dt.isoformat()}, {txt}")def notify_order(self, order):"""订单状态通知"""if order.status in [order.Submitted, order.Accepted]:returnif order.status in [order.Completed]:if order.isbuy():self.log(f"买入执行, 价格: {order.executed.price:.2f}, 数量: {order.executed.size}, 成本: {order.executed.value:.2f}, 佣金: {order.executed.comm:.2f}")self.buy_price = order.executed.priceself.buy_date = self.datas[0].datetime.date(0)elif order.issell():profit = order.executed.value - order.created.valueself.log(f"卖出执行, 价格: {order.executed.price:.2f}, 数量: {order.executed.size}, 收益: {profit:.2f}, 佣金: {order.executed.comm:.2f}")elif order.status in [order.Canceled, order.Margin, order.Rejected]:self.log(f"订单取消/保证金不足/拒绝")def order_by(self, topK=1, dropN=0, desc=True):# 步骤1:计算所有资产的当前指标值ranking = []for d in self.datas:# 跳过数据不足的资产if len(d) < self.p.lookback:continue# 获取当前指标值if 'sorter' not in self.inds[d].keys():print('order_by==>sorter指标不存在,请检查')returnind_value = self.inds[d]['sorter'][0]# 跳过无效值if np.isnan(ind_value):continueranking.append((d, ind_value))# 按指标值降序排序(从大到小)ranking.sort(key=lambda x: x[1], reverse=desc)selected = [asset for asset, _ in ranking[dropN:topK]]return selecteddef weight_equally(self,selected):weights = {}for data in selected:weights[data] = 0.98/len(selected)return weightsdef rebalance(self,weights):"""根据新权重调整仓位"""total_value = self.broker.getvalue()#print(weights)to_buy = {}for i, data in enumerate(self.datas):if data in weights.keys():# 计算目标市值target_value = total_value * weights[data]else:target_value = 0# 计算当前持仓市值current_value = self.getposition(data).size * data.close[0]# 计算需要交易的数量size_diff = (target_value - current_value) / data.close[0]# 执行订单if size_diff > 0:to_buy[data] = size_diffelif size_diff < 0:self.sell(data=data, size=abs(size_diff))# self.buy(data=data, size=size_diff)for data, size in to_buy.items():self.buy(data=data, size=size)
再实现这个策略就简单了:
class TrendScoreRotation(RotationStrategyTemplate):params = (('lookback',25),)def __init__(self):self.inds = defaultdict(dict) # 存储各资产ROC指标for data in self.datas:self.inds[data]['sorter'] = TrendScore(data, period=self.params.lookback)
在引擎里调用:
import osimport backtrader as btimport pandas as pdclass Engine:def __init__(self, symbols):# 设置回测cerebro = bt.Cerebro()cerebro.broker.setcash(1000000.0) # 设置初始资金# 添加分析器cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe')cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')cerebro.addanalyzer(bt.analyzers.Returns, _name='returns')# 添加PyFolio分析器cerebro.addanalyzer(bt.analyzers.PyFolio, _name='pyfolio')self.cerebro = cerebroself._add_datas(symbols,'2013-08-30','2025-08-04')def _add_datas(self, symbols, start_dt, end_dt):current_dir = os.path.dirname(os.path.abspath(__file__))print(current_dir)for s in symbols:csv = f'{current_dir}/data/{s}.csv'data = pd.read_csv(csv)data.set_index('date', inplace=True)data.index = pd.to_datetime(data.index)data = bt.feeds.PandasData(dataname=data,fromdate=pd.to_datetime(start_dt),todate=pd.to_datetime(end_dt),timeframe=bt.TimeFrame.Days)self.cerebro.adddata(data)def run(self, strategy):self.cerebro.addstrategy(strategy)print('回测开始...')results = self.cerebro.run()print('回测完成!')# 获取策略实例strat = results[0]# 提取PyFolio分析结果pyfoliozer = strat.analyzers.getbyname('pyfolio')returns, positions, transactions, gross_lev = pyfoliozer.get_pf_items()import ffnperf = (1 + returns).cumprod().calc_stats()print(perf.display())# 打印分析结果print('\n===== 策略分析 =====')print(f"夏普比率: {strat.analyzers.sharpe.get_analysis()['sharperatio']:.3f}")print(f"最大回撤: {strat.analyzers.drawdown.get_analysis()['max']['drawdown']:.2f}%")print(f"年化收益率: {strat.analyzers.returns.get_analysis()['rnorm100']:.2f}%")print(f"期末值: {self.cerebro.broker.getvalue()}")perf.plot()import matplotlib.pyplot as pltplt.show()if __name__ == '__main__':symbols = {'513100': '纳指100',# '513500':'标普500',#'510300': '沪深300','159915':'创业板','518880': '黄金','510180':'上证180',# '512890':'红利低波',# '159985':'豆粕',# '511880':'银华日利-货币ETF',# '511260':'十年国债',#'511220': '城投债'}e = Engine(symbols=symbols)from notebooks.rotation_strategy import TrendScoreRotatione.run(TrendScoreRotation)


代码、策略和数据已经提交:

大家只需要运行engine.py就可以看到结果:

代码和数据下载:AI量化实验室——2025量化投资的星辰大海
AI量化实验室 星球,已经运行三年多,1700+会员。
aitrader代码,因子表达式引擎、遗传算法(Deap)因子挖掘引擎等,支持vnpy,qlib,backtrader和bt引擎,内置多个年化30%+的策略,每周五迭代一次,代码和数据在星球全部开源。
年化收益548%,回撤才6%,夏普比5.72,这个策略一直很稳定,附python代码
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)