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
-
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!!
-
@KT said in Hourly Data:
timeframe=bt.TimeFrame.Minutes,
If you don't specify the
compression=60
, the default ofcompression=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 strategyself.datetime.datetime()
-
Thanks @backtrader !!