Metadata-Version: 2.5
Name: finance-dates
Version: 0.4.1
Summary: Standard financial dates
Project-URL: Repository, https://github.com/prettygoodcapital/finance-dates
Project-URL: Homepage, https://github.com/prettygoodcapital/finance-dates
Author-email: PrettyGoodCapital <prettygoodcapital@gmail.com>
License: Apache-2.0
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Rust
Requires-Python: >=3.11
Requires-Dist: finance-enums<0.8,>=0.5.1
Requires-Dist: polars>=1.0
Provides-Extra: develop
Requires-Dist: build; extra == 'develop'
Requires-Dist: bump-my-version; extra == 'develop'
Requires-Dist: check-dist; extra == 'develop'
Requires-Dist: cibuildwheel; extra == 'develop'
Requires-Dist: codespell; extra == 'develop'
Requires-Dist: exchange-calendars; extra == 'develop'
Requires-Dist: hatch-rs; extra == 'develop'
Requires-Dist: hatchling; extra == 'develop'
Requires-Dist: mdformat; extra == 'develop'
Requires-Dist: mdformat-tables>=1; extra == 'develop'
Requires-Dist: pandas-market-calendars; extra == 'develop'
Requires-Dist: pytest; extra == 'develop'
Requires-Dist: pytest-cov; extra == 'develop'
Requires-Dist: ruff; extra == 'develop'
Requires-Dist: twine; extra == 'develop'
Requires-Dist: ty; extra == 'develop'
Requires-Dist: uv; extra == 'develop'
Requires-Dist: wheel; extra == 'develop'
Requires-Dist: yardang; extra == 'develop'
Provides-Extra: reference
Requires-Dist: exchange-calendars; extra == 'reference'
Requires-Dist: pandas-market-calendars; extra == 'reference'
Description-Content-Type: text/markdown

# finance dates

Fast date ranges, holiday calendars, and trading hours for financial markets

