Backtrader 文档学习-Bracket Orders

Backtrader 文档学习-Bracket Orders

1. 概述

组合订单类型是一个非常宽泛的订单类别,只要brokder支持的订单类型都可以,
包括(Market, Limit, Close, Stop, StopLimit, StopTrail, StopTrailLimit, OCO)。

该功能用于回测,交互broker

Bracket订单不是单个订单,而是由3个订单组成,考虑多头情况。

  • 一个主要的买入订单,通常设置为限价或止损限价订单。
  • 一个低位卖出订单,通常设置为止损单以限制损失。(止损单)
  • 一个高位卖出订单,通常设置为限价单以获利。(止盈单)

相反如果是空头情况,有相应的卖出和2个买入订单。
低/高位订单实际上在主订单周围创建了一个bracket。
从逻辑上讲,以下规则适用:

  • 3个订单是同时提交的,以避免其中任何一个单独触发
  • 低/高侧订单被标记为主订单的子订单
  • 子订单在主订单被执行之前不会被激活
  • 主订单的取消同时取消了低端和高端的子订单
  • 一旦激活,任何低/高端的订单的执行或取消都会自动取消另外的订单

2.使用模式

创建Bracket订单集有两种可能性 :

  • 单次触发3个订单
  • 手动触发3个订单
(1) 单次触发Bracket订单

要控制bracket订单,backtrader在
strategy
中提供了2个新的方法:
buy_bracket 和 sell_bracket
下面一条语句返回一个包含3个订单组合

brackets = self.buy_bracket(limitprice=14.00, price=13.50, stopprice=13.00)

注意上面参数 stopprice 和 limitprice 如何环绕在 price 周围。
实际成交的数据默认是data0,成交数量由默认的sizer自动计算得到。除了可以指定这两个参数,也可以指定其他参数,执行精细控制。

因为当发出sell_bracket订单时,低端和高端将被转向,参数的命名遵循常规stop 和 limit 。

  • 代码返回list,list中包含3个订单[main, stop, limit]。
  • 因为当生成一个sell_bracket订单,low和high会环绕在price两边,参数的命名遵循stop和 limit的约定。
  • stop意味着止损(低的一侧是买入,高的一侧是卖出)
  • limit意味着止盈(高的一侧是买入,低的一侧是卖出)
(2)手工触发Backet订单

涉及到3个订单的生成,通过transmit和parent参数实现。规则:

  • 主端订单必须首先创建,并且传入transmit=False
  • 低/高侧订单必传入parent=main_side_order
  • 要创建的第一个低/高侧订单必须传入transmit=False
  • 最后一个要创建的命令(低位或高位)设置transmit=True
    测试用例:
mainside = self.buy(price=13.50, exectype=bt.Order.Limit, transmit=False)
lowside  = self.sell(price=13.00, size=mainside.size, exectype=bt.Order.Stop,transmit=False, parent=mainside)
highside = self.sell(price=14.00, size=mainside.size, exectype=bt.Order.Limit,transmit=True, parent=mainside)
  • 保持跟踪主侧订单,标识它是其他订单的父订单
  • 控制传输,以确保只有最后一个订单会被联合触发
  • 定义执行类型
  • 定义低位和高位的size

由于size必须相同。如果没有手工指定参数,最终用户引入了sizer,那么sizer实际上可以为订单指示不同的值。这就是为什么必须先设置主侧订单后手动添加到调用中。

3. 示例

交易核心代码

