A lean and modern Python library to fetch data from NSE (National Stock Exchange of India)
Project description
aynse
aynse is a lean, modern python library for fetching data from the national stock exchange (nse) of india. it includes a resilient http client (http/2, retries with jitter, connection pooling), adaptive batching, and efficient streaming utilities.
features
- historical data: stocks, indices, derivatives (f&o)
- bhavcopy: equity, f&o, index downloads
- live market data: real-time quotes, option chains
- cli: simple commands for quick downloads
- resilient networking: http/2, connection pooling, retries with exponential backoff, rate limiting, circuit breaker
- batching & streaming: adaptive concurrency and low-memory processing
- comprehensive type hints: full typing support for ide autocomplete
- extensive test coverage: robust test suite for reliability
installation
install aynse directly from pypi:
pip install aynse
for development:
pip install aynse[dev]
# or
pip install -r requirements.dev.txt
quick start
get historical stock data
retrieve historical data for a stock as a pandas dataframe:
from datetime import date
from aynse import stock_df
# Fetch data for RELIANCE from January 1-31, 2024
df = stock_df(
symbol="RELIANCE",
from_date=date(2024, 1, 1),
to_date=date(2024, 1, 31)
)
print(df.head())
download daily bhavcopy
download the daily bhavcopy for a specific date:
from datetime import date
from aynse import bhavcopy_save
# Download equity bhavcopy for July 26, 2024
bhavcopy_save(date(2024, 7, 26), "downloads/")
get live stock quote
fetch live price information for a stock:
from aynse import NSELive
live = NSELive()
quote = live.stock_quote("INFY")
print(f"Price: ₹{quote['priceInfo']['lastPrice']}")
print(f"Change: {quote['priceInfo']['pChange']}%")
get option chain data
fetch option chain for index or equity:
from aynse import NSELive
live = NSELive()
# Index option chain
nifty_chain = live.index_option_chain("NIFTY")
# Equity option chain
reliance_chain = live.equities_option_chain("RELIANCE")
check trading holidays
get the list of trading holidays:
from aynse import holidays
from aynse.holidays import is_trading_day
from datetime import date
# Get all 2024 holidays
holidays_2024 = holidays(year=2024)
print(f"Trading holidays in 2024: {len(holidays_2024)}")
# Check if a date is a trading day
print(f"Is Jan 15, 2024 a trading day? {is_trading_day(date(2024, 1, 15))}")
command-line interface
aynse comes with a command-line tool for quick downloads.
download bhavcopy
# Download today's bhavcopy
aynse bhavcopy -d /path/to/directory
# Download for a specific date
aynse bhavcopy -d /path/to/directory -f 2024-01-15
# Download for a date range
aynse bhavcopy -d /path/to/directory -f 2024-01-01 -t 2024-01-31
# Download F&O bhavcopy
aynse bhavcopy -d /path/to/directory --fo
# Download index bhavcopy
aynse bhavcopy -d /path/to/directory --idx
# Download full bhavcopy (includes delivery info)
aynse bhavcopy -d /path/to/directory --full
download historical stock data
aynse stock -s RELIANCE -f 2024-01-01 -t 2024-03-31 -o reliance_q1_2024.csv
download historical index data
aynse index -s "NIFTY 50" -f 2024-01-01 -t 2024-03-31 -o nifty_q1_2024.csv
download derivatives data
# Stock futures
aynse derivatives -s SBIN -f 2024-01-01 -t 2024-01-30 -e 2024-01-25 -i FUTSTK
# Index options
aynse derivatives -s NIFTY -f 2024-01-01 -t 2024-01-25 -e 2024-01-25 -i OPTIDX -p 21000 --pe
get live quote
aynse quote -s RELIANCE
list holidays
# Current year
aynse holidays
# Specific year
aynse holidays -y 2024
advanced usage
connection pooling
the library uses a centralized connection pool for efficient http connections:
from aynse.nse import get_connection_pool
# Get the global connection pool
pool = get_connection_pool()
# Get a client for NSE
client = pool.get_client("https://www.nseindia.com")
data = client.get_json("/api/marketStatus")
request batching
process multiple requests efficiently:
from aynse import RequestBatcher, BatchStrategy
batcher = RequestBatcher(
max_batch_size=10,
max_concurrent_batches=3,
strategy=BatchStrategy.ADAPTIVE
)
# Batch multiple stock requests
from aynse import batch_stock_requests
results = batch_stock_requests(
symbols=["RELIANCE", "TCS", "INFY", "HDFC", "SBIN"],
from_date="2024-01-01",
to_date="2024-01-31"
)
streaming for large datasets
process large files without loading everything into memory:
from aynse import StreamingProcessor, StreamConfig
processor = StreamingProcessor(
StreamConfig(chunk_size=1000)
)
def process_chunk(records):
# Process each chunk of 1000 records
return sum(r.get('volume', 0) for r in records)
total_volume = processor.process_csv_file(
"large_bhavcopy.csv",
process_chunk
)
stock history backend configuration
stock_raw/stock_df/stock_csv support configurable backends:
auto(default): try NSE historical endpoint, fallback to bhavcopy reconstructionnse: NSE historical endpoint onlybhavcopy: bhavcopy-only reconstructioncustom: user-registered provider (for broker/internal APIs)
from aynse import (
set_stock_history_backend,
get_stock_history_backend,
register_stock_history_provider,
)
# Global backend selection
set_stock_history_backend("bhavcopy")
print(get_stock_history_backend()) # bhavcopy
# Optional custom provider
def my_provider(symbol, from_date, to_date, series):
# Return list[dict] in stock_raw schema
return []
register_stock_history_provider(my_provider)
set_stock_history_backend("custom")
You can also set backend using environment variable:
# auto | nse | bhavcopy | custom
export AYNSE_STOCK_HISTORY_BACKEND=bhavcopy
api reference
historical data (aynse.nse)
| function | description |
|---|---|
stock_raw(symbol, from_date, to_date, series="EQ") |
get raw stock data as list of dicts |
stock_df(symbol, from_date, to_date, series="EQ") |
get stock data as dataframe |
stock_csv(symbol, from_date, to_date, series="EQ", output="") |
save stock data to csv |
derivatives_raw(...) |
get raw derivatives data |
derivatives_df(...) |
get derivatives data as dataframe |
derivatives_csv(...) |
save derivatives data to csv |
index_raw(symbol, from_date, to_date) |
get raw index data |
index_df(symbol, from_date, to_date) |
get index data as dataframe |
index_csv(symbol, from_date, to_date, output="") |
save index data to csv |
index_pe_raw(symbol, from_date, to_date) |
get index pe/pb/dividend payload |
index_pe_df(symbol, from_date, to_date) |
get index pe/pb/dividend data as dataframe |
set_stock_history_backend(backend) |
configure stock history backend globally |
get_stock_history_backend() |
get current stock history backend |
register_stock_history_provider(provider) |
register custom stock history provider |
archives (aynse.nse)
| function | description |
|---|---|
bhavcopy_raw(dt) |
get equity bhavcopy as csv string |
bhavcopy_save(dt, dest) |
save equity bhavcopy to file |
full_bhavcopy_raw(dt) |
get full equity bhavcopy (with delivery info) |
full_bhavcopy_save(dt, dest) |
save full equity bhavcopy to file |
bhavcopy_fo_raw(dt) |
get f&o bhavcopy |
bhavcopy_fo_save(dt, dest) |
save f&o bhavcopy |
bhavcopy_index_raw(dt) |
get index bhavcopy as csv string |
bhavcopy_index_save(dt, dest) |
save index bhavcopy to file |
bulk_deals_raw(from_date, to_date) |
get bulk deals json in date range |
bulk_deals_save(from_date, to_date, dest) |
save bulk deals json to file |
index_constituent_raw(index_type) |
get index constituents csv string |
index_constituent_save(index_type, dest) |
save index constituents csv to file |
index_constituent_save_all(dest) |
save all supported index constituent files |
expiry_dates(dt, instrument_type="", symbol="", contracts=0, months_ahead=6) |
calculate contract expiry dates |
live data (NSELive)
| method | description |
|---|---|
stock_quote(symbol) |
get live stock quote |
stock_quote_fno(symbol) |
get f&o quote for stock |
trade_info(symbol) |
get detailed trade and order-book info |
tick_data(symbol, indices=False, flag="1D") |
get chart/tick data |
chart_data(symbol, indices=False, flag="1D") |
alias for tick/chart response |
market_turnover() |
get market turnover payload |
eq_derivative_turnover(type="allcontracts") |
get equity derivative turnover |
index_option_chain(symbol) |
get index option chain |
equities_option_chain(symbol) |
get equity option chain |
currency_option_chain(symbol="USDINR") |
get currency option chain |
market_status() |
get market status |
all_indices() |
get all indices data |
live_index(symbol) |
get live index data |
live_fno() |
get securities in f&o snapshot |
pre_open_market(key) |
get pre-open market data |
holiday_list() |
get nse holiday payload by segment |
corporate_announcements(...) |
get filtered corporate announcements |
bulk_equities_option_chain(symbols, max_workers=3) |
fetch many option chains concurrently |
get_options_around_date(symbol, target_date, ...) |
analyze options around a target date |
analyze_earnings_options(symbols_and_dates, ...) |
run bulk earnings options analysis |
holidays (aynse.holidays)
| function | description |
|---|---|
holidays(year=None, month=None) |
get list of trading holidays |
is_holiday(dt) |
check if date is a holiday |
is_trading_day(dt) |
check if date is a trading day |
get_trading_days(from_date, to_date) |
get trading days in range |
count_trading_days(from_date, to_date) |
count trading days in range |
etymology / musings
aynse is a portmanteau of "ayn" from miss ayn rand and "nse" from national stock exchange. ayn rand was a russian-american writer and philosopher known for her philosophy of objectivism, which emphasizes individualism and rational self-interest. among other things, she was a strong advocate for laissez-faire capitalism.
the name serves as a fun ironical reminder of the library's purpose: to provide a tool for individuals to access and analyze financial data independently, without relying on large institutions or complex systems.
in a cruel twist of fate, this open source library wouldn't be encouraged under ayn rand's philosophy, as she discouraged altruism and believed in the pursuit of one's own happiness as the highest moral purpose.
and as the final act of irony, we gather to use this library to analyze financial markets while generating zero (and possibly, negative) intrinsic value for humankind as a whole - this is capitalism.
contributing
contributions are welcome! please:
- fork the repository
- create a feature branch
- add tests for new functionality
- ensure all tests pass (
pytest) - submit a pull request
for bugs or feature requests, please open an issue on the github repository.
test command matrix
# deterministic/offline checks only
pytest -m offline -v --tb=short
# live NSE/RBI integration checks
pytest -m live -v --tb=short
# end-to-end contract and integration checks
pytest -m e2e -v --tb=short
# full suite (offline + live)
pytest tests -v --tb=short
release workflow
- make your changes
- bump version
make bump-patch # or bump-minor, bump-major
- commit and tag
git commit -am "Bump version to X.Y.Z"
git tag vX.Y.Z
git push && git push --tags
- create github release → automatically publishes to pypi.
everything to do with release/version control
show current version
python scripts/bump_version.py --current
bump versions (updates pyproject.toml only)
python scripts/bump_version.py patch # 1.1.0 -> 1.1.1 python scripts/bump_version.py minor # 1.1.0 -> 1.2.0 python scripts/bump_version.py major # 1.1.0 -> 2.0.0 python scripts/bump_version.py --set 2.0.0 # set exact version
preview changes without modifying
python scripts/bump_version.py patch --dry-run
license
this project has a (custom) mit* license but extends limitations. if you're an agency/corporate with >2 employees, you cannot wrap this project or use it without prior written permission from the author. if you're an individual, you can use it freely for personal projects.
this project is not intended for commercial use without prior permission. if caught using this project in violation of the license, it may result in automated reporting and/or legal action.
please see the license file for more details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aynse-1.4.0.tar.gz.
File metadata
- Download URL: aynse-1.4.0.tar.gz
- Upload date:
- Size: 79.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
230a533501ff3c34d46e3d7cd4ccdcdc016b27343f3a7c03d1d78dd54293a136
|
|
| MD5 |
864ed663516f3b8c4515795a72ee7f08
|
|
| BLAKE2b-256 |
e0e2a792ac7957cf5abc2613f27942b0d34d8bee8ad112a7f8047e557447b739
|
File details
Details for the file aynse-1.4.0-py3-none-any.whl.
File metadata
- Download URL: aynse-1.4.0-py3-none-any.whl
- Upload date:
- Size: 56.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2bb646473b4450d6a61387e4ba8fba09ae36a41e2071db4d4b7c45169a17b1bb
|
|
| MD5 |
868368221fab98215c78dd724bb4923e
|
|
| BLAKE2b-256 |
6f3d480f137bf4bb91ce2d60096881c23d1d7795df6a4ef843953118e15ecd6d
|