原创内容第785篇,专注量化投资、个人成长与财富自由。
大年初五,年很快就过完了。
其实就是本身也只是休假一周,但是我们赋予了它太多意义。
周五咱们发布发aitrader v4.1,带了backtrader+ctp期货的实盘接口:
aitrader_v4.1系统更新|含年化39.1%的组合策略代码|backtrader+openctp实盘(代码+数据)
组合策略运行效果如下:
今天,我们把qmt的整合代码带上,然后对照着学习,backtrader对接实盘,需要三个文件:broker,datafeed和store。
需要pip install xtquant,xtquant其实是与本机的qmt终端连接,需要本机安装并登录qmt终端:
我运行的是投研版本:
import backtrader as bt from live_trade.backtrader_qmt import QMTStore from datetime import datetime from xtquant import xtdata import math class BuyCondition(bt.Indicator): '''买入条件''' lines = ('buy_signal',) params = ( ('up_days', 10), # 连续上涨的天数 ) def __init__(self): self.lines.buy_signal = bt.If(self.data.close > self.data.close(-250), 1, 0) def next(self): # 检查250线斜率是否恰好连续向上self.params.up_days个交易日,再往前一个交易日斜率下降 if len(self) >= self.params.up_days + 1: slope_up = all(self.data.close[-i] > self.data.close[-i - 1] for i in range(1, self.params.up_days + 1)) slope_down_before = self.data.close[-self.params.up_days - 1] < self.data.close[-self.params.up_days - 2] if slope_up and slope_down_before: self.lines.buy_signal[0] = 1 else: self.lines.buy_signal[0] = 0 class SellCondition(bt.Indicator): '''卖出条件''' lines = ('sell_signal',) params = ( ('hold_days', 20), # 持有天数 ) def __init__(self): self.hold_days = 0 def next(self): # 持有self.params.hold_days个交易日卖出 if self.hold_days >= self.params.hold_days: self.lines.sell_signal[0] = 1 self.hold_days = 0 else: self.lines.sell_signal[0] = 0 self.hold_days += 1 class Sizer(bt.Sizer): '''仓位控制''' params = ( ('buy_count', 1), # 最大持仓股票个数 ) def __init__(self): pass def _getsizing(self, comminfo, cash, data, isbuy): if isbuy: # 如果是买入,平均分配仓位 commission_rate = comminfo.p.commission size = math.floor(cash * (1 - commission_rate) / data.close[0] / self.params.buy_count / 100) * 100 else: # 如果是卖出,全部卖出 position = self.broker.getposition(data) size = position.size return size class DemoStrategy(bt.Strategy): params = ( ('max_positions', 5), # 最大持仓股票个数 ('up_days', 10), # 连续上涨的天数 ('hold_days', 20), # 持有天数 ) def log(self, txt, dt=None): """ 记录交易日志 """ dt = dt or self.datas[0].datetime.date(0) print(f'{dt.isoformat()}, {txt}') def __init__(self): # 初始化函数 self.sizer = Sizer() self.buy_condition = {d: BuyCondition(d, up_days=self.params.up_days) for d in self.datas} self.sell_condition = {d: SellCondition(d, hold_days=self.params.hold_days) for d in self.datas} def next(self): # 先收集所有需要买入和卖出的股票 buy_list = [] sell_list = [] for i, d in enumerate(self.datas): pos = self.getposition(d).size if pos and self.sell_condition[d].lines.sell_signal[0] > 0: sell_list.append(d) if self.buy_condition[d].lines.buy_signal[0] > 0: buy_list.append(d) # 动态设置Sizer的buy_count参数 self.sizer.params.buy_count = len(buy_list) # 先执行卖出操作 for d in sell_list: self.sell(data=d) # 再执行买入操作 for d in buy_list: self.buy(data=d) if __name__ == '__main__': store = QMTStore() code_list = xtdata.get_stock_list_in_sector('沪深300') # 添加数据 datas = store.getdatas(code_list=code_list, timeframe=bt.TimeFrame.Days, fromdate=datetime(2022, 7, 1)) for d in datas: # print(len(d)) cerebro = bt.Cerebro(maxcpus=16) cerebro.adddata(d) # 添加策略 # buy_date = datetime(2022, 8, 1).date() # 设置固定买入日期 cerebro.addstrategy(DemoStrategy) # cerebro.optstrategy # # 设置初始资金 cerebro.broker.setcash(1000000.0) # 设置佣金 cerebro.broker.setcommission(commission=0.001) # 运行回测 # print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.run() if cerebro.broker.getvalue() != 1000000.0: print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) xtdata.run() #绘制结果 cerebro.plot()
显示连接成功:
明天继续。
代码和数据下载:AI量化实验室——2025量化投资的星辰大海
AI量化实验室 星球,已经运行三年多,1300+会员。
aitrader代码,含几十个策略源代码,因子表达式引擎、遗传算法(Deap)因子挖掘引擎等,支持vnpy,qlib,backtrader和bt引擎,内置多个年化30%+的策略,每周五迭代一次,代码和数据在星球全部开源。
扩展 • 历史文章
EarnMore(赚得更多)基于RL的投资组合管理框架:一致的股票表示,可定制股票池管理。(附论文+代码)
deap系统重构,再新增一个新的因子,年化39.1%,卡玛提升至2.76(附python代码)
deap时间序列函数补充,挖掘出年化39.12%的轮动因子,卡玛比率2.52
年化19.3%,回撤仅8%的实盘策略,以及backtrader整合CTPBee做实盘(附python代码和数据)
近四年年化收益19.3%,而最大回撤仅8%,卡玛比率2.34,投资应该是一件简单的事情。(附python代码+数据)
AGI通用智能实验室
紧跟前沿AGI研究进展,论文复现,可运行的代码,落地应用等。
既做科研,也做科普;研究基础大模型,也关心应用场景。
通往前沿通用人工智能(AGI)的路径已经展开。
这是一场史诗级的工业革命级别的技术变革,奇点临近,未来已来!