Getting Historical Data of Reliance​ In Pandas Using Python and Zerodha API

Now, coming back to our old discussion of getting the historical data. So lets backtest from the start of 1/1/2019 to today. Although Kite gives data from far behind, Let’s just hold onto last few years to get faster results. You may chose older dates as you may please.
				
					import datetime
starting_date=datetime.datetime(2019, 1, 1)
ending_date=datetime.datetime.today()
				
			

The starting_date and ending_date variables are now initiated with two datetime datatypes. 

Now, lets fetch the data –

				
					zap=kite.historical_data(token,starting_date,ending_date,"day")
zap= pd.DataFrame(zap)
print(zap.head(10))
				
			

It will output –

The initial display exhibits the first 10 rows, utilizing the ‘head’ function to offer a more concise data view of the Pandas Dataframe. It effectively presents OHLC data and volume for each day.

				
					date	open	high	low	close	volume
0	2019-01-01 00:00:00+05:30	1072.60	1074.55	1058.15	1068.55	4674622
1	2019-01-02 00:00:00+05:30	1062.35	1074.25	1049.45	1054.60	7495772
2	2019-01-03 00:00:00+05:30	1055.65	1062.45	1039.05	1041.60	7812061
3	2019-01-04 00:00:00+05:30	1046.05	1052.75	1030.50	1047.25	8880761
4	2019-01-07 00:00:00+05:30	1055.20	1066.10	1049.45	1053.05	5784262
5	2019-01-08 00:00:00+05:30	1053.35	1058.00	1044.70	1052.95	5901336
6	2019-01-09 00:00:00+05:30	1059.95	1064.70	1047.30	1058.75	6049942
7	2019-01-10 00:00:00+05:30	1055.90	1059.00	1051.40	1055.65	4280616
8	2019-01-11 00:00:00+05:30	1055.75	1061.65	1037.65	1046.65	6781266
9	2019-01-14 00:00:00+05:30	1043.75	1049.00	1035.55	1045.45	4313661
				
			

Now, Let’s try to find data for each minute – 

				
					zap=kite.historical_data(token,starting_date,ending_date,"minute")
zap= pd.DataFrame(zap)
print(zap.head(10))
				
			

It throws an error – 

				
					---------------------------------------------------------------------------
InputException                            Traceback (most recent call last)
Cell In[6], line 1
----> 1 zap=kite.historical_data(token,starting_date,ending_date,"minute")
      2 zap= pd.DataFrame(zap)
      3 print(zap.head(10))

File ~/apps/zerodha/../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/zerodha/../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/zerodha/../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 max limit: 60 days
				
			

To fetch minute-level historical data for a period longer than the 60-day limit imposed by the API, you need to divide your query into multiple smaller queries, each fetching data for up to 60 days. Then, you can stitch these smaller data sets together to create a continuous time series. 

Python Script to Fetch and Stitch Minute-Level Historical Data

				
					def fetch_historical_data(kite, token, start_date, end_date, interval):
    # Initialize an empty DataFrame to store the historical data
    full_data = pd.DataFrame()

    # Split the date range into 60-day intervals
    while start_date < end_date:
        # Calculate the end date of the 60-day interval
        interval_end = start_date + datetime.timedelta(days=60)

        # Ensure the interval end does not exceed the overall end date
        if interval_end > end_date:
            interval_end = end_date

        # Fetch historical data for the 60-day interval
        data = kite.historical_data(token, start_date, interval_end, interval)
        data_df = pd.DataFrame(data)

        # Append the fetched data to the full dataset
        full_data = full_data.append(data_df, ignore_index=True)

        # Update the start date for the next interval
        start_date = interval_end

    return full_data

historical_data = fetch_historical_data(kite, token, starting_date, ending_date, "minute")
historical_data
				
			

It took an abnormal amuont of massive time and then it gave output of results with each data of all 454068 trading minutes till date in that range.

				
					date	open	high	low	close	volume
0	2019-01-01 09:15:00+05:30	1062.55	1063.90	1060.25	1061.65	53427
1	2019-01-01 09:16:00+05:30	1062.25	1063.85	1061.65	1063.40	18209
2	2019-01-01 09:17:00+05:30	1063.40	1063.90	1063.25	1063.40	42785
3	2019-01-01 09:18:00+05:30	1063.40	1063.50	1062.30	1062.60	40647
4	2019-01-01 09:19:00+05:30	1062.30	1062.30	1059.50	1059.50	44316
...	...	...	...	...	...	...
454063	2023-11-24 15:25:00+05:30	2395.95	2396.75	2395.00	2395.65	18228
454064	2023-11-24 15:26:00+05:30	2395.55	2396.00	2394.85	2394.85	12166
454065	2023-11-24 15:27:00+05:30	2395.00	2395.30	2394.50	2394.80	17623
454066	2023-11-24 15:28:00+05:30	2394.55	2394.80	2394.00	2394.00	19879
454067	2023-11-24 15:29:00+05:30	2394.40	2394.90	2394.00	2394.25	9111
454068 rows × 6 columns
				
			
Post a comment

Leave a Comment

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

×Close