Backtrader开场作弊

  |  

“发布”1.9.44.116 添加了对 Cheat-On-Open的支持。这似乎是那些全力以赴的人的需求功能,他们在酒吧 close 后进行了计算,但希望与 open 价格相匹配。

当开盘价跳空(上涨或下跌,取决于是否buysell有效)并且现金不足以进行全面运营时,这样的用例就会失败。这将强制代理拒绝该操作。

尽管人们可以尝试使用正[1] 指数方法展望未来,但这需要预加载并不总是可用的数据。

模式:

cerebro = bt.Cerebro(cheat_on_open=True)

这:

  • 激活系统中调用策略next_open中的方法的额外循环, nextstart_open 以及 prenext_open

    已经决定增加一系列方法,以便在常规方法之间明确区分,这些方法的运作依据是所审查的价格不再可用,未来是未知的,并且操作处于作弊模式。

    这也避免了对常规next 方法的 2 次调用。

在方法中xxx_open,以下内容true

  • 指针尚未重新计算,并保持在等效xxx常规方法中上一个周期中last的值

  • 经纪人尚未评估新周期的挂单,可以引入新订单,如果可能的话,将对其进行评估。

请注意:

  • Cerebro 还有一个 broker_coo (缺省: True)参数,告诉 cerebro ,如果 cheat-on-open 已经启动,如果可能的话,它应该尝试在代理中启动它。

    模拟代理有一个名为:coo 的参数和一个将其设置为 set_coo

尝试作弊open

下面的示例具有具有 2 种不同行为的策略:

  • 如果作弊openTrue,则只能从next_open

  • 如果作弊openFalse,则只能从next

在这两种情况下,匹配的价格必须相同

  • 如果没有作弊,订单将在前一天结束时发出,并将与下一个传入价格(即价格)open 匹配

  • 如果作弊,订单将在运行的同一天发出。由于订单是在经纪人评估订单之前发出的,因此它也将与下一个传入价格(价格)open 匹配。

    第二种情况允许计算全押策略的确切赌注,因为可以直接访问当前open 价格。

在这两种情况下

  • 目前 openclose 价格将从打印自 next

定期运行:

$ ./cheat-on-open.py --cerebro cheat_on_open=False

...
2005-04-07 next, open 3073.4 close 3090.72
2005-04-08 next, open 3092.07 close 3088.92
Strat Len 68 2005-04-08 Send Buy, fromopen False, close 3088.92
2005-04-11 Buy Executed at price 3088.47
2005-04-11 next, open 3088.47 close 3080.6
2005-04-12 next, open 3080.42 close 3065.18
...

顺序:

  • 发表于 2005-04-08 之后 close

  • 运行于 2005-04-11open 价格 3088.47

作弊运行:

$ ./cheat-on-open.py --cerebro cheat_on_open=True

...
2005-04-07 next, open 3073.4 close 3090.72
2005-04-08 next, open 3092.07 close 3088.92
2005-04-11 Send Buy, fromopen True, close 3080.6
2005-04-11 Buy Executed at price 3088.47
2005-04-11 next, open 3088.47 close 3080.6
2005-04-12 next, open 3080.42 close 3065.18
...

顺序:

  • 发表于 2005-04-11 之前 open

  • 运行于 2005-04-11open 价格 3088.47

图表上显示的总体结果也是相同的。

结论

open作弊允许在open例如可以精确计算全力以赴场景的赌注。

示例用法

$ ./cheat-on-open.py --help
usage: cheat-on-open.py [-h] [--data0 DATA0] [--fromdate FROMDATE]
                        [--todate TODATE] [--cerebro kwargs] [--broker kwargs]
                        [--sizer kwargs] [--strat kwargs] [--plot [kwargs]]

Cheat-On-Open Sample

optional arguments:
  -h, --help           show this help message and exit
  --data0 DATA0        Data to read in (default:
                       ../../datas/2005-2006-day-001.txt)
  --fromdate FROMDATE  Date[time] in YYYY-MM-DD[THH:MM:SS] format (default: )
  --todate TODATE      Date[time] in YYYY-MM-DD[THH:MM:SS] format (default: )
  --cerebro kwargs     kwargs in key=value format (default: )
  --broker kwargs      kwargs in key=value format (default: )
  --sizer kwargs       kwargs in key=value format (default: )
  --strat kwargs       kwargs in key=value format (default: )
  --plot [kwargs]      kwargs in key=value format (default: )

示例源

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

import argparse
import datetime

import backtrader as bt


