from datetime import time from zoneinfo import ZoneInfo import pandas as pd import functools from pandas.tseries.offsets import CustomBusinessDay from .precomputed_exchange_calendar import PrecomputedExchangeCalendar from .pandas_extensions.offsets import MultipleWeekmaskCustomBusinessDay """ References for precomputed BSE/NSE holidays: NSE: https://www.nseindia.com/products-services/equity-market-timings-holidays BSE: https://www.bseindia.com/static/markets/marketinfo/listholi.aspx Zerodha: https://zerodha.com/z-connect/category/traders-zone/holidays Although NSE/BSE provides only current year's dates, Zerodha provides holidays since 2013. """ precomputed_bse_holidays = pd.to_datetime( [ "1997-01-23", "1997-03-07", "1997-03-24", "1997-04-08", "1997-04-14", "1997-04-16", "1997-04-18", "1997-05-01", "1997-05-08", "1997-08-15", "1997-08-18", "1997-08-25", "1997-10-02", "1997-10-28", "1997-10-29", "1997-10-31", "1997-12-25", "1998-04-09", "1998-04-14", "1998-04-28", "1998-12-25", "1999-01-01", "1999-01-20", "1999-01-26", "1999-03-02", "1999-03-18", "1999-03-25", "1999-03-29", "1999-04-02", "1999-04-14", "1999-04-27", "1999-04-30", "1999-09-13", "1999-10-19", "1999-11-08", "1999-11-10", "1999-11-23", "1999-12-31", "2000-01-26", "2000-03-17", "2000-03-20", "2000-04-14", "2000-04-21", "2000-05-01", "2000-08-15", "2000-09-01", "2000-10-02", "2000-12-25", "2001-01-01", "2001-01-26", "2001-03-06", "2001-04-05", "2001-04-13", "2001-05-01", "2001-08-15", "2001-08-22", "2001-10-02", "2001-10-26", "2001-11-16", "2001-11-30", "2001-12-17", "2001-12-25", "2002-03-25", "2002-03-29", "2002-05-01", "2002-08-15", "2002-09-10", "2002-10-02", "2002-10-15", "2002-11-06", "2002-11-19", "2002-12-25", "2003-02-13", "2003-03-14", "2003-03-18", "2003-04-14", "2003-04-18", "2003-05-01", "2003-08-15", "2003-10-02", "2003-11-26", "2003-12-25", "2004-01-01", "2004-01-26", "2004-02-02", "2004-03-02", "2004-04-09", "2004-04-14", "2004-04-26", "2004-10-13", "2004-10-22", "2004-11-15", "2004-11-26", "2005-01-21", "2005-01-26", "2005-03-25", "2005-04-14", "2005-07-28", "2005-08-15", "2005-09-07", "2005-10-12", "2005-11-03", "2005-11-04", "2005-11-15", "2006-01-11", "2006-01-26", "2006-02-09", "2006-03-15", "2006-04-06", "2006-04-11", "2006-04-14", "2006-05-01", "2006-08-15", "2006-10-02", "2006-10-24", "2006-10-25", "2006-12-25", "2007-01-01", "2007-01-26", "2007-01-30", "2007-02-16", "2007-03-27", "2007-04-06", "2007-05-01", "2007-05-02", "2007-08-15", "2007-10-02", "2007-12-21", "2007-12-25", "2008-03-06", "2008-03-20", "2008-03-21", "2008-04-14", "2008-04-18", "2008-05-01", "2008-05-19", "2008-08-15", "2008-09-03", "2008-10-02", "2008-10-09", "2008-10-30", "2008-11-13", "2008-11-27", "2008-12-09", "2008-12-25", "2009-01-08", "2009-01-26", "2009-02-23", "2009-03-10", "2009-03-11", "2009-04-03", "2009-04-07", "2009-04-10", "2009-04-14", "2009-04-30", "2009-05-01", "2009-09-21", "2009-09-28", "2009-10-02", "2009-10-13", "2009-10-19", "2009-11-02", "2009-12-25", "2009-12-28", "2010-01-01", "2010-01-26", "2010-02-12", "2010-03-01", "2010-03-24", "2010-04-02", "2010-04-14", "2010-09-10", "2010-11-17", "2010-12-17", "2011-01-26", "2011-03-02", "2011-04-12", "2011-04-14", "2011-04-22", "2011-08-15", "2011-08-31", "2011-09-01", "2011-10-06", "2011-10-27", "2011-11-07", "2011-11-10", "2011-12-06", "2012-01-26", "2012-02-20", "2012-03-08", "2012-04-05", "2012-04-06", "2012-05-01", "2012-08-15", "2012-08-20", "2012-09-19", "2012-10-02", "2012-10-24", "2012-11-14", "2012-11-28", "2012-12-25", "2013-03-27", "2013-03-29", "2013-04-14", "2013-04-19", "2013-04-24", "2013-05-01", "2013-08-09", "2013-08-15", "2013-09-09", "2013-10-02", "2013-10-13", "2013-10-16", "2013-11-03", "2013-11-04", "2013-11-14", "2013-11-17", "2013-12-25", "2014-01-26", "2014-02-27", "2014-03-17", "2014-04-08", "2014-04-13", "2014-04-14", "2014-04-18", "2014-04-24", "2014-05-01", "2014-07-29", "2014-08-15", "2014-08-29", "2014-10-02", "2014-10-03", "2014-10-06", "2014-10-15", "2014-10-23", "2014-10-24", "2014-11-04", "2014-11-06", "2014-12-25", "2015-01-26", "2015-02-17", "2015-03-06", "2015-03-28", "2015-04-02", "2015-04-03", "2015-04-14", "2015-05-01", "2015-07-18", "2015-08-15", "2015-09-17", "2015-09-25", "2015-10-02", "2015-10-22", "2015-10-24", "2015-11-11", "2015-11-12", "2015-11-25", "2015-12-25", "2026-01-15", "2016-01-26", "2016-03-07", "2016-03-24", "2016-03-25", "2016-04-14", "2016-04-15", "2016-04-19", "2016-05-01", "2016-07-06", "2016-08-15", "2016-09-05", "2016-09-13", "2016-10-02", "2016-10-11", "2016-10-12", "2016-10-30", "2016-10-31", "2016-11-14", "2016-12-25", "2017-01-26", "2017-02-24", "2017-03-13", "2017-04-04", "2017-04-09", "2017-04-14", "2017-04-14", "2017-05-01", "2017-06-26", "2017-08-15", "2017-08-25", "2017-09-02", "2017-09-30", "2017-10-01", "2017-10-02", "2017-10-19", "2017-10-20", "2017-11-04", "2017-12-25", "2018-01-26", "2018-02-13", "2018-03-02", "2018-03-25", "2018-03-29", "2018-03-30", "2018-04-14", "2018-05-01", "2018-06-16", "2018-08-15", "2018-08-22", "2018-09-13", "2018-09-20", "2018-10-02", "2018-10-18", "2018-11-07", "2018-11-08", "2018-11-23", "2018-12-25", "2019-01-26", "2019-03-04", "2019-03-21", "2019-04-13", "2019-04-14", "2019-04-17", "2019-04-19", "2019-04-29", "2019-05-01", "2019-06-05", "2019-08-12", "2019-08-15", "2019-09-02", "2019-09-10", "2019-10-02", "2019-10-08", "2019-10-21", "2019-10-27", "2019-10-28", "2019-11-12", "2019-12-25", "2020-01-26", "2020-02-21", "2020-03-10", "2020-04-02", "2020-04-06", "2020-04-10", "2020-04-14", "2020-05-01", "2020-05-25", "2020-08-01", "2020-08-15", "2020-08-22", "2020-08-30", "2020-10-02", "2020-10-25", "2020-11-14", "2020-11-16", "2020-11-30", "2020-12-25", "2021-01-26", "2021-03-11", "2021-03-29", "2021-04-02", "2021-04-14", "2021-04-21", "2021-04-25", "2021-05-01", "2021-05-13", "2021-07-21", "2021-08-15", "2021-08-19", "2021-09-10", "2021-10-02", "2021-10-15", "2021-11-04", "2021-11-05", "2021-11-19", "2021-12-25", "2022-01-26", "2022-03-01", "2022-03-18", "2022-04-14", "2022-04-15", "2022-05-03", "2022-08-09", "2022-08-15", "2022-08-31", "2022-10-05", "2022-10-22", "2022-10-24", "2022-10-26", "2022-11-08", "2023-01-26", "2023-03-07", "2023-03-30", "2023-04-04", "2023-04-07", "2023-04-14", "2023-05-01", "2023-06-29", "2023-08-15", "2023-09-19", "2023-10-02", "2023-10-24", "2023-11-14", "2023-11-27", "2023-12-25", "2024-01-22", # Ram Mandir inauguration holiday "2024-01-26", "2024-03-08", "2024-03-25", "2024-03-29", "2024-04-11", "2024-04-17", "2024-05-01", "2024-05-20", # Parliamentary Elections "2024-06-17", "2024-07-17", "2024-08-15", "2024-10-02", "2024-11-01", "2024-11-15", "2024-11-20", # Maharashtra Assembly Elections "2024-12-25", "2025-02-26", "2025-03-14", "2025-03-31", "2025-04-10", "2025-04-14", "2025-04-18", "2025-05-01", "2025-08-15", "2025-08-27", "2025-10-02", "2025-10-21", "2025-10-22", "2025-11-05", "2025-12-25", "2026-01-26", "2026-03-03", "2026-03-26", "2026-03-31", "2026-04-03", "2026-04-14", "2026-05-01", "2026-05-28", "2026-06-26", "2026-09-14", "2026-10-02", "2026-10-20", "2026-11-10", "2026-11-24", "2026-12-25", ] ) class XBOMExchangeCalendar(PrecomputedExchangeCalendar): """ Exchange calendar for the Bombay Stock Exchange (BSE, XBOM). Open Time: 9:15 AM, Asia/Kolkata Close Time: 3:30 PM, Asia/Kolkata Due to the complexity around the BSE holidays, we are hardcoding a list of holidays back to 1997, and forward through 2025. There are no known early closes or late opens. """ name = "XBOM" tz = ZoneInfo("Asia/Kolkata") open_times = ((None, time(9, 15)),) close_times = ((None, time(15, 30)),) @classmethod def precomputed_holidays(cls): return precomputed_bse_holidays @property def special_weekmasks(self): """ Returns ------- list: List of (date, date, str) tuples that represent special weekmasks that applies between dates. """ return [ # Special trading session on Saturday, January 20, 2024. # https://www.bseindia.com/downloads/SPDJ_ANN/MediaReleasePDF/1470003_mediareleasespecialtradingsessionfors&pbseindices20240105.pdf (pd.Timestamp("2024-01-15"), pd.Timestamp("2024-01-21"), "1111110"), # Special trading session on Saturday, February 1, 2025 # https://www.angelone.in/news/will-bse-and-nse-be-open-on-budget-day-feb-1 (pd.Timestamp("2025-01-27"), pd.Timestamp("2025-02-02"), "1111110"), ] @functools.cached_property def day(self): if self.special_weekmasks: return MultipleWeekmaskCustomBusinessDay( holidays=self.adhoc_holidays, calendar=self.regular_holidays, weekmask=self.weekmask, weekmasks=self.special_weekmasks, ) return CustomBusinessDay( holidays=self.adhoc_holidays, calendar=self.regular_holidays, weekmask=self.weekmask, )