Intraday time issue/Orders waiting until T+1
-
All,
Have been using Backtrader for about a week and still trying to get the hang of it. I thought I was doing well with some daily stock ideas, but get out over my skis with intraday data.
I have a year of minute-by-minute EUR/USD data in a OHLC csv. The date is in %Y%M%D and time in %H%M%D. I even added a third column to combine them into a datetime thinking that was the problem.
20150101,130000,20150101 130000,,1.20965,1.20977,1.20962,1.20962,0 20150101,130100,20150101 130100,,1.20963,1.20968,1.20962,1.20962,0 20150101,130200,20150101 130200,,1.20965,1.2097,1.20961,1.20961,0
I add the data to the strategy via the GenericCSVData function
data = btfeed.GenericCSVData( dataname='M:\\EURUSD2.csv', fromdate=datetime.datetime(2015, 1, 1), todate=datetime.datetime(2015, 1, 3), nullvalue=0.0, dtformat=('%Y%m%d %H%M%S'), timefame=bt.TimeFrame.Minutes, compression=1, datetime=2, time=-1, open=4, high=5, low=6, close=7, volume=-1, openinterest=-1 )
When I run a test strategy, all orders wait until the next day to complete. All log data is timestamped "23:59:59.999". From all I can tell, the time isn't being passed to the strategy right. I was under the impression that the strategy is agnostic to tick/minute/hour/etc., it only cares about the next bar.
I must be missing something simple.
Thank you.
-
The marking of each bar with the end of day time indicates the data feed is being interpreted as `bt.TimeFrame.Days'. The obvious culprit:
@iswanb said in Intraday time issue/Orders waiting until T+1:
timefame=bt.TimeFrame.Minutes,
-
Thank you. Realize now that calling bt.TimeFrame.minutes was to be done if I wanted to resample or compress the data. However, there was no change when I commented out those lines.
I even stripped everything down using the simple TestStrategy from the docs/quickstart with no change.
from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime import backtrader as bt import backtrader.feeds as btfeed class TestStrategy(bt.Strategy): def log(self, txt, dt=None): ''' Logging function fot this strategy''' #changed to datetime to view time as well dt = dt or self.datas[0].datetime.datetime(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): # Keep a reference to the "close" line in the data[0] dataseries self.dataclose = self.datas[0].close def next(self): # Simply log the closing price of the series from the reference self.log('Close, %.2f' % self.dataclose[0]) if __name__ == '__main__': # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(TestStrategy) # Create a Data Feed data = btfeed.GenericCSVData( dataname='M:\\Stock Data\\EURUSD2.csv', fromdate=datetime.datetime(2015, 1, 1), todate=datetime.datetime(2015, 1, 3), nullvalue=0.0, dtformat=('%Y%m%d %H%M%S'), datetime=2, time=-1, open=4, high=5, low=6, close=7, volume=-1, openinterest=-1 ) # Add the Data Feed to Cerebro cerebro.adddata(data) # Set our desired cash start cerebro.broker.setcash(10000.0) cerebro.broker.setcommission(commission=0.001) # Print out the starting conditions print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Run over everything cerebro.run() # Print out the final result print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
Results in:
2015-01-02T23:59:59.999989, Close, 1.20 2015-01-02T23:59:59.999989, Close, 1.20 2015-01-02T23:59:59.999989, Close, 1.20 2015-01-02T23:59:59.999989, Close, 1.20 2015-01-02T23:59:59.999989, Close, 1.20 2015-01-02T23:59:59.999989, Close, 1.20 2015-01-02T23:59:59.999989, Close, 1.20 2015-01-02T23:59:59.999989, Close, 1.20 2015-01-02T23:59:59.999989, Close, 1.20 2015-01-02T23:59:59.999989, Close, 1.20 2015-01-02T23:59:59.999989, Close, 1.20 Final Portfolio Value: 10000.00
-
It seems you missed why the specific line of your code was extracted and highlighted:
-
You had written
timefame
(notice the missingr
) as the name of the argument to the data feed. -
And the name of the argument is
timeframe
The examples in the quickstart docs use a daily timeframe and this is the default. That's why there is no need in that case to specify
timeframe=bt.TimeFrame.Minutes
-
-
Got it. Thanks so much!