Skip to main content

A lean and modern Python library to fetch data from NSE (National Stock Exchange of India)

Project description

aynse

build status PyPI version license: CMIT misc badge

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 reconstruction
  • nse: NSE historical endpoint only
  • bhavcopy: bhavcopy-only reconstruction
  • custom: 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:

  1. fork the repository
  2. create a feature branch
  3. add tests for new functionality
  4. ensure all tests pass (pytest)
  5. 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

  1. make your changes
  2. bump version
make bump-patch  # or bump-minor, bump-major
  1. commit and tag
git commit -am "Bump version to X.Y.Z"
git tag vX.Y.Z
git push && git push --tags
  1. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aynse-1.4.0.tar.gz (79.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aynse-1.4.0-py3-none-any.whl (56.0 kB view details)

Uploaded Python 3

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

Hashes for aynse-1.4.0.tar.gz
Algorithm Hash digest
SHA256 230a533501ff3c34d46e3d7cd4ccdcdc016b27343f3a7c03d1d78dd54293a136
MD5 864ed663516f3b8c4515795a72ee7f08
BLAKE2b-256 e0e2a792ac7957cf5abc2613f27942b0d34d8bee8ad112a7f8047e557447b739

See more details on using hashes here.

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

Hashes for aynse-1.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2bb646473b4450d6a61387e4ba8fba09ae36a41e2071db4d4b7c45169a17b1bb
MD5 868368221fab98215c78dd724bb4923e
BLAKE2b-256 6f3d480f137bf4bb91ce2d60096881c23d1d7795df6a4ef843953118e15ecd6d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page