class St(bt.Strategy):
    params = dict(
        periods=[10, 30],
        matype=bt.ind.SMA,
    )

    def __init__(self):
        self.cheating = self.cerebro.p.cheat_on_open
        mas = [self.p.matype(period=x) for x in self.p.periods]
        self.signal = bt.ind.CrossOver(*mas)
        self.order = None

    def notify_order(self, order):
        if order.status != order.Completed:
            return

        self.order = None
        print('{} {} Executed at price {}'.format(
            bt.num2date(order.executed.dt).date(),
            'Buy' * order.isbuy() or 'Sell', order.executed.price)
        )

    def operate(self, fromopen):
        if self.order is not None:
            return
        if self.position:
            if self.signal < 0:
                self.order = self.close()
        elif self.signal > 0:
            print('{} Send Buy, fromopen {}, close {}'.format(
                self.data.datetime.date(),
                fromopen, self.data.close[0])
            )
            self.order = self.buy()

    def next(self):
        print('{} next, open {} close {}'.format(
            self.data.datetime.date(),
            self.data.open[0], self.data.close[0])
        )

        if self.cheating:
            return
        self.operate(fromopen=False)

    def next_open(self):
        if not self.cheating:
            return
        self.operate(fromopen=True)


def runstrat(args=None):
    args = parse_args(args)

    cerebro = bt.Cerebro()

    # Data feed kwargs
    kwargs = dict()

    # Parse from/to-date
    dtfmt, 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 feed
    data0 = bt.feeds.BacktraderCSVData(dataname=args.data0, **kwargs)
    cerebro.adddata(data0)

    # Broker
    cerebro.broker = bt.brokers.BackBroker(**eval('dict(' + args.broker + ')'))

    # Sizer
    cerebro.addsizer(bt.sizers.FixedSize, **eval('dict(' + args.sizer + ')'))

    # Strategy
    cerebro.addstrategy(St, **eval('dict(' + args.strat + ')'))

    # Execute
    cerebro.run(**eval('dict(' + args.cerebro + ')'))

    if args.plot:  # Plot if requested to
        cerebro.plot(**eval('dict(' + args.plot + ')'))


def parse_args(pargs=None):
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        description=(
            'Cheat-On-Open Sample'
        )
    )

    parser.add_argument('--data0', default='../../datas/2005-2006-day-001.txt',
                        required=False, help='Data to read in')

    # Defaults for dates
    parser.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()

推荐阅读

相关文章

Backtrader期货展期

并非每个供应商都为可以交易的工具提供连续的未来。有时提供的数据是仍然有效的到期日期的数据,即:仍在交易的日期 这在回溯测试方面并不是很有帮助,因为数据分散在几个不同的仪器上,这些仪器另外...时间重叠。 能够正确地将这些仪器的数据从过去连接到连续的流中,可以减轻疼痛。

Backtrader观察员和统计

在 backtrader 内部运行的策略主要处理数据 和 指针。 数据被添加到Cerebro 实例中,并最终成为策略输入的一部分(解析并用作实例的属性),而指针由策略本身声明和管理。

Backtrader标杆

backtrader 包括 2 种不同类型的对象,可帮助进行跟踪: Observers Analyzers 工单 #89 是关于添加资产基准测试的。明智的是,人们实际上可能有一个策略,即使积极,也低于简单地跟踪资产所能提供的策略。

Backtrader股票筛选

在寻找其他一些东西时,我在StackOverlow家族网站之一上遇到了一个问题:Quantitative Finance aka Quant StackExchange。问题: 它被标记为Python,因此值得一看的是 backtrader 是否能够胜任这项任务。 分析仪本身 该问题似乎适合用于简单的分析器。

Backtrader教程:观察者 - 基准测试

工单 #89 是关于针对资产添加基准测试的。明智的是,人们实际上可能有一个策略,即使积极,也低于简单地跟踪资产所能提供的策略。

数据多时间帧

有时投资决策是使用不同的时间框架做出的: 每周评估趋势 每天执行条目 或者5分钟对60分钟。 这意味着需要将多个时间帧的数据组合在 backtrader 中以支援此类组合。 对它的本机支持已经内置。

Backtrader教程:佣金计划 - 信贷利息

在某些情况下,真实经纪人的现金金额可能会减少,因为资产操作包括利率。例子: 卖空股票 交易所买卖基金包括多头和空头 该费用直接与经纪人帐户中的现金余额挂钩。但它仍然可以被视为佣金计划的一部分。因此,它已被建模为 backtrader。

Backtrader教程:尺寸调整器

智能质押 策略提供了交易方法,即:buy和 sell close。

Backtrader卡尔曼等

注意 对以下指令的支持从提交开始 发布1.9.30.x 将是包含它的第1个版本 。 backtrader的原始目标之一是成为纯python,即:仅使用标准发行版中可用的软件包。只有一个例外是matplotlib在没有重新发明轮子的情况下进行绘图。

Backtrader 多数据范例

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