原创内容第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 mathclass 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] = 1else:self.lines.buy_signal[0] = 0class SellCondition(bt.Indicator):'''卖出条件'''lines = ('sell_signal',)params = (('hold_days', 20), # 持有天数)def __init__(self):self.hold_days = 0def next(self):# 持有self.params.hold_days个交易日卖出if self.hold_days >= self.params.hold_days:self.lines.sell_signal[0] = 1self.hold_days = 0else:self.lines.sell_signal[0] = 0self.hold_days += 1class Sizer(bt.Sizer):'''仓位控制'''params = (('buy_count', 1), # 最大持仓股票个数)def __init__(self):passdef _getsizing(self, comminfo, cash, data, isbuy):if isbuy:# 如果是买入,平均分配仓位commission_rate = comminfo.p.commissionsize = math.floor(cash * (1 - commission_rate) / data.close[0] / self.params.buy_count / 100) * 100else:# 如果是卖出,全部卖出position = self.broker.getposition(data)size = position.sizereturn sizeclass 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).sizeif 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)的路径已经展开。
这是一场史诗级的工业革命级别的技术变革,奇点临近,未来已来!