1. 程式人生 > 實用技巧 >Backtrader中文筆記之CSV Data Feed Data - Data Resampling

Backtrader中文筆記之CSV Data Feed Data - Data Resampling

When data is only available in a single timeframe and the analysis has to be done for a different timeframe, it’s time to do some resampling.

當資料只在單個時間框架可用,並且必須在不同的時間段內進行分析時,就需要進行一些重取樣

“Resampling” should actually be called “Upsampling” given that one goes from a source timeframe to a larger time frame (for example: days to weeks)

“重取樣”實際上應該稱為“上取樣”,因為它是從一個源時間框架到一個更大的時間框架(例如:天到周)

backtrader has built-in support for resampling by passing the original data through a filter object. Although there are several ways to achieve this, a straightforward interface exists to achieve this:

backtrader內建了對重新取樣的支援,通過過濾物件傳遞原始資料。雖然有幾種方法可以實現這一點,但有一個簡單的介面可以實現這一點:

  • Instead of using cerebro.adddata(data) to put a data into the system use

  • cerebro.resampledata(data, **kwargs)

  • 使用cerebro.resampledata(data, **kwargs)代替使用cerebro.adddata(data)給系統新增資料

There are two main options that can be controlled

有兩個主要的控制選項

  • Change the timeframe

  • 改變時間框架
  • Compress bars

  • 壓縮bars

To do so, use the following parameters when calling resampledata:

為此,在呼叫resampledata時使用以下引數:

  • timeframe (default: bt.TimeFrame.Days)

    Destination timeframe which to be useful has to be equal or larger than the source

  • 目標時間框架必須等於或大於源時間框架
  • compression (default: 1)

    Compress the selected value “n” to 1 bar

  • 壓縮可以是1或者n

Let’s see an example from Daily to Weekly with a handcrafted script:

讓我們看看一個例子,從每日到每週的手工指令碼:

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

輸出

We can compare it to the original daily data

$ ./resampling-example.py --timeframe daily --compression 1

The output:

The magic is done by executing the following steps:

魔術是通過以下步驟完成的

  • Loading the data as usual

  • 像以往一樣載入資料
  • Feeding the data into cerebro with resampledata with the desired parameters:

  • 將所需引數的資料用resampledata輸入cerebro:
    • timeframe

    • compression

The code in the sample (the entire script at the bottom).

    # Load the Data
    datapath = args.dataname or '../../datas/2006-day-001.txt'
    data = btfeeds.BacktraderCSVData(dataname=datapath)

    # Handy dictionary for the argument timeframe conversion
    tframes = dict(
        daily=bt.TimeFrame.Days,
        weekly=bt.TimeFrame.Weeks,
        monthly=bt.TimeFrame.Months)

    # Add the resample data instead of the original
    cerebro.resampledata(data,
                         timeframe=tframes[args.timeframe],
                         compression=args.compression)

A last example in which we first change the time frame from daily to weekly and then apply a 3 to 1 compression:

最後一個例子,我們首先將時間框架從每天改為每週,然後應用3到1壓縮:

$ ./resampling-example.py --timeframe weekly --compression 3

The output:

From the original 256 daily bars we end up with 18 3-week bars. The breakdown:

從最初的256日線bars到18個 3粥bars。分解如下

  • 52 weeks

  • 52 / 3 = 17.33 and therefore 18 bars

It doesn’t take much more. Of course intraday data can also be resampled.

不需要更多。當然,日內資料也可以重新取樣。

The resampling filter supports additional parameters, which in most cases should not be touched:

重取樣過濾器支援附加引數,在大多數情況下不應觸及:

  • bar2edge (default: True)

    resamples using time boundaries as the target. For example with a “ticks -> 5 seconds” the resulting 5 seconds bars will be aligned to xx:00, xx:05, xx:10 …

  • 使用時間邊界作為目標重新取樣。例如,對於“ticks-> 5秒”,得到的5秒bars將對齊到xx:00、xx:05、xx:10…
  • adjbartime (default: True)

    Use the time at the boundary to adjust the time of the delivered resampled bar instead of the last seen timestamp. If resampling to “5 seconds” the time of the bar will be adjusted for example to hh:mm:05 even if the last seen timestamp was hh:mm:04.33
    使用邊界處的時間來調整交付的重取樣條的時間,而不是最後看到的時間戳。如果重新取樣到“5秒”,則條的時間將調整為hh:mm:05,即使最後看到的時間戳是hh:mm:04.3

  • Note

    Time will only be adjusted if “bar2edge” is True. It wouldn’t make sense to adjust the time if the bar has not been aligned to a boundary

    只有當“bar2edge”正確時,時間才會調整。如果工具條沒有對齊到邊界,那麼調整時間就沒有意義了

  • rightedge (default: True)

    Use the right edge of the time boundaries to set the time.

  • 使用時間邊界的右邊界來設定時間。

    If False and compressing to 5 seconds the time of a resampled bar for seconds between hh:mm:00 and hh:mm:04 will be hh:mm:00 (the starting boundary

  • 如果為假,壓縮到5秒,則重新取樣的時間條在hh:mm:00和hh:mm:04之間的秒將為hh:mm:00(起始邊界)
  • If True the used boundary for the time will be hh:mm:05 (the ending boundary)

  • 如果為真,使用的時間邊界將是hh:mm:05(結束邊界)
  • boundoff (default: 0)

    Push the boundary for resampling/replaying by an amount of units.

  • 將重取樣/重放的邊界按單位數量推進。
  • If for example the resampling is from 1 minute to 15 minutes, the default behavior is to take the 1-minute bars from 00:01:00 until 00:15:00 to produce a 15-minutes replayed/resampled bar.

  • 例如,如果重新取樣從1分鐘到15分鐘,預設行為是將1分鐘的條從00:01:00到00:15:00使用,以生成15分鐘的重播/重新取樣條。
  • If boundoff is set to 1, then the boundary is pushed 1 unit forward. In this case the original unit is a 1-minute bar. Consequently the resampling/replaying will now:

  • 如果boundoff設定為1,則邊界向前推1個單位。在這種情況下,最初的單位是1分鐘的巧克力棒。因此重取樣/重放現在將:
    • Use the bars from 00:00:00 to 00:14:00 for the generation of the 15-minutes bar
    • 使用從00:00:00到00:14:00的條形圖來生成15分鐘條形圖

The sample code for the resampling test script.

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

import argparse

import backtrader as bt
import backtrader.feeds as btfeeds


def runstrat():
    args = parse_args()

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

    # Add a strategy
    cerebro.addstrategy(bt.Strategy)

    # Load the Data
    datapath = args.dataname or '../../datas/2006-day-001.txt'
    data = btfeeds.BacktraderCSVData(dataname=datapath)

    # Handy dictionary for the argument timeframe conversion
    tframes = dict(
        daily=bt.TimeFrame.Days,
        weekly=bt.TimeFrame.Weeks,
        monthly=bt.TimeFrame.Months)

    # Add the resample data instead of the original
    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='Pandas test script')

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

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

    return parser.parse_args()


if __name__ == '__main__':
    runstrat()