Scanning Inside Bar Candles in Reliance Using Python and Zerodha

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.

Step 1 - Detecting Inside Bars

Now that we have historical data, we can start detecting Inside Bars. Inside Bars are candlestick patterns where the current candle’s high is lower than the previous candle’s high, and the current candle’s low is higher than the previous candle’s low.
				
					# 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.

Step 2 - Displaying Detected Inside Bars

The final step is to display the detected Inside Bars, if any.
				
					# Print or post detected inside bars
for candle in inside_bars:
    print(f"Inside Bar detected at {candle['date']} for RELIANCE")

				
			
In this code snippet, we loop through the 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")

				
			

Step 3 - Writing a For Loop to Workaround Zerodha's Limitation

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
				
			

Step 4 - Displaying Daily Inside Bars

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
				
			
Post a comment

Leave a Comment

Your email address will not be published. Required fields are marked *

×Close