Download tick data for a given stock from NSE's website suing python

Getting tick level stock data is difficult and very few sources provide this data, In this blog will fetch the stock data at minute level for a given stock from NSE’s website. But this still comes with its some limitations-

But something is much better than nothing and besides this is the only option available for free, so nothing much to complain here. (If you have Zerodha account, you can still get the minute level stock data, please read this blog post for details - https://marketsetup.in/posts/download-stock-data-zerodha/)

We will be using this url - https://www.nseindia.com/api/chart-databyindex?index=SBINEQN for data. A simple get request to https://www.nseindia.com/api/chart-databyindex with index=STOCKEQN fetches the minute data.

Pre-requisites/Dependencies

pip install requests pandas Click

Code walk thru

Let us import required modules

from datetime import datetime
from requests import Session
import pandas as pd

You can use the fetch_data function to download 1 minute stock data for that day.

page_url = "https://www.nseindia.com/get-quotes/equity?symbol=LT"
chart_data_url = "https://www.nseindia.com/api/chart-databyindex"

s = Session()
h = {"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
     "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
    "accept-encoding": "gzip, deflate, br",
    "accept-language": "en-GB,en-US;q=0.9,en;q=0.8",
    }
s.headers.update(h)
r = s.get(page_url)
def fetch_data(symbol):
    data = {"index": symbol + "EQN"}
    r = s.get(chart_data_url, params=data)
    data = r.json()['grapthData']
    return [[datetime.utcfromtimestamp(d[0]/1000),d[1]] for d in data]

d = fetch_data("MARUTI")

The data will be in below format-

[[datetime.datetime(2021, 1, 8, 9, 15), 7600],
 [datetime.datetime(2021, 1, 8, 9, 15, 1), 7610],
 [datetime.datetime(2021, 1, 8, 9, 15, 2), 7613],
 [datetime.datetime(2021, 1, 8, 9, 15, 3), 7613.5],
 [datetime.datetime(2021, 1, 8, 9, 15, 4), 7606.05],
 [datetime.datetime(2021, 1, 8, 9, 15, 5), 7615],
 .
 .
 ]

As you can see data is available for every second

Let’s plot the data

df = pd.DataFrame(d)
df.columns = ['Time', "Price"]
df.index = df['Time'].dt.time
df['Price'].plot(figsize=(12,6), grid=True)
<AxesSubplot:xlabel='Time'>

minute_data.py

As a bonus I have written a command-line utility as below, simply copy-paste this code and save it as minute_data.py. Ensure that you have installed dependencies. And execute below command from command-line-

$ python minute_data.py --s SBIN

This will download the minute data in a csv file and save it with name - SBIN-YYYY-DD-MM.csv


from datetime import datetime
from requests import Session
import click
import csv

page_url = "https://www.nseindia.com/get-quotes/equity?symbol=LT"
chart_data_url = "https://www.nseindia.com/api/chart-databyindex"

s = Session()
h = {"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
     "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
    "accept-encoding": "gzip, deflate, br",
    "accept-language": "en-GB,en-US;q=0.9,en;q=0.8",
    }
s.headers.update(h)
r = s.get(page_url)

def fetch_data(symbol):
    data = {"index": symbol + "EQN"}
    r = s.get(chart_data_url, params=data)
    data = r.json()['grapthData']
    return [[datetime.utcfromtimestamp(d[0]/1000),d[1]] for d in data]


@click.command()
@click.option('--symbol','--s', help="Symbol", required=True)
def main(symbol):
    d = fetch_data(symbol)
    today = datetime.now().date()
    
    with open("{}-{}.csv".format(symbol, today), "w") as fp:
        w = csv.writer(fp)
        w.writerow(["Time", "Price"])
        w.writerows(d)

if __name__=="__main__":
    main()
    

Hope this helps you in your intraday backtesting. Happy coding and trading!