import backtrader
import pandas as pd
from datetime import datetime, date, time
import argparse
class OpeningInsideCandle(backtrader.Strategy):
params = dict(
num_bar = 15
)
def __init__(self):
self.opening_candle_low = 0
self.opening_candle_high = 0
self.order = None
def log(self, txt, dt=None):
if dt is None:
dt = self.datas[0].datetime.datetime()
print('%s, %s' % (dt, txt))
def notify_order(self, order):
if order.status in [order.Submitted, order.Accepted]:
self.order = order
return
if order.status in [order.Expired, order.Canceled, order.Margin, order.Rejected]:
self.log('ORDER Canceled/Margins/Rejected')
elif order.status in [order.Completed]:
if order.isbuy():
self.log(
'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
(order.executed.price,
order.executed.value,
order.executed.comm))
else:
self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
(order.executed.price,
order.executed.value,
order.executed.comm))
self.order = None
def next(self):
current_candle_datetime = self.data.num2date(self.data.datetime(0))
previous_candle_datetime = self.data.num2date(
self.data.datetime(-1))
if current_candle_datetime.date() != previous_candle_datetime.date():
self.opening_candle_high = 0
self.opening_candle_low = 0
self.brought_today = False
if current_candle_datetime.time() == time(9, 30, 00):
side = 1 if self.data.close[-1] > self.data.open[-1] else -1
is_inside_candle = self.data.high[0] < self.data.high[-1] and self.data.low[0] < self.data.low[-1]
if is_inside_candle:
self.opening_candle_high = self.data.high[-1]
self.opening_candle_low = self.data.low[0]
if (current_candle_datetime.time() < time(9, 15, 00) and current_candle_datetime.time() >= time(9, 45, 00)):
if self.position and current_candle_datetime.time() == time(15, 30, 00):
self.log("Day Closing")
self.close()
if side == 1:
buyPrice = self.opening_candle_high
stoploss = self.opening_candle_low - \
(self.opening_candle_low*0.0005)
sl = buyPrice - stoploss
if ((abs(buyPrice - stoploss) / buyPrice) * 100) >= 0.35:
target = buyPrice + sl
self.order = self.buy_bracket(
limitprice=target, price=buyPrice, stopprice=stoploss, valid=0)
else:
target = buyPrice + (sl*2)
self.order = self.buy_bracket(
limitprice=target, price=buyPrice, stopprice=stoploss, valid=0)
else:
sellPrice = self.opening_candle_low
stoploss = self.opening_candle_high + \
(self.opening_candle_high*0.0005)
sl = sellPrice - stoploss
if ((abs(sellPrice - stoploss) / sellPrice) * 100) >= 0.35:
target = sellPrice - sl
self.order = self.sell_bracket(
limitprice=target, price=sellPrice, stopprice=stoploss, valid=0)
else:
target = sellPrice - (sl*2)
self.order = self.sell_bracket(
limitprice=target, price=sellPrice, stopprice=stoploss, valid=0)
def parse_args():
parser = argparse.ArgumentParser(
description='Pandas test script')
parser.add_argument('--noheaders', action='store_true', default=False,
required=False,
help='Do not use header rows')
parser.add_argument('--noprint', action='store_true', default=False,
help='Print the dataframe')
return parser.parse_args()
if __name__ == '__main__':
args = parse_args()
cerebro = backtrader.Cerebro()
cerebro.broker.setcash(1000000.0)
skiprows = 1 if args.noheaders else 0
header = None if args.noheaders else 0
dataframe = pd.read_csv(
"bnf_data.csv", skiprows=skiprows,
header=header,index_col=0, parse_dates=True)
data = backtrader.feeds.PandasData(dataname=dataframe)
cerebro.adddata(data)
cerebro.addstrategy(OpeningInsideCandle)
cerebro.run()
cerebro.plot()
Traceback (most recent call last):
File "/Users/hrithikjain/BackTrade Backtesting/Trader.py", line 121, in <module>
cerebro.run()
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/backtrader/cerebro.py", line 1127, in run
runstrat = self.runstrategies(iterstrat)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/backtrader/cerebro.py", line 1293, in runstrategies
self._runonce(runstrats)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/backtrader/cerebro.py", line 1695, in _runonce
strat._oncepost(dt0)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/backtrader/strategy.py", line 311, in _oncepost
self.nextstart() # only called for the 1st value
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/backtrader/lineiterator.py", line 347, in nextstart
self.next()
File "/Users/hrithikjain/BackTrade Backtesting/Trader.py", line 46, in next
current_candle_datetime = self.data.num2date(self.data.datetime(0))
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/backtrader/feed.py", line 256, in num2date
return num2date(dt, tz or self._tz, naive)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/backtrader/utils/dateintern.py", line 165, in num2date
ix = int(x)
TypeError: int() argument must be a string, a bytes-like object or a number, not '_LineDelay'
Getting this error please help