CLI tool
jugaad-py/jugaad-data avatar
jugaad-py/jugaad-data

jugaad-data pulls NSE, RBI and AMFI market data without an exchange API key

Download live and historical data for Indian stock market

588 stars212 forksPythonLicense varies

At a glance

What is it?
jugaad-data is a Python library that downloads historical and live stock, index, derivatives and mutual fund data by reading the public websites of NSE, RBI and AMFI rather than a licensed feed. It ships a jdata command line tool, a built in cache so you do not hammer the exchange, and optional pandas support, and its licence is a custom YOLO file rather than a standard one.
Who is it for?
Adopt jugaad-data if you need NSE, index, derivatives or mutual fund NAV history for research, teaching or personal portfolio tracking, and you are willing to treat the exchange website as an unstable dependency. Do not adopt it for anything that must run to a service level agreement, because the library scrapes public pages with no API contract, and do not redistribute the data without checking the terms of the source sites.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

It reads the public websites instead of an API

jugaad-data is a Python library to download historical and live stock, index as well as economic data from NSE and the RBI website. The mechanism is the interesting part and it is stated plainly in the feature list: it supports the new NSE website, with the parenthetical warning that all libraries based on the old NSE website might stop working.

That warning is the whole architecture in one sentence. There is no licensed market data feed behind this library, no API key to obtain, and no contract with the exchange. It reads the same pages a browser would, and it depends on those pages continuing to look the way they do.

The dependency list in requirements.txt confirms the approach. requests and beautifulsoup4 with lxml for fetching and parsing HTML, brotli for compressed responses, click for the command line interface, and appdirs for locating the cache directory. There is no market data SDK in the list because there is no market data API being called.

The project also has a road map table that is worth reading as a statement of coverage. NSE stocks, NSE stocks F&O, NSE index, NSE index F&O and RBI current rates are all marked supported, and AMFI mutual fund NAV is marked supported. Everything else in the table would be a no.

The homepage and documentation both point to marketsetup.in, and the repository carries an AGENTS.md, a CHANGELOG.md and a docs/ directory, so the code is maintained as a working project rather than a script collection.

Three ways to get a price history, and the cache that keeps you unblocked

The Python interface covers historical data, live data and, as the README has grown, index and mutual fund history.

Historical data starts with the bhavcopy, the daily file NSE publishes for every traded instrument. Two functions cover it, one for the equity file and one for futures and options:

python
from datetime import date
from jugaad_data.nse import bhavcopy_save, bhavcopy_fo_save

# Download bhavcopy
bhavcopy_save(date(2020,1,1), "/path/to/directory")

# Download bhavcopy for futures and options
bhavcopy_fo_save(date(2020,1,1), "/path/to/directory")

For a single symbol over a date range there is a pandas helper, and the series argument selects the instrument series, with EQ being the default for equities:

python
from jugaad_data.nse import stock_df
df = stock_df(symbol="SBIN", from_date=date(2020,1,1),
            to_date=date(2020,1,30), series="EQ")

Live data goes through the NSELive class, which returns the raw price information dictionary for a symbol:

python
from jugaad_data.nse import NSELive
n = NSELive()
q = n.stock_quote("HDFC")
print(q['priceInfo'])

The priceInfo block in the README shows what comes back, including lastPrice, change, previousClose, open, vwap, a price band, and a weekHighLow sub-dictionary with its own min and max dates. It is the raw exchange payload, not a tidied model.

The caching mechanism is the feature that makes this usable rather than a curiosity. The README describes a built-in caching mechanism to play nice with NSE, avoiding unnecessary requests to NSE's website and getting blocked. Since the underlying access is a public website, the cache is the difference between a script that works and one that gets your IP throttled.

The jdata CLI makes the same downloads reachable without writing Python

The command line tool is the entry point the README emphasises, with the claim that even non-coders can use it easily. The help output is a standard Click interface:

code
$ jdata stock --help

Usage: jdata stock [OPTIONS]

  Download historical stock data

  $jdata stock --symbol STOCK1 -f yyyy-mm-dd -t yyyy-mm-dd --o file_name.csv

Options:
  -s, --symbol TEXT  [required]
  -f, --from TEXT    [required]
  -t, --to TEXT      [required]
  -S, --series TEXT  [default: EQ]
  -o, --output TEXT
  --help             Show this message and exit.

