In the world of trading and investing, candlestick patterns play a significant role in helping traders make informed decisions. One such pattern is the “Inside Bar,” which can signal potential changes in price direction.
In this article, we will explore how to use Python and the Zerodha Kite Connect API to detect Inside Bars for a specific stock, such as RELIANCE.
# Initialize variables to track inside bars
inside_bars = []
# Iterate through historical data to detect inside bars
for i in range(1, len(historical_data)):
current_candle = historical_data[i]
previous_candle = historical_data[i - 1]
if (current_candle['high'] < previous_candle['high']) and (current_candle['low'] > previous_candle['low']):
inside_bars.append(current_candle)
In this section of the code, we initialize an empty list called inside_bars
to keep track of detected Inside Bars.
We then loop through the historical data, comparing each candle with the previous one to check if it meets the Inside Bar criteria. If a candle meets the conditions, it is added to the inside_bars
list.
# Print or post detected inside bars
for candle in inside_bars:
print(f"Inside Bar detected at {candle['date']} for RELIANCE")
inside_bars
list and print the date and time of each detected Inside Bar for RELIANCE.
Now, let’s put it all together to complete the code:
# Fetch the instrument token for RELIANCE
instrument_token = None
# Use Kite Connect's search instruments API to find RELIANCE's instrument token
instruments = kite.ltp(['NSE:RELIANCE'])
if 'NSE:RELIANCE' in instruments:
instrument_token = instruments['NSE:RELIANCE']['instrument_token']
if instrument_token:
# Fetch historical data for RELIANCE
historical_data = kite.historical_data(instrument_token, '2023-01-01', '2023-09-01', interval='minute')
# Initialize variables to track inside bars
inside_bars = []
# Iterate through historical data to detect inside bars
for i in range(1, len(historical_data)):
current_candle = historical_data[i]
previous_candle = historical_data[i - 1]
if (current_candle['high'] < previous_candle['high']) and (current_candle['low'] > previous_candle['low']):
inside_bars.append(current_candle)
# Print or post detected inside bars
for candle in inside_bars:
print(f"Inside Bar detected at {candle['date']} for RELIANCE")
else:
print("Instrument token not found for RELIANCE")
But it throws an error the moment it runs –
---------------------------------------------------------------------------
InputException Traceback (most recent call last)
Cell In[8], line 6
2 instrument_token = instruments['NSE:RELIANCE']['instrument_token']
4 if instrument_token:
5 # Fetch historical data for RELIANCE
----> 6 historical_data = kite.historical_data(instrument_token, '2023-01-01', '2023-09-01', interval='minute')
8 # Initialize variables to track inside bars
9 inside_bars = []
File ~/apps/trident/../kiteconnect/connect.py:503, in KiteConnect.historical_data(self, instrument_token, from_date, to_date, interval, continuous, oi)
500 from_date_string = from_date.strftime(date_string_format) if type(from_date) == datetime.datetime else from_date
501 to_date_string = to_date.strftime(date_string_format) if type(to_date) == datetime.datetime else to_date
--> 503 data = self._get("market.historical", {
504 "instrument_token": instrument_token,
505 "from": from_date_string,
506 "to": to_date_string,
507 "interval": interval,
508 "continuous": 1 if continuous else 0,
509 "oi": 1 if oi else 0
510 })
512 return self._format_historical(data, oi)
File ~/apps/trident/../kiteconnect/connect.py:601, in KiteConnect._get(self, route, params)
599 def _get(self, route, params=None):
600 """Alias for sending a GET request."""
--> 601 return self._request(route, "GET", params)
File ~/apps/trident/../kiteconnect/connect.py:671, in KiteConnect._request(self, route, method, parameters)
669 # native Kite errors
670 exp = getattr(ex, data["error_type"], ex.GeneralException)
--> 671 raise exp(data["message"], code=r.status_code)
673 return data["data"]
674 elif "csv" in r.headers["content-type"]:
InputException: interval exceeds limit: 60 days
Well, KiteConnect API does not allow intraday day for more than 60 days in one go. Anyways, We can run for loop by breaking up the date range to each 60 days to make it work.
So, Let’s iterate through smaller date ranges (each within 60 days) –
from datetime import datetime, timedelta
# Define the date range
start_date = datetime.strptime('2023-01-01', '%Y-%m-%d')
end_date = datetime.strptime('2023-09-01', '%Y-%m-%d')
# Define the interval (in minutes)
interval = 'minute'
# Initialize variables to track inside bars
inside_bars = []
# Iterate through smaller date ranges (each within 60 days)
while start_date < end_date:
# Calculate the end date for the current batch (within 60 days)
batch_end_date = start_date + timedelta(days=60)
# Ensure that the batch end date does not exceed the overall end date
if batch_end_date > end_date:
batch_end_date = end_date
# Fetch historical data for the current batch
historical_data = kite.historical_data(instrument_token, start_date, batch_end_date, interval)
# Iterate through historical data to detect inside bars for this batch
for i in range(1, len(historical_data)):
current_candle = historical_data[i]
previous_candle = historical_data[i - 1]
if (
current_candle['high'] < previous_candle['high']
and current_candle['low'] > previous_candle['low']
):
inside_bars.append(current_candle)
# Move the start date for the next batch
start_date = batch_end_date
# Print or post detected inside bars for the entire date range
for candle in inside_bars:
print(f"Inside Bar detected at {candle['date']} for RELIANCE")
Here is the output that shows the time of each 1 minute candle that was ever an Inside Bar in Reliance in that time period!
Inside Bar detected at 2023-01-02 09:16:00+05:30 for RELIANCE
Inside Bar detected at 2023-01-02 09:19:00+05:30 for RELIANCE
Inside Bar detected at 2023-01-02 09:22:00+05:30 for RELIANCE
Inside Bar detected at 2023-01-02 09:35:00+05:30 for RELIANCE
Inside Bar detected at 2023-01-02 09:40:00+05:30 for RELIANCE
...........
...........
...........
...........
Inside Bar detected at 2023-08-31 14:49:00+05:30 for RELIANCE
Inside Bar detected at 2023-08-31 14:50:00+05:30 for RELIANCE
Inside Bar detected at 2023-08-31 14:58:00+05:30 for RELIANCE
Inside Bar detected at 2023-08-31 15:04:00+05:30 for RELIANCE
Inside Bar detected at 2023-08-31 15:08:00+05:30 for RELIANCE
To display the inside bar candles that happened in Daily Timeframe, all one has to do is change the
interval = 'minute'
to
interval = 'day'
The logic works same. It is just basically shifting the timeframe! The output is also neat –
Inside Bar detected at 2023-02-02 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-02-06 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-02-21 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-03-01 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-03-17 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-04-10 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-04-11 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-04-13 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-04-19 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-04-25 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-04-27 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-07-05 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-07-25 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-07-27 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-08-21 00:00:00+05:30 for RELIANCE
Inside Bar detected at 2023-08-30 00:00:00+05:30 for RELIANCE