Hourly Data



  • Hi Just wanna check whether this is the way to import an hourly data.

    data0 = btfeeds.GenericCSVData(dataname=datapath0,
                                       timeframe=bt.TimeFrame.Minutes,
                                      fromdate = datetime.datetime(2017,3,15),
                                      todate=datetime.datetime(2017,3,20),                                  
                                      nullvalue=0.0,
                                      dtformat=('%Y.%m.%d'),
                                      tmformat=('%H:%M'),
                                      datetime=0,
                                      time=1,
                                      open=2,
                                      high=3,
                                      low=4,
                                      close=5,
                                      volume=6,
                                      openinterest=-1)
    

    is this the way to set the order to be valid for an hour?

    self.sell(exectype = bt.Order.Limit,price=self.data.close[-1],
                                transmit=False,valid=datetime.datetime.now()+datetime.timedelta(hours=1))
    
    

    This is the full code.

    
    
    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    import os.path
    import argparse
    import datetime
    
    import backtrader as bt
    import backtrader.feeds as btfeeds
    import backtrader.plot as plt
    import backtrader.indicators as btinds
    
    class EMA(btinds.PeriodN):
        lines = ('signal1','signal2')
        params = (('p1',5),('p2',20),('p3',50),)
        
        def __init__(self):
            ema5 = btinds.ExponentialMovingAverage(self.data.close, period=self.p.p1)
            ema20 = btinds.ExponentialMovingAverage(self.data.close, period=self.p.p2)
            ema50 = btinds.ExponentialMovingAverage(self.data.close,period=self.p.p3)
            self.lines.signal1 = ema5-ema20
            self.lines.signal2 = ema20-ema50
    
    class St(bt.Strategy):
        
        def log(self, txt, dt=None):
            ''' Logging function fot this strategy'''
            dt = dt or self.data0.datetime.date(0)
            dt1 = self.data0.datetime.time(0)
            print('%s,%s, %s' % (dt.isoformat(),dt1.isoformat(), txt))
            
        def __init__(self):
            self.trigger = EMA()
            self.spread = btinds.AverageTrueRange(period=20)
            
        def notify_order(self, order):
            print('{} {}: Order ref: {} / Type {} / Status {}'.format(
                self.data.datetime.date(0),self.data.datetime.time(0),
                order.ref, 'Buy' * order.isbuy() or 'Sell',
                order.getstatusname()))
            
            if order.status in [order.Submitted, order.Accepted]:
                return
            
            if order.status in [order.Completed]:
                if order.isbuy():
                    self.log(
                        'BUY EXECUTED, Ref: %d, Price: %.5f, Cost: %.5f' %
                        (order.ref,order.executed.price,
                         order.executed.value))
                    
                    self.buyprice = order.executed.price
                    
                else:  # Sell
                    self.log('SELL EXECUTED, Ref: %d,Price: %.5f, Cost: %.5f' %
                             (order.ref,order.executed.price,
                              order.executed.value))
            
                self.bar_executed = len(self)
                
            elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                self.log('Order Canceled/Margin/Rejected')
            
            if not order.alive() and order.ref in self.orefs:
                self.orefs.remove(order.ref)
            
        def notify_trade(self, trade):
            if not trade.isclosed:
                return
    
            self.log('OPERATION PROFIT, GROSS %.5f, NET %.5f' %
                     (trade.pnl, trade.pnlcomm))
            
        def next(self):
            txt = ','.join(
                ['%04d' % len(self.data0),
                 self.data0.datetime.date(0).isoformat(),
                 self.data0.datetime.time(0).isoformat(),
                 'Open : %.5f' % self.data0.open[0],
                 'High : %.5f' % self.data.high[0],
                 'Low : %.5f' % self.data.low[0],
                 'Close : %.5f' % self.data.close[0]]) 
            print(txt)
    
     
    
            if (self.trigger.signal1[0] > 0) and (self.trigger.signal2[0] > 0):
                 o1 = self.sell(exectype = bt.Order.Limit,price=self.data.close[-1],
                                transmit=False,valid=datetime.datetime.now()+datetime.timedelta(hours=1))
                 
                 print(self.datetime.date(0),self.datetime.time(0),' : Oref %d / Sell at %.5f' % (
                            o1.ref, self.data.close[-1]))
                
                 o2 = self.buy(exectype=bt.Order.Limit,price=(self.data.close[-1] - self.spread.atr[0] * 2),
                                parent=o1,transmit=False)
                 
                 print(self.datetime.date(0),self.datetime.time(0),' : Oref %d / Sell Take Profit at %.5f' % (
                            o2.ref, (self.data.close[-1] - self.spread.atr[0] * 2)))
                 
                 o3 = self.buy(exectype=bt.Order.Stop,price = (self.spread.atr[0] * 2 +self.data.close[-1]),
                               parent=o1,transmit = True)
                 
                 print(self.datetime.date(0),self.datetime.time(0),' : Oref %d / Sell Stop Loss at %.5f' % (
                            o3.ref, (self.spread.atr[0] * 2 +self.data.close[-1])))
                 
                 self.orefs = [o1.ref, o2.ref, o3.ref]
                 
            elif (self.trigger.signal1[0] < 0) and (self.trigger.signal2[0] < 0):
                 o1 = self.buy(exectype = bt.Order.Limit,price=self.data.close[-1],
                                transmit=False,valid= datetime.datetime.now()+datetime.timedelta(hours=1))
                 
                 print(self.datetime.date(0),self.datetime.time(0),' : Oref %d / Buy at %.5f' % (
                            o1.ref, self.data.close[-1]))
                
                 o2 = self.sell(exectype=bt.Order.Limit,price=(self.spread.atr[0] * 2 +self.data.close[-1]),
                                parent=o1,transmit=False)
                 
                 print(self.datetime.date(0),self.datetime.time(0),' : Oref %d / Buy Take Profit at %.5f' % (
                            o2.ref, (self.spread.atr[0] * 2 +self.data.close[-1])))
                 
                 o3 = self.sell(exectype=bt.Order.Stop,price = (self.data.close[-1] - self.spread.atr[0] * 2),
                               parent=o1,transmit = True)
                 
                 print(self.datetime.date(0),self.datetime.time(0),' : Oref %d / Buy Stop Loss at %.5f' % (
                            o3.ref, (self.data.close[-1] - self.spread.atr[0] * 2))) 
                 
                 self.orefs = [o1.ref, o2.ref, o3.ref]
            
            else:
                 return
    
    
    
    class Plotter(plt.Plot):
    
        def __init__(self):
            super().__init__(volup='#60cc73')  # custom color for volume up bars 
    
        def show(self):
            mng = self.mpyplot.get_current_fig_manager()
            mng.window.state('zoomed')
            self.mpyplot.show()  
                      
    def runstrat():
        args = parse_args()
    
        cerebro = bt.Cerebro()
        modpath = 'd:\\I - TradersGPS\\'
        datapath0 = os.path.join(modpath, 'GBPUSD_H1_UTC+2_00.csv')
       
        data0 = btfeeds.GenericCSVData(dataname=datapath0,
                                       timeframe=bt.TimeFrame.Minutes,
                                      fromdate = datetime.datetime(2017,3,15),
                                      todate=datetime.datetime(2017,3,20),                                  
                                      nullvalue=0.0,
                                      dtformat=('%Y.%m.%d'),
                                      tmformat=('%H:%M'),
                                      datetime=0,
                                      time=1,
                                      open=2,
                                      high=3,
                                      low=4,
                                      close=5,
                                      volume=6,
                                      openinterest=-1)
    
        cerebro.adddata(data0,name ="Hourly Data")
    
    
        cerebro.addstrategy(St)
        cerebro.broker.setcash(100000.0)
        print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
        cerebro.run(stdstats=False)
        print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
        plotter = Plotter()
        cerebro.plot(plotter=plotter,subplot=False)
        
    
            
    def parse_args():
        parser = argparse.ArgumentParser(
            formatter_class=argparse.ArgumentDefaultsHelpFormatter,
            description='Sample for pivot point and cross plotting')
    
        parser.add_argument('--data0',
                            default='d:\\I - TradersGPS\\GBPUSD_D1_UTC+2_00.csv',
                            required=False, help='Data0 to read in')
    
        parser.add_argument('--data1', 
                            default='d:\\I - TradersGPS\\GBPUSD_H1_UTC+2_00.csv',
                            required=False, help='Data1 to read in')
    
        parser.add_argument('--fromdate', required=False, default='2001-01-01',
                            help='Date[time] in YYYY-MM-DD[THH:MM:SS] format')
        
        parser.add_argument('--todate', required=False, default='2007-01-01',
                            help='Date[time] in YYYY-MM-DD[THH:MM:SS] format')
    
        parser.add_argument('--plot', required=False, action='store_true',
                            help=('Plot the result'))
    
        return parser.parse_args()
    
    
    if __name__ == '__main__':
        runstrat()
        
    

    This is the full data used for the code. Its in csv format. The col names are date, time, open, high,low,close,and volume.

    2017.03.15,00:00,1.21542,1.21545,1.21469,1.21524,2206
    2017.03.15,01:00,1.21526,1.21579,1.21512,1.21565,2452
    2017.03.15,02:00,1.21564,1.21629,1.21543,1.21585,6088
    2017.03.15,03:00,1.21585,1.2165,1.21583,1.21614,5760
    2017.03.15,04:00,1.21615,1.21641,1.21561,1.21563,5428
    2017.03.15,05:00,1.21561,1.21578,1.21547,1.21573,3666
    2017.03.15,06:00,1.21573,1.21652,1.21568,1.21632,5902
    2017.03.15,07:00,1.21633,1.21775,1.21632,1.21761,5403
    2017.03.15,08:00,1.21759,1.22564,1.21724,1.2222,16657
    2017.03.15,09:00,1.22222,1.22303,1.22128,1.22296,14750
    2017.03.15,10:00,1.22295,1.22361,1.22216,1.22276,15442
    2017.03.15,11:00,1.22276,1.22369,1.21891,1.22035,19990
    2017.03.15,12:00,1.22034,1.22037,1.21783,1.21926,13041
    2017.03.15,13:00,1.21926,1.21959,1.21845,1.21933,10811
    2017.03.15,14:00,1.21936,1.22084,1.21913,1.21942,13239
    2017.03.15,15:00,1.21943,1.22046,1.21929,1.22,12251
    2017.03.15,16:00,1.22,1.22058,1.21905,1.22004,12706
    2017.03.15,17:00,1.22004,1.22258,1.21993,1.22209,13129
    2017.03.15,18:00,1.22212,1.22264,1.22104,1.22214,12973
    2017.03.15,19:00,1.22216,1.22228,1.21994,1.22021,12341
    2017.03.15,20:00,1.22021,1.23017,1.21963,1.22933,34103
    2017.03.15,21:00,1.22932,1.23022,1.22725,1.22972,21987
    2017.03.15,22:00,1.22972,1.23091,1.22814,1.22911,16419
    2017.03.15,23:00,1.22904,1.22911,1.22789,1.22869,3891
    2017.03.16,00:00,1.2287,1.22958,1.22856,1.22908,5988
    2017.03.16,01:00,1.22907,1.22945,1.22765,1.22822,7144
    2017.03.16,02:00,1.22822,1.22913,1.22731,1.2274,11114
    2017.03.16,03:00,1.22745,1.22778,1.22654,1.22672,8733
    2017.03.16,04:00,1.22676,1.22776,1.22649,1.2269,7097
    2017.03.16,05:00,1.2269,1.22734,1.22601,1.22641,10835
    2017.03.16,06:00,1.22641,1.22714,1.22627,1.2266,10021
    2017.03.16,07:00,1.2266,1.22724,1.22651,1.22659,7106
    2017.03.16,08:00,1.2266,1.22816,1.22618,1.22804,12500
    2017.03.16,09:00,1.2281,1.22956,1.22669,1.22725,21005
    2017.03.16,10:00,1.22728,1.22795,1.22551,1.22554,16387
    2017.03.16,11:00,1.22554,1.22659,1.22413,1.22497,13910
    2017.03.16,12:00,1.22497,1.22758,1.22473,1.22548,14495
    2017.03.16,13:00,1.22549,1.22718,1.22472,1.22639,14245
    2017.03.16,14:00,1.2264,1.23721,1.22639,1.23694,29017
    2017.03.16,15:00,1.23686,1.23713,1.23365,1.23411,17264
    2017.03.16,16:00,1.23411,1.23665,1.23404,1.23621,15739
    2017.03.16,17:00,1.23621,1.2375,1.2344,1.2368,14576
    2017.03.16,18:00,1.23682,1.23721,1.23589,1.23711,11462
    2017.03.16,19:00,1.23711,1.23769,1.2348,1.23522,10574
    2017.03.16,20:00,1.2352,1.2364,1.2343,1.23588,10558
    2017.03.16,21:00,1.23589,1.23602,1.23463,1.2357,11578
    2017.03.16,22:00,1.23567,1.2363,1.23526,1.23586,6554
    2017.03.16,23:00,1.23586,1.23628,1.23512,1.23595,3276
    2017.03.17,00:00,1.23587,1.23589,1.23501,1.23552,4564
    2017.03.17,01:00,1.23558,1.23559,1.23451,1.23498,3733
    2017.03.17,02:00,1.23499,1.23572,1.23487,1.23561,5700
    2017.03.17,03:00,1.23561,1.23576,1.23476,1.2349,6879
    2017.03.17,04:00,1.23489,1.23521,1.23433,1.23518,4409
    2017.03.17,05:00,1.23517,1.23547,1.23477,1.23519,4274
    2017.03.17,06:00,1.23521,1.23559,1.23492,1.23553,3473
    2017.03.17,07:00,1.23553,1.23572,1.2349,1.23538,3402
    2017.03.17,08:00,1.2354,1.23723,1.23538,1.23649,7620
    2017.03.17,09:00,1.23646,1.23689,1.23237,1.23378,15104
    2017.03.17,10:00,1.23375,1.23893,1.23333,1.2387,14981
    2017.03.17,11:00,1.23866,1.23983,1.23783,1.23888,16611
    2017.03.17,12:00,1.2389,1.23958,1.23779,1.23842,16616
    2017.03.17,13:00,1.23846,1.23849,1.23346,1.23598,21205
    2017.03.17,14:00,1.23602,1.23702,1.23461,1.23574,16343
    2017.03.17,15:00,1.23576,1.23694,1.23485,1.23653,15528
    2017.03.17,16:00,1.23653,1.23765,1.23615,1.23676,14217
    2017.03.17,17:00,1.23675,1.23729,1.23603,1.23701,14439
    2017.03.17,18:00,1.23701,1.23895,1.23671,1.23874,14336
    2017.03.17,19:00,1.23873,1.23972,1.2386,1.23936,10018
    2017.03.17,20:00,1.23936,1.24047,1.23908,1.23956,6863
    2017.03.17,21:00,1.23961,1.24014,1.23907,1.23908,6511
    2017.03.17,22:00,1.23908,1.23984,1.23886,1.23945,5466
    2017.03.19,23:00,1.2381,1.23915,1.23796,1.23847,1394
    2017.03.20,00:00,1.23847,1.23911,1.23838,1.23868,2758
    2017.03.20,01:00,1.23868,1.23881,1.2382,1.23833,2955
    2017.03.20,02:00,1.23833,1.23884,1.23812,1.23824,4078
    2017.03.20,03:00,1.23825,1.23907,1.2382,1.23902,5344
    2017.03.20,04:00,1.23902,1.23926,1.23838,1.23848,4912
    2017.03.20,05:00,1.23852,1.23877,1.23804,1.23839,4008
    2017.03.20,06:00,1.23838,1.23877,1.23832,1.23866,3246
    2017.03.20,07:00,1.23868,1.23944,1.23868,1.23937,3854
    2017.03.20,08:00,1.23935,1.24018,1.23871,1.23994,6686
    2017.03.20,09:00,1.23995,1.24354,1.23976,1.24177,14185
    2017.03.20,10:00,1.24177,1.24256,1.24023,1.24095,13778
    2017.03.20,11:00,1.24095,1.24246,1.2406,1.24115,13768
    2017.03.20,12:00,1.24117,1.24202,1.23997,1.24183,10369
    2017.03.20,13:00,1.24184,1.24184,1.23787,1.23839,13195
    2017.03.20,14:00,1.23842,1.23883,1.23664,1.23822,13276
    2017.03.20,15:00,1.23818,1.23961,1.23747,1.23884,11533
    2017.03.20,16:00,1.23883,1.23964,1.23827,1.2383,12111
    2017.03.20,17:00,1.23832,1.23874,1.2364,1.23655,13787
    2017.03.20,18:00,1.23655,1.23715,1.2335,1.23453,14811
    2017.03.20,19:00,1.2346,1.23538,1.23396,1.23443,11122
    2017.03.20,20:00,1.23442,1.23511,1.23431,1.23462,7742
    2017.03.20,21:00,1.23462,1.23593,1.23454,1.23562,6938
    2017.03.20,22:00,1.23562,1.23606,1.23532,1.23578,5342
    2017.03.20,23:00,1.23573,1.23601,1.2355,1.23573,2112
    

    Thanks!!


  • administrators

    @KT said in Hourly Data:

    timeframe=bt.TimeFrame.Minutes,

    If you don't specify the compression=60, the default of compression=1 will be used.

    @KT said in Hourly Data:

    valid=datetime.datetime.now()+datetime.timedelta(hours=1)

    If you were doing live trading, the current clock time would approximate the data source time. But it doesn't in backtesting. Use self.dataX.datetime.datetime(), or the reference clock of the strategy self.datetime.datetime()



  • Thanks @backtrader !!


Log in to reply
 

Looks like your connection to Backtrader Community was lost, please wait while we try to reconnect.