簡體   English   中英

Backtrader 重采樣到每日的問題

[英]Backtrader problems in resampling to daily

使用 backtrader,我想以五分鍾的規模檢索報價並以每日的規模重新采樣。

我可以重新采樣五分鍾到六十分鍾,但不能每天都這樣做。 這是代碼:

from __future__ import absolute_import, division, print_function, unicode_literals
import backtrader as bt
import backtrader.stores.ibstore as ibstore
import datetime
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

_CLIENTID = 100

class St(bt.Strategy):
    def __init__(self):
        self.sma = bt.indicators.SMA(self.data)

    def logdata(self):
        txt = []
        txt.append('{}'.format(len(self)))
        txt.append('{}'.format(self.data.datetime.datetime(0).isoformat()))
        txt.append('{:.2f}'.format(self.data.open[0]))
        txt.append('{:.2f}'.format(self.data.high[0]))
        txt.append('{:.2f}'.format(self.data.low[0]))
        txt.append('{:.2f}'.format(self.data.close[0]))
        txt.append('{:.2f}'.format(self.data.volume[0]))
        logger.debug(','.join(txt))

    data_live = False

    def notify_data(self, data, status, *args, **kwargs):
        print('*' * 5, 'DATA Notification:', data._getstatusname(status), *args)
        if status == data.LIVE:
            self.data_live = True

    def next(self):
        self.logdata()
        if not self.data_live:
            return

_TICKER = "TSLA-STK-SMART-USD"
_FROMDATE = datetime.datetime(2021,1,4)
_TODATE = datetime.datetime(2021,1,29)
_HAS_STATS = False

def run(args=None):
    cerebro = bt.Cerebro(stdstats=_HAS_STATS)

    store = ibstore.IBStore(host="127.0.0.1", port=7497, clientId= _CLIENTID )
    cerebro.broker = store.getbroker()
    stockkwargs = dict(
        timeframe=bt.TimeFrame.Minutes,
        compression=10,
        rtbar=False,
        historical=True,
        qcheck=0.5,
        fromdate=_FROMDATE,
        todate=_TODATE,
        latethrough=False,
        tradename=None
    )

    data0 = store.getdata(dataname=_TICKER, **stockkwargs)
    # cerebro.resampledata(data0, timeframe=bt.TimeFrame.Minutes, compression=60)
    cerebro.resampledata(data0, timeframe=bt.TimeFrame.Days, compression=1)

    cerebro.run()

if __name__ == "__main__":
    run()

我得到一個連接,但沒有天。 這是 output(沒有打印條):

Server Version: 76
TWS Time at connection:20210303 09:39:17 EST
***** DATA Notification: DELAYED
***** DATA Notification: DISCONNECTED

但是,如果我對 go 進行 60 分鍾的重新采樣,一切都很好。 編碼

cerebro.resampledata(data0, timeframe=bt.TimeFrame.Minutes, compression=60)
# cerebro.resampledata(data0, timeframe=bt.TimeFrame.Days, compression=1)

結果是

Server Version: 76
TWS Time at connection:20210303 09:36:27 EST
***** DATA Notification: DELAYED
DEBUG:__main__:30,2021-01-05T17:00:00,749.65,754.40,735.11,753.21,6011.00
DEBUG:__main__:31,2021-01-05T18:00:00,753.39,754.18,751.60,753.34,1126.00
DEBUG:__main__:32,2021-01-05T19:00:00,753.32,753.32,750.49,752.90,1179.00
DEBUG:__main__:33,2021-01-06T04:00:00,748.00,752.55,746.66,751.88,331.00
DEBUG:__main__:34,2021-01-06T05:00:00,751.60,753.00,749.26,750.50,137.00
(omitted)
DEBUG:__main__:286,2021-01-28T17:00:00,833.00,833.25,831.36,831.61,116.00
DEBUG:__main__:287,2021-01-28T18:00:00,831.60,833.96,830.11,831.00,175.00
DEBUG:__main__:288,2021-01-28T19:00:00,830.51,832.00,829.45,829.45,358.00
***** DATA Notification: DISCONNECTED

我正在使用這些版本:

Python 3.7.4
ib                   0.8.0
IbPy2                0.8.0
numpy                1.19.2
pandas               1.1.3

TL; DR 我做了其他幾個實驗。

獲取數據時間范圍 獲取數據壓縮 重新采樣時間范圍 重采樣壓縮 結果
分鍾 5 分鍾 60 正如預期的那樣,可以每小時查看一次
分鍾 5 1 (空的)
(空白的) (空白的) 1 (空的)
1 1 (空的)
1 (注釋掉) (注釋掉) (空的)

