You are here:  Home » 量化交易与机器学习 » backtrader » 策略选择Revisited- backtrader中文教程

策略选择Revisited

The原来的战略选择方法使用两种策略,这是手动注册和简单的[0, 1]列表来决定这将是在strategy.

Because的Python的目标提供了大量的instrospection可能性与元类,一个可能实际上自动化的方法。让我们从一个decorator做方法这可能是在这种情况下,侵入性最小的(不需要定义metaclass的策略)

现在再处理工厂factory

The:

  • 声明的strategies
  • has空`前_STRATS类属性(它的策略返回前)
  • 具有register类方法,其将被用作装饰和接受其将被添加到_STRATS
  • 的参数`具有COUNT类方法将返回一个迭代(一个range实际上)与可用策略的计数是optimized
  • bears不改变实际的工厂方法:__new__,它不断使用idx参数返回无论是在_STRATS类属性在给定index
class StFetcher(object):
    _STRATS = []

    @classmethod
    def register(cls, target):
        cls._STRATS.append(target)

    @classmethod
    def COUNT(cls):
        return range(len(cls._STRATS))

    def __new__(cls, *args, **kwargs):
        idx = kwargs.pop("idx")

        obj = cls._STRATS[idx](*args, **kwargs)
        return obj

As例如:

  • `的StFetcher战略厂不再包含任何硬编码在itself

Decorating策略在本例中待优化strategies

The策略并不需要返工。装饰用register`的方法StFetcher是足够让它们加入到该选择添加策略工厂时mix.

@StFetcher.register
class St0(bt.SignalStrategy):

and

@StFetcher.register
class St1(bt.SignalStrategy):

Taking优势COUNT

手动[0, 1]名单从过去该系统与optstrategy可与透明呼叫被充分置换以StFetcher.COUNT()。硬编码是over.

    cerebro.optstrategy(StFetcher, idx=StFetcher.COUNT())

A样品run

$ ./stselection-revisited.py --optreturn
Strat 0 Name OptReturn:
  - analyzer: OrderedDict([(u"rtot", 0.04847392369449283), (u"ravg", 9.467563221580632e-05), (u"rnorm", 0.02414514457151587), (u"rnorm100", 2.414514457151587)])

Strat 1 Name OptReturn:
  - analyzer: OrderedDict([(u"rtot", 0.05124714332260593), (u"ravg", 0.00010009207680196471), (u"rnorm", 0.025543999840699633), (u"rnorm100", 2.5543999840699634)])

Our 2个策略已经运行,并提供(如预期)不同results.

Note

The样品是最小的,但已与所有可用运行的CPU。与执行它--maxpcpus=1会更快。欲了解更多使用所有的CPU将是useful.

Conclusion

选择已经完全自动化。如前一个可以想象像查询数据库可用策略的数量,然后取策略之一由one.

Sample Usage

$ ./stselection-revisited.py --help
usage: strategy-selection.py [-h] [--data DATA] [--maxcpus MAXCPUS]
                             [--optreturn]

Sample for strategy selection

optional arguments:
  -h, --help         show this help message and exit
  --data DATA        Data to be read in (default:
                     ../../datas/2005-2006-day-001.txt)
  --maxcpus MAXCPUS  Limit the numer of CPUs to use (default: None)
  --optreturn        Return reduced/mocked strategy object (default: False)

The code

Which已列入backtrader

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

import argparse

import backtrader as bt
from backtrader.utils.py3 import range


class StFetcher(object):
    _STRATS = []

    @classmethod
    def register(cls, target):
        cls._STRATS.append(target)

    @classmethod
    def COUNT(cls):
        return range(len(cls._STRATS))

    def __new__(cls, *args, **kwargs):
        idx = kwargs.pop("idx")

        obj = cls._STRATS[idx](*args, **kwargs)
        return obj


@StFetcher.register
class St0(bt.SignalStrategy):
    def __init__(self):
        sma1, sma2 = bt.ind.SMA(period=10), bt.ind.SMA(period=30)
        crossover = bt.ind.CrossOver(sma1, sma2)
        self.signal_add(bt.SIGNAL_LONG, crossover)


@StFetcher.register
class St1(bt.SignalStrategy):
    def __init__(self):
        sma1 = bt.ind.SMA(period=10)
        crossover = bt.ind.CrossOver(self.data.close, sma1)
        self.signal_add(bt.SIGNAL_LONG, crossover)


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

    cerebro = bt.Cerebro()
    data = bt.feeds.BacktraderCSVData(dataname=args.data)
    cerebro.adddata(data)

    cerebro.addanalyzer(bt.analyzers.Returns)
    cerebro.optstrategy(StFetcher, idx=StFetcher.COUNT())
    results = cerebro.run(maxcpus=args.maxcpus, optreturn=args.optreturn)

    strats = [x[0] for x in results]  # flatten the result
    for i, strat in enumerate(strats):
        rets = strat.analyzers.returns.get_analysis()
        print("Strat {} Name {}:\n  - analyzer: {}\n".format(
            i, strat.__class__.__name__, rets))


def parse_args(pargs=None):

    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        description="Sample for strategy selection")

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

    parser.add_argument("--maxcpus", required=False, action="store",
                        default=None, type=int,
                        help="Limit the numer of CPUs to use")

    parser.add_argument("--optreturn", required=False, action="store_true",
                        help="Return reduced/mocked strategy object")

    return parser.parse_args(pargs)


if __name__ == "__main__":
    runstrat()

评论被关闭。