Backtrader Community

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Hourly Data

    General Discussion
    2
    3
    3378
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • K
      KT last edited by KT

      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!!

      B 1 Reply Last reply Reply Quote 0
      • B
        backtrader administrators @KT last edited by

        @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()

        1 Reply Last reply Reply Quote 0
        • K
          KT last edited by

          Thanks @backtrader !!

          1 Reply Last reply Reply Quote 0
          • 1 / 1
          • First post
            Last post
          Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors