AION Indian Market Calendar
A Python package that answers one question cleanly across every Indian exchange segment: is this market open right now, on this date, or at this time? Covers NSE, BSE, MCX, NSE Currency Derivatives (CDS), and Muhurat trading, including CDS-specific session windows and holiday calendars that differ from equity markets. Use it as a stock market holiday calendar for NSE, BSE and MCX in 2026, or to check whether a market is open today.
MIT License No API key required NSE · BSE · MCX · CDS Muhurat trading Market-times agnostic
What's new in 1.7.1 (2 November 2026)
The MCX and NSE commodity close now depends on the date. It is 23:30 IST while US Daylight Saving is in effect and 23:55 IST during US Standard Time, so 23:55 from 2 November 2026 to 12 March 2027. The state is read from the IANA zone database for New York, so no change date is written in the package.
| Function | Answers |
|---|---|
is_us_daylight_saving(day) | Is US Daylight Saving in effect on this day? |
commodity_close(day) | The regular non-agri close by that rule. Use get_session for a specific day, which also applies holidays. |
from datetime import date from aion_indian_market_calendar import commodity_close, is_us_daylight_saving commodity_close(date(2026, 10, 30)) # 23:30 commodity_close(date(2026, 11, 2)) # 23:55 is_us_daylight_saving(date(2026, 11, 2)) # False
Before this release MCX stayed at 23:30 all year. Earlier dates are corrected too: 15 January and 3 March 2026 now report 23:55. Evening-only holiday sessions use the same close. These times are for non-agri contracts: MCX agri contracts close earlier and are not modelled per contract. 1.7.0 was tagged but never reached PyPI; 1.7.1 has the same behaviour. Sources: MCX/TRD/068/2026, MCX/TRD/550/2026, NSE/COM/76446, NSE/COM/71784.
What's new in 1.6.0 (25 October 2026)
Four questions a holiday list does not answer, computed from the same hash-verified data. No new dependency and no network access.
| Function | Answers |
|---|---|
is_settlement_day(day) | Does NSE Clearing settle that day? Not the same as a trading day: on 19 February, 19 March, 1 April and 26 August 2026 equity trades and does not settle. Follows NSE's published clearing-holiday list. |
get_market_phase(at, market) | PRE_OPEN, CONTINUOUS, CLOSING_AUCTION, POST_CLOSE, MUHURAT_TRADING or CLOSED |
get_expiry_day(index, day) | The next expiry on or after a date. NIFTY weekly on Tuesday; NIFTY, BANKNIFTY, FINNIFTY, MIDCPNIFTY and NIFTYNXT50 monthly on the last Tuesday; SENSEX weekly on Thursday and monthly on the last Thursday. A holiday expiry moves to the previous trading day. |
is_muhurat_trading(day) | Is there a Diwali Muhurat session? muhurat_session() gives the window and says when the timings are still provisional. |
from aion_indian_market_calendar import get_expiry_day, get_market_phase, is_settlement_day
get_expiry_day("NIFTY", "2026-10-25") # 2026-10-27
get_expiry_day("BANKNIFTY", "2026-03-25") # 2026-03-30: 31 March is a holiday
get_market_phase("2026-10-26T09:05+05:30", "NSE") # "PRE_OPEN"
is_settlement_day("2026-04-01") # False: annual bank closing
Expiry rules come from NSE circular NSE/FAOP/68747 and BSE notice 20250623-59, for contracts expiring from 1 September 2025. Dates outside the bundled data (currently to 25 December 2026) raise an error instead of guessing. A datetime without a timezone is read as IST and now raises a warning; pass a timezone-aware one. The CLI update command now runs the verified data refresh.
1.5.0 and 1.5.1 (18 October 2026)
SEBI revised the Closing Auction Session (CAS) on 15 October 2026 (circular HO/47/11/11(3)2025-MRD-POD2/I/23843/2026). From 7 December 2026, the calendar applies the new timings:
| Segment | Until 6 Dec 2026 | From 7 Dec 2026 |
|---|---|---|
| NSE and BSE stocks with F&O contracts | Continuous to 15:15, auction 15:15-15:35 | Continuous to 15:30, auction 15:30-15:40 |
| NSE and BSE equity derivatives | To 15:40 | To 15:45 (expiring index contracts stop at 15:30 on expiry day) |
| Other NSE and BSE equities | To 15:30 | To 15:30 (unchanged) |
| Cash post-close session | 15:50-16:00 | 15:50-16:00 (unchanged) |
Dates before 7 December keep the August timings, so backtests stay correct. Also in this release: NSE commodity non-agri contracts trade to 23:55 from 2 November 2026 to 12 March 2027 (NSE/COM/76446). Installs of 1.4.x receive the new timing rules through the hash-verified data refresh. 1.5.1 corrects the PyPI description and links that 1.5.0 published out of date; the code is the same.
Why this exists
Indian exchanges do not keep the same hours, and they do not share the same holiday calendar. NSE equity closes at 15:30. MCX commodity runs until 23:30 during US Daylight Saving and 23:55 during US Standard Time. NSE Currency Derivatives (CDS), the segment for USDINR, EURINR, GBPINR, and JPYINR, closes at 17:00 and observes holidays that sometimes differ from the equity segment on the same exchange.
Scripts that hardcode "NSE closes at 15:30 and is closed on NSE holidays" are wrong for CDS, wrong for MCX evening sessions, and silently wrong on days when one segment is closed but another is open. The typical fix is a scattered patch: a local holiday list, a hardcoded close time, a comment saying "update this every year." This package replaces all of that with one install.
No configuration file. No API key. Works offline with the bundled holiday and session data. Since 1.4.0 the data also refreshes at most once a day from a public, hash-verified repository, so a new closure or timing change does not wait for a release; set AION_IN_CALENDAR_OFFLINE=1 to turn the refresh off.
CDS coverage: the differentiator
NSE Currency Derivatives is the segment most market calendar packages miss or get wrong. CDS covers currency futures and options: USDINR, EURINR, GBPINR, JPYINR.
CDS operates on its own schedule: 09:00-17:00 IST, 90 minutes longer than NSE equity. It also observes holidays that do not always coincide with NSE equity holidays, meaning a script that checks "is NSE open today?" can return the wrong answer for a CDS workflow.
This package is market-times agnostic: pass the segment key and it returns the correct session window and holiday calendar for that segment, not a one-size-fits-all equity answer.
| Segment | Session | Note |
|---|---|---|
| NSE Equity | 09:00-15:30 IST | |
| NSE F&O | 09:15-15:40 IST | To 15:45 from 7 Dec 2026 |
| NSE and BSE stocks with F&O contracts | To 15:15, closing auction 15:15-15:35 | To 15:30, auction 15:30-15:40 from 7 Dec 2026 |
| NSE Currency Derivatives (CDS) | 09:00-17:00 IST | Separate holiday calendar |
| BSE | 09:15-15:30 IST | |
| MCX and NSE commodity (non-agri) | 09:00-23:30 IST during US Daylight Saving, 09:00-23:55 IST during US Standard Time | Follows the US clock change |
| Muhurat | Annual Diwali session | Detected automatically |
Quick usage
from aion_indian_market_calendar import IndiaMarketCalendar
from datetime import datetime
from zoneinfo import ZoneInfo
cal = IndiaMarketCalendar.bundled(year=2026)
tz = ZoneInfo("Asia/Kolkata")
now = datetime.now(tz)
# Instance method: datetime first, market as a keyword.
# Is NSE equity open right now?
cal.is_market_open(now, market="NSE")
# Is CDS (currency derivatives) open?
cal.is_market_open(now, market="NSE_CURRENCY_DERIVATIVES")
cal.is_market_open(now, market="CDS") # alias works too
# Is MCX open on a specific date and time?
cal.is_market_open(datetime(2026, 1, 26, 10, 0, tzinfo=tz), market="MCX") # False: Republic Day
# Is today a Muhurat trading session?
cal.is_trading_day(now, market="NSE")
# Get all NSE Currency Derivatives holidays for 2026
cal.holidays("NSE_CURRENCY_DERIVATIVES")
# Which instruments trade on CDS?
# USDINR, EURINR, GBPINR, JPYINR: pass the instrument name directly
cal.is_market_open(now, market="USDINR") # resolves to NSE_CURRENCY_DERIVATIVES
Common use cases
- Scheduling: skip weekends and segment-specific holidays in automated workflows
- CDS workflows: gate currency derivative orders on the correct 09:00-17:00 window
- Backtesting: generate valid trading day sequences per segment, not a shared equity calendar
- MCX evening sessions: confirm commodity market is open after 15:30 when NSE is closed
- Muhurat trading: detect the annual Diwali special equity session window
- Derivatives schedules: find the next NIFTY, BANKNIFTY or SENSEX expiry date, holiday-adjusted
- Settlement jobs: tell a trading day from a settlement day, such as the annual bank closing on 1 April
- CI pipelines: gate data ingestion jobs per segment without hardcoding holiday lists
Package details
- License: MIT, use freely in commercial and open-source projects
- Latest version: 1.7.1, 2 November 2026
- Python: 3.10 and above
- Segments: NSE, NSE F&O, NSE Currency Derivatives, BSE, MCX, NSE Commodity Derivatives, Muhurat
- Holiday data: bundled, and refreshed at most daily from a hash-verified public repository
- No account: works immediately after pip install
- Offline use:
AION_IN_CALENDAR_OFFLINE=1turns off the data refresh; the bundled data still answers
Verify the number yourself
curl -sS "https://pypistats.org/api/packages/aion-indian-market-calendar/overall" | python3 -m json.tool
The download counter above is sourced from /api/calendar/public-metrics (backed by PyPIStats, cached hourly). PyPI numbers count download events, not unique humans.