Backtrader教程:數據饋送 - 多個時間幀

  |  

有時投資決策是使用不同的時間框架做出的:

  • 每周評估趨勢

  • 每天執行條目

或者5分鐘對60分鐘。

這意味著需要組合多個時間幀的數據backtrader 來支援這種組合。

對它的本機支持已經內置。最終使用者只能遵循以下規則:

  • 具有最小時間幀(因此柱數較大的數據)必須是要添加到Cerebro實例中的第1個數據

  • 數據必須正確對齊日期時間,以便平臺從中產生任何意義

除此之外,最終使用者可以自由地在較短/較長的時間範圍內按預期應用指標。答案是肯定的:

  • 應用於較大時間幀的指標將產生較少的柱線

該平臺還將考慮以下因素

  • 較大時間幀的最小週期

最小週期,這可能會產生副作用,即在將策略添加到 Cerebro 開始行動之前,必須消耗幾個數量級的較小時間幀柱。

內置cerebro.resample 的將用於創建更大的時間範圍。

下面是一些示例,但首先是測試腳本的醬汁。

    # Load the Data
    datapath = args.dataname or '../../datas/2006-day-001.txt'
    data = btfeeds.BacktraderCSVData(dataname=datapath)
    cerebro.adddata(data)  # First add the original data - smaller timeframe

    tframes = dict(daily=bt.TimeFrame.Days, weekly=bt.TimeFrame.Weeks,
                   monthly=bt.TimeFrame.Months)

    # Handy dictionary for the argument timeframe conversion
    # Resample the data
    if args.noresample:
        datapath = args.dataname2 or '../../datas/2006-week-001.txt'
        data2 = btfeeds.BacktraderCSVData(dataname=datapath)
        # And then the large timeframe
        cerebro.adddata(data2)
    else:
        cerebro.resampledata(data, timeframe=tframes[args.timeframe],
                             compression=args.compression)

    # Run over everything
    cerebro.run()

步驟:

  • 載入數據

  • 根據使用者指定的參數對其進行重新採樣

    該腳本還允許載入第 2 個 數據

  • 將資料新增到 cerebro

  • 將重新採樣的數據(更大的時間幀)添加到 cerebro

示例 1 - 每日和每周

文稿的呼叫:

$ ./multitimeframe-example.py --timeframe weekly --compression 1

和輸出圖表:

範例 2 - 每日和每日壓縮(2 個 bar 到 1)

文稿的呼叫:

$ ./multitimeframe-example.py --timeframe daily --compression 2

和輸出圖表:

範例 3 - 使用 SMA 的策略

雖然繪圖很好,但這裡的關鍵問題是顯示更大的時間框架如何影響系統,特別是當它歸結為起點時。

該腳本可以添加--indicators 一個策略,該策略在較小和較大的時間幀數據上創建 週期為10 的簡單移動平均線。

如果只考慮較小的時間範圍:

  • next 將在10根柱線後首先調用,這是簡單移動平均線產生值所需的時間

    注意:請記住,Strategy 監控已創建的指標,並且僅在所有指標都生成值時才調用 next 。基本原理是最終使用者已添加指標以在邏輯中使用它們,因此,如果指標未生成任何值,則不應發生任何邏輯。

但是在這種情況下,較大的時間幀(每周)延遲調用next ,直到每周數據產生一個值的簡單移動平均線,這需要...10周。

該腳本將nextstart 覆蓋僅調用一次且預設為調用 next 以顯示首次調用時的腳本。

呼叫 1:

只有較小的時間幀,每天,得到一個簡單的移動平均線

命令 line 和輸出

$ ./multitimeframe-example.py --timeframe weekly --compression 1 --indicators --onlydaily
--------------------------------------------------
nextstart called with len 10
--------------------------------------------------

和圖表。

呼叫 2:

兩個時間幀都得到一個簡單的移動平均線

命令 line

$ ./multitimeframe-example.py --timeframe weekly --compression 1 --indicators
--------------------------------------------------
nextstart called with len 50
--------------------------------------------------
--------------------------------------------------
nextstart called with len 51
--------------------------------------------------
--------------------------------------------------
nextstart called with len 52
--------------------------------------------------
--------------------------------------------------
nextstart called with len 53
--------------------------------------------------
--------------------------------------------------
nextstart called with len 54
--------------------------------------------------

這裡要注意兩件事:

  • 該策略不是在10 個週期后調用,而是在50個週期后調用1st

    之所以如此,是因為應用於較大(每周)時間幀的簡單移動平均線在10周後產生一個值......那就是10 weeks * 5 days / week … 50 days

  • nextstart 被調用 5 次,而不僅僅是 1 次。

    這是混合時間幀並將指標(在本例中只有一個)應用於較大時間幀的自然副作用。

    較大的時間幀簡單移動平均線產生相同值的 5 倍,而 5 個日柱線被消耗。

    而且由於周期的開始被較大的時間幀nextstart 控制,因此被調用了5次。

和圖表。

結論

多個時間幀數據可以在沒有特殊物件或調整的情況下使用backtrader :只需先添加較小的時間幀即可。

測試腳本。

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

import argparse

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


class SMAStrategy(bt.Strategy):
    params = (
        ('period', 10),
        ('onlydaily', False),
    )

    def __init__(self):
        self.sma_small_tf = btind.SMA(self.data, period=self.p.period)
        if not self.p.onlydaily:
            self.sma_large_tf = btind.SMA(self.data1, period=self.p.period)

    def nextstart(self):
        print('--------------------------------------------------')
        print('nextstart called with len', len(self))
        print('--------------------------------------------------')

        super(SMAStrategy, self).nextstart()


def runstrat():
    args = parse_args()

    # Create a cerebro entity
    cerebro = bt.Cerebro(stdstats=False)

    # Add a strategy
    if not args.indicators:
        cerebro.addstrategy(bt.Strategy)
    else:
        cerebro.addstrategy(
            SMAStrategy,

            # args for the strategy
            period=args.period,
            onlydaily=args.onlydaily,
        )

    # Load the Data
    datapath = args.dataname or '../../datas/2006-day-001.txt'
    data = btfeeds.BacktraderCSVData(dataname=datapath)
    cerebro.adddata(data)  # First add the original data - smaller timeframe

    tframes = dict(daily=bt.TimeFrame.Days, weekly=bt.TimeFrame.Weeks,
                   monthly=bt.TimeFrame.Months)

    # Handy dictionary for the argument timeframe conversion
    # Resample the data
    if args.noresample:
        datapath = args.dataname2 or '../../datas/2006-week-001.txt'
        data2 = btfeeds.BacktraderCSVData(dataname=datapath)
        # And then the large timeframe
        cerebro.adddata(data2)
    else:
        cerebro.resampledata(data, timeframe=tframes[args.timeframe],
                             compression=args.compression)

    # Run over everything
    cerebro.run()

    # Plot the result
    cerebro.plot(style='bar')


def parse_args():
    parser = argparse.ArgumentParser(
        description='Multitimeframe test')

    parser.add_argument('--dataname', default='', required=False,
                        help='File Data to Load')

    parser.add_argument('--dataname2', default='', required=False,
                        help='Larger timeframe file to load')

    parser.add_argument('--noresample', action='store_true',
                        help='Do not resample, rather load larger timeframe')

    parser.add_argument('--timeframe', default='weekly', required=False,
                        choices=['daily', 'weekly', 'monhtly'],
                        help='Timeframe to resample to')

    parser.add_argument('--compression', default=1, required=False, type=int,
                        help='Compress n bars into 1')

    parser.add_argument('--indicators', action='store_true',
                        help='Wether to apply Strategy with indicators')

    parser.add_argument('--onlydaily', action='store_true',
                        help='Indicator only to be applied to daily timeframe')

    parser.add_argument('--period', default=10, required=False, type=int,
                        help='Period to apply to indicator')

    return parser.parse_args()


if __name__ == '__main__':
    runstrat()

推薦閱讀

相關文章

Backtrader期貨展期

並非每個供應商都為可以交易的工具提供連續的未來。有時提供的數據是仍然有效的到期日期的數據,即:仍在交易的日期 這在回溯測試方面並不是很有幫助,因為數據分散在幾個不同的儀器上,這些儀器另外...時間重疊。 能夠正確地將這些儀器的數據從過去連接到連續的流中,可以減輕疼痛。

Backtrader按日線交易

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

Backtrader傭金計劃

backtrader 的誕生是出於必要。我自己的...有一種感覺,我控制著自己的回溯測試平臺,可以嘗試新的想法。但是,在這樣做並且從一開始就完全 open 採購它時,很明顯它必須有一種方法來滿足他人的需求和願望。 作為未來的交易者,我本可以選擇基於點的計算和每輪傭金的固定價格,但這將是一個錯誤。

BacktraderPython Hidden Powers 2

讓我們進一步討論一下Python的隱藏功能如何在 backtrader 中使用,以及如何實現它以嘗試實現主要目標:易用性 這些定義是什麼? 例如指標: import backtrader as bt class MyIndicator(bt.

Backtrader教程:操作平臺

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

Backtrader教程:觀察者 - 基準測試

工單 #89 是關於針對資產添加基準測試的。明智的是,人們實際上可能有一個策略,即使積極,也低於簡單地跟蹤資產所能提供的策略。

Backtrader教程:Cerebro - 優化 - 改進

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

Backtraderta-lib 集成

即使 backtrader 提供了已經 high 數量的內置指標,並且開發指標主要是定義輸入,輸出和以自然的方式編寫公式的問題,有些人也希望使用TA-LIB。

Backtrader開場作弊

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

Backtrader信號策略

操作 backtrader 也是可能的,而無需編寫策略。雖然這是首選方式,但由於構成機器的對象層次結構,使用信號也是可能的。