Metadata-Version: 2.4
Name: futuresclock
Version: 0.1.0
Summary: Client for the Futures Clock open futures reference data: trading hours, contract specifications, expiry dates and China market access for 75 futures contracts.
Author: Futures Clock
License-Expression: MIT
Project-URL: Homepage, https://futuresclock.com/en/data/
Project-URL: Documentation, https://futuresclock.com/en/data-methodology/
Project-URL: Dataset, https://doi.org/10.5281/zenodo.23031489
Keywords: futures,trading-hours,market-hours,expiry,contract-specifications,commodities,SHFE,CME,LME,open-data
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# futuresclock (Python)

Typed, dependency-free client for the [Futures Clock open data](https://futuresclock.com/en/data/):
trading hours, contract specifications, expiry dates and China market-access
status for 75 futures contracts on SHFE, INE, DCE, CZCE, GFEX, CFFEX, CME,
COMEX, NYMEX, CBOT, ICE, LME, Eurex, SGX, OSE and HKEX.

Every record carries the official exchange source it was checked against and
its review date. The data is versioned and archived on Zenodo
(DOI [10.5281/zenodo.23031490](https://doi.org/10.5281/zenodo.23031490) for
release 1.3.0; concept DOI 10.5281/zenodo.23031489 always resolves to the
newest release).

## Install

```sh
pip install futuresclock
```

Python 3.9+, standard library only.

## Use

```python
from futuresclock import FuturesClock

fc = FuturesClock()

hours = fc.trading_hours()
copper = next(p for p in hours["products"] if p["slug"] == "shfe-cu")
print(copper["timeZone"], copper["sessions"][0])
# Asia/Shanghai {'label': 'Day session', 'open': '09:00', 'close': '10:15', ...}

expiries = fc.expiries()
print(expiries["nextByProduct"]["cme-es"]["ltd"])
# {'symbol': 'ESZ6', 'date': '2026-12-18', 'estimated': False, ...}

contracts = fc.contracts()["contracts"]
access = fc.china_access()["products"]
```

Each dataset is one JSON document (returned as a `dict`) with
`datasetVersion`, `dataReviewed`, `license` and the rows. Read the version
before caching: the site republishes on every review and the expiry window
rolls forward daily (`asOf`).

Options:

```python
FuturesClock(
    base_url="https://futuresclock.com",  # default
    timeout=30.0,                          # seconds
    fetch=None,  # callable(url, headers, timeout) -> bytes, to route through requests/httpx
)
```

A non-2xx response raises `FuturesClockError` with `.status` and `.url`.

## Datasets

| Method            | Path                       | Rows                                          |
| ----------------- | -------------------------- | --------------------------------------------- |
| `trading_hours()` | `/data/trading-hours.json` | 69 products, sessions in exchange-local time  |
| `contracts()`     | `/data/contracts.json`     | 75 contracts: size, tick, expiry rule, source |
| `expiries()`      | `/data/expiries.json`      | last-trading and first-notice days, 12 months |
| `china_access()`  | `/data/china-access.json`  | 42 Chinese products: 特定品种 / QFI / hedge   |

CSV twins of every file, the field-by-field method and the correction process
are documented at <https://futuresclock.com/en/data-methodology/>.

## License

This client is MIT. The data is published under the
[Futures Clock Open Data Compilation License 1.0.0](https://futuresclock.com/data/license.txt):
free to copy, transform and redistribute, commercially or not, with factual
attribution to futuresclock.com. Exchange facts remain the exchanges'.

This is reference material, not prices, signals or advice. Verify every fact
against the linked official notice before trading.
