Backtrader量化&回测4——定义策略参数&添加额外数据集

本文介绍了如何在Backtrader平台上定义和使用策略参数,包括通过`addstrategy`和`optstrategy`添加静态和可迭代的参数。同时,展示了如何在策略中手动添加额外的数据集,以实现更复杂的回测场景。示例代码详细演示了如何创建一个基于简单移动平均线的交易策略,并进行回测,包括买入和卖出条件的设定,以及结果的可视化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需要提前知道的一点是:Backtrader是一个回测平台,并不是一个训练模型的平台,因为添加数据比较繁琐,因此不建议使用Backtrader训练模型。而是训练完模型后,放到Backtrader上进行回测

1. 定义策略中的参数

  1. 定义策略参数使用:

    class MyStrategy1(backtrader.Strategy):  # 策略
        params = (
            ("参数名", 参数值),  # 注意要有逗号!!
        )
    

    后续就可以通过self.params.参数名直接调用了

  2. 通过外部指定参数时,使用以下两种方法:

    cerebral_system.addstrategy(MyStrategy1, simple_period=5)  # 这里定义参数
    
    # optstrategy与addstrategy类似,但是要求参数为可迭代对象
    # cerebral_system.optstrategy(MyStrategy1, simple_period=range(4, 10))
    

    addstrategy参数接收的是一个固定值,一般回测用;
    optstrategy参数接收的是一个可迭代的值,一般参数调优用

2. 添加额外的数据集

比如用到文本数据,或是其他数据时,不好通过框架添加进来,就可以在策略类中使用:

class MyStrategy1(backtrader.Strategy):  # 策略
    def __init__(self):
		# ...
        self.new_data = pd.read_csv('其他外部数据.csv')  # 这里可以手动添加额外的数据集或参考

这样就可以把任意外部数据添加进来了,但是这样相当于摆脱了框架的管理,策略里要注意逻辑

示例代码

from datetime import datetime
import backtrader
from loguru import logger
import matplotlib.pyplot as plt
from utils import get_k_data
import pandas as pd


class MyStrategy1(backtrader.Strategy):  # 策略
    # 初始化策略参数
    # 初始化模型参数,默认为3,可以使用策略的 addstrategy() 时修改
    params = (
        ("simple_period", 3),  # 注意要有逗号!!
    )

    def __init__(self):
        # 策略
        logger.debug('模型参数:{}', self.params.simple_period)
        # 借用移动平均的策略,计算5日的均线
        self.sma = backtrader.indicators.SimpleMovingAverage(self.datas[0], period=self.params.simple_period)

        # 这里添加一些快捷的方法,运行过程中会实时更新这部分数据
        self.close_price = self.datas[0].close  # self.close_price会在next中显示当天的收盘价

        # self.new_data = pd.read_csv('其他外部数据.csv')  # 这里可以手动添加额外的数据集或参考

    def next(self):  # 固定的函数,框架执行过程中会不断循环next(),过一个K线,执行一次next()

        # 执行买入条件判断:当天收盘价格突破5日均线
        if self.close_price[0] > self.sma[0]:
            # 执行买入
            logger.debug("buy 500 in {}, 预期购入金额 {}, 剩余可用资金 {}", self.datetime.date(), self.data.close[0],
                         self.broker.getcash())
            self.buy(size=500, price=self.data.close[0])
        # 执行卖出条件已有持仓,且收盘价格跌破5日均线
        if self.position:
            if self.close_price[0] < self.sma[0]:
                # 执行卖出
                logger.debug("sell in {}, 预期卖出金额 {}, 剩余可用资金 {}", self.datetime.date(), self.data.close[0],
                             self.broker.getcash())
                self.sell(size=500, price=self.data.close[0])


if __name__ == '__main__':
    # 获取数据
    start_time = datetime(2015, 1, 1)
    end_time = datetime(2021, 1, 1)
    dataframe = get_k_data('600519', begin=start_time, end=end_time)
    # =============== 为系统注入数据 =================
    # 加载数据
    data = backtrader.feeds.PandasData(dataname=dataframe, fromdate=start_time, todate=end_time)
    # 初始化cerebro回测系统
    cerebral_system = backtrader.Cerebro()  # Cerebro引擎在后台创建了broker(经纪人)实例,系统默认每个broker的初始资金量为10000
    # 将数据传入回测系统
    cerebral_system.adddata(data)  # 导入数据,在策略中使用 self.datas 来获取数据源
    # 将交易策略加载到回测系统中
    cerebral_system.addstrategy(MyStrategy1, simple_period=5)  # 这里定义参数
    # optstrategy与addstrategy类似,但是要求参数为可迭代对象
    # cerebral_system.optstrategy(MyStrategy1, simple_period=range(4, 10))
    # =============== 系统设置 ==================
    # 设置启动资金为 100000
    start_cash = 1000000
    cerebral_system.broker.setcash(start_cash)
    # 设置手续费 万2.5
    cerebral_system.broker.setcommission(commission=0.00025)
    logger.debug('初始资金: {} 回测期间:from {} to {}'.format(start_cash, start_time, end_time))
    # 运行回测系统
    cerebral_system.run()
    # 获取回测结束后的总资金
    portvalue = cerebral_system.broker.getvalue()
    pnl = portvalue - start_cash
    # 打印结果
    logger.debug('净收益: {}', pnl)
    logger.debug("总资金: {}", portvalue)
    cerebral_system.plot(style='candlestick')
    plt.show()

其中utils中的get_k_data函数如下:

import efinance
import pandas as pd
from datetime import datetime


def get_k_data(stock_code, begin: datetime, end: datetime) -> pd.DataFrame:
    """
    根据efinance工具包获取股票数据
    :param stock_code:股票代码
    :param begin: 开始日期
    :param end: 结束日期
    :return:
    """
    # stock_code = '600519'  # 股票代码,茅台
    k_dataframe: pd.DataFrame = efinance.stock.get_quote_history(
        stock_code, beg=begin.strftime("%Y%m%d"), end=end.strftime("%Y%m%d"))
    k_dataframe = k_dataframe.iloc[:, :9]
    k_dataframe.columns = ['name', 'code', 'date', 'open', 'close', 'high', 'low', 'volume', 'turnover']
    k_dataframe.index = pd.to_datetime(k_dataframe.date)
    k_dataframe.drop(['name', 'code', "date"], axis=1, inplace=True)
    return k_dataframe
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呆萌的代Ma

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值