pandas_market_calendars

repository·master·Indexed 21 days ago

https://github.com/rsheftel/pandas_market_calendars

Market and exchange trading calendars for pandas, providing holiday, late open, and early close schedules for over 50 global equity, futures, Forex/OTC, and bond exchanges. Version 5.4.0 includes specialized support for CME_TradeDate and EUREX pre/post session endpoints. The library allows users to generate market schedules, identify valid business days, and implement custom exchange calendars by inheriting from the MarketCalendar class.

Tokens
15.3K
Snippets
60
Records
71
Agent score
75%

What's inside pandas_market_calendars

  1. How market calendars and data updates work

    master

    The pandas_market_calendars package ships calendar rules and market hours as part of the package code itself. It does not fetch live market hours from a server at runtime.

    To receive updated or corrected market hours, you must:

    1. Install a newer package release.
    2. Or manually update the source code.

    Calendars mirrored from exchange_calendars also rely on the version installed in your local Python environment rather than a live data feed.

  2. Understand and use regular_market_times

    master

    The regular_market_times attribute is a dictionary containing moments in a trading day.

    Key requirements for the dictionary:

    • Must contain market_open and market_close.
    • If a break exists, it must contain break_start and break_end (only one break is supported).
    • Each entry is a tuple of tuples in the format (first_date_used, time[, offset]).
    • The first tuple's date should be None to mark the start. Subsequent tuples use the date when the time was first used.
    • Dates must be in ascending order.

    Common keys include pre, market_open, market_close, and post.

    print("The original NYSE calendar: \n", nyse.regular_market_times)
    # Example output structure:
    # ProtectedDict({'pre': ((None, datetime.time(4, 0)),), 
    #                'market_open': ((None, datetime.time(10, 0)), ('1985-01-01', datetime.time(9, 30))), ...})
    
    # To get all historical time changes for a specific market time:
    print(nyse.get_time("market_close", all_times=True))
  3. Access exchange_calendars through pandas_market_calendars

    master
    The pandas_market_calendars package provides access to all calendars found in the exchange_calendars project. You can use the ISO codes from the trading_calendars page to access these calendars. Note that many calendars are duplicated between pandas_market_calendars and trading_calendars; you can use whichever project you prefer for your workflow.
  4. Handle trading breaks in market schedules

    master

    Some markets (such as CME_Equity) have daily intraday breaks where the market is closed for a specific period. When calling schedule() on these calendars, the resulting DataFrame includes additional columns to represent these breaks: break_start and break_end.

    When using mcal.date_range() with a schedule that contains breaks, the function properly accounts for them by including the break start and end times in the generated DatetimeIndex.

    import pandas_market_calendars as mcal
    
    # Get a calendar with intraday breaks
    cme = mcal.get_calendar('CME_Equity')
    
    # Generate the schedule
    schedule = cme.schedule('2020-01-01', '2020-01-04')
    
    # The schedule DataFrame will contain: market_open, break_start, break_end, market_close
    print(schedule)
    
    # date_range() accounts for the breaks in the index
    dr = mcal.date_range(schedule, '5H')
    print(dr)
  5. Setup an exchange calendar and access basic properties

    master

    Use mcal.get_calendar(name) to initialize a calendar object for a specific exchange (e.g., 'NYSE'). Once initialized, you can access the exchange's timezone via the .tz.zone attribute and retrieve its holiday schedule using the .holidays() method, which returns an AbstractHolidayCalendar object.

    import pandas_market_calendars as mcal
    
    # Setup new exchange calendar
    nyse = mcal.get_calendar('NYSE')
    
    # Get the time zone
    print(nyse.tz.zone)  # e.g., 'America/New_York'
    
    # Get the AbstractHolidayCalendar object
    holidays = nyse.holidays()
    print(holidays.holidays[-5:])
  6. Customize regular trading hours in a calendar

    master

    The simplest way to modify the open and/or close times of regular trading hours is to pass datetime.time objects to the constructor when creating a calendar via mcal.get_calendar().

    import pandas_market_calendars as mcal
    from datetime import time
    
    # Create an NYSE calendar with custom regular trading hours
    cal = mcal.get_calendar('NYSE', open_time=time(10, 0), close_time=time(14, 30))
    print('open, close: %s, %s' % (cal.open_time, cal.close_time))
  7. Import pandas_market_calendars

    master

    To use the library, import pandas_market_calendars (commonly aliased as mcal). You will typically also need pandas for data handling and datetime.time for specifying market hours.

    Note: If you are running scripts from a subdirectory and the package is not installed in your environment, you may need to manually append the parent directory to sys.path to locate the module.

    import sys
    sysys.path.append("../") 
    from datetime import time
    import pandas as pd
    import pandas_market_calendars as mcal
  8. Create a new market or exchange calendar

    master

    To implement a custom exchange or OTC market, you must create a new class that inherits from MarketCalendar. This allows you to define custom trading hours, holidays, and special market conditions.

    Implementation Steps

    1. Inheritance: Create a class inheriting from MarketCalendar.
    2. Registration: Set the aliases class attribute (a list of strings) so the calendar can be retrieved via mcal.get_calendar(alias).
    3. Trading Hours: Define the regular_market_times class attribute as a dictionary.
      • Each entry must contain market_open and market_close.
      • If a break is required, include break_start and break_end (only one break is supported).
      • Values are tuples of tuples in the format: (first_date_used, time[, offset]).
      • The first tuple's date must be None. Subsequent tuples use the date when that time was first used. Dates must be in ascending order.
    4. Required Properties: Define name and tz (time zone) as property methods.
    5. Register the Class: Import your new class into calendar_registry.py using the format: from .exchange_calendar_xxx import XXXExchangeCalendar.
    class MyNewExchangeCalendar(MarketCalendar):
        aliases = ['MY_EXCHANGE']
        
        regular_market_times = {
            'market_open': {
                (None, datetime.time(9, 30)),
                (datetime.date(2023, 1, 1), datetime.time(10, 0))
            },
            'market_close': {
                (None, datetime.time(16, 0))
            }
        }
    
        @property
        def name(self):
            return 'My New Exchange'
    
        @property
        def tz(self):
            return pytz.timezone('America/New_York')