Backtrader量化&回测5——交易情况跟踪&生成策略每日交易报告

2023-10-31

这一部分的API可以参考官网:https://www.backtrader.com/docu/strategy/

Backtrader的策略中有四个常用的函数:

  • notify_order(order):订单状态变化时会触发这个函数
  • notify_trade(trade):交易状态变化时会触发这个函数
  • notify_cashvalue(cash, value):每过一个next()都会触发
  • notify_fund(cash, value, fundvalue, shares):每过一个next()都会触发

其中:notify_order(order)notify_trade(trade)是需要触发订单和交易触发才可以执行,可以跟踪订单和交易情况

剩余的函数执行顺序是:next()->notify_cashvalue(cash, value)->notify_fund(cash, value, fundvalue, shares),可以做每日报告

示例代码

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


class MyStrategy1(backtrader.Strategy):  # 策略
    def __init__(self):
        # 初始化交易指令、买卖价格和手续费
        self.close_price = self.datas[0].close  # 这里加一个数据引用,方便后续操作
        self.sma = backtrader.indicators.SimpleMovingAverage(self.datas[0], period=5)  # 借用这个策略,计算5日的均线

    def notify_order(self, order):  # 当订单状态变化时触发
        # 通知订单状态
        if order.status in [order.Submitted, order.Accepted]:  # 接受订单交易,正常情况
            return
        if order.status in [order.Completed]:
            if order.isbuy():
                logger.debug('已买入, 购入金额 {:.2f}, 费用 {:.2f} ,手续费{:.2f}'.format(
                    order.executed.price, order.executed.value, order.executed.comm))
            elif order.issell():
                logger.debug('已卖出, 卖出金额 {:.2f}, 费用 {:.2f} ,手续费{:.2f}'.format(
                    order.executed.price, order.executed.value, order.executed.comm))
        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            logger.debug('订单取消、保证金不足、金额不足拒绝交易')

    def notify_trade(self, trade):
        if not trade.isclosed:
            return
        logger.debug('交易利润, 毛利润 {:.2}, 净利润 {:.2}'.format(trade.pnl, trade.pnlcomm))

    def notify_cashvalue(self, cash, value):
        # 现金,总价值
        logger.info("notify_cashvalue报告 —— 今天是:{},当前现金:{},总价值:{}", self.datetime.date(), cash, value)

    def notify_fund(self, cash, value, fundvalue, shares):
        # 当前现金、现有总价值、基金价值和股份份额
        logger.info("notify_fund报告 —— 今天是:{},现金:{},总价值:{}", self.datetime.date(), cash, value)

    def next(self):  # 固定的函数,框架执行过程中会不断循环next(),过一个K线,执行一次next()
        # 此时调用 self.datas[0]即可查看当天的数据
        # 执行买入条件判断:当天收盘价格突破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)
    # =============== 系统设置 ==================
    # 设置启动资金为 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Backtrader量化&回测5——交易情况跟踪&生成策略每日交易报告 的相关文章