你說得對,幾年前就有一個已知問題。 不過,有一個簡單的解決方法。 不要使用反向交易者重采樣工具,而是使用盈透證券。

您可以繞過重采樣並直接從 IB 調用數據。 請記住,您必須首先將最短的時間范圍添加到 Backtrader。


for tf_com in [(bt.TimeFrame.Minutes, 1), (bt.TimeFrame.Days, 1)]:
    stockkwargs = dict(
        timeframe=tf_com[0],
        compression=tf_com[1],
        rtbar=False,
        historical=True,
        qcheck=0.5,
        fromdate=_FROMDATE,
        todate=_TODATE,
        latethrough=False,
        tradename=None
    )

    data0 = store.getdata(dataname=_TICKER, **stockkwargs)

    cerebro.adddata(data0)

您可以在第一行的元組中調整時間范圍和壓縮。 我將其調整為 5 和 15 分鍾,以便您可以看到 output。

for tf_com in [(bt.TimeFrame.Minutes, 5), (bt.TimeFrame.Minutes, 15)]:

************ OUTPUT ************

2021-03-25 12:00:00 636.77 632.71 
2021-03-25 12:05:00 634.69 632.71 
2021-03-25 12:10:00 632.71 632.71 
2021-03-25 12:15:00 640.39 643.00 
2021-03-25 12:20:00 640.68 643.00 
2021-03-25 12:25:00 643.00 643.00 
2021-03-25 12:30:00 641.33 640.00 
2021-03-25 12:35:00 637.84 640.00 
2021-03-25 12:40:00 640.00 640.00 
2021-03-25 12:45:00 640.34 633.95 
2021-03-25 12:50:00 636.15 633.95 
2021-03-25 12:55:00 633.95 633.95 
2021-03-25 13:00:00 633.50 637.43 
2021-03-25 13:05:00 634.95 637.43 
2021-03-25 13:10:00 637.43 637.43 

編輯:回應 OP 評論

我不敢苟同。 天數由盈透證券抽樣,因此您將獲得每日信息。 您必須確保在同時使用 5 分鍾數據時不要將 go 與您的開始日期相差太遠。 IB不是歷史數據提供者。

這是完整的代碼供您參考。

import backtrader as bt
import backtrader.stores.ibstore as ibstore
import datetime
import os
from dotenv import load_dotenv

load_dotenv()


class St(bt.Strategy):

    def __init__(self):
        self.data_live = False
        self.timeframes = {4: "minute", 5: "day"}


    def next(self):
        time = self.data.datetime.time()
        start_day = datetime.time(4, 20, 0)
        end_day = datetime.time(19, 40, 0)
        if time < start_day or time > end_day:
            print_date = True
        else:
            print_date = False

        if not self.data_live and print_date:
            print(
                f"{self.data.datetime.datetime()}   "
                
                f"data0: tf: {self.timeframes[self.datas[0]._timeframe]} "
                f"comp: {self.datas[0]._compression},   "
                f"{self.datas[0].close[0]:5.2f} "
                
                f"data1: tf: {self.timeframes[self.datas[1]._timeframe]} "
                f"comp: {self.datas[1]._compression} "
                f"{self.datas[1].close[0]:5.2f} "
            )
            return


_TICKER = "TSLA-STK-SMART-USD"
_FROMDATE = datetime.datetime(2021, 3, 10)
_TODATE = datetime.datetime(2021, 3, 24)
_HAS_STATS = False
_CLIENTID = os.getenv("CLIENTID")
_PORT = os.getenv("SOCKET_PORT")


def run():
    cerebro = bt.Cerebro(stdstats=_HAS_STATS)
    cerebro.addstrategy(St)

    store = ibstore.IBStore(host="127.0.0.1", port=int(_PORT), clientId=_CLIENTID)
    cerebro.broker = store.getbroker()

    for tf_com in [(bt.TimeFrame.Minutes, 5), (bt.TimeFrame.Days, 1)]:
        stockkwargs = dict(
            timeframe=tf_com[0],
            compression=tf_com[1],
            rtbar=False,
            historical=True,
            qcheck=0.5,
            fromdate=_FROMDATE,
            todate=_TODATE,
            latethrough=False,
            tradename=None,
        )

        data = store.getdata(dataname=_TICKER, **stockkwargs)

        cerebro.adddata(data)

    cerebro.run()


if __name__ == "__main__":
    run()

這是刪除了中間日期的 output。

請注意,反向交易者將在前一天最后一根柱線的末尾設置下一天的值。

