【量化回测】backtracker整体架构和使用示例

backtrader整体框架

backtrader 是一个量化回测的库,支持多品种、多策略、多周期的回测和交易。更重要的是可以集成 torch 等神经网络分析模块。

Cerebro类是 backtrader 的核心。Strategy类、BrokerSizer类都是由Cerebro类实例化而来。

整体流程

  • backtrade 自带的数据源是yahoofinance(),也可使用自己本地的 csv 文件。
  • DataFeed模块会将原始数据导入到 Cerebro ,之后就可以进行矢量化操作。
  • Strategy模块会根据策略将订单提交到BrokerBroker是一个抽象的交易所,里面定义了订单执行、仓位管理和交易费率等。
  • Strategy模块中包括了三个模块ObserverAnalyzerIndicatorObserver负责观测市场数据。Analyzer负责分析算法产生的数据,可以看做是一个评估模块。Indicator是指标和信号模块,策略主要通过指标和信号来判断是否触发交易。
  • Sizer主要负责仓位的管理。因为Strategy只负责触发交易,但不知道怎么分配仓位。Sizer就可以独立控制仓位管理。

数据流程

实操流程

安装环境

python 复制代码
pip install backtrader matplotlib

回测示例

注意,需要准备CSV格式的个股数据。

python 复制代码
import backtrader as bt
import pandas as pd
import matplotlib.pyplot as plt
import datetime as dt
import numpy as np


class SMAStrategy(bt.Strategy):
    '''
    自定义的策略, 需继承 bt.Strategy
    '''
    def __init__(self):
        self.dataclose = self.data0.close
        self.order = None
        self.buyprice = None
        self.buycomm = None

        self.sma = bt.indicators.SimpleMovingAverage(self.data0, period=15)

    def next(self):
        '''
        一般在这里写实际的策略。
        这里就是收盘价上穿sma买入,反之则卖出。
        '''
        if not self.position:  # 判断是否有持仓
            if self.dataclose[0] > self.sma[0]:  # 判断收盘价是否上穿sma
                self.buy()
        else:
            if self.dataclose[0] < self.sma[0]:
                self.close()  # 平仓

    def notify_order(self, order):
        '''
        获取订单状态,这个函数一般可以通用。
        '''
        if order.status in [order.Submitted, order.Accepted]:
            return
        
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log(
                    'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                    (order.executed.price,
                    order.executed.value,
                    order.executed.comm)
                )
                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
            else:
                self.log(
                    'SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                    (order.executed.price,
                    order.executed.value,
                    order.executed.comm)
                )
                self.bar_executed = len(self)
        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('Drder Canceled / Margin / Rejected')
        self.order = None
    
    def notify_trade(self, trade):
        '''
        追踪每笔交易的状态,这个函数一般可以通用。
        '''
        if not trade.isclosed:
            return
        self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                 (trade.pnl, trade.pnlcomm))
        
    def log(self, txt, dt=None, doprint=False):
        '''
        保存日志
        '''
        if doprint:
            dt = dt or self.datas[0].datetiem.date(0)
            print('%s, %s' % (dt.isoformat(), txt))



if __name__ == "__main__":
    # 实例化cerebro
    cerebro = bt.Cerebro()

    # 处理数据
    dataframe = pd.read_csv('TSLA.csv')
    dataframe['Datetime'] = pd.to_datetime(dataframe['Date'])
    dataframe.set_index('Datetime', inplace=True)

    # 加载数据源
    data_TSLA = bt.feeds.PandasData(dataname = dataframe,
                                    fromdate = dt.datetime(2025,1,2), 
                                    todate = dt.datetime(2025,1,31))
    cerebro.adddata(data_TSLA)

    # 加载策略
    cerebro.addstrategy(SMAStrategy)

    # 加载Analyzer
    cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name="SharpeRatio")
    cerebro.addanalyzer(bt.analyzers.DrawDown, _name = "DrawDown")

    # 在Broker中设置初始资金和手续费
    cerebro.broker.setcash(10000.0)
    cerebro.broker.setcommission(commission = 0.0006)

    # 设置Sizer
    cerebro.addsizer(bt.sizers.PercentSizer, percents = 90)

    result = cerebro.run()

    print("夏普比率", result[0].analyzers.SharpeRatio.get_analysis()['sharperatio'])
    print("最大回撤", result[0].analyzers.DrawDown.get_analysis["max"]['drawdown'])
    cerebro.plot()

参考:【【Backtrader教程01】Python Backtrader量化回测框架 | 代码实战教学 | 单均线回测收益率570%?】 https://www.bilibili.com/video/BV1QR4y147rS/?share_source=copy_web\&vd_source=9eb6d7fad45f9fa869cd9abb34fa68ca

相关推荐
大飞记Python13 分钟前
【2026更新】Python基础学习指南(AI版)——04数据类型
开发语言·人工智能·python
Hello eveybody2 小时前
介绍一下背包DP(Python)
开发语言·python·动态规划·dp·背包dp
2301_795099742 小时前
让 CSS Grid 自适应容器尺寸的动态布局方案
jvm·数据库·python
呆萌的代Ma2 小时前
python读取并加载.env的配置文件
python
Muyuan19982 小时前
27.RAG 系统中的上下文充分性判断:从 Chunk 数量、FAISS 距离到 LLM Relevance Gate
python·django·pdf·fastapi·faiss
U盘失踪了2 小时前
python curl转python脚本
开发语言·chrome·python
FQNmxDG4S2 小时前
Java泛型编程:类型擦除与泛型方法的应用场景
java·开发语言·python
bzmK1DTbd3 小时前
JDBC编程规范:PreparedStatement与事务管理
数据库·python·eclipse
我星期八休息3 小时前
IT疑难杂症诊疗室:AI时代工程师Superpowers进化论
linux·开发语言·数据结构·人工智能·python·散列表
代码小书生3 小时前
math,一个基础的 Python 库!
人工智能·python·算法