KlineTimestamp is a Python library designed to accurately and efficiently handle timestamps within discrete time intervals (klines or candlesticks), commonly used in financial time series and market analysis.
It provides a clean, immutable, timezone-aware API that makes reasoning about candle boundaries extremely intuitive.
Repository: https://github.com/nand0san/KlineTimestamp
-
Canonical open/close computation Automatically snap any timestamp (ms) to the correct candle open/close.
-
Timezone-aware conversions Built-in support for
pytzwith proper DST handling. -
Clean datetime integration Convert directly to
datetime.datetimeorpandas.Timestamp. -
Immutable API Every transformation returns a new instance (
with_timezone,with_interval, addition/subtraction withtimedelta). -
Navigation between candles Use
next()andprev()to move through consecutive klines. -
Strict comparison semantics Candle identity depends only on
(open, tick_ms); timezone affects display only. -
Guaranteed total ordering Timestamps are comparable via lexicographic
(open, tick_ms)ordering. -
All Binance intervals All fixed-duration Binance intervals (1m to 1w) plus the variable-duration monthly interval (
1M). -
Monthly candles (1M) Calendar-aware: handles 28/29/30/31-day months correctly, including leap years.
pip install kline_timestampRequires Python 3.9+.
pandas>=2.3.0,<3.0pytz>=2024.1
These are declared automatically in the installed package.
from kline_timestamp import KlineTimestampKlineTimestamp(timestamp_ms: int, interval: str, tzinfo: str | pytz.BaseTzInfo = "UTC")| Parameter | Type | Description |
|---|---|---|
timestamp_ms |
int |
Epoch milliseconds (UTC). Must be int. |
interval |
str |
Candle interval (see table below). Case-insensitive except 1M. |
tzinfo |
str or pytz.BaseTzInfo |
Timezone for display. Default "UTC". |
| Attribute | Type | Description |
|---|---|---|
open |
int |
Candle open timestamp (epoch ms, UTC). |
close |
int |
Candle close timestamp (epoch ms, UTC). |
tick_ms |
int |
Duration of the candle in milliseconds. For 1M, varies per month. |
interval |
str |
Normalized interval string. |
tzinfo |
pytz.BaseTzInfo |
Timezone instance. |
Fixed-duration intervals (constant tick_ms):
| Interval | Duration |
|---|---|
1m |
1 minute |
3m |
3 minutes |
5m |
5 minutes |
15m |
15 minutes |
30m |
30 minutes |
1h |
1 hour |
2h |
2 hours |
4h |
4 hours |
6h |
6 hours |
8h |
8 hours |
12h |
12 hours |
1d |
1 day |
3d |
3 days |
1w |
1 week |
Variable-duration interval:
| Interval | Duration |
|---|---|
1M |
1 calendar month (28-31 days) |
Important: 1M (uppercase) is monthly. 1m (lowercase) is 1 minute. The interval is case-sensitive for 1M; all others are case-insensitive.
kt.to_datetime() # -> datetime.datetime (tz-aware)
kt.to_pandas_timestamp() # -> pd.Timestamp (tz-aware)kt.with_timezone("UTC") # -> new KlineTimestamp, same candle, different tz
kt.with_interval("15m") # -> new KlineTimestamp, re-snapped to new intervalkt.next() # -> next candle (same interval)
kt.prev() # -> previous candle (same interval)For 1M, next()/prev() correctly navigate calendar months (handles Dec->Jan, Jan->Dec, variable month lengths).
kt + timedelta(hours=1) # -> new KlineTimestamp shifted forward
kt - timedelta(hours=1) # -> new KlineTimestamp shifted backward
kt - kt_other # -> timedelta (difference between opens)kt == kt_other # equality by (open, tick_ms)
kt < kt_other # ordering by (open, tick_ms)Timezone is ignored for equality, hashing, and ordering.
from kline_timestamp import KlineTimestamp
from datetime import timedelta
kt = KlineTimestamp(1633036800000, "1h", "Europe/Madrid")
print("Open:", kt.open)
print("Close:", kt.close)
print("Datetime:", kt.to_datetime())
print("Pandas:", kt.to_pandas_timestamp())
kt_utc = kt.with_timezone("UTC")
print("UTC:", kt_utc.to_datetime())
kt_plus = kt + timedelta(hours=1)
print("After +1h:", kt_plus.to_datetime())
print("Next:", kt.next().to_datetime())
print("Prev:", kt.prev().to_datetime())
kt_other = KlineTimestamp(1633033200000, "1h", "UTC")
print("Comparison:", kt > kt_other)
print("Time delta:", kt - kt_other)from kline_timestamp import KlineTimestamp
# March 2024
kt = KlineTimestamp(1709251200000, "1M", "UTC")
print("Open:", kt.to_datetime()) # 2024-03-01 00:00:00+00:00
print("Close ms:", kt.close) # last ms of March 31
# Navigate months
kt_apr = kt.next() # April 2024
kt_feb = kt.prev() # February 2024 (leap year, 29 days)
print("Feb days:", kt_feb.tick_ms // 86400000) # 29
# Any timestamp within a month snaps to that month's open
kt_mid = KlineTimestamp(1710000000000, "1M", "UTC") # ~Mar 9
print(kt_mid.open == kt.open) # TrueMIT License. See the LICENSE file for details.
Pull requests are welcome. Open an issue or send a PR at:
https://github.com/nand0san/KlineTimestamp
- Inspired by practical needs in quantitative financial analysis.
- Uses the excellent
pytzandpandaslibraries for timezone and datetime handling.