Scheduling
Exchange calendars — sessions, minutes, and trading index.
Included in the base pip install mktlib — no extra dependencies.
- mktlib.scheduling.get_calendar(name)[source]
Get an exchange calendar by name or alias.
- Return type:
- Parameters:
name (str)
ExchangeCalendar
Core
- ExchangeCalendar.valid_days(start, end)[source]
Return a Polars Series of trading days within [start, end].
Trading dates are weekdays (Mon-Fri) minus closures. For calendars with
open_offset < 0(e.g. Globex, FX), a session’s market_open may fall on the prior calendar day (e.g. Sunday 17:00 for Monday’s session), but the session is still attributed to the weekday. Minute-level methods likeis_open_on_minutehandle the cross-day lookup.
- ExchangeCalendar.schedule(start, end)[source]
Return a Polars DataFrame with columns: date, market_open, market_close.
For calendars with
open_offset < 0, market_open falls on the prior calendar day (e.g. Sunday 17:00 for a Monday FX session).
- ExchangeCalendar.is_session(day)[source]
Check if a given date is a trading day.
Minute Queries
- ExchangeCalendar.is_open_on_minute(dt)
Check if the exchange is open at dt. Uses
[open, close)semantics.
- ExchangeCalendar.next_open(dt)
Next market open strictly after dt (or today’s open if before it).
- ExchangeCalendar.next_close(dt)
Next market close at or after dt (today’s close if still open).
- ExchangeCalendar.previous_open(dt)
Most recent market open strictly before dt.
- ExchangeCalendar.previous_close(dt)
Most recent market close strictly before dt.
Trading Helpers
- ExchangeCalendar.filter_market_hours(df, date_column='date')
Filter rows to market hours using a schedule join.
More efficient than
trading_index()— joins on ~252 schedule rows per year instead of materializing all trading minutes.- Parameters:
df (
DataFrame) – DataFrame with a Datetime column for bar timestamps.date_column (
str) – Name of the datetime column (default"date").self (_CalendarProtocol)
- Returns:
Rows within
[market_open, market_close - 1min], excluding lunch breaks for break calendars.- Return type:
DataFrame
- ExchangeCalendar.trading_index(start, end, period='1m', closed='left')
Generate a Polars Series of trading timestamps at the given frequency.
closed:
"left"(default) =[open, close),"right"=(open, close],"both"=[open, close],"none"=(open, close).
Full Class Reference
- class mktlib.scheduling.ExchangeCalendar(name, *, timezone, open_time, close_time, holidays, adhoc_closures=None, early_closes=None, special_closures_fn=None, special_early_closes_fn=None, exclusions=None, open_offset=0)[source]
Bases:
SessionNavigationMixin,MinuteQueryMixin,TradingHelperMixinPolars-native exchange calendar with holiday/early-close support.
- Parameters:
name (str)
timezone (str)
open_time (time)
close_time (time)
holidays (list[HolidayRule])
adhoc_closures (list[AdhocClosure] | None)
early_closes (list[EarlyClose] | None)
special_closures_fn (Callable[[date, date], list[date]] | None)
special_early_closes_fn (Callable[[date, date], dict[date, time]] | None)
exclusions (set[date] | None)
open_offset (int)
- valid_days(start, end)[source]
Return a Polars Series of trading days within [start, end].
Trading dates are weekdays (Mon-Fri) minus closures. For calendars with
open_offset < 0(e.g. Globex, FX), a session’s market_open may fall on the prior calendar day (e.g. Sunday 17:00 for Monday’s session), but the session is still attributed to the weekday. Minute-level methods likeis_open_on_minutehandle the cross-day lookup.
- schedule(start, end)[source]
Return a Polars DataFrame with columns: date, market_open, market_close.
For calendars with
open_offset < 0, market_open falls on the prior calendar day (e.g. Sunday 17:00 for a Monday FX session).
ExchangeCalendarWithBreaks
ExchangeCalendarWithBreaks extends ExchangeCalendar with lunch-break
support (JPX, HKEX, SSE). The BreakMixin overrides four methods:
schedule()addsbreak_start/break_endcolumnsis_open_on_minute()returnsFalseduring the break windowtrading_index()generates separate morning and afternoon rangesfilter_market_hours()excludes lunch bars
- class mktlib.scheduling.ExchangeCalendarWithBreaks(name, *, break_start, break_end, **kwargs)[source]
Bases:
BreakMixin,ExchangeCalendarExchange calendar with lunch break support (e.g. JPX, HKEX).
- Parameters:
name (str)
break_start (time)
break_end (time)
kwargs (Any)
Custom Calendar Example
from datetime import date, time
from mktlib.scheduling import ExchangeCalendarWithBreaks, register_exchange
from mktlib.scheduling.rules import HolidayRule
cal = ExchangeCalendarWithBreaks(
name="XSHG",
timezone="Asia/Shanghai",
open_time=time(9, 30),
close_time=time(15, 0),
break_start=time(11, 30),
break_end=time(13, 0),
holidays=[
HolidayRule("New Year's Day", month=1, day=1),
HolidayRule("National Day", month=10, day=1),
],
)
register_exchange("XSHG", lambda: cal, aliases=["Shanghai", "SSE"])
Holiday Rules
- class mktlib.scheduling.rules.HolidayRule(name, month, day=None, weekday=None, week=None, observance=None, start_year=None, end_year=None)[source]
A recurring holiday rule.
Either (month, day) for fixed-date holidays or (month, weekday, week) for relative holidays (e.g., 3rd Monday of January).
- Parameters:
- class mktlib.scheduling.rules.AdhocClosure(name, dates=<factory>)[source]
An explicit list of closure dates (e.g., 9/11, Hurricane Sandy).