Why Backtesting matters
Time Travel for Traders – Backtesting lets you rewind history and see how your strategy would have performed in past markets. No Time machine required!
Risk Radar – It helps spot potential dangers like big drawdowns or sudden crashes before you risk real money. Think of it as your trading seatbelt.
Numbers Don’t Lie – You get hard data on profitability, win rate, and risk metrics—no more relying on gut feelings or wishful thinking.
Tweak & Tune – Want to optimize your strategy? Backtesting lets you fine-tune parameters to find the sweet spot.
Confidence Booster – Knowing your strategy has worked before makes it easier to stick to the plan when real money is on the line.
Example Backtesting Results
Expired Contracts Data
Expired Options data is a critical component for Options backtesting, Also at the same time it can cost upto Lakhs to access expired data.
In this blog we will see how we can get it for free using icicidirect Breeze api.
We can access upto 3 years of options data from it.
Code to download data from ICICI Direct Breeze Api
import os # Import operating system module for directory creation
import pdb # Import debugger for debugging purposes
import pandas as pd # Import pandas for data handling
from breeze_connect import BreezeConnect # Import Breeze API for fetching market data
# Initialize Breeze API with API key
breeze = BreezeConnect(api_key=”h23J9r0446442o(93~55n9G7270e9p89″)
# Generate session using secret key and session token
breeze.generate_session(api_secret=”174957B6939Q2j92120A929D912697Qs”, session_token=”50784494″)
# Define parameters for options data
underlying = “NIFTY” # Underlying asset
no_of_strikes_from_atm = 20 # Number of strikes above and below ATM
step_value = 50 # Strike price step size
opening_price = 22939 # Opening price of underlying
expiry_date = ‘2025-02-20T07:00:00.000Z’ # Expiry date of options contract
start_date = ‘2025-02-20T07:00:00.000Z’ # Start date for fetching data
file_name = ‘2025-02-20’ # Name of the folder for storing data
# Create directory to store options data
os.makedirs(f”Options Data/{underlying}/{file_name}”, exist_ok=True)
# Calculate the ATM strike price (nearest multiple of step value)
atm_strike = int(opening_price / step_value) * step_value # Round opening price to nearest 50
# Generate a list of strike prices ranging from (ATM – n steps) to (ATM + n steps)
strikes = [atm_strike + i * step_value for i in range(-no_of_strikes_from_atm, no_of_strikes_from_atm + 1)]
# Loop through each strike price
for strike in strikes:
for right in [‘call’, ‘put’]: # Loop through call and put options
try:
print(f”{strikes.index(strike)} Getting data for {strike} {right} strike”) # Print progress
# Fetch historical data from Breeze API
df = pd.DataFrame(breeze.get_historical_data(interval=”1minute”,
from_date=start_date,
to_date=expiry_date,
stock_code=underlying,
exchange_code=”NFO”,
product_type=”options”,
expiry_date=expiry_date,
right=right,
strike_price=strike)[‘Success’])
pdb.set_trace() # Pause execution for debugging
except Exception as e:
print(e) # Print any error that occurs
continue # Skip to the next iteration if an error occurs
# Extract year, month, and date from expiry date for naming files
expiry_unit = expiry_date.split(“-“)
year = expiry_unit[0][2:] # Extract last two digits of the year
month = expiry_unit[1] # Extract month
date = expiry_unit[2][:2] # Extract date
# Generate file name for storing the option data
name = f”{underlying}_{year}_{month}_{date}_{strike}_{right}”
# Save data to CSV file in the created directory
df.to_csv(f”Options Data/{underlying}/{file_name}/{name}.csv”)