Calendar / seasonality¶

The one family whose input is a timestamp, not price or volume. Markets have clocks: Monday behaves differently from Friday, the first hour differently from lunchtime, month-end differently from mid-month. These turn a datetime column into features that capture those recurring effects.
day_of_week/is_weekend— weekday effects and the crypto weekend regime.hour_of_day/minute_of_day/time_since_midnight— intraday position, the raw material for your own session definitions.month_of_year/is_month_end— seasonal and month-end rebalancing effects.bars_since_session_open— how far into the session each bar is; apply with.over(session_id)so the count restarts each session.
No hardcoded market sessions
This module deliberately doesn't bake in market-specific session windows
(FX Asian/London/NY hours vary by instrument and are UTC-hour conventions).
hour_of_day / minute_of_day give you the primitives to define your own —
see the calendar how-to.
polars_ta.calendar
¶
Calendar / seasonality feature expressions.
Every other module in this library takes a price or volume column as input.
This module is the odd one out: it takes a pl.Datetime (or pl.Date)
column and derives features from the calendar, not the market data —
day-of-week, hour-of-day, time-since-session-open, and similar. These are
mundane compared to the rest of the toolkit but a real gap in a full feature
pipeline: seasonality effects (day-of-week volume patterns, intraday
volatility curves) are common enough in practice that most desks compute
some version of these.
Timestamps must already be a proper pl.Datetime/pl.Date column — convert
epoch integers first with pl.from_epoch(col, time_unit=...). This module
intentionally does not hardcode market-specific trading-session windows
(e.g. FX Asian/London/NY hours): those are UTC-hour conventions that vary by
instrument and would be silently wrong for half of any given user's data.
hour_of_day / minute_of_day give you the building blocks to define your
own session boundaries per instrument.
day_of_week
¶
day_of_week(timestamp: str | Expr) -> Expr
Day of week as an integer, Monday=0 .. Sunday=6.
Source code in polars_ta/calendar.py
26 27 28 29 | |
is_weekend
¶
is_weekend(timestamp: str | Expr) -> Expr
True for Saturday/Sunday. Meaningless (always False) on 24/7 markets like crypto, but relevant for equities/FX data that excludes weekends.
Source code in polars_ta/calendar.py
32 33 34 35 36 | |
hour_of_day
¶
hour_of_day(timestamp: str | Expr) -> Expr
Hour of day in the timestamp's own timezone/offset, [0, 23].
Source code in polars_ta/calendar.py
39 40 41 42 | |
minute_of_day
¶
minute_of_day(timestamp: str | Expr) -> Expr
Minutes since midnight, [0, 1439] — a finer-grained alternative to
hour_of_day for defining custom intraday session boundaries.
Source code in polars_ta/calendar.py
45 46 47 48 49 50 51 52 53 | |
time_since_midnight
¶
time_since_midnight(timestamp: str | Expr, unit: str = 'm') -> Expr
Elapsed time since the start of the timestamp's own calendar day.
unit is "s", "m" (default), or "h".
Source code in polars_ta/calendar.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | |
bars_since_session_open
¶
bars_since_session_open(session_col: str | Expr) -> Expr
Bar count elapsed since the start of the current session, where a "session" is any grouping column that changes value at each session boundary — a date column for a daily session, or a custom session-id column for intraday sessions with gaps.
This counts bars, not wall-clock time, so it's correct regardless of
whether bars are evenly spaced. Apply with .over(session_col) so the
counter restarts at zero for every session:
calendar.bars_since_session_open("date").over("date")
Source code in polars_ta/calendar.py
74 75 76 77 78 79 80 81 82 83 84 85 86 87 | |
month_of_year
¶
month_of_year(timestamp: str | Expr) -> Expr
Month as an integer, [1, 12] — for detecting monthly seasonality
(e.g. "January effect"-style patterns).
Source code in polars_ta/calendar.py
90 91 92 93 94 | |
is_month_end
¶
is_month_end(timestamp: str | Expr, window_days: int = 3) -> Expr
True within window_days of the end of the calendar month —
approximates the month-end rebalancing window that drives elevated
volume/volatility at many institutional desks.
Source code in polars_ta/calendar.py
97 98 99 100 101 102 103 | |