And a real run prints a progress bar and then the destination:

code
$ jdata stock -s SBIN -f 2020-01-01 -t 2020-01-31 -o SBIN-Jan.csv
SBIN  [####################################]  100%

Saved file to : SBIN-Jan.csv

The package metadata registers the entry point as jdata pointing at jugaad_data.cli:cli, so the same binary name is used in the docs and in the install.

The derivatives subcommand follows the same pattern with more flags, because an options download needs the instrument type, the expiry date and the strike price. The instrument values are FUTSTK for stock futures, FUTIDX for index futures, OPTSTK for stock options and OPTIDX for index options, and the --ce and --pe flags select a call or a put, both of which are only used for the option instrument types. The -p price flag is likewise limited to the option types, which is a sensible guard since a strike price is meaningless for a future.

The progress bar is the visible sign of the download happening, and the fact that the output file is written at the end rather than streamed means a partial download does not leave a truncated CSV behind.

Index data comes with a discovery API for the three level hierarchy

The index section is the part of the README that shows how much has been added recently, because it does not assume you know the index names. The data comes from niftyindices.com rather than NSE itself, and there are separate functions for each kind of series.

index_raw gives OHLC data for an index, index_pe_raw gives P/E, P/B and dividend yield, and index_tri_raw gives total return index values. The third one takes two names, because for standard indices the name matches the index name, while for strategy indices the short code is used as the name.

The discovery functions are the practical part. The README describes a three level hierarchy, and index_type_list returns the top level, with the example output showing Equity, Fixed Income and Multi Asset. index_subtype_list takes a type and a section, and for Equity with Historical Index Data returns Broad Market Indices, Sectoral Indices and others. index_name_list takes the subtype and the section and returns the actual index names, with the example showing NIFTY 50 and NIFTY 100.

So rather than hardcoding a list of index names, you can walk the hierarchy and discover what exists. That is a meaningful difference from a script that only knows about NIFTY 50 and breaks when NSE renames something.

The index_group values are fixed and documented in the README: Historical Index Data, Total returns Index Values, and P/E, P/B & Div.Yield values. The trailing space in the second of those is in the source string, which is the kind of detail that will bite anyone matching on it exactly.

AMFI mutual fund NAV history is the newest addition

The mutual fund section downloads NAV history from AMFI, and it comes with three entry points for the same data in three shapes. nav_history_raw returns the raw rows, nav_history_df returns a pandas DataFrame with the nav as a float and the date as a datetime, and nav_history_csv writes the result to a file:

python
from jugaad_data.amfi import nav_history_raw, nav_history_df, nav_history_csv

# Raw rows (every scheme / AMC / date)
rows = nav_history_raw(date(2026, 9, 1), date(2026, 10, 6))

# pandas DataFrame (nav as float, date as datetime)
df = nav_history_df(date(2026, 9, 1), date(2026, 10, 6))
df[df["scheme_type"] == "Interval Fund"].head()

# Save to CSV
nav_history_csv(date(2026, 9, 1), date(2026, 10, 6), output="nav.csv")

The data model is described in the README in one paragraph, and it is the part that makes the dataset usable rather than merely available. Every row carries scheme_type, which is Open Ended, Close Ended or Interval Fund, along with category, of which Money Market is the example, and amc, the asset management company, alongside the scheme NAV fields.

That means you can filter a decade of NAV history by fund type, by category or by AMC without joining to another table, which is the usual way AMFI data turns out to be organised.

The date range in the example is recent, September to October 2026, and the two functions taking a date range rather than a single date is the signal that this is a bulk history endpoint rather than a per scheme lookup.

The licence is a custom file, and the package metadata is inconsistent

Two things about the packaging are worth checking before you depend on this.

First, the licence. The repository listing shows no licence identifier, and the pyproject.toml records license = {text = "YOLO"}, with a file named LICENSE.YOLO.md at the repository root rather than a standard LICENSE. There is also a Buy Me a Coffee section in the README with a funding link, and the author is listed as jugaad-coder. Whatever the YOLO file grants, it is not one of the standard licences, so read it directly rather than assuming MIT from the pattern of similar packages.

Second, the package description does not match the project. The pyproject.toml description reads "Free Zerodha API python library" and the author email is the placeholder [email protected], while the project itself downloads data from NSE, RBI and AMFI and is not a Zerodha library at all. The keywords are accurate, listing NSE, Live, Bhavcopy, History, Futures, Options and Stock Data. So the metadata is partly stale, which is a small thing but a reminder to read the README rather than the package card.

The version in the pyproject.toml is 0.35.10, the package requires Python 3.9 or later, and the build backend is setuptools with a dynamic dependencies list read from requirements.txt. The repository has no GitHub releases, so the PyPI version is the reference point, and the last push was on 2026-10-06 with the repository not archived.

The development setup in the repository is thorough for a scraping library, with a pytest.ini, a tests/ directory, a run_tests.sh, a blog_run_test.sh, a .devcontainer/ directory, a .githooks/ directory and a check-version.ps1, which is what you would expect from a project whose main risk is that an upstream page changed.

Where scraping stops being the right answer

The limitation is structural and worth naming plainly. A library that reads a public website has no guarantee about the page structure, no rate limit agreement, and no notice when the format changes. The README says the new NSE website is supported and that libraries based on the old one might stop working, which is an implicit admission that this has already happened once.

The built-in cache reduces the volume of requests, and the README is candid about why: to avoid making unnecessary requests to NSE's website and getting blocked. That is a polite way of saying the exchange will rate limit you.

For personal research, a course project or a small portfolio tracker, none of this matters much. You run a script a few times a day, the cache absorbs the repetition, and the cost of the library being wrong for a week is a redownload.

For anything else, the alternatives are different in kind rather than degree. A licensed market data feed gives you a contract, a support commitment and a rate limit you can plan around, at a price. A broker API such as the one the package description mistakenly advertises gives you authenticated access to the same exchange data, with credentials and terms attached. The difference in approach is that jugaad-data is unauthenticated scraping, which is free to start and free of a service guarantee.

There is also a question about redistributing what you download. Exchange market data carries its own terms, and a library's licence does not grant you the right to republish the underlying data. If your use case involves publishing derived datasets, that is a separate conversation from the library's licence, and the README does not address it.

Editorial conclusion

Adopt jugaad-data if you need NSE, index, derivatives or mutual fund NAV history for research, teaching or personal portfolio tracking, and you are willing to treat the exchange website as an unstable dependency. Do not adopt it for anything that must run to a service level agreement, because the library scrapes public pages with no API contract, and do not redistribute the data without checking the terms of the source sites. Verify first which segment of data you need is on the README's support table, whether the built in cache is sufficient for your request volume, and what the LICENSE.YOLO.md file actually grants before you depend on it commercially.

Frequently asked questions

How do I install jugaad-data and download historical stock data?

Install it with pip install jugaad-data, then either use the CLI with jdata stock -s SBIN -f 2020-01-01 -t 2020-01-31 -o SBIN-Jan.csv, or call bhavcopy_save and stock_df from jugaad_data.nse in Python. The package requires Python 3.9 or later.

Does jugaad-data need an API key from NSE?

No. It reads the public NSE, RBI and AMFI websites the way a browser would, using requests, beautifulsoup4 and lxml. A built-in caching mechanism is included to avoid making unnecessary requests to NSE and getting blocked.

What data sources does jugaad-data cover?

The README's road map table marks NSE stocks, NSE stocks F&O, NSE index, NSE index F&O and RBI current rates as supported, along with AMFI mutual fund NAV. Index history comes from niftyindices.com, and index names can be discovered through the index_type_list, index_subtype_list and index_name_list functions.

What licence does jugaad-data use?

The pyproject.toml records license = {text = "YOLO"} and the repository ships a file named LICENSE.YOLO.md rather than a standard licence file, and the repository listing records no licence identifier. The package is also version 0.35.10 with the last push on 2026-10-06.

Can jugaad-data get live quotes and mutual fund NAV history?

Live quotes come from the NSELive class, where n.stock_quote("HDFC") returns a dictionary with a priceInfo block. Mutual fund NAV history comes from the jugaad_data.amfi module with nav_history_raw, nav_history_df and nav_history_csv, and each row carries scheme_type, category and amc.

Official sources

  1. Issues
  2. jugaad-py/jugaad-data on GitHub
  3. Project website
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jugaad-py-jugaad-data.svg)](https://hysenlabs.com/projects/jugaad-py-jugaad-data)

Was this useful?