Skip to main content

NSE trading calendar with holidays, date arithmetic, flexible formatting

Project description

🗓️ nse-calendar

📦 NSE (National Stock Exchange of India) trading calendar for Python.

PyPI version Python versions GitHub Stars GitHub Forks Pepy Total Downloads License: MIT PyPI - Implementation

Features: Holiday detection, trading day arithmetic, flexible date parsing/formatting, and seamless Pandas integration. Zero mandatory dependencies.


🔍 Data Coverage

The package includes one of the most comprehensive publicly available NSE holiday datasets, covering trading holidays from 1996 onwards and updated annually using official NSE circulars and archives.

Year Range Status Source
1996–2009 ✅ Available NSE historical archives
2010–2025 ✅ Available NSE official annual circulars
2026 ✅ Available NSE official annual circular
2027 and beyond ⏳ Added each December NSE official annual circular

⚡ Installation

pip install nse-calendar

Note: pandas and requests are optional dependencies. The library works flawlessly with Python's standard library alone.


🚀 Quick Start

import nse_calendar as nse

# Is this a trading day?
nse.is_nse_holiday("2026-01-26")       # True (Republic Day)
nse.is_nse_holiday("2026-05-25")       # False

# Move forward by trading days
nse.add_trading_days("2026-01-23", 1)   # 2026-01-27

# Count trading days in a range
nse.trading_days_between("2026-01-01", "2026-01-31")

# Parse and format dates easily
d = nse.parse_date("25-May-2026")
nse.format_date(d, "dd/mm/yyyy")       # '25/05/2026'
nse.format_date(d, "dd Month yyyy")   # '25 May 2026'

🛠️ API Reference

1. Holiday Checks

is_nse_holiday(date) -> bool

Returns True if the date is an NSE trading holiday or a weekend. Returns False for normal trading days.

nse.is_nse_holiday("2026-01-26")                  # True  - Republic Day
nse.is_nse_holiday("2026-05-23")                  # True  - Saturday
nse.is_nse_holiday("2026-05-25")                  # False - Monday, normal session
nse.is_nse_holiday(datetime.date(2026, 12, 25))    # True  - Christmas

get_holidays(year) -> list[dict]

Returns all NSE holidays for a given year as a list of dictionaries. Returns an empty list if the year is not present in the dataset.

nse.get_holidays(2026)
# Output:
# [
#     {"date": "2026-01-26", "description": "Republic Day"},
#     {"date": "2026-03-03", "description": "Maha Shivaratri"},
#     ...
# ]

len(nse.get_holidays(2026))   # 16
nse.get_holidays(1995)        # []

2. Special Sessions

Special sessions, such as Muhurat Trading on Diwali, override normal weekday and weekend rules. They are considered trading days even if they fall on a weekend.

is_special_session(date) -> bool

Returns True if the date is a special trading session.

nse.is_special_session("2026-11-08")   # True (Diwali Lakshmi Puja)
nse.is_special_session("2026-01-26")   # False

get_special_sessions(year) -> list[dict]

Returns all special trading sessions for a given year.

nse.get_special_sessions(2026)
# Output:
# [
#     {"date": "2026-11-08", "description": "Diwali Lakshmi Puja"}
# ]

3. Trading Day Arithmetic

add_trading_days(date, n) -> datetime.date

Advances a date by exactly n trading days, skipping weekends and NSE holidays. A negative value of n moves backward.

nse.add_trading_days("2026-01-23", 1)   # date(2026, 1, 27)
nse.add_trading_days("2026-05-25", 5)   # date(2026, 6, 1)
nse.add_trading_days("2026-05-25", -3)  # date(2026, 5, 20)

subtract_trading_days(date, n) -> datetime.date

Moves a date backward by exactly n trading days.

nse.subtract_trading_days("2026-01-27", 1) # date(2026, 1, 23)
nse.subtract_trading_days("2026-06-01", 5) # date(2026, 5, 25)

trading_days_between(start, end, inclusive="both") -> int

Counts trading days between two dates. The order of start and end does not matter.

