Backtrader策略選擇

  |  

休士頓我們有一個問題:

  • cerebro 不應多次運行。這不是第1 ,而不是認為使用者做錯了,這似乎是一個用例。

這個有趣的用例是通過票證177出現的。在這種情況下, cerebro 被多次用於評估從外部數據源獲取的不同策略。

backtrader 仍然可以支援此用例,但不能以直接嘗試的方式支援。

backtrader中的內置優化已經完成了所需的操作:

  • 實例化多個策略實例並收集結果

是唯一一個實例都屬於同一類的東西。這就是Python通過讓我們控制對象的創建來提供説明的地方。

首先,讓我們使用內置的信號技術向腳本中添加非常快速的策略 backtrader

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)


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)

它再簡單不過了。

現在讓我們來做一個神奇的實現這兩個策略。

class StFetcher(object):
    _STRATS = [St0, St1]

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

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

Et voilá!實例化類StFetcher 時,方法 __new__ 將控制實例的創建。在這種情況下:

  • 獲取idx 傳遞給它的參數

  • 使用此參數從_STRATS 存儲了我們之前的範例策略的清單中獲取策略

    注意

    沒有什麼可以阻止使用此idx 值從伺服器和/或資料庫獲取策略。

  • 實例化並返回受影響的策略

主持演出

    cerebro.addanalyzer(bt.analyzers.Returns)
    cerebro.optstrategy(StFetcher, idx=[0, 1])
    results = cerebro.run(maxcpus=args.maxcpus, optreturn=args.optreturn)

事實上!優化就是這樣!而不是addstrategy 我們使用 optstrategy 並傳遞的值陣列 idx。這些值將由優化引擎反覆運算。

由於cerebro 可以在每個優化傳遞中託管多個策略,因此結果將包含清單清單。每個子清單都是每個優化傳遞的結果。

在我們的例子中,每次通過只有 1 個策略,我們可以快速平展結果並提取我們添加的分析器的值。

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

示例運行

./strategy-selection.py

Strat 0 Name St0:
  - analyzer: OrderedDict([(u'rtot', 0.04847392369449283), (u'ravg', 9.467563221580632e-05), (u'rnorm', 0.02414514457151587), (u'rnorm100', 2.414514457151587)])

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

我們的2個策略已經運行,並交付(如預期)不同的結果。

注意

該示例很少,但已使用所有可用的CPU運行。執行--maxpcpus=1 它將更快。對於使用所有 CPU 的更複雜的方案,將非常有用。

結論

策略選擇用例是可能的,並且不需要繞過 backtrader 或Python本身中的任何內置設施。

示例用法

$ ./strategy-selection.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)

代碼

這已被包括在 backtrader

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

import argparse

import backtrader as bt


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)


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)


class StFetcher(object):
    _STRATS = [St0, St1]

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

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


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=[0, 1])
    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()

推薦閱讀

相關文章

Backtrader按日線交易

似乎在世界某個地方有一種权益(Interest)可以總結如下: 使用每日柱線引入訂單,但使用開盤價 這來自工單#105订单执行逻辑与当前数据和#101动态投注计算中的對話 backtrader 嘗試盡可能保持現實,並且在處理每日柱線時適用以下前提: 當每日柱被評估時,柱線已經結束 這是有道理的,

Backtrader教程:經紀人 - 開倉作弊

“發佈”1.9.44.116 添加了對 Cheat-On-Open的支援。這似乎是那些全力以赴的人的需求功能,他們在酒吧 close 后進行了計算,但希望與 open 價格相匹配。 當開盤價跳空(上漲或下跌,取決於是否buysell有效)並且現金不足以進行全面運營時,這樣的用例就會失敗。這將強制代理拒絕該操作。

Backtrader改進代碼

時不時地,帶有 backtrader 代碼的示例會在互聯網上彈出。在我看來,有幾個是中國人。最新的一個在這裡: 標題是: backtrader-學習筆記2,這顯然(感謝谷歌)翻譯成 backtrader- 學習筆記2。

Backtrader教程:指標 - 開發

如果必須開發任何東西(除了一個或多個獲勝策略之外),那麼這個東西就是一個自定義指標。 根據作者的說法,平臺內的這種開發很容易。 需要滿足以下條件: 從指標派生的類(直接或從現有的子類派生) 定義它將保持lines 指標必須至少具有 1 line。

Backtrader期貨補償與現貨補償

版本1.9.32.116 增加了對社區中呈現的有趣用例 的支援 以期貨開始交易,包括實物交割 讓一個指標告訴你一些事情 如果需要, close 現貨價格操作,有效地取消實物交割,無論是為了接收貨物還是為了必須交付貨物(並希望獲利)來頭寸。

Backtrader教程:操作平臺

Line 反覆運算器 為了參與操作,plaftorm使用 line 反覆運算器的概念。它們已經鬆散地模仿了Python的反覆運算器,但實際上與它們無關。 策略和指標是 line 反覆運算器。

Backtrader迪克森移動平均線

下面的reddit帖子以自己的作者Nathan Dickson(reddit句柄)命名了這個平均值Dickson移動平均線。 在一次對reddit Algotrading 的定期訪問中,我發現了一篇關於移動平均線的帖子,該移動平均線試圖模仿Jurik移動平均線(又名JMA)。

Backtrader教程:Cerebro - 優化 - 改進

backtrader版本1.8.12.99改進了在多處理過程中管理data feeds和結果的方式。

Backtrader Python隐藏的细节

只有當遇到 backtrader 的真實使用者時,人們才能意識到平臺中使用的抽象和Python功能是否有意義。 在不撇開python的座右銘的情況下, backtrader 試圖為使用者提供盡可能多的控制權,同時通過將Python提供的隱藏功能付諸行動來簡化使用。 第一個示例是系列文章的第一篇。

Backtrader交叉回溯測試陷阱

在backtrader 社區中 ,傾向於重複的事情是,用戶解釋了複製在例如 TradingView 中獲得的回溯測試結果的意願,這些天非常流行,或者其他一些回溯測試平臺。