@run-out Thanks for the response. I was able to find out the erro. Just posting the corrected code here -
import con_config as conf
import backtrader as bt
import pandas as pd
import sqlite3
from datetime import date, datetime, time, timedelta
import matplotlib
import psycopg2
import os
import rootpath
class OpeningRangeBreakout(bt.Strategy):
params = dict(
num_opening_bars=3,
fast_length= 5*12*6,
slow_length= 25*12*6
)
def __init__(self):
self.bought_today = False
self.order = None
self.crossovers = []
self.opening_range_low = {}
self.opening_range_high = {}
self.bought_today = {}
self.opening_range = {}
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]:
# Buy/Sell order submitted/accepted to/by broker - Nothing to do
return
# Check if an order has been completed
if order.status in [order.Completed]:
order_details = f"{order.executed.price}, Cost: {order.executed.value}, Comm {order.executed.comm}"
if order.isbuy():
self.log(f"BUY EXECUTED, Price: {order_details}")
else: # Sell
self.log(f"SELL EXECUTED, Price: {order_details}")
elif order.status in [order.Canceled, order.Margin, order.Rejected]:
self.log('Order Canceled/Margin/Rejected')
self.order = None
def next(self):
for i, d in enumerate(self.datas):
current_bar_datetime = d.num2date(d.datetime[0])
previous_bar_datetime = d.num2date(d.datetime[-1])
print("current_bar_datetime",current_bar_datetime,
"previous_bar_datetime", previous_bar_datetime)
if (current_bar_datetime.date() != previous_bar_datetime.date()) :
self.opening_range_low[i] = d.low[0]
self.opening_range_high[i] = d.high[0]
self.bought_today[i] = False
opening_range_start_time = time(9, 30, 0)
dt = datetime.combine(date.today(), opening_range_start_time) + \
timedelta(minutes=self.p.num_opening_bars * 5)
opening_range_end_time = dt.time()
print("self.opening_range_high",self.opening_range_high)
if (current_bar_datetime.time() >= opening_range_start_time) \
and (current_bar_datetime.time() < opening_range_end_time):
self.opening_range_high[i] = max(d.high[0], self.opening_range_high[i])
self.opening_range_low[i] = min(d.low[0], self.opening_range_low[i])
self.opening_range[i] = self.opening_range_high[i] - self.opening_range_low[i]
else:
if self.order:
return
if self.getposition(d).size and (d.close[0] > (self.opening_range_high[i] + self.opening_range[i])):
self.close()
if d.close[0] > self.opening_range_high[i] and not self.getposition(d).size and not self.bought_today[i]:
self.order = self.buy()
self.bought_today[i] = True
if self.getposition(d).size and (self.data.close[0] < (self.opening_range_high[i] - self.opening_range[i])):
self.order = self.close()
if self.getposition(d).size and current_bar_datetime.time() >= time(15, 45, 0):
self.log("RUNNING OUT OF TIME - LIQUIDATING POSITION")
self.close()
def stop(self):
self.roi = (self.broker.get_value() / 100000) - 1.0
if __name__ == '__main__':
# Reading in the csv
# Getting the rootpath of the working directory
working_dir = rootpath.detect(__file__)
# working_dir = "C:\\Users\\40100147\\Abhishek\\Projects\\fullstack-trading-app"
nifty50_path = os.path.join(working_dir, "data\\nifty50.csv")
outputpath = os.path.join(working_dir, "data\\result_df_2.csv")
nifty50 = pd.read_csv(nifty50_path, header=0, sep='\t')
nifty50_list = tuple(nifty50['Symbol'].tolist())
conn = psycopg2.connect(**conf.con_dict)
query = f"""--sql
select a.tradingsymbol
from (
select tradingsymbol, avg(Volume) as volume
from equities.candlestick
where candle_date_time >= '01-15-2021'
and cast(candle_date_time as time(0)) > '09:30:00'
and cast(candle_date_time as time(0)) < '15:30:00'
and candle_length = '5minute'
and tradingsymbol in {nifty50_list}
group by tradingsymbol) as a;
"""
stocks = pd.read_sql(query, con=conn)
stocks_list = stocks['tradingsymbol']
result_df = []
cerebro = bt.Cerebro()
for stock in stocks_list:
query = f"""--sql
select *
from equities.candlestick
where candle_date_time >= '01-15-2021'
and cast(candle_date_time as time(0)) >= '09:30:00'
and cast(candle_date_time as time(0)) <= '15:30:00'
and tradingsymbol = '{stock}'
and candle_length = '5minute';
"""
dataframe = pd.read_sql(query,
con=conn,
index_col='candle_date_time',
parse_dates=['datetime'])
data = bt.feeds.PandasData(dataname=dataframe)
cerebro.adddata(data, name = stock)
temp_list = []
initial_cash = 100000.0
cerebro.broker.setcash(initial_cash)
# 0.01% of the operation value
cerebro.broker.setcommission(commission=0.0001)
cerebro.addsizer(bt.sizers.PercentSizer, percents=95)
cerebro.addwriter(bt.WriterFile, csv=True)
cerebro.addstrategy(OpeningRangeBreakout)
strats = cerebro.optstrategy(OpeningRangeBreakout, num_opening_bars=\
[15, 30, 60])
cerebro.run()
# Get final portfolio Value
portvalue = cerebro.broker.getvalue()
# Print out the final result
print('Final Portfolio Value: ${}'.format(portvalue))