Backtrader佣金计划

  |  

backtrader 的诞生是出于必要。我自己的...有一种感觉,我控制着自己的回溯测试平台,可以尝试新的想法。但是,在这样做并且从一开始就完全 open 采购它时,很明显它必须有一种方法来满足他人的需求和愿望。

作为未来的交易者,我本可以选择基于点的计算和每轮佣金的固定价格,但这将是一个错误。

注意

7月31, 2015

使用新添加的操作/交易通知跟进帖子,修复交易损益数字的绘图,并避免手动计算,如下面的示例所示

提高佣金:股票与期货

相反,backtrader 它提供了使用常规的基于%大小/价格的方案和固定价格/点方案的可能性。选择权在您手中。

不可知论

在继续之前,让我们记住,backtrader 尝试对数据所代表的内容保持不可知论。不同的佣金方案可以应用于同一数据集。

让我们看看如何做到这一点。

使用代理快捷方式

这使最终用户远离CommissionInfo 对象,因为可以使用单个函数调用创建/设置佣金方案。在常规 cerebro 创建/设置过程中,只需在成员变量上添加对 setcomission 成员变量的 broker 调用即可。以下电话会议为 Eurostoxx50 期货在与交互经纪商合作时设置了通常的佣金方案:

cerebro.broker.setcommission(commission=2.0, margin=2000.0, mult=10.0)

由于大多数用户通常只测试一台仪器,因此仅此而已。如果您已经对data feed给出了 aname,因为图表上同时考虑了多个工具,则可以稍微扩展此调用,如下所示:

cerebro.broker.setcommission(commission=2.0, margin=2000.0, mult=10.0,
name='Eurostoxxx50')

在这种情况下,此即时佣金计划仅适用于名称匹配的工具Eurostoxx50

设置委托参数的含义

  • commission (默认值:0.0)

    以绝对或百分比形式表示每个操作 成本的货币单位。

    在上面的例子中,abuy 的每张合约为2.0欧元,每张合约为 sell2.0欧元。

    这里的重要问题是何时使用绝对值或百分比值。

    • 如果margin 计算结果为 False (例如,它是 False,0或None),则将考虑 commission 表示操作值的 pricesize 分比

    • 如果margin 是其他东西,则认为操作发生在类似仪器上 futures ,并且是 commissionsize 张合约的固定价格

  • margin (默认值:无)

    使用futures 类似工具操作时所需的保证金。如上文所述

    • 如果设置了nomargin,则将commission理解为以百分比表示,并应用于 price \* sizebuy sell 操作的组件

    • 如果设置了 amargin,则 commission 将理解为一个固定值,该值乘以 或 sell 操作的sizebuy分量

  • mult (默认值:1.0)

    对于future 类似的工具,这决定了乘法器应用于损益计算。

    这就是期货同时具有吸引力和风险的原因。

  • name (默认值:无)

    将佣金方案的应用限制在工具匹配name

    这可以在创建 data feed期间设置。

    如果未设置,该方案将适用于系统中存在的任何数据。

现在有两个例子:股票与期货

上面的期货例子:

cerebro.broker.setcommission(commission=2.0, margin=2000.0, mult=10.0)

股票示例:

cerebro.broker.setcommission(commission=0.005)  # 0.5% of the operation value

创建永久金计划

可以通过直接使用类来创建更永久的CommissionInfo 佣金计划。用户可以选择在以下位置使用此定义:

from bt import CommissionInfo

commEurostoxx50 = CommissionInfo(commission=2.0, margin=2000.0, mult=10.0)

稍后在另一个Python模块addcommissioninfo中应用它:

from mycomm import commEurostoxx50

...

cerebro.broker.addcomissioninfo(commEuroStoxx50, name='Eurostoxxx50')

CommissionInfo是一个对象,它像环境中backtrader的其他对象一params样使用声明。因此,上述内容也可以表示为:

from bt import CommissionInfo

class CommEurostoxx50(CommissionInfo):
    params = dict(commission=2.0, margin=2000.0, mult=10.0)

稍后:

from mycomm import CommEurostoxx50

...

cerebro.broker.addcomissioninfoCommEuroStoxx50(), name='Eurostoxxx50')

