Creating and loading calendars¶
There are two main ways to work with calendars:
construct a
Calendar(...)directly from holidays and nonworking weekdaysload a calendar with
Calendar.load(...)
Use the constructor when your application already owns the holiday data. Use load when you want packaged calendars or a JSON file.
Calendars that come with the package¶
The package ships with these calendar names:
ANBIMAB3Actual
[1]:
from bizdays import Calendar, list_calendars
{name: Calendar.load(name=name).name for name in ["ANBIMA", "B3", "Actual"]}
[1]:
{'ANBIMA': 'ANBIMA', 'B3': 'B3', 'Actual': 'Actual'}
[2]:
list_calendars()
[2]:
{'packaged': ['ANBIMA', 'B3', 'Actual'],
'pandas_market_calendars': {'available': True,
'prefix': 'PMC/',
'calendars': ['ASX',
'BMF',
'B3',
'BSE',
'NSE',
'XNSE',
'CFE',
'CBOE_Futures',
'CBOE_Equity_Options',
'CBOE_Index_Options',
'CME_Equity',
'CBOT_Equity',
'CME_Agriculture',
'CBOT_Agriculture',
'COMEX_Agriculture',
'NYMEX_Agriculture',
'CME_Rate',
'CBOT_Rate',
'CME_InterestRate',
'CBOT_InterestRate',
'CME_Bond',
'CBOT_Bond',
'CMEGlobex_Livestock',
'CMEGlobex_Live_Cattle',
'CMEGlobex_Feeder_Cattle',
'CMEGlobex_Lean_Hog',
'CMEGlobex_Port_Cutout',
'CMEGlobex_Grains',
'CMEGlobex_Oilseeds',
'CME Globex Cryptocurrencies',
'CME Globex Crypto',
'CMEGlobex_EnergyAndMetals',
'CMEGlobex_Energy',
'CMEGlobex_CrudeAndRefined',
'CMEGlobex_NYHarbor',
'CMEGlobex_HO',
'HO',
'CMEGlobex_Crude',
'CMEGlobex_CL',
'CL',
'CMEGlobex_Gas',
'CMEGlobex_RB',
'RB',
'CMEGlobex_MicroCrude',
'CMEGlobex_MCL',
'MCL',
'CMEGlobex_NatGas',
'CMEGlobex_NG',
'NG',
'CMEGlobex_Dutch_NatGas',
'CMEGlobex_TTF',
'TTF',
'CMEGlobex_LastDay_NatGas',
'CMEGlobex_NN',
'NN',
'CMEGlobex_CarbonOffset',
'CMEGlobex_CGO',
'CGO',
'C-GEO',
'CMEGlobex_NGO',
'NGO',
'CMEGlobex_GEO',
'GEO',
'CMEGlobex_Metals',
'CMEGlobex_PreciousMetals',
'CMEGlobex_Gold',
'CMEGlobex_GC',
'GC',
'CMEGlobex_Silver',
'CMEGlobex_SI',
'SI',
'CMEGlobex_Platinum',
'CMEGlobex_PL',
'PL',
'CMEGlobex_BaseMetals',
'CMEGlobex_Copper',
'CMEGlobex_HG',
'HG',
'CMEGlobex_Aluminum',
'CMEGlobex_ALI',
'ALI',
'CMEGlobex_QC',
'QC',
'CMEGlobex_FerrousMetals',
'CMEGlobex_HRC',
'HRC',
'CMEGlobex_BUS',
'BUS',
'CMEGlobex_TIO',
'TIO',
'CME Globex Equity',
'CMEGlobex_FX',
'CME_FX',
'CME_Currency',
'CME Globex Fixed Income',
'CME Globex Interest Rate Products',
'EUREX',
'EUREX_Bond',
'HKEX',
'ICE',
'ICEUS',
'NYFE',
'NYSE',
'stock',
'NASDAQ',
'BATS',
'DJIA',
'DOW',
'IEX',
'Investors_Exchange',
'JPX',
'XJPX',
'LSE',
'OSE',
'SIFMAUS',
'SIFMA_US',
'Capital_Markets_US',
'Financial_Markets_US',
'Bond_Markets_US',
'SIFMAUK',
'SIFMA_UK',
'Capital_Markets_UK',
'Financial_Markets_UK',
'Bond_Markets_UK',
'SIFMAJP',
'SIFMA_JP',
'Capital_Markets_JP',
'Financial_Markets_JP',
'Bond_Markets_JP',
'SIX',
'SSE',
'TASE',
'TSX',
'TSXV',
'AIXK',
'ASEX',
'BVMF',
'XCYS',
'CMES',
'IEPA',
'XAMS',
'XASX',
'XBEL',
'XBDA',
'XBKK',
'XBOG',
'XBOM',
'XBRU',
'XBSE',
'XBUD',
'XBUE',
'XBRA',
'XCBF',
'XCSE',
'XDUB',
'XDUS',
'XEEE',
'XFRA',
'XETR',
'XHAM',
'XHEL',
'XHKG',
'XICE',
'XIDX',
'XIST',
'XJSE',
'XKAR',
'XKLS',
'XKRX',
'XLIM',
'XLIS',
'XLIT',
'XLJU',
'XLON',
'XLUX',
'XMAD',
'XMEX',
'XMIL',
'XMOS',
'XNYS',
'XNZE',
'XOSL',
'XPAR',
'XPHS',
'XPRA',
'XRIS',
'XSAU',
'XSES',
'XSGO',
'XSHG',
'XSTO',
'XSWX',
'XTAE',
'XTAI',
'XTAL',
'XTKS',
'XTSE',
'XWAR',
'XWBO',
'XZAG',
'us_futures',
'24/7',
'24/5']},
'exchange_calendars': {'available': True,
'prefix': 'XCAL/',
'calendars': ['24/5',
'24/7',
'AIXK',
'ARCX',
'ASEX',
'ASX',
'BATS',
'BMF',
'BSE',
'BVB',
'BVMF',
'CBOT',
'CFE',
'CME',
'CMES',
'COMEX',
'FWB',
'HKEX',
'ICE',
'ICEUS',
'IEPA',
'JKT',
'JPX',
'LSE',
'LUXSE',
'NASDAQ',
'NYFE',
'NYMEX',
'NYSE',
'OOTC',
'OSE',
'SIX',
'SSE',
'TASE',
'TSX',
'XAMS',
'XASE',
'XASX',
'XBDA',
'XBEL',
'XBKK',
'XBOG',
'XBOM',
'XBRA',
'XBRU',
'XBSE',
'XBUD',
'XBUE',
'XCBF',
'XCSE',
'XCYS',
'XDUB',
'XDUS',
'XEEE',
'XETR',
'XFRA',
'XHAM',
'XHEL',
'XHKG',
'XICE',
'XIDX',
'XIST',
'XJSE',
'XKAR',
'XKLS',
'XKRX',
'XLIM',
'XLIS',
'XLIT',
'XLJU',
'XLON',
'XLUX',
'XMAD',
'XMEX',
'XMIL',
'XMOS',
'XNAS',
'XNYS',
'XNZE',
'XOSL',
'XPAR',
'XPHS',
'XPRA',
'XRIS',
'XSAU',
'XSES',
'XSGO',
'XSHG',
'XSTO',
'XSWX',
'XTAE',
'XTAI',
'XTAL',
'XTKS',
'XTSE',
'XTSX',
'XWAR',
'XWBO',
'XZAG',
'us_futures']},
'workalendar': {'available': True,
'prefix': 'WORK/',
'calendars': ['AT',
'BY',
'BE',
'BG',
'KY',
'HR',
'CY',
'CZ',
'DK',
'EE',
'FI',
'FR',
'GE',
'GR',
'GG',
'HU',
'IS',
'IE',
'IT',
'LV',
'LT',
'LU',
'MT',
'MC',
'NL',
'NO',
'PL',
'PT',
'RO',
'RU',
'RS',
'SK',
'SI',
'SE',
'CH',
'UA',
'GB',
'GB-NIR',
'TR',
'DE',
'DE-BW',
'DE-BY',
'DE-BE',
'DE-BB',
'DE-HB',
'DE-HH',
'DE-HE',
'DE-MV',
'DE-NI',
'DE-NW',
'DE-RP',
'DE-SL',
'DE-SN',
'DE-ST',
'DE-SH',
'DE-TH',
'ES',
'ES-AN',
'ES-AR',
'ES-CT',
'ES-CL',
'ES-CM',
'ES-CN',
'ES-EX',
'ES-GA',
'ES-IB',
'ES-RI',
'ES-MD',
'ES-MC',
'ES-NA',
'ES-AS',
'ES-PV',
'ES-CB',
'ES-VC',
'CH-AG',
'CH-AI',
'CH-AR',
'CH-BE',
'CH-BL',
'CH-BS',
'CH-FR',
'CH-GE',
'CH-GL',
'CH-GR',
'CH-JU',
'CH-LU',
'CH-NE',
'CH-NW',
'CH-OW',
'CH-SG',
'CH-SH',
'CH-SO',
'CH-SZ',
'CH-TG',
'CH-TI',
'CH-UR',
'CH-VD',
'CH-VS',
'CH-ZG',
'CH-ZH',
'US',
'US-AL',
'US-AK',
'US-AZ',
'US-AR',
'US-CA',
'US-CO',
'US-CT',
'US-DE',
'US-DC',
'US-FL',
'US-GA',
'US-HI',
'US-ID',
'US-IL',
'US-IN',
'US-IA',
'US-KS',
'US-KY',
'US-LA',
'US-ME',
'US-MD',
'US-MA',
'US-MI',
'US-MN',
'US-MS',
'US-MO',
'US-MT',
'US-NE',
'US-NV',
'US-NH',
'US-NJ',
'US-NM',
'US-NY',
'US-NC',
'US-ND',
'US-OH',
'US-OK',
'US-OR',
'US-PA',
'US-RI',
'US-SC',
'US-SD',
'US-TN',
'US-TX',
'US-UT',
'US-VT',
'US-VA',
'US-WA',
'US-WV',
'US-WI',
'US-WY',
'US-AS',
'US-GU',
'BR',
'BR-AC',
'BR-AL',
'BR-AP',
'BR-AM',
'BR-BA',
'BR-CE',
'BR-DF',
'BR-ES',
'BR-GO',
'BR-MA',
'BR-MG',
'BR-MT',
'BR-MS',
'BR-PA',
'BR-PB',
'BR-PE',
'BR-PI',
'BR-PR',
'BR-RJ',
'BR-RN',
'BR-RS',
'BR-RO',
'BR-RR',
'BR-SC',
'BR-SP',
'BR-SE',
'BR-TO',
'CA',
'CA-ON',
'CA-QC',
'CA-BC',
'CA-AB',
'CA-SK',
'CA-MB',
'CA-NB',
'CA-NS',
'CA-PE',
'CA-NL',
'CA-YT',
'CA-NT',
'CA-NU',
'BB',
'CL',
'CO',
'MX',
'PA',
'PY',
'AR',
'SV',
'DZ',
'BJ',
'CI',
'KE',
'MG',
'ST',
'ZA',
'AO',
'MZ',
'NG',
'TN',
'CN',
'HK',
'JP',
'MY',
'QA',
'SG',
'KR',
'TW',
'IL',
'PH',
'KZ',
'AU',
'AU-ACT',
'AU-NSW',
'AU-NT',
'AU-QLD',
'AU-SA',
'AU-TAS',
'AU-VIC',
'AU-WA',
'MH',
'NZ']}}
list_calendars() is the programmatic discovery helper for calendar sources.
It returns a dictionary with:
packaged: the curated calendars shipped withbizdayspandas_market_calendars: metadata about the optional PMC integrationexchange_calendars: metadata about the optional exchange calendar integrationworkalendar: metadata about the optional workalendar integration
Each integration entry contains:
available: whether the optional dependency is installedprefix: the prefix used withCalendar.load(name="<prefix><calendar>")calendars: the discovered calendar names when available, otherwise an empty list
[3]:
info = list_calendars()
{
"packaged": info["packaged"],
"pmc_available": info["pandas_market_calendars"]["available"],
"pmc_prefix": info["pandas_market_calendars"]["prefix"],
"xcal_available": info["exchange_calendars"]["available"],
"xcal_prefix": info["exchange_calendars"]["prefix"],
"work_available": info["workalendar"]["available"],
"work_prefix": info["workalendar"]["prefix"],
}
[3]:
{'packaged': ['ANBIMA', 'B3', 'Actual'],
'pmc_available': True,
'pmc_prefix': 'PMC/',
'xcal_available': True,
'xcal_prefix': 'XCAL/',
'work_available': True,
'work_prefix': 'WORK/'}
Actual is the simplest packaged calendar: it has no holidays and no nonworking weekdays, so every day is a business day.
[4]:
actual = Calendar.load(name="Actual")
actual.isbizday(["2024-01-01", "2024-01-06", "2024-01-07"])
[4]:
masked_array(data=[True, True, True],
mask=[False, False, False],
fill_value=False)
Creating a calendar from scratch with Calendar(...)¶
The constructor accepts:
holidays: ISO date strings or date-like objectsweekdays: names of nonworking weekdaysstartdateandenddate: optional calendar boundsname: a display namefinancial: whether to use financial counting rules
[5]:
custom = Calendar(
holidays=["2024-01-01", "2024-04-21", "2024-12-25"],
weekdays=["Saturday", "Sunday"],
startdate="2024-01-01",
enddate="2024-12-31",
name="Example",
financial=True,
)
custom
[5]:
Calendar: Example
Start: 2024-01-01
End: 2024-12-31
Weekdays: Saturday, Sunday
Holidays: 3
Financial: True
[6]:
{
"name": custom.name,
"weekdays": custom.weekdays,
"startdate": str(custom.startdate),
"enddate": str(custom.enddate),
"holidays": [str(day) for day in custom.holidays],
}
[6]:
{'name': 'Example',
'weekdays': ('Saturday', 'Sunday'),
'startdate': '2024-01-01',
'enddate': '2024-12-31',
'holidays': ['2024-01-01', '2024-04-21', '2024-12-25']}
If you omit startdate and enddate, they are inferred from the holiday range. If you construct a calendar without holidays, a broad default range is used.
[7]:
weekends_only = Calendar(
weekdays=["Saturday", "Sunday"],
name="WeekendsOnly",
)
{
"startdate": str(weekends_only.startdate),
"enddate": str(weekends_only.enddate),
"isbizday": weekends_only.isbizday(["2024-01-05", "2024-01-06", "2024-01-07"]),
}
[7]:
{'startdate': '1970-01-01',
'enddate': '2071-01-01',
'isbizday': masked_array(data=[True, False, False],
mask=[False, False, False],
fill_value=False)}
JSON calendar layout¶
Calendar.load(filename=...) expects a JSON object with this layout:
name: stringweekdays: list of stringsholidays: list of ISO date stringsfinancial: booleanstart.dateandend.date: optional ISO date strings (YYYY-MM-DD) that setstartdateandenddate; a bad value raisesValueErroradjust.fromandadjust.to: optional; only the defaults"following"and"preceding"are accepted, and other values raiseValueError
[8]:
payload = {
"name": "CustomJson",
"weekdays": ["saturday", "sunday"],
"holidays": ["2024-01-01", "2024-04-21", "2024-12-25"],
"financial": True,
"adjust.from": "following",
"adjust.to": "preceding",
}
payload
[8]:
{'name': 'CustomJson',
'weekdays': ['saturday', 'sunday'],
'holidays': ['2024-01-01', '2024-04-21', '2024-12-25'],
'financial': True,
'adjust.from': 'following',
'adjust.to': 'preceding'}
[9]:
import json
import tempfile
from pathlib import Path
with tempfile.TemporaryDirectory() as tmpdir:
filename = Path(tmpdir) / "custom-calendar.json"
filename.write_text(json.dumps(payload), encoding="utf-8")
json_calendar = Calendar.load(filename=str(filename))
json_calendar
[9]:
Calendar: CustomJson
Start: 2024-01-01
End: 2024-12-25
Weekdays: Saturday, Sunday
Holidays: 3
Financial: True
Optional calendar provider integrations¶
If you install the optional bizdays[pmc] extra, Calendar.load(name="PMC/<calendar>") can load calendars from pandas_market_calendars.
If you install the optional bizdays[xcal] extra, Calendar.load(name="XCAL/<calendar>") can load calendars from exchange_calendars.
If you install the optional bizdays[work] extra, Calendar.load(name="WORK/<code>") can load calendars from workalendar.
These are not packaged calendars; they come from optional integrations.
[10]:
{
"pmc": Calendar.load(name="PMC/B3").name,
"xcal": Calendar.load(name="XCAL/XNYS").name,
"work": Calendar.load(name="WORK/FR").name,
}
[10]:
{'pmc': 'PMC/B3', 'xcal': 'XCAL/XNYS', 'work': 'WORK/FR'}