随机推荐

  • win/linux集群源码,Linux win/linux集群源码 - 下载 - 搜珍网

    linux linux Bin linux Bin Control exe linux Bin Control zip linux Bin dat linux Bin dat WinDDOS dat linux Claer bat linu
  • [机缘参悟-76]:沟通技巧-职场中常见不合适语言的案例分析(尽量避免使用反问式语言)

    目录 第一部分 针对他人的用词 避免使用 怎么 这样的责难的词 避免使用 老实说 这样过虚假的词 避免说 xxx几点左右 这种的不确定性词 避免使用 是xxx人的错 这种强烈的否定性的词 避免使用 但是 这一种强烈的转折性的词 避免使用 务
  • 判断一个数是否偶数(深度思考)

    当看到这个题 很明显就能想到 if unm 2 0 return true else return false 那么如果继续优化 我们都知道 计算机都是2进制计算 那么我们可以从二进制入手 2 gt 0010 4 gt 0100 3 gt
  • 【SpringMVC】SpringMVC :@RequestMapping注解

    文章目录 1 美图 2 概述 3 使用 4 源码 4 0 RequestMapping 4 1 AbstractHandlerMethodMapping 1 美图 2 概述 如 果 Web 工程使用 了 Spring MVC 那么它在启动阶
  • Vue连接数据库实现登录注册

    在前端开发中 经常需要将用户的注册和登录信息存储到数据库中 然后再进行登录验证 本文将介绍如何使用Vue连接数据库实现登录注册功能 前提条件 在开始之前 需要安装并配置好以下环境 Vue js Node js MongoDB 安装依赖 安装
  • kl散度学习笔记python实现

    KL Divergence KL Kullback Leibler Divergence中文译作KL散度 从信息论角度来讲 这个指标就是信息增益 Information Gain 或相对熵 Relative Entropy 用于衡量一个分布
  • windows下如何恢复notepad未保存的文件

    notepad恢复未保存的文件 备份文件 C Users 你当前用户的用户名 AppData Roaming Notepad backup可以恢复 如果找不到此文件 因为文件被隐藏了 打开隐藏文件即可
  • tomcat 和 apache跟CGI都有什么关系呢?

    tomcat 和 apache跟CGI都有什么关系呢 IIS和古老的PWS都是win下运行的 web服务程序 对吧 这下边跑的是 asp对吧 这些不会跨平台对吧 web服务程序 是 apache还是tomcat 呢 jsp跟 asp是一种功
  • 简搭(jabdp)快速入门(一)

    一 文件夹说明 本应用包为绿色免安装版本 只需要将本jabdp文件夹复制至系统英文名称目录下即可 mysql目录为默认集成的数据库目录 webapps目录为应用程序所在目录 其中设计器包含ae与iDesigner工程 项目平台包含iPlat
  • JAVA 内部类 inner class

    内部类 在一个类的内部定义的类称为内部类 类的内部 第一 与属性或方法 同级 内部类 这个类与外部类的每个对象是一对一的关系 Person与Birthday 静态内部类 这个类与外部类是1对1的关系 每个对象共享这个内部类对象 Hero和C
  • 编程实用工具大全(二)(前后端皆可用,不来看看?)

    个人主页 个人主页 系列专栏 精品推荐 由于之前编程实用工具大全深受大家喜欢 所以出了第二期 对于没有看过第一期的小伙伴 可以点击这个链接 编程实用工具大全 一 目录 1 零代码工具箱 专为前端打造 1 SVG波浪背景生成器 2 在线生成
  • Activity启动流程概述

    总结 Activity的启动过程 我们可以从Context的startActivity说起 其实现是ContextImpl的startActivity 内部调用startActivityForResult 然后内部会通过Instrument
  • Mathpix公式识别OCR软件使用教程

    最近 发现一款公式识别OCR软件 配合Mathtype 公式编辑器 非常好用 省去很多时间 所以就写一篇文章介绍Mathpix的使用方法 1 打开Mathpix软件后 可以鼠标单击下图中小电脑图标进行截图 也可以使用快捷键Ctrl Alt
  • IntelliJ IDEA基于maven构建的web项目找不到jar包

    手把手教你搭建基于Maven的SSM框架 附源代码 SSM框架 详细整合教程 GitHub源码地址 SSM整合框架 基于maven构建的springMVC项目 下载好jar包import后 运行提示ClassNotFoundExceptio
  • 数仓/数据开发-零基础入坑(小白学习路径)

    这段时间各大公司的春招陆续开始了 但是也有很多同学还在因为刚刚入坑或者还在纠结 对学习路径比较迷茫 这也是去年的我 所以这边总结一下 一个面向面试的学习路径 后面也会补充上全面的学习路径 面向面试就是掌握到基本能应付暑期实习面试的基本技能和
  • 论文笔记之CSPNet

    本文解决的是减少推理计算的问题 本文收录于CVPR2019 论文地址 https arxiv org pdf 1911 11929 pdf 1 摘要 目前最先进的能够在计算机视觉任务上取得非常好的结果的方法往往很大程度上依赖于昂贵的计算资源
  • Window Server IIS日志导入到SQL Server查看

    配置ODBC log日志可以导出到提供ODBC访问接口的数据库查看 控制面板 ODBC 添加DSN gt SQL Server 起个名称 随意命名 下一步 选择数据库 下一步 默认就行 点完成 测试数据源 点击确定 点击应用 确定 打开lo
  • Error:Could not create the Java Virtual Machine. Error:A Fatal exception has occurred错误解决

    问题情况 出现以上情况 可以通过以下方式进行解决 1 判断机子是否安装了Java环境 确定自己已经设置环境变量 如JAVA HOME CLASSPATH PATH 2 有些程序会有内存设置 有些程序内存设置过大时 超过虚拟机的范围会报错 3
  • 剑指offer——剪绳子

    题目描述 给你一根长度为n的绳子 请把绳子剪成整数长的m段 m n都是整数 n gt 1并且m gt 1 每段绳子的长度记为k 0 k 1 k m 请问k 0 xk 1 x xk m 可能的最大乘积是多少 例如 当绳子的长度是8时 我们把它
  • Backtrader量化&回测5——交易情况跟踪&生成策略每日交易报告

    这一部分的API可以参考官网 https www backtrader com docu strategy Backtrader的策略中有四个常用的函数 notify order order 订单状态变化时会触发这个函数 notify tr