I have following Option Buying code for backtest
import tardehull_options_bt_lib as tob
from pprint import pprint
import pandas as pd
import datetime
import pandas_ta as ta
import pdb
pd.set_option('display.max_rows', None)
start_date = datetime.date(2019, 9, 5)
end_date = datetime.date(2022, 6, 30)
start_date = start_date.strftime("%Y-%m-%d") + " 09:15:00+05:30"
end_date = end_date.strftime("%Y-%m-%d") + " 15:15:00+05:30"
watchlist = ['NIFTY 50']
current_order = {'name':None, 'date':None , 'entry_time': None, 'entry_price': None, 'buy_sell': None, 'qty': None, 'sl': None, 'exit_time': None, 'exit_price': None, 'pnl': None, 'remark': None, 'traded':None, "options_script_name":None, "opt_entry_price":None, "opt_exit_price":None, "opt_pnl":None}
rsi_timeperiod = 14
atr_timeperiod = 14
bb_timeperiod = 14
stoploss_multiplier = 1
risk_per_trade = 500
final_result = []
for name in watchlist:
# -------------------------------------------- Read Data and clean it --------------------------------------------
print(f"Backtesting {name} number is {watchlist.index(name)}")
df = tob.get_spot_data()
df = df[start_date : end_date]
df = df.set_index(df['date'])
df = df[['open', 'high', 'low', 'close', 'volume']]
# -------------------------------------------- Read Data and clean it --------------------------------------------
df['rsi'] = df['rsi'] = ta.rsi(df['close'], length=rsi_timeperiod)
df['atr'] = ta.atr(df['high'], df['low'], df['close'], length=atr_timeperiod)
# Bollinger Bands calculation
bbands = ta.bbands(df['close'], length=bb_timeperiod, std=2) # std represents nbdevup and nbdevdn in TA-Lib
df['upperband'] = bbands['BBU_{}_2.0'.format(bb_timeperiod)]
df['middleband'] = bbands['BBM_{}_2.0'.format(bb_timeperiod)]
df['lowerband'] = bbands['BBL_{}_2.0'.format(bb_timeperiod)]
# -------------------------------------------- Read data candle by candle --------------------------------------------
df.dropna()
for datetimex, candle in df.iterrows():
print(f"Index: {datetimex}, Candle: {candle}")
try:
# -------------------------------------------- Buy Entry Conditions --------------------------------------------
buy_c1 = candle['rsi'] > 60
buy_c2 = current_order['traded'] is None
buy_c3 = candle['close'] > candle['upperband']
if buy_c1 and buy_c2 and buy_c3:
print(f"Buy {name} on {datetimex} {candle['rsi']}")
todays_date_in_datetime = datetime.datetime.strptime(datetimex[:10], '%Y-%m-%d').date()
this_expiry_file_format, expiry = tob.get_expiry_according_to_rules(todays_date_in_datetime)
atm_strike = round(candle['close']/50)*50
if datetimex == '2019-10-14 09:15:00+05:30':
x =1 #pdb.set_trace()
options_filename, options_data , ce_entry_premium = tob.get_options_price(file_name = "search", underlying = 'NIFTY' , expiry_file_format=this_expiry_file_format , strike= atm_strike, right= 'CE', spot_datetime=datetimex[:19])
current_order["options_script_name"] = options_filename
current_order["opt_entry_price"] = ce_entry_premium
sl_points = candle['atr']
current_order['name'] = name
current_order['date'] = datetimex[:10]
current_order['entry_time'] = datetimex[11:16]
current_order['entry_price'] = candle['close']
current_order['buy_sell'] = "buy"
current_order['qty'] = 50
current_order['sl'] = (current_order['entry_price'] - sl_points)
current_order['traded'] = "yes"
continue
sell_c1 = candle['rsi'] < 40
sell_c2 = current_order['traded'] is None
sell_c3 = candle['close'] < candle['lowerband']
if sell_c1 and sell_c2 and sell_c3:
print(f"Sell {name} on {datetimex} {candle['rsi']}")
todays_date_in_datetime = datetime.datetime.strptime(datetimex[:10], '%Y-%m-%d').date()
this_expiry_file_format, expiry = tob.get_expiry_according_to_rules(todays_date_in_datetime)
atm_strike = round(candle['close']/50)*50
options_filename, options_data , ce_entry_premium = tob.get_options_price(file_name = "search", underlying = 'NIFTY' , expiry_file_format=this_expiry_file_format , strike= atm_strike, right= 'PE', spot_datetime=datetimex[:19])
current_order["options_script_name"] = options_filename
current_order["opt_entry_price"] = ce_entry_premium
# print(f"Sell {name} on {datetimex} {candle['rsi']}")
sl_points = candle['atr']
current_order['name'] = name
current_order['date'] = datetimex[:10]
current_order['entry_time'] = datetimex[11:16]
current_order['entry_price'] = candle['close']
current_order['buy_sell'] = "sell"
current_order['qty'] = 50
current_order['sl'] = (current_order['entry_price'] + sl_points)
current_order['traded'] = "yes"
continue
# -------------------------------------------- Exit Entry Conditions --------------------------------------------
if current_order['traded'] == "yes":
bought = current_order['buy_sell'] == "buy"
sold = current_order['buy_sell'] == "sell"
if bought:
stoploss_hit = candle['low'] <= current_order['sl']
market_over = datetimex[11:16] >= "15:15"
if stoploss_hit:
print("buy .. sl_hit")
options_filename, options_data , ce_exit_premium = tob.get_options_price(file_name = current_order['options_script_name'], underlying = 'NIFTY' , expiry_file_format=this_expiry_file_format , strike= atm_strike, right= 'CE', spot_datetime=datetimex[:19])
current_order["opt_exit_price"] = ce_exit_premium
current_order["opt_pnl"] = (current_order['opt_exit_price'] - current_order['opt_entry_price'])*50
current_order['exit_time'] = datetimex[11:16]
current_order['exit_price'] = current_order['sl']
# current_order['pnl'] = (current_order['exit_price'] - current_order['entry_price'])*current_order['qty']
current_order['remark'] = "buy .. sl_hit"
final_result.append(current_order)
current_order = {'name':None, 'date':None , 'entry_time': None, 'entry_price': None, 'buy_sell': None, 'qty': None, 'sl': None, 'exit_time': None, 'exit_price': None, 'pnl': None, 'remark': None, 'traded':None, "options_script_name":None, "opt_entry_price":None, "opt_exit_price":None, "opt_pnl":None}
continue
if market_over:
print("buy .. market_over")
options_filename, options_data , ce_exit_premium = tob.get_options_price(file_name = current_order['options_script_name'], underlying = 'NIFTY' , expiry_file_format=this_expiry_file_format , strike= atm_strike, right= 'CE', spot_datetime=datetimex[:19])
current_order["opt_exit_price"] = ce_exit_premium
current_order["opt_pnl"] = (current_order['opt_exit_price'] - current_order['opt_entry_price'])*50
current_order['exit_time'] = datetimex[11:16]
current_order['exit_price'] = candle['close']
# current_order['pnl'] = (current_order['exit_price'] - current_order['entry_price'])*current_order['qty']
current_order['remark'] = "buy .. market_over"
final_result.append(current_order)
current_order = {'name':None, 'date':None , 'entry_time': None, 'entry_price': None, 'buy_sell': None, 'qty': None, 'sl': None, 'exit_time': None, 'exit_price': None, 'pnl': None, 'remark': None, 'traded':None, "options_script_name":None, "opt_entry_price":None, "opt_exit_price":None, "opt_pnl":None}
continue
if sold:
stoploss_hit = candle['high'] > current_order['sl']
market_over = datetimex[11:16] >= "15:15"
if stoploss_hit:
print("sold .. sl_hit")
options_filename, options_data , pe_exit_premium = tob.get_options_price(file_name = current_order['options_script_name'], underlying = 'NIFTY' , expiry_file_format=this_expiry_file_format , strike= atm_strike, right= 'PE', spot_datetime=datetimex[:19])
current_order["opt_exit_price"] = pe_exit_premium
current_order["opt_pnl"] = (current_order['opt_exit_price'] - current_order['opt_entry_price'])*50
current_order['exit_time'] = datetimex[11:16]
current_order['exit_price'] = current_order['sl']
# current_order['pnl'] = (current_order['entry_price'] - current_order['exit_price'])*current_order['qty']
current_order['remark'] = "sold .. sl_hit"
final_result.append(current_order)
current_order = {'name':None, 'date':None , 'entry_time': None, 'entry_price': None, 'buy_sell': None, 'qty': None, 'sl': None, 'exit_time': None, 'exit_price': None, 'pnl': None, 'remark': None, 'traded':None, "options_script_name":None, "opt_entry_price":None, "opt_exit_price":None, "opt_pnl":None}
continue
if market_over:
print("sold .. market_over")
options_filename, options_data , pe_exit_premium = tob.get_options_price(file_name = current_order['options_script_name'], underlying = 'NIFTY' , expiry_file_format=this_expiry_file_format , strike= atm_strike, right= 'PE', spot_datetime=datetimex[:19])
current_order["opt_exit_price"] = pe_exit_premium
current_order["opt_pnl"] = (current_order['opt_exit_price'] - current_order['opt_entry_price'])*50
current_order['exit_time'] = datetimex[11:16]
current_order['exit_price'] = candle['close']
# current_order['pnl'] = (current_order['entry_price'] - current_order['exit_price'])*current_order['qty']
current_order['remark'] = "sold .. market_over"
final_result.append(current_order)
current_order = {'name':None, 'date':None , 'entry_time': None, 'entry_price': None, 'buy_sell': None, 'qty': None, 'sl': None, 'exit_time': None, 'exit_price': None, 'pnl': None, 'remark': None, 'traded':None, "options_script_name":None, "opt_entry_price":None, "opt_exit_price":None, "opt_pnl":None}
continue
except Exception as e:
print(f"Error fetching or parsing creds from URL: {e}")
pdb.set_trace()
pd.DataFrame(final_result).to_excel('BT6_OPT_BACKTESTING_fixed_PNL_FORMULA.xlsx')
Dependency file for reading option file is in tardehull_options_bt_lib.py which is as follows
import pandas as pd
import pdb
import pickle
from pprint import pprint
import datetime
import os
import warnings
pd.set_option('display.max_rows', None)
dir_path = os.path.dirname(os.path.realpath(__file__)) + "\\"
warnings.filterwarnings("ignore")
spot_path = dir_path + "NIFTY 50.csv"
expiry_path = "Spot Data\\"
ce_path = "D:\\TradeHull\\Option Strategies\\Option csv data\\CE\\"
pe_path = "D:\\TradeHull\\Option Strategies\\Option csv data\\PE\\"
step_value = 50
lot_size = 50
dbfile = open(dir_path + 'icici_dates_and_strike_storage', 'rb')
icici_dates_and_strike_storage = pickle.load(dbfile)
def get_spot_data():
spot = pd.read_csv(dir_path + "NIFTY 50.csv")
spot = spot.set_index(spot['date'])
spot = spot['2019-10-09 09:15:00+05:30':]
return spot
def get_expiry_according_to_rules(todays_date_in_datetime):
all_possible_expries = [expiry for expiry in icici_dates_and_strike_storage]
for exp in all_possible_expries:
if exp >= todays_date_in_datetime:
this_expiry = icici_dates_and_strike_storage[exp]['expiry_date'].split("T")[0]
this_expiry = datetime.datetime.strptime(this_expiry, '%Y-%m-%d').date()
this_expiry_file_format = this_expiry.strftime("%y_%m_%d")
return this_expiry_file_format, this_expiry
def get_options_price(file_name, underlying, expiry_file_format, strike, right, spot_datetime):
if file_name == "search":
options_filename = f"{underlying}_{expiry_file_format}_{str(strike)}_{right}.csv"
else:
options_filename = file_name
try:
if right == "CE":
options_data = pd.read_csv(ce_path + options_filename)
if right == "PE":
options_data = pd.read_csv(pe_path + options_filename)
except Exception as e:
print(f"File not Found {options_filename}")
return 99999999 , 99999999, 99999999
options_data = options_data.set_index(options_data['datetime'])
# Remove duplicate candle data in options_data
options_data = options_data.set_index(options_data['datetime'])
options_data.index = pd.to_datetime(options_data.index)
options_data = options_data[~options_data.index.duplicated(keep='first')]
# for spot/futures to options .. sometime data can be missing so use nearst candle value
time_to_locate = pd.to_datetime(spot_datetime[:19])
# This is th file format in Excel "10/9/2019 11:30:00 AM"
time_to_locate_nearest = options_data.index[options_data.index.get_loc(time_to_locate, method='nearest')]
candle_data = options_data.loc[time_to_locate_nearest]
return options_filename, options_data , candle_data['close']
The csv files are as given in mentorship program.
The backtest code is showing error in dependency library file when it read the file data from csv file.
As per my test i found the problem in following line
time_to_locate_nearest = options_data.index[options_data.index.get_loc(time_to_locate, method=‘nearest’)]
Can you please help me to find the problem in above code