[![Build Status](https://github.com/prettygoodcapital/finance-dates/actions/workflows/build.yaml/badge.svg?branch=main&event=push)](https://github.com/prettygoodcapital/finance-dates/actions/workflows/build.yaml)
[![codecov](https://codecov.io/gh/prettygoodcapital/finance-dates/branch/main/graph/badge.svg)](https://codecov.io/gh/prettygoodcapital/finance-dates)
[![License](https://img.shields.io/github/license/prettygoodcapital/finance-dates)](https://github.com/prettygoodcapital/finance-dates)
[![PyPI](https://img.shields.io/pypi/v/finance-dates.svg)](https://pypi.python.org/pypi/finance-dates)

## Overview

`finance-dates` provides calendar-aware date utilities for the
`finance-*` stack. The Rust core handles holiday-rule expansion,
weekend observance, early closes, and DST-aware regular and extended
trading sessions; the Python package exposes a compact API for date
series, exchange calendars, and open/close timestamps.

The library is useful when you need to answer questions like:

- What are the valid trading dates for NYSE between two dates?
- Which dates in a range are holidays or otherwise invalid for a venue?
- Is a UTC timestamp inside a market session after DST and early closes?
- What are the UTC open/close datetimes for regular and extended
  trading windows?

### Quick start

```python
from datetime import date, datetime, timezone

from finance_dates import Calendar
from finance_enums import EnergyType, ExchangeCode, UnderlyingAssetClass

c = Calendar.from_range(start=date(2024, 1, 1), end=date(2024, 1, 5))

# Inclusive plain calendar dates.
c.days()

# Mon-Fri only, holiday-blind.
c.business_days()

# Exchange-aware calendar with holidays, sessions, and early closes.
nyse = Calendar.from_exchange("XNYS")
nyse.business_days(date(2024, 7, 1), date(2024, 7, 5))
nyse.holidays(date(2024, 7, 1), date(2024, 9, 30))
nyse.sessions(date(2024, 7, 1), date(2024, 7, 5))
nyse.extended_sessions(date(2024, 7, 1), date(2024, 7, 5))
nyse.is_open(datetime(2024, 3, 11, 13, 30, tzinfo=timezone.utc))

gas = Calendar.from_asset(
  ExchangeCode.XNYM,
  UnderlyingAssetClass.Commodity,
  subclass=EnergyType.NaturalGas,
)
gas.regular_sessions
```

For US equity calendars, `regular_sessions` contains the standard
09:30-16:00 New York session template, while `extended_hours` includes
`pre_open` and `after_close` templates. On early-close days, the
after-close window begins at the early close.

Calendars with lunch breaks expose multiple regular session templates. For
example, Tokyo (`XTKS`) currently returns separate 09:00-11:30 and
12:30-15:30 local sessions, and `sessions()` returns one UTC open/close pair
per regular interval. Tokyo is date-effective around the 2024-11-05 close-time
extension, so historical dates before that change close at 15:00 local while
current dates close at 15:30.

Commodity futures can also use split sessions. Prefer `Calendar.from_asset()`
with `finance-enums` exchange and asset/subclass enum members, or their string
values, when you know the instrument vocabulary; for example
`ExchangeCode.XNYM` plus `EnergyType.NaturalGas` resolves to the NYMEX energy
template without requiring synthetic names like `NYMEX_ENERGY`. Synthetic
product-group codes such as `CBOT_GRAINS` and product mnemonics such as `CL` or
`ZC` remain accepted by `from_exchange()` for lower-level calendar inspection
and compatibility.

### Exchange and country calendars

Calendars cover US equities, options, bonds, and futures alongside major
international equity venues across the Americas, Europe, the Middle East,
Africa, and Asia-Pacific. Each international venue has a dedicated
national holiday rule set, including lunar (China, Hong Kong, Korea,
Taiwan), Islamic (Saudi Arabia, Turkey, UAE), and Hebrew (Israel)
calendars, plus computed rules such as the Japanese equinoxes.

Calendars can be resolved by exchange/MIC code or by ISO country code:

```python
from finance_dates import Calendar
from finance_enums import EnergyType, ExchangeCode, UnderlyingAssetClass

Calendar.from_exchange("XLON")   # London Stock Exchange
Calendar.from_exchange("XTKS")   # Tokyo Stock Exchange, split lunch sessions
Calendar.from_exchange("XKRX")   # Korea Exchange, lunar holidays
Calendar.from_exchange("XCME")   # CME futures-style overnight sessions
Calendar.from_exchange("CBOT_GRAINS")  # CBOT grain/oilseed futures sessions
Calendar.from_exchange("CME_ENERGY")  # Globex energy-category alias
Calendar.from_asset(ExchangeCode.XNYM, UnderlyingAssetClass.Commodity, subclass=EnergyType.NaturalGas)
Calendar.from_product("ICE_US", "Sugar")  # ICE US product-specific template
Calendar.from_exchange("FOREX")  # 24x5 FX family
Calendar.from_region("US")       # representative US equity calendar
```

`Calendar.from_exchange()` accepts additional resolver-only
calendar aliases such as `CBOT_GRAINS`, `CME_ENERGY`, `CL`, and `ZC`; those are
documented in the Calendars page.

### Polars integration

When Polars is installed, importing `finance_dates` registers a `.fdates`
namespace on expressions and series for business-day shifting, business-day
alignment, and day-count fractions. The top-level `period_grid()` helper
buckets a date column into period boundaries.

```python
import polars as pl
from finance_dates import period_grid

df = pl.DataFrame({"trade": [date(2024, 7, 3), date(2024, 12, 24)]})
df.with_columns(
    settle=pl.col("trade").fdates.shift_business_days(2, exchange="XNYS"),
    bucket=period_grid(pl.col("trade"), "1mo"),
)
```

### Documentation

See the [Calendars](docs/src/CALENDARS.md) page for supported concepts,
market families, date-series patterns, and trading-hours conventions.
See the [API](docs/src/API.md) page for the public Python API and
recipes.

### Rust crate

The Rust library crate is published as `finance-dates` and imported as
`finance_dates` in Rust code:

```toml
[dependencies]
finance-dates = "0.4.0"
```

```rust
use finance_dates::{calendar_for_exchange, date_range};
```