o1 exectype=bt.Order.Limit 主单
o2 exectype=bt.Order.Stop 止损单
o3 exectype=bt.Order.Limit 止盈单

            if self.cross > 0.0:  # crossing upclose = self.data.close[0]p1 = close * (1.0 - self.p.limit)p2 = p1 - 0.02 * closep3 = p1 + 0.02 * closevalid1 = datetime.timedelta(self.p.limdays)valid2 = valid3 = datetime.timedelta(self.p.limdays2)if self.p.switchp1p2:p1, p2 = p2, p1valid1, valid2 = valid2, valid1if not self.p.usebracket:o1 = self.buy(exectype=bt.Order.Limit,price=p1,valid=valid1,transmit=False)print('{}: Oref {} / Buy at {}'.format(self.datetime.date(), o1.ref, p1))o2 = self.sell(exectype=bt.Order.Stop,price=p2,valid=valid2,parent=o1,transmit=False)print('{}: Oref {} / Sell Stop at {}'.format(self.datetime.date(), o2.ref, p2))o3 = self.sell(exectype=bt.Order.Limit,price=p3,valid=valid3,parent=o1,transmit=True)print('{}: Oref {} / Sell Limit at {}'.format(self.datetime.date(), o3.ref, p3))self.orefs = [o1.ref, o2.ref, o3.ref]

python ./bracket.py --plot

(1)主侧订单过期
2005-01-28: Oref 1 / Buy at 2941.11055
2005-01-28: Oref 2 / Sell Stop at 2881.99275
2005-01-28: Oref 3 / Sell Limit at 3000.22835
2005-01-31: Order ref: 1 / Type Buy / Status Submitted
2005-01-31: Order ref: 2 / Type Sell / Status Submitted
2005-01-31: Order ref: 3 / Type Sell / Status Submitted
2005-01-31: Order ref: 1 / Type Buy / Status Accepted
2005-01-31: Order ref: 2 / Type Sell / Status Accepted
2005-01-31: Order ref: 3 / Type Sell / Status Accepted
2005-02-01: Order ref: 1 / Type Buy / Status Expired
2005-02-01: Order ref: 2 / Type Sell / Status Canceled
2005-02-01: Order ref: 3 / Type Sell / Status Canceled

第一个案例中,主侧订单过期,这自动取消了其他两个订单。
2005-02-01 1号买单过期,2/3号订单取消。

(2)止损单执行
2005-08-11: Oref 16 / Buy at 3337.3891999999996
2005-08-11: Oref 17 / Sell Stop at 3270.3059999999996
2005-08-11: Oref 18 / Sell Limit at 3404.4723999999997
2005-08-12: Order ref: 16 / Type Buy / Status Submitted
2005-08-12: Order ref: 17 / Type Sell / Status Submitted
2005-08-12: Order ref: 18 / Type Sell / Status Submitted
2005-08-12: Order ref: 16 / Type Buy / Status Accepted
2005-08-12: Order ref: 17 / Type Sell / Status Accepted
2005-08-12: Order ref: 18 / Type Sell / Status Accepted
2005-08-12: Order ref: 16 / Type Buy / Status Completed
2005-08-18: Order ref: 17 / Type Sell / Status Completed
2005-08-18: Order ref: 18 / Type Sell / Status Canceled

第二个案例中,主侧订单已完成,低位(在买入情况下为止损)被执行,限制了损失 。
2005-08-12 ,16号主单完成,17号止损单完成,18日止盈单取消

(3)止盈单执行
2005-09-26: Oref 22 / Buy at 3383.92535
2005-09-26: Oref 23 / Sell Stop at 3315.90675
2005-09-26: Oref 24 / Sell Limit at 3451.94395
2005-09-27: Order ref: 22 / Type Buy / Status Submitted
2005-09-27: Order ref: 23 / Type Sell / Status Submitted
2005-09-27: Order ref: 24 / Type Sell / Status Submitted
2005-09-27: Order ref: 22 / Type Buy / Status Accepted
2005-09-27: Order ref: 23 / Type Sell / Status Accepted
2005-09-27: Order ref: 24 / Type Sell / Status Accepted
2005-09-27: Order ref: 22 / Type Buy / Status Completed
2005-10-04: Order ref: 24 / Type Sell / Status Completed
2005-10-04: Order ref: 23 / Type Sell / Status Canceled

第三个案例中,主侧订单已完成,高位(限价)被执行,能够注意到,因为完成的id是22和24,高侧订单是最后一个发出的,这意味着未执行的低侧订单id是23。
2005-09-27,22号主单完成,23号止损单取消,24号止盈单完成。

(4)图示