现在是与SMA分频器的「真实」比较

使用SimpleMovingAverage交叉作为进入/退出信号,相同的数据集将使用futures 类似的佣金方案进行测试,然后使用类似的佣金方案进行测试 stocks

注意

期货头寸不仅可以给出进入/退出行为,还可以在每次情况下给出反转行为。但这个例子是关于比较佣金方案的。

代码(完整策略请参见底部)是相同的,可以在定义策略之前选择方案。

futures_like = True

if futures_like:
    commission, margin, mult = 2.0, 2000.0, 10.0
else:
    commission, margin, mult = 0.005, None, 1

只需设置为futures_likefalse以使用stocks类似方案运行。

添加了一些 logging 代码来评估不同佣金计划的影响。让我们只关注前 2 个操作。

对于期货:

2006-03-09, BUY CREATE, 3757.59
2006-03-10, BUY EXECUTED, Price: 3754.13, Cost: 2000.00, Comm 2.00
2006-04-11, SELL CREATE, 3788.81
2006-04-12, SELL EXECUTED, Price: 3786.93, Cost: 2000.00, Comm 2.00
2006-04-12, OPERATION PROFIT, GROSS 328.00, NET 324.00
2006-04-20, BUY CREATE, 3860.00
2006-04-21, BUY EXECUTED, Price: 3863.57, Cost: 2000.00, Comm 2.00
2006-04-28, SELL CREATE, 3839.90
2006-05-02, SELL EXECUTED, Price: 3839.24, Cost: 2000.00, Comm 2.00
2006-05-02, OPERATION PROFIT, GROSS -243.30, NET -247.30

对于股票:

2006-03-09, BUY CREATE, 3757.59
2006-03-10, BUY EXECUTED, Price: 3754.13, Cost: 3754.13, Comm 18.77
2006-04-11, SELL CREATE, 3788.81
2006-04-12, SELL EXECUTED, Price: 3786.93, Cost: 3786.93, Comm 18.93
2006-04-12, OPERATION PROFIT, GROSS 32.80, NET -4.91
2006-04-20, BUY CREATE, 3860.00
2006-04-21, BUY EXECUTED, Price: 3863.57, Cost: 3863.57, Comm 19.32
2006-04-28, SELL CREATE, 3839.90
2006-05-02, SELL EXECUTED, Price: 3839.24, Cost: 3839.24, Comm 19.20
2006-05-02, OPERATION PROFIT, GROSS -24.33, NET -62.84

第 1 操作具有以下价格:

  • 买入(运行)-> 3754.13 / 卖出(运行)-> 3786.93

    • 期货损益(带佣金):324.0

    • 股票盈亏(含佣金):-4.91

    嘿!!佣金已经完全吞噬了运营的任何利润,stocks 但只意味着对运营的 futures 一个小小的影响。

第 2 操作:

  • 买入(运行)-> 3863.57 / 卖出(运行)-> 3389.24

    • 期货损益(含佣金):-247.30

    • 股票损益(含佣金):-62.84

    对于这种负操作,咬合已经明智地更大了futures

但:

  • 期货累计净损益:324.00 + (-247.30) = 76.70

  • 股票累计净损益: (-4.91) + (-62.84) = -67.75

累积效应可以在下面的图表上看到,在那里也可以看出,在全年结束时,期货产生了更大的利润,但也遭受了更大的回撤(在水下更深)

但重要的是:是否futures stocks ... 它可以进行回溯测试。

期货佣金

股票佣金

代码

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import backtrader as bt
import backtrader.feeds as btfeeds
import backtrader.indicators as btind


futures_like = True

if futures_like:
    commission, margin, mult = 2.0, 2000.0, 10.0
else:
    commission, margin, mult = 0.005, None, 1


class SMACrossOver(bt.Strategy):
    def log(self, txt, dt=None):
        ''' Logging function fot this strategy'''
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(), txt))

    def notify(self, order):
        if order.status in [order.Submitted, order.Accepted]:
            # Buy/Sell order submitted/accepted to/by broker - Nothing to do
            return

        # Check if an order has been completed
        # Attention: broker could reject order if not enougth cash
        if order.status in [order.Completed, order.Canceled, order.Margin]:
            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
                self.opsize = order.executed.size
            else:  # Sell
                self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                         (order.executed.price,
                          order.executed.value,
                          order.executed.comm))

                gross_pnl = (order.executed.price - self.buyprice) * \
                    self.opsize

                if margin:
                    gross_pnl *= mult

                net_pnl = gross_pnl - self.buycomm - order.executed.comm
                self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                         (gross_pnl, net_pnl))

    def __init__(self):
        sma = btind.SMA(self.data)
        # > 0 crossing up / < 0 crossing down
        self.buysell_sig = btind.CrossOver(self.data, sma)

    def next(self):
        if self.buysell_sig > 0:
            self.log('BUY CREATE, %.2f' % self.data.close[0])
            self.buy()  # keep order ref to avoid 2nd orders

        elif self.position and self.buysell_sig < 0:
            self.log('SELL CREATE, %.2f' % self.data.close[0])
            self.sell()


if __name__ == '__main__':
    # Create a cerebro entity
    cerebro = bt.Cerebro()

    # Add a strategy
    cerebro.addstrategy(SMACrossOver)

    # Create a Data Feed
    datapath = ('../datas/2006-day-001.txt')
    data = bt.feeds.BacktraderCSVData(dataname=datapath)

    # Add the Data Feed to Cerebro
    cerebro.adddata(data)

    # set commission scheme -- CHANGE HERE TO PLAY
    cerebro.broker.setcommission(
        commission=commission, margin=margin, mult=mult)

    # Run over everything
    cerebro.run()

    # Plot the result
    cerebro.plot()

推荐阅读

相关文章

Backtrader规范与非规范

这个问题或多或少地出现了几次:这样: backtrader如何最好/规范地实现这一点或那样? 作为 backtrader 的目标之一,可以灵活地 支持尽可能多的情况和用例,答案很简单:“至少在几种方式上”。

Backtrader教程:分析仪

无论是回溯测试还是交易,能够分析交易系统的性能是了解是否不仅获得了利润,而且是否在风险太大的情况下实现了利润,或者与参考资产(或无风险资产)相比,是否真的值得付出努力的关键。 这就是对象家族的用武之Analyzer 地:提供对所发生事件甚至实际发生的事情的分析。

Backtrader教程:指针 - 开发

如果必须开发任何东西(除了一个或多个获胜策略之外),那么这个东西就是一个自定义指针。 根据作者的说法,平台内的这种开发很容易。 需要满足以下条件: 从指针派生的类(直接或从现有的子类派生) 定义它将保持lines 指针必须至少具有 1 line。

Backtrader教程:日志记录 - 编写器

将以下内容写出到流中: csv 流,

Backtrader绘制日期范围

该版本1.9.31.x 增加了制作部分绘图的功能。 使用策略实例中保存的完整时间戳数组的索引 或者使用实际datetime.date 或 datetime.datetime 实例来限制必须绘制的内容。 一切都超过标准cerebro.plot。

Backtrader教程:筛检程序

此功能是 backtrader 的相对较新的补充,必须安装到已经存在的内部结构中。这使得它不像希望的那样灵活且100%功能齐全,但在许多情况下它仍然可以达到目的。 尽管该实现试图允许随插即用的筛检程序链接,但预先存在的内部结构使得很难确保始终可以实现。因此,某些筛选器可能是链接的,而其他一些筛选器可能不是。

Backtrader教程:Cerebro - 优化 - 改进

backtrader版本1.8.12.99改进了在多处理过程中管理data feeds和结果的方式。

Backtrader节省内存

1.3.1.92版本已经重新设计并完全实现了以前到位的内存节省方案,尽管没有太多的吹捧和使用。

Backtrader教程:经纪商

经纪商仿真器该模拟支持不同的订单类型,根据当前现金检查提交的订单现金需求,跟踪每次反复运算的cerebro 现金和价值,并在不同数据上保持当前位置。

Backtrader 多数据范例

社区中的几个主题似乎以如何跟踪订单为导向,特别是当几个data feeds在起作用时,还包括当多个订单一起工作时,