inclusive option Count Start? Count End?
"both" Yes Yes
"left" Yes No
"right" No Yes
"neither" No No
nse.trading_days_between("2026-06-01", "2026-06-05")                       # 5
nse.trading_days_between("2026-06-01", "2026-06-05", inclusive="neither")  # 3
nse.trading_days_between("2026-01-22", "2026-01-30")                       # 5

next_trading_day(date) -> datetime.date | prev_trading_day(date)

Returns the next or previous strict trading day.

nse.next_trading_day("2026-01-26")  # date(2026, 1, 27)
nse.prev_trading_day("2026-01-27")  # date(2026, 1, 23)

nearest_trading_day(date, direction="forward") -> datetime.date

If the supplied date is already a trading day, it returns it unchanged. Otherwise, it finds the nearest one based on direction ("forward" or "backward").

nse.nearest_trading_day("2026-05-25")                        # date(2026, 5, 25)
nse.nearest_trading_day("2026-01-26")                        # date(2026, 1, 27)
nse.nearest_trading_day("2026-01-26", direction="backward")  # date(2026, 1, 23)

4. Date Parsing & Formatting

parse_date(value) -> datetime.date

Converts strings ("2026-05-25", "25-May-26", "May 25, 2026"), Unix timestamps, or Pandas/Python datetimes smoothly into a datetime.date object.

nse.parse_date("25-May-2026")  # date(2026, 5, 25)
nse.parse_date(1748131200)     # date from Unix timestamp

format_date(date, fmt) -> str

Formats a date using human-readable tokens (dd-mm-yyyy, dd Month yyyy, etc.) or any standard % strftime pattern.

nse.format_date("2026-05-25", "dd Month yyyy")  # '25 May 2026'
nse.format_date("2026-05-25", "%A, %d %B %Y")    # 'Monday, 25 May 2026'

5. Pandas Integration

resolve_dataframe(df, col, output_col=None, fmt="dd-mm-yyyy") -> pd.DataFrame

Parses mixed-format data columns, formats them uniformly, and returns helper flags without modifying your original DataFrame.

Added Column Type Description
{col} or output_col str Reformatted dates using fmt
{col}_is_holiday bool True if an NSE holiday or weekend
{col}_is_weekend bool True if a Saturday or Sunday
import pandas as pd
import nse_calendar as nse

df = pd.DataFrame({"trade_date": ["2026-01-26", "25-05-2026", "2026-05-23"]})
out = nse.resolve_dataframe(df, "trade_date", fmt="dd-mm-yyyy")

🔄 Data Control & Management

The library uses a smart two-layer data loading strategy:

  1. Local Cache: Stored at ~/.cache/nse_calendar/holidays.json (Valid for 30 days).
  2. Remote Source: Fetched from GitHub if the cache expires or is missing.
nse.refresh_holidays(force=True)  # Manually force a fresh fetch from remote
nse.get_data_source_info()        # View active cache metadata status

🤝 Contributing

Spot a missing holiday or a wrong date? Please open an issue and include the official NSE circular reference so the dataset can be updated for everyone!

📄 License

MIT License. See LICENSE for details.


Maintained with ❤️ by Kartik Kasat*

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

nse_calendar-1.0.0.tar.gz (9.6 kB view details)

Uploaded Source

Built Distribution

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

nse_calendar-1.0.0-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

Details for the file nse_calendar-1.0.0.tar.gz.

File metadata

  • Download URL: nse_calendar-1.0.0.tar.gz
  • Upload date:
  • Size: 9.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.11

File hashes

Hashes for nse_calendar-1.0.0.tar.gz
Algorithm Hash digest
SHA256 c49b4a936afed17faac116accfd04a29300fe31912a9cf9c683a677d22b83bfa
MD5 dadf3b8d514d56bf7e9711bfdae9c7d9
BLAKE2b-256 1be544b84123f1205dd949391f284b7ba28f00a0d9c9dd0b91c1e92ce221a3f2

See more details on using hashes here.

File details

Details for the file nse_calendar-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: nse_calendar-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 10.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.11

File hashes

Hashes for nse_calendar-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 92deaeade43f144b55664c8bb2998c2356a23c824711162c6b05f90afc4beda6
MD5 d006a813b9f3f0586ccc71358539a9e7
BLAKE2b-256 bf57b25f809aed586f6821c06e92496a25eb547544b2d40716b85a93edefbd8b

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