在这里插入图片描述
It can be immediately seen that the losing trades align around the same value and winning trades too, which is the purpose of the backeting. Controlling both sides.

能够立刻看到,亏损交易都在同一个值附近,赢利交易也是如此,这就是backeting的目的。控制双侧,即控制止损,控制盈利。

(5)用参数usebracket=True
python  ./bracket.py --strat usebracket=True --plot

相同的结果。
图示:
在这里插入图片描述

4. 完整代码

from __future__ import (absolute_import, division, print_function,unicode_literals)import argparse
import datetimeimport backtrader as btclass St(bt.Strategy):params = dict(ma=bt.ind.SMA,p1=5,p2=15,limit=0.005,limdays=3,limdays2=1000,hold=10,usebracket=False,  # use order_target_sizeswitchp1p2=False,  # switch prices of order1 and order2)def notify_order(self, order):print('{}: Order ref: {} / Type {} / Status {}'.format(self.data.datetime.date(0),order.ref, 'Buy' * order.isbuy() or 'Sell',order.getstatusname()))if order.status == order.Completed:self.holdstart = len(self)if not order.alive() and order.ref in self.orefs:self.orefs.remove(order.ref)def __init__(self):ma1, ma2 = self.p.ma(period=self.p.p1), self.p.ma(period=self.p.p2)self.cross = bt.ind.CrossOver(ma1, ma2)self.orefs = list()if self.p.usebracket:print('-' * 5, 'Using buy_bracket')def next(self):if self.orefs:return  # pending orders do nothingif not self.position:if self.cross > 0.0:  # crossing upclose = self.data.close[0]p1 = close * (1.0 - self.p.limit)p2 = p1 - 0.02 * closep3 = p1 + 0.02 * closevalid1 = datetime.timedelta(self.p.limdays)valid2 = valid3 = datetime.timedelta(self.p.limdays2)if self.p.switchp1p2:p1, p2 = p2, p1valid1, valid2 = valid2, valid1if not self.p.usebracket:o1 = self.buy(exectype=bt.Order.Limit,price=p1,valid=valid1,transmit=False)print('{}: Oref {} / Buy at {}'.format(self.datetime.date(), o1.ref, p1))o2 = self.sell(exectype=bt.Order.Stop,price=p2,valid=valid2,parent=o1,transmit=False)print('{}: Oref {} / Sell Stop at {}'.format(self.datetime.date(), o2.ref, p2))o3 = self.sell(exectype=bt.Order.Limit,price=p3,valid=valid3,parent=o1,transmit=True)print('{}: Oref {} / Sell Limit at {}'.format(self.datetime.date(), o3.ref, p3))self.orefs = [o1.ref, o2.ref, o3.ref]else:os = self.buy_bracket(price=p1, valid=valid1,stopprice=p2, stopargs=dict(valid=valid2),limitprice=p3, limitargs=dict(valid=valid3),)self.orefs = [o.ref for o in os]else:  # in the marketif (len(self) - self.holdstart) >= self.p.hold:pass  # do nothing in this casedef runstrat(args=None):args = parse_args(args)cerebro = bt.Cerebro()# Data feed kwargskwargs = dict()# Parse from/to-datedtfmt, tmfmt = '%Y-%m-%d', 'T%H:%M:%S'for a, d in ((getattr(args, x), x) for x in ['fromdate', 'todate']):if a:strpfmt = dtfmt + tmfmt * ('T' in a)kwargs[d] = datetime.datetime.strptime(a, strpfmt)# Data feeddata0 = bt.feeds.BacktraderCSVData(dataname=args.data0, **kwargs)cerebro.adddata(data0)# Brokercerebro.broker = bt.brokers.BackBroker(**eval('dict(' + args.broker + ')'))# Sizercerebro.addsizer(bt.sizers.FixedSize, **eval('dict(' + args.sizer + ')'))# Strategycerebro.addstrategy(St, **eval('dict(' + args.strat + ')'))# Executecerebro.run(**eval('dict(' + args.cerebro + ')'))if args.plot:  # Plot if requested tocerebro.plot(**eval('dict(' + args.plot + ')'))def parse_args(pargs=None):parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter,description=('Sample Skeleton'))parser.add_argument('--data0', default='./datas/2005-2006-day-001.txt',required=False, help='Data to read in')# Defaults for datesparser.add_argument('--fromdate', required=False, default='',help='Date[time] in YYYY-MM-DD[THH:MM:SS] format')parser.add_argument('--todate', required=False, default='',help='Date[time] in YYYY-MM-DD[THH:MM:SS] format')parser.add_argument('--cerebro', required=False, default='',metavar='kwargs', help='kwargs in key=value format')parser.add_argument('--broker', required=False, default='',metavar='kwargs', help='kwargs in key=value format')parser.add_argument('--sizer', required=False, default='',metavar='kwargs', help='kwargs in key=value format')parser.add_argument('--strat', required=False, default='',metavar='kwargs', help='kwargs in key=value format')parser.add_argument('--plot', required=False, default='',nargs='?', const='{}',metavar='kwargs', help='kwargs in key=value format')return parser.parse_args(pargs)if __name__ == '__main__':runstrat()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/246077.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

银行数据仓库体系实践(3)--数据架构

狭义的数据仓库数据架构用来特指数据分布,广义的数据仓库数据架构还包括数据模型、数据标准和数据治理。即包含相对静态部分如元数据、业务对象数据模型、主数据、共享数据,也包含相对动态部分如数据流转、ETL、整合、访问应用和数据全生命周期管控治理。…

TensorFlow2实战-系列教程2:神经网络分类任务

🧡💛💚TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 1、Mnist数据集 下载mnist数据集: %matplotlib inline from pathlib imp…

项目实战——Qt实现FFmpeg音视频转码器

文章目录 前言一、移植 FFmpeg 相关文件二、绘制 ui 界面三、实现简单的转码四、功能优化1、控件布局及美化2、缩放界面3、实现拖拽4、解析文件5、开启独立线程6、开启定时器7、最终运行效果 五、附录六、资源自取 前言 本文记录使用 Qt 实现 FFmepg 音视频转码器项目的开发过…

【干货】【常用电子元器件介绍】【电阻】(二)--敏感电阻器

声明:本人水平有限,博客可能存在部分错误的地方,请广大读者谅解并向本人反馈错误。   电子电路中除了采用普通电阻器外,还有一些敏感电阻器(如热敏电阻器、压敏电阻器、光敏电阻器等)也被广泛地应用。然而…

【华为 ICT HCIA eNSP 习题汇总】——题目集10

1、以下哪个动态路由协议不能应用在 IPv6 网络中? A、IS-IS B、RIPng C、BGP4 D、OSPFv3 考点:路由技术原理 解析:(A) IS-ISv6 是在 IPv6 环境下,IS-IS 协议进行了相应的扩展和改进,以适应 IPv6…

css中隐藏页面元素的方式(详细讲解)

这里写目录标题 一、前言二、实现方式display:nonevisibility:hiddenopacity:0设置height、width属性为0position:absoluteclip-path小结 三、区别参考文献 一、前言 在平常的样式排版中,我们经常遇到将某个模块隐藏的场景 通过css隐藏元素的方法有很多种&#xf…

vue项目中使用Element多个Form表单同时验证

一、项目需求 在项目中一个页面中需要实现多个Form表单,并在页面提交时需要对多个Form表单进行校验,多个表单都校验成功时才能提交。 二、实现效果 三、多个表单验证 注意项:多个form表单,每个表单上都设置单独的model和ref&am…

matlab对负数开立方根得到虚数的解决方案

问题描述:在matlab中,对负数开立方根,不出意外你将得到虚数。 例如 − 27 3 \sqrt[3]{-27} 3−27 ​,我们知道其实数解是-3,但在matlab中的计算结果如下: 问题原因:matlab中的立方根运算是在…

详细分析Java的树形工具类(含注释)

目录 前言1. 基本框架2. 实战应用 前言 对应的每个子孙属于该父亲,这其实是数据结构的基础知识,那怎么划分怎么归属呢 对应的基本知识推荐如下: 【数据结构】树和二叉树详细分析(全)【数据结构】B树和B树的笔记详细…

vue实现在线Excel表格功能

目录 1.安装x-data-spreadsheet xlsx 2.引入 3.使用 1.安装x-data-spreadsheet xlsx npm i x-data-spreadsheet xlsx2.引入 import zhCN from "x-data-spreadsheet/src/locale/zh-cn"; import Spreadsheet from "x-data-spreadsheet"; import * as X…

Scala基础知识

scala 1、scala简介 ​ scala是运行在JVM上的多范式编程语言,同时支持面向对象和面向函数式编程。 2、scala解释器 要启动scala解释器,只需要以下几步: 按住windows键 r输入scala即可 在scala命令提示窗口中执行:quit,即可退…

mybatis基础知识

title: mybatis的基础知识创建mybatis数据库&#xff0c;创建user表&#xff0c;在里面添加数据 创建空项目&#xff0c;创建maven模块 导入相关的依赖 在pom.xml文件中导入mysql&#xff0c;junit测试&#xff0c;mybatis依赖。 <!--导入mysql依赖--><dependency&g…

四步搞定国赛!快速入门大小模型融合的AI产品开发

前不久&#xff0c;2024中国大学生服务外包创新创业大赛正式启动&#xff01;作为中国高等教育学会“全国普通高校学科竞赛排行榜”竞赛&#xff0c;飞桨赛道已经吸引了超过200位选手报名参赛。 本文旨在助力“A01-基于文心大模型智能阅卷平台设计”赛道选手&#xff0c;更快地…

7.【SpringBoot3】项目部署、属性配置、多环境开发

1. SpringBoot 项目部署 项目完成后&#xff0c;需要部署到服务器上。 SpringBoot 项目需要经过编译打包生成一个 jar 包&#xff08;借助打包插件 spring-boot-maven-plugin&#xff09;&#xff0c;再将该 jar 包发送或拷贝到服务器上&#xff0c;然后就可以通过执行 java …

手机视频压缩怎么压缩?一键瘦身~

现在手机已经成为我们日常生活中必不可少的工具&#xff0c;而在手机的应用领域中&#xff0c;文件的传输和存储是一个非常重要的问题。很多用户都会遇到这样一个问题&#xff0c;那就是在手机上存储的文件太多太大&#xff0c;导致手机存储空间不足&#xff0c;那么怎么在手机…

Typora 无法导出 pdf 问题的解决

目录 问题描述 解决困难 解决方法 问题描述 Windows 下&#xff0c;以前&#xff08;Windows 11&#xff09; Typora 可以顺利较快地由 .md 导出 .pdf 文件&#xff0c;此功能当然非常实用与重要。 然而&#xff0c;有一次电脑因故重装了系统&#xff08;刷机&#xff09;…

SpringMVC 环境搭建入门

SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架&#xff0c;属于SpringFrameWork 的后续产品&#xff0c;已经融合在 Spring Web Flow 中。 SpringMVC 已经成为目前最主流的MVC框架之一&#xff0c;并且随着Spring3.0 的发布&#xff0c;全面…

论述Python中列表、元组、字典和集合的概念

Python列表是用于存储任意数目、任意类型的数据集合&#xff0c;包含多个元素的有序连续的内存空间&#xff0c;是内置可变序列&#xff0c;或者说可以任意修改。在Python中&#xff0c;列表以方括号&#xff08;[ ]&#xff09;形式编写。 Python元组与Python列表类似&#x…

Flink 集成 Debezium Confluent Avro ( format=debezium-avro-confluent )

博主历时三年精心创作的《大数据平台架构与原型实现:数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,京东购书链接:https://item.jd.com/12677623.html,扫描左侧二维…

docker生命周期管理命令

文章目录 前言1、docker create2、docker run2.1、常用选项2.2、系统2.3、网络2.4、健康检查 3、docker start/stop/restart4、docker kill5、docker rm6、docker pause/unpause总结 前言 在云原生时代&#xff0c;Docker已成为必不可少的容器管理工具。通过掌握Docker常用的容…