Skip to content

跨越数字

原文: https://www.backtrader.com/blog/posts/2017-02-04-crossing-over-numbers/crossing-over-numbers/

已通过发布反向交易者1.9.27.105纠正了疏忽。这是一个疏忽,因为拼图的所有部分都已就位,但激活并非在所有角落进行。

该机制使用一个名为_mindatas的属性,因此我们将其命名为:mindatas

社区提出了这个问题,但答案并不十分正确。请参见此处的对话:

即使对话是关于其他事情的,这个问题也可以很快得到回答:“嘿,它应该真的有用!”。但是现在谁有时间考虑一个恰当的、周到的答案。

让我们考虑使用一个普通的旧数字参数的用例。像这样的

mycrossover = bt.ind.CrossOver(bt.ind.RSI(), 50.0) 

这会像在

Traceback (most recent call last):
  File "./cross-over-num.py", line 114, in <module>
    runstrat()
  File "./cross-over-num.py", line 70, in runstrat
    cerebro.run(**eval('dict(' + args.cerebro + ')'))
  File "d:\dro\01-docs\01-home\src\backtrader\backtrader\cerebro.py", line 810, in run
    runstrat = self.runstrategies(iterstrat)
  File "d:\dro\01-docs\01-home\src\backtrader\backtrader\cerebro.py", line 878, in runstrategies
    strat = stratcls(*sargs, **skwargs)
  File "d:\dro\01-docs\01-home\src\backtrader\backtrader\metabase.py", line 87, in __call__
    _obj, args, kwargs = cls.doinit(_obj, *args, **kwargs)
  File "d:\dro\01-docs\01-home\src\backtrader\backtrader\metabase.py", line 77, in doinit
    _obj.__init__(*args, **kwargs)
  File "./cross-over-num.py", line 35, in __init__
    bt.ind.CrossOver(bt.ind.RSI(), 50)
  File "d:\dro\01-docs\01-home\src\backtrader\backtrader\indicator.py", line 53, in __call__
    return super(MetaIndicator, cls).__call__(*args, **kwargs)
  File "d:\dro\01-docs\01-home\src\backtrader\backtrader\metabase.py", line 87, in __call__
    _obj, args, kwargs = cls.doinit(_obj, *args, **kwargs)
  File "d:\dro\01-docs\01-home\src\backtrader\backtrader\metabase.py", line 77, in doinit
    _obj.__init__(*args, **kwargs)
 Typeerror: __init__() takes exactly 1 argument (2 given) 

最后一行内容最丰富,因为它告诉我们,有些东西有太多的论点。这意味着50.0正在伤害我们。

为了解决手头的问题,给出了一个数字包装器作为答案。

class ConstantValue(bt.Indicator):
    lines = ('constant',)
    params = (('constant', float('NaN')),)

    def next(self):
        self.lines.constant[0] = self.p.constant

...

mycrossover = bt.ind.CrossOver(bt.ind.RSI(), ConstantValue(50.0)) 

问题解决了。但是等一下,解决方案已经出台了。有个内帮,解决问题,完全忘记了:LineNum。它做了名称试图暗示的事情:取一个 num,并将其变成一行。问题解决方案就在那里,解决方案可能是这样的:

mycrossover = bt.ind.CrossOver(bt.ind.RSI(), bt.LineNum(50.0)) 

通常的后台线程一直在滴答作响,告诉用户某些东西仍然不是 100%清楚,解决方案应该是显而易见的,而用户没有指定包装器

这就是疏忽。即使mindatas机制存在并应用于 echosystem 的某些部分,但它并未应用于CrossOver。这是尝试过的,但人类有时不幸地失败了,因为他们相信自己做了一些事情只是为了找到答案,所以他们没有进一步向下滚动。事实就是这样。像这样的一行加法:

class CrossOver(Indicator):
    ...
    _mindatas = 2
    ... 

现在这个问题的解决办法很简单:

mycrossover = bt.ind.CrossOver(bt.ind.RSI(), 50.0) 

应该一直保持在 1st位置的方式(见下面的示例和图表)

mindatas工作中

这是一个方便的属性,用于特定情况,因此前导的_表示应谨慎使用。指示器的默认值为:

  • _mindatas = 1

    这告诉系统,如果数据源已传递给指示器,则系统应从父级复制 1st数据源。如果没有这一点,举例来说,实例化RelativeStrengthIndicator应该这样做:

    py class Strategy(bt.Indicator): def __init__(self): rsi = bt.ind.RSI(self.data0)

    但根据_mindatas给出的默认指示,以下情况是可能的:

    py class Strategy(bt.Indicator): def __init__(self): rsi = bt.ind.RSI()

    结果完全一样,因为策略中的 1st数据源self.data0被传递给RSI的实例化

CrossOver这样的指示器需要两个数据馈送,因为它检查的是一个东西是否与另一个东西交叉。在这种情况下,如上所述,默认设置为:

  • _mindatas = 2

这会告诉系统如下情况:

  • 如果未传递任何数据,则从父级复制 2 个数据源(如果可能)

  • 如果只传递了 1 个数据,请尝试将下一个传入参数转换为一个对象,以便有 2 个数据提要可用。USSELECT 适用于管线穿过普通旧浮子的用例。再次供参考:

    py mycrossover = bt.ind.CrossOver(bt.ind.RSI(), 50.0)

  • 如果向CrossOver传递了 2 个或更多数据馈送,则不执行任何操作并继续

在社区中,该机制最近已应用于例如 1st草图,以实现配对交易的KalmanFilter。当谈到配对时,需要 2 个数据源,并使用它:_mindatas = 2

用于测试完整解决方案的小样本(尽管有完整的骨架):

$ ./cross-over-num.py --plot 

它输出这个。

!image

样本使用

$ ./cross-over-num.py --help
usage: cross-over-num.py [-h] [--data0 DATA0] [--fromdate FROMDATE]
                         [--todate TODATE] [--cerebro kwargs]
                         [--broker kwargs] [--sizer kwargs] [--strat kwargs]
                         [--plot [kwargs]]

Sample Skeleton

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 = ()

    def __init__(self):
        bt.ind.CrossOver(bt.ind.RSI(), 50)

    def next(self):
        pass

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=(
            'Sample Skeleton'
        )
    )

    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() 

我们一直在努力

apachecn/AiLearning

【布客】中文翻译组