Backtrader交易基础

查看账户情况:

class TestStrategy(bt.Strategy):def next(self):print('当前可用资金', self.broker.getcash())print('当前总资产', self.broker.getvalue())print('当前持仓量', self.broker.getposition(self.data).size)print('当前持仓成本', self.broker.getposition(self.data).price)# 也可以直接获取持仓print('当前持仓量', self.getposition(self.data).size)print('当前持仓成本', self.getposition(self.data).price)# 注:getposition() 需要指定具体的标的数据集

滑点设置:

# 方式1:通过 BackBroker 类中的 slip_perc 参数设置百分比滑点
cerebro.broker = bt.brokers.BackBroker(slip_perc=0.0001)
# 方式2:通过调用 brokers 的 set_slippage_perc 方法设置百分比滑点
cerebro.broker.set_slippage_perc(perc=0.0001)# 方式1:通过 BackBroker 类中的 slip_fixed 参数设置固定滑点
cerebro.broker = bt.brokers.BackBroker(slip_fixed=0.001)
# 方式2:通过调用 brokers 的 set_slippage_fixed 方法设置固定滑点
cerebro.broker = cerebro.broker.set_slippage_fixed(fixed=0.001)

参数说明:

有关滑点的其他设置
slip_open:是否对开盘价做滑点处理,该参数在 BackBroker() 类中默认为 False,在 set_slippage_perc 和set_slippage_fixed 方法中默认为 True;
slip_match:是否将滑点处理后的新成交价与成交当天的价格区间 low ~ high 做匹配,如果为 True,则根据新成交价重新匹配调整价格区间,确保订单能被执行;如果为 False,则不会与价格区间做匹配,订单不会执行,但会在下一日执行一个空订单;默认取值为 True;
slip_out:如果新成交价高于最高价或低于最高价,是否以超出的价格成交,如果为 True,则允许以超出的价格成交;如果为 False,实际成交价将被限制在价格区间内  low ~ high;默认取值为 False;
slip_limit:是否对限价单执行滑点,如果为 True,即使 slip_match 为Fasle,也会对价格做匹配,确保订单被执行;如果为 False,则不做价格匹配;默认取值为 True。

# 情况1:
set_slippage_fixed(fixed=0.35,slip_open=False,slip_match=True,slip_out=False)
# 由于 slip_open=False ,不会对开盘价做滑点处理,所以仍然以原始开盘价 32.63307367 成交# 情况2:
set_slippage_fixed(fixed=0.35,slip_open=True,slip_match=True,slip_out=False)# 情况3:
set_slippage_fixed(fixed=0.35,slip_open=True,slip_match=True,slip_out=True)
# 滑点调整的新成交价为 32.63307367+0.35 = 32.98307367,超出了当天最高价 32.94151482
# 允许做价格匹配 slip_match=True, 而且运行以超出价格区间的新成交价执行 slip_out=True
# 最终以新成交价 32.98307367 成交# 情况4:
set_slippage_fixed(fixed=0.35,slip_open=True,slip_match=False,slip_out=True)
# 滑点调整的新成交价为 32.63307367+0.35 = 32.98307367,超出了当天最高价 32.94151482
# 由于不进行价格匹配 slip_match=False,新成交价超出价格区间无法成交
# 2019-01-17 这一天订单不会执行,但会在下一日 2019-01-18 执行一个空订单
# 再往后的 2019-07-02,也未执行订单,下一日 2019-07-03 执行空订单
# 即使 2019-07-03的 open 39.96627412+0.35 < high 42.0866713 满足成交条件,也不会补充成交

交易税费管理

股票:目前 A 股的交易费用分为 2 部分:佣金和印花税,
其中佣金双边征收,不同证券公司收取的佣金各不相同,一般在 0.02%-0.03% 左右,单笔佣金不少于 5 元;
印花税只在卖出时收取,税率为 0.1%。


期货:期货交易费用包括交易所收取手续费和期货公司收取佣金 2 部分,交易所手续费较为固定,
不同期货公司佣金不一致,而且不同期货品种的收取方式不相同,有的按照固定费用收取,有的按成交金额的固定百分比收取:
合约现价*合约乘数*手续费费率。除了交易费用外,期货交易时还需上交一定比例的保证金 。

Backtrader 也提供了多种交易费设置方式,既可以简单的通过参数进行设置,也可以结合交易条件自定义费用函数:

根据交易品种的不同,Backtrader 将交易费用分为 股票 Stock-like 模式和期货 Futures-like 种模式;
根据计算方式的不同,Backtrader 将交易费用分为 PERC 百分比费用模式 和 FIXED 固定费用模式 ;

Stock-like 模式与 PERC 百分比费用模式对应,期货 Futures-like 与 FIXED 固定费用模式对应;

在设置交易费用时,最常涉及如下 3 个参数:

commission:手续费 / 佣金;

mult:乘数;

margin:保证金 / 保证金比率 。

双边征收:买入和卖出操作都要收取相同的交易费用 。

cerebro.broker.setcommission(# 交易手续费,根据margin取值情况区分是百分比手续费还是固定手续费commission=0.0,# 期货保证金,决定着交易费用的类型,只有在stocklike=False时起作用margin=None,# 乘数,盈亏会按该乘数进行放大mult=1.0,# 交易费用计算方式,取值有:# 1.CommInfoBase.COMM_PERC 百分比费用# 2.CommInfoBase.COMM_FIXED 固定费用# 3.None 根据 margin 取值来确定类型commtype=None,# 当交易费用处于百分比模式下时,commission 是否为 % 形式# True,表示不以 % 为单位,0.XX 形式;False,表示以 % 为单位,XX% 形式percabs=True,# 是否为股票模式,该模式通常由margin和commtype参数决定# margin=None或COMM_PERC模式时,就会stocklike=True,对应股票手续费;# margin设置了取值或COMM_FIXED模式时,就会stocklike=False,对应期货手续费stocklike=False,# 计算持有的空头头寸的年化利息# days * price * abs(size) * (interest / 365)interest=0.0,# 计算持有的多头头寸的年化利息interest_long=False,# 杠杆比率,交易时按该杠杆调整所需现金leverage=1.0,# 自动计算保证金# 如果False,则通过margin参数确定保证金# 如果automargin<0,通过mult*price确定保证金# 如果automargin>0,如果automargin*price确定保证金automargin=False,# 交易费用设置作用的数据集(也就是作用的标的)# 如果取值为None,则默认作用于所有数据集(也就是作用于所有assets)name=None)

从上述各参数的含义和作用可知,margin 、commtype、stocklike 存在 2 种默认的配置规则:股票百分比费用、期货固定费用,具体如下:
第 1 条规则:未设置 margin(即 margin 为 0 / None / False)→ commtype 会指向 COMM_PERC 百分比费用 → 底层的 _stocklike 属性会设置为 True → 对应的是“股票百分比费用”。
所以如果想为股票设置交易费用,就令 margin = 0 / None / False,或者令 stocklike=True;

第 2 条规则:为 margin 设置了取值 →   commtype 会指向 COMM_FIXED 固定费用 → 底层的 _stocklike 属性会设置为 False → 对应的是“期货固定费用”,因为只有期货才会涉及保证金。
所以如果想为期货设置交易费用,就需要设置 margin,此外还需令 stocklike=True,margin 参数才会起作用 。

自定义交易费用的例子

# 自定义期货百分比费用
class CommInfo_Fut_Perc_Mult(bt.CommInfoBase):params = (('stocklike', False), # 指定为期货模式('commtype', bt.CommInfoBase.COMM_PERC), # 使用百分比费用('percabs', False), # commission 以 % 为单位)def _getcommission(self, size, price, pseudoexec):# 计算交易费用return (abs(size) * price) * (self.p.commission/100) * self.p.mult# pseudoexec 用于提示当前是否在真实统计交易费用# 如果只是试算费用,pseudoexec=False# 如果是真实的统计费用,pseudoexec=Truecomminfo = CommInfo_Fut_Perc_Mult(commission=0.1, # 0.1%mult=10,margin=2000) # 实例化
cerebro.broker.addcommissioninfo(comminfo)# 上述自定义函数,也可以通过 setcommission 来实现
cerebro.broker.setcommission(commission=0.1, #0.1%mult=10,margin=2000,percabs=False,commtype=bt.CommInfoBase.COMM_PERC,stocklike=False)

下面是考虑佣金和印花税的股票百分比费用:

class StockCommission(bt.CommInfoBase):params = (('stocklike', True), # 指定为期货模式('commtype', bt.CommInfoBase.COMM_PERC), # 使用百分比费用模式('percabs', True), # commission 不以 % 为单位('stamp_duty', 0.001),) # 印花税默认为 0.1%# 自定义费用计算公式def _getcommission(self, size, price, pseudoexec):if size > 0: # 买入时,只考虑佣金return abs(size) * price * self.p.commissionelif size < 0: # 卖出时,同时考虑佣金和印花税return abs(size) * price * (self.p.commission + self.p.stamp_duty)else:return 0

成交量限制管理

形式1:bt.broker.fillers.FixedSize(size) 

通过 FixedSize() 方法设置最大的固定成交量:size,该种模式下的成交量限制规则如下:

订单实际成交量的确定规则:取(size、订单执行那天的 volume 、订单中要求的成交数量)中的最小者;

订单执行那天,如果订单中要求的成交数量无法全部满足,则只成交部分数量。第二天不会补单。

# 通过 BackBroker() 类直接设置
cerebro = Cerebro()
filler = bt.broker.fillers.FixedSize(size=xxx)
newbroker = bt.broker.BrokerBack(filler=filler)
cerebro.broker = newbroker# 通过 set_filler 方法设置
cerebro = Cerebro()
cerebro.broker.set_filler(bt.broker.fillers.FixedSize(size=xxx))# self.order = self.buy(size=2000) # 每次买入 2000 股
# cerebro.broker.set_filler(bt.broker.fillers.FixedSize(size=3000)) # 固定最大成交量

形式2:bt.broker.fillers.FixedBarPerc(perc)

通过 FixedBarPerc(perc) 将 订单执行当天 bar 的总成交量 volume 的 perc % 设置为最大的固定成交量,该模式的成交量限制规则如下:

订单实际成交量的确定规则:取 (volume * perc /100、订单中要求的成交数量) 的 最小者;
订单执行那天,如果订单中要求的成交数量无法全部满足,则只成交部分数量。

# 通过 BackBroker() 类直接设置
cerebro = Cerebro()
filler = bt.broker.fillers.FixedBarPerc(perc=xxx)
newbroker = bt.broker.BrokerBack(filler=filler)
cerebro.broker = newbroker# 通过 set_filler 方法设置
cerebro = Cerebro()
cerebro.broker.set_filler(bt.broker.fillers.FixedBarPerc(perc=xxx))
# perc 以 % 为单位,取值范围为[0.0,100.0]# self.order = self.buy(size=2000) # 以下一日开盘价买入2000股
# cerebro.broker.set_filler(bt.broker.fillers.FixedBarPerc(perc=50))

形式3:bt.broker.fillers.BarPointPerc(minmov=0.01,perc=100.0)

BarPointPerc() 在考虑了价格区间的基础上确定成交量,在订单执行当天,成交量确定规则为:

通过 minmov 将 当天 bar 的价格区间 low ~ high 进行均匀划分,得到划分的份数:

part =  (high -low +minmov)  // minmov  (向下取整)

再对当天 bar 的总成交量 volume 也划分成相同的份数 part ,这样就能得到每份的平均成交量:

volume_per = volume // part 

最终,volume_per * (perc / 100)就是允许的最大成交量,实际成交时,对比订单中要求的成交量,就可以得到最终实际成交量

实际成交量 = min ( volume_per * (perc / 100), 订单中要求的成交数量 )

# 通过 BackBroker() 类直接设置
cerebro = Cerebro()
filler = bt.broker.fillers.BarPointPerc(minmov=0.01,perc=100.0)
newbroker = bt.broker.BrokerBack(filler=filler)
cerebro.broker = newbroker# 通过 set_filler 方法设置
cerebro = Cerebro()
cerebro.broker.set_filler(bt.broker.fillers.BarPointPerc(minmov=0.01,perc=100.0))
# perc 以 % 为单位,取值范围为[0.0,100.0]# self.order = self.buy(size=2000) # 以下一日开盘价买入2000股# cerebro.broker.set_filler(bt.broker.fillers.BarPointPerc(minmov=0.1, perc=50)) # 表示 50%

交易时机管理
对于交易订单生成和执行时间,Backtrader 默认是 “当日收盘后下单,次日以开盘价成交”,这种模式在回测过程中能有效避免使用未来数据。
但对于一些特殊的交易场景,比如“all_in”情况下,当日所下订单中的数量是用当日收盘价计算的(总资金 / 当日收盘价),次日以开盘价执行订单时,
如果开盘价比昨天的收盘价提高了,就会出现可用资金不足的情况。
为了应对一些特殊交易场景,Backtrader 还提供了一些 cheating 式的交易时机模式:Cheat-On-Open 和 Cheat-On-Close。

Cheat-On-Open

Cheat-On-Open 是“当日下单,当日以开盘价成交”模式,在该模式下,Strategy 中的交易逻辑不再写在 next() 方法里,而是写在特定的 next_open()、nextstart_open() 、prenext_open() 函数中,具体设置可参考如下案例:

方式1:bt.Cerebro(cheat_on_open=True);
方式2:cerebro.broker.set_coo(True);
方式3:BackBroker(coo=True)。

Cheat-On-Close

Cheat-On-Close 是“当日下单,当日以收盘价成交”模式,在该模式下,Strategy 中的交易逻辑仍写在 next() 中,具体设置如下:

方式1:cerebro.broker.set_coc(True);
方式2:BackBroker(coc=True)

class TestStrategy(bt.Strategy):......def next(self):# 取消之前未执行的订单if self.order:self.cancel(self.order)# 检查是否有持仓if not self.position:# 10日均线上穿5日均线,买入if self.crossover > 0:print('{} Send Buy, open {}'.format(self.data.datetime.date(),self.data.open[0]))self.order = self.buy(size=100) # 以下一日开盘价买入100股# # 10日均线下穿5日均线,卖出elif self.crossover < 0:self.order = self.close() # 平仓,以下一日开盘价卖出......# 实例化大脑
cerebro= bt.Cerebro()
.......
# 当日下单,当日收盘价成交
cerebro.broker.set_coc(True)

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

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

相关文章

IP地址分类/IP地址10开头和172开头和192开头的区别

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 IP地址分类/IP地址10开头和172开头和192开头的区别/判断是否同一网段 简单来说在公司或企业内部看到的就基本都是内网IP&#xff0c;AB…

Redis数据结构之简单动态字符串SDS

Redis的底层数据结构非常多&#xff0c;其中包括SDS、ZipList、SkipList、LinkedList、HashTable、Intset等。如果你对Redis的理解还只停留在get、set的水平的话&#xff0c;是远远不足以应对面试提问的。本文简单介绍了Redis底层最重要的数据结构 - 简单动态字符串&#xff08…

Centos7 安装OpenTSDB

Centos7 安装OpenTSDB https://www.imzcy.cn/1697.html转载于:https://www.cnblogs.com/RHadoop-Hive/p/10563385.html

职场潜规则冷思考:别让老板“杀”了你

一位3年前共事过的同事走了&#xff0c;就在他以200多万的房贷代价拿到大门钥匙的时候&#xff0c;猝然倒在新房的楼梯上。另一个曾经在同一战壕里冲锋陷阵的同事被老板辞掉了&#xff0c;兢兢业业&#xff0c;起早贪黑&#xff0c;竟然没有熬过35岁下岗这一关&#xff0c;这时…

Backtrader交易基础2

成交价格确定&#xff1a; Order.Market 市价单&#xff0c;以当时市场价格成交的订单&#xff0c;不需要自己设定价格。市价单能被快速达成交易&#xff0c;防止踏空&#xff0c;尽快止损/止盈&#xff1b; 按下一个 Bar &#xff08;即生成订单的那个交易日的下一个交易日&…

windows 小技巧

2019独角兽企业重金招聘Python工程师标准>>> 桌面图标显示不全、图标呈现白色方块 ie4uinit -show 关闭占用指定端口的进程 获取进程: netstat -ano | findstr 端口号关闭进程&#xff1a;taskkill -f -pid 进程号文件被占用 打开任务管理器&#xff0c;切换到 性能…

进一步了解 apt-get 的几个命令

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 用 apt-get 也很久了&#xff0c;没多想它的实现&#xff0c;最近遇到 gstreamer 装不上的问题&#xff0c;才多看看了它 apt-get 就是…

java学习笔记20(Arraylist复习,Collection接口方法,迭代器,增强型for循环)

集合&#xff1a;集合是Java提供的一种容器&#xff0c;可以用来存储多个数据&#xff1b; 集合与数组的区别&#xff1a;集合的长度是可变的&#xff0c;数组的长度是固定的 集合中存储的数据必须是引用类型数据&#xff1b; ArrayList回顾&#xff1a; public class Person {…

backtrader数据基础

cerebro bt.Cerebro() cerebro.addstrategy(TestStrategy2) codes[600862.SH,300326.SZ,300394.SZ] #加载最近两日交易数据 for code in codes:feed Addmoredata(dataname get_data(code,20200506),namecode)cerebro.adddata(feed) cerebro.run() 数据查看&#xff1a; cl…

谈判学:三招了解对方底线

导读&#xff1a;谈判者都希望能了解对方的底线&#xff0c;最直接的一招就是将对手变成“朋友”&#xff0c;只是这种“内奸法”毕竟不是常规之法。大多数情况下&#xff0c;谈判双方也不可能像《无间道》一样在对方阵营安放卧底&#xff0c;但是我们完全可以通过一些办法来揣…

JSLint检测Javascript语法规范

前端javascript代码编写中&#xff0c;有一个不错的工具叫JSLint&#xff0c;可以检查代码规范化&#xff0c;压缩JS&#xff0c;CSS等&#xff0c;但是他的语法规范检查个人觉得太“苛刻”了&#xff0c;会提示各种各样的问题修改建议&#xff0c;有时候提示的信息我们看的莫名…

Apt 命令解说(apt-get update、apt-cache search package、apt-get install package、apt-get remove )

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 高级打包工具&#xff08;英语&#xff1a;Advanced Packaging Tools&#xff0c;缩写为APT&#xff09;是Debian及其派生发行版的软件包…

SQL SERVER 2012 AlwaysOn - 维护篇 03

搭建 AlwaysOn 是件非常繁琐的工作&#xff0c;需要从两方面考虑&#xff0c;操作系统层面和数据库层面&#xff0c;AlwaysOn 非常依赖于操作系统&#xff0c;域控&#xff0c;群集&#xff0c;节点等概念&#xff1b; DBA 不但要熟悉数据库也要熟悉操作系统的一些概念&#xf…

指标研究与多周期

哪些地方会用到指标 &#xff1f; 回顾一下 Backtrader 的主要功能模块和回测流程&#xff08;见&#xff1a;Backtrader 来了&#xff01;&#xff09;可以发现&#xff0c;只有在编写策略Strategy 时才会涉及到指标的计算和使用&#xff0c;而且是 Strategy 中的 __init__()…

区块链BAAS平台:公共或私人区块链编程以用于各种用途

2019独角兽企业重金招聘Python工程师标准>>> 人们可以为公共或私人区块链编程以用于各种用途。理论上&#xff0c;我认为牺牲权力下放的方面可以解决区块链技术背后的许多当前问题。区块链仍然可以包容&#xff0c;而不是分散。这如何解决当前的一些问题&#xff1f…

CURL 是什么

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 cURL是一个利用URL语法在命令行下工作的文件传输工具&#xff0c;1997年首次发行。 它支持文件上传和下载&#xff0c;所以是综合传输工…

易用性问题回复

针对淘宝网为例&#xff0c;以一次完整的购物流程为背景&#xff0c;我们分析了在淘宝网中的一些易用性的体现&#xff0c;主要场景如下图所示: 在本场景中&#xff0c;新用户下载淘宝app时&#xff0c;第一次打开应用&#xff0c;淘宝app会出现新手指引&#xff0c;教会用户如…

易盛极星期货量化教学

我目前量化实盘做期货交易用的是这个软件。主要就是因为它可以做套利合约&#xff0c;还有就是国企的外包&#xff0c;安全&#xff08;vnpy的狗咬狗害怕&#xff09;。 策略模板&#xff1a; 设置全局参数变量&#xff1a; #导入包 import talib #选择合约代码 code1 #设…

eBay是如何进行大数据集元数据发现的

很多大数据系统每天都会收集数PB的数据。这类系统通常主要用于查询给定时间范围内的原始数据记录&#xff0c;并使用了多个数据过滤器。但是&#xff0c;要发现或识别存在于这些大型数据集中的唯一属性可能很困难。 在大型数据集上执行运行时聚合&#xff08;例如应用程序在特定…

职业发展 先“立功”还是先“安内”?

导读&#xff1a;职业生涯更上一层楼&#xff0c;章良踌躇满志&#xff0c;想在短期内建功立业&#xff0c;奠定江湖地位。但他清楚&#xff0c;自己运筹中的分公司服务升级计划&#xff0c;对公司整体和自己的职业生涯都非常有利&#xff0c;却将不可避免地转移老将掌握的部分…