2021-03-10 19:55:00   data0: tf: minute comp: 5,   664.56 data1: tf: day comp: 1 664.56 
2021-03-11 04:00:00   data0: tf: minute comp: 5,   699.10 data1: tf: day comp: 1 664.56 
2021-03-11 04:05:00   data0: tf: minute comp: 5,   701.50 data1: tf: day comp: 1 664.56 
2021-03-11 04:10:00   data0: tf: minute comp: 5,   699.00 data1: tf: day comp: 1 664.56 
2021-03-11 04:15:00   data0: tf: minute comp: 5,   701.00 data1: tf: day comp: 1 664.56 
2021-03-11 19:45:00   data0: tf: minute comp: 5,   698.05 data1: tf: day comp: 1 664.56 
2021-03-11 19:50:00   data0: tf: minute comp: 5,   698.09 data1: tf: day comp: 1 664.56 
2021-03-11 19:55:00   data0: tf: minute comp: 5,   698.50 data1: tf: day comp: 1 664.56 
2021-03-11 19:55:00   data0: tf: minute comp: 5,   698.50 data1: tf: day comp: 1 698.50 
2021-03-12 04:00:00   data0: tf: minute comp: 5,   674.25 data1: tf: day comp: 1 698.50 
2021-03-12 04:05:00   data0: tf: minute comp: 5,   676.00 data1: tf: day comp: 1 698.50 
2021-03-12 04:10:00   data0: tf: minute comp: 5,   669.00 data1: tf: day comp: 1 698.50 
2021-03-12 04:15:00   data0: tf: minute comp: 5,   669.46 data1: tf: day comp: 1 698.50 
2021-03-12 19:45:00   data0: tf: minute comp: 5,   693.30 data1: tf: day comp: 1 698.50 
2021-03-12 19:50:00   data0: tf: minute comp: 5,   692.80 data1: tf: day comp: 1 698.50 
2021-03-12 19:55:00   data0: tf: minute comp: 5,   692.99 data1: tf: day comp: 1 698.50 
2021-03-12 19:55:00   data0: tf: minute comp: 5,   692.99 data1: tf: day comp: 1 692.99 
2021-03-15 04:00:00   data0: tf: minute comp: 5,   689.00 data1: tf: day comp: 1 692.99 
2021-03-15 04:05:00   data0: tf: minute comp: 5,   692.13 data1: tf: day comp: 1 692.99 
2021-03-15 04:10:00   data0: tf: minute comp: 5,   692.12 data1: tf: day comp: 1 692.99 
2021-03-15 04:15:00   data0: tf: minute comp: 5,   692.31 data1: tf: day comp: 1 692.99 
2021-03-15 19:45:00   data0: tf: minute comp: 5,   702.00 data1: tf: day comp: 1 692.99 
2021-03-15 19:50:00   data0: tf: minute comp: 5,   702.00 data1: tf: day comp: 1 692.99 
2021-03-15 19:55:00   data0: tf: minute comp: 5,   702.00 data1: tf: day comp: 1 692.99 
2021-03-15 19:55:00   data0: tf: minute comp: 5,   702.00 data1: tf: day comp: 1 702.00 
2021-03-16 04:00:00   data0: tf: minute comp: 5,   704.01 data1: tf: day comp: 1 702.00 
2021-03-16 04:05:00   data0: tf: minute comp: 5,   704.98 data1: tf: day comp: 1 702.00 
2021-03-16 04:10:00   data0: tf: minute comp: 5,   704.99 data1: tf: day comp: 1 702.00 
2021-03-16 04:15:00   data0: tf: minute comp: 5,   706.20 data1: tf: day comp: 1 702.00 
2021-03-16 19:45:00   data0: tf: minute comp: 5,   673.65 data1: tf: day comp: 1 702.00 
2021-03-16 19:50:00   data0: tf: minute comp: 5,   674.00 data1: tf: day comp: 1 702.00 
2021-03-16 19:55:00   data0: tf: minute comp: 5,   674.10 data1: tf: day comp: 1 702.00 
2021-03-16 19:55:00   data0: tf: minute comp: 5,   674.10 data1: tf: day comp: 1 674.10 
2021-03-17 04:00:00   data0: tf: minute comp: 5,   672.00 data1: tf: day comp: 1 674.10 
2021-03-17 04:05:00   data0: tf: minute comp: 5,   675.80 data1: tf: day comp: 1 674.10 
2021-03-17 04:10:00   data0: tf: minute comp: 5,   677.19 data1: tf: day comp: 1 674.10 
2021-03-17 04:15:00   data0: tf: minute comp: 5,   676.03 data1: tf: day comp: 1 674.10 
2021-03-17 19:45:00   data0: tf: minute comp: 5,   699.66 data1: tf: day comp: 1 674.10 
2021-03-17 19:50:00   data0: tf: minute comp: 5,   699.90 data1: tf: day comp: 1 674.10 
2021-03-17 19:55:00   data0: tf: minute comp: 5,   699.74 data1: tf: day comp: 1 674.10 
2021-03-17 19:55:00   data0: tf: minute comp: 5,   699.74 data1: tf: day comp: 1 699.74 
2021-03-18 04:00:00   data0: tf: minute comp: 5,   685.00 data1: tf: day comp: 1 699.74 
2021-03-18 04:05:00   data0: tf: minute comp: 5,   686.35 data1: tf: day comp: 1 699.74 
2021-03-18 04:10:00   data0: tf: minute comp: 5,   688.32 data1: tf: day comp: 1 699.74 
2021-03-18 04:15:00   data0: tf: minute comp: 5,   692.50 data1: tf: day comp: 1 699.74 
2021-03-18 19:45:00   data0: tf: minute comp: 5,   652.10 data1: tf: day comp: 1 699.74 
2021-03-18 19:50:00   data0: tf: minute comp: 5,   651.00 data1: tf: day comp: 1 699.74 
2021-03-18 19:55:00   data0: tf: minute comp: 5,   650.56 data1: tf: day comp: 1 699.74 
2021-03-18 19:55:00   data0: tf: minute comp: 5,   650.56 data1: tf: day comp: 1 650.56 
2021-03-19 04:00:00   data0: tf: minute comp: 5,   661.00 data1: tf: day comp: 1 650.56 
2021-03-19 04:05:00   data0: tf: minute comp: 5,   663.00 data1: tf: day comp: 1 650.56 
2021-03-19 04:10:00   data0: tf: minute comp: 5,   663.60 data1: tf: day comp: 1 650.56 
2021-03-19 04:15:00   data0: tf: minute comp: 5,   666.48 data1: tf: day comp: 1 650.56 
2021-03-19 19:45:00   data0: tf: minute comp: 5,   652.50 data1: tf: day comp: 1 650.56 
2021-03-19 19:50:00   data0: tf: minute comp: 5,   652.02 data1: tf: day comp: 1 650.56 
2021-03-19 19:55:00   data0: tf: minute comp: 5,   652.20 data1: tf: day comp: 1 650.56 
2021-03-19 19:55:00   data0: tf: minute comp: 5,   652.20 data1: tf: day comp: 1 652.20 
2021-03-22 04:00:00   data0: tf: minute comp: 5,   665.97 data1: tf: day comp: 1 652.20 
2021-03-22 04:05:00   data0: tf: minute comp: 5,   664.00 data1: tf: day comp: 1 652.20 
2021-03-22 04:10:00   data0: tf: minute comp: 5,   665.00 data1: tf: day comp: 1 652.20 
2021-03-22 04:15:00   data0: tf: minute comp: 5,   663.94 data1: tf: day comp: 1 652.20 
2021-03-22 19:45:00   data0: tf: minute comp: 5,   668.39 data1: tf: day comp: 1 652.20 
2021-03-22 19:50:00   data0: tf: minute comp: 5,   668.56 data1: tf: day comp: 1 652.20 
2021-03-22 19:55:00   data0: tf: minute comp: 5,   669.35 data1: tf: day comp: 1 652.20 
2021-03-22 19:55:00   data0: tf: minute comp: 5,   669.35 data1: tf: day comp: 1 669.35 
2021-03-23 04:00:00   data0: tf: minute comp: 5,   670.25 data1: tf: day comp: 1 669.35 
2021-03-23 04:05:00   data0: tf: minute comp: 5,   665.33 data1: tf: day comp: 1 669.35 
2021-03-23 04:10:00   data0: tf: minute comp: 5,   664.11 data1: tf: day comp: 1 669.35 
2021-03-23 04:15:00   data0: tf: minute comp: 5,   662.93 data1: tf: day comp: 1 669.35 
2021-03-23 19:45:00   data0: tf: minute comp: 5,   661.00 data1: tf: day comp: 1 669.35 
2021-03-23 19:50:00   data0: tf: minute comp: 5,   661.08 data1: tf: day comp: 1 669.35 
2021-03-23 19:55:00   data0: tf: minute comp: 5,   663.00 data1: tf: day comp: 1 669.35 
2021-03-23 19:55:00   data0: tf: minute comp: 5,   663.00 data1: tf: day comp: 1 663.00 

=== OP 驗證 ===

這是 data0 和 data1 plot 的樣子,在cerebro.plot()之后添加cerebro.run()

腦圖

這是好看的每日數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM