Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## 0.75.0 - 2026-04-07

#### Enhancements
- Upgraded `databento-dbn` to 0.53.0:
- Made `ts_out` a permanent field on all Python record types, replacing the
dynamic `__dict__` attribute. `ts_out` returns an `int` (`UNDEF_TIMESTAMP` when
not set)
- Removed `__dict__` from all Python record classes, eliminating a separate
per-instance allocation

## 0.74.1 - 2026-03-31

#### Enhancements
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ The library is fully compatible with distributions of Anaconda 2023.x and above.
The minimum dependencies as found in the `pyproject.toml` are also listed below:
- python = "^3.10"
- aiohttp = "^3.8.3"
- databento-dbn = "~0.52.1"
- databento-dbn = "~0.53.0"
- numpy = ">=1.23.5"
- pandas = ">=1.5.3"
- pip-system-certs = ">=4.0" (Windows only)
Expand Down
6 changes: 3 additions & 3 deletions databento/common/dbnstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,9 @@ def to_ndarray(
schema_rtype = RType.from_schema(schema)
schema_filter = filter(lambda r: r.rtype == schema_rtype, self)

if self._metadata.ts_out:
schema_dtype.append(("ts_out", "u8"))

reader = self.reader
reader.seek(self._metadata_length)
ndarray_iter = NDArrayBytesIterator(
Expand All @@ -1256,9 +1259,6 @@ def to_ndarray(
schema_struct = self._schema_struct_map[self.schema]
schema_dtype = schema_struct._dtypes

if self._metadata.ts_out:
schema_dtype.append(("ts_out", "u8"))

if schema is not None and schema != self.schema:
# This is to maintain identical behavior with NDArrayBytesIterator
ndarray_iter = iter([np.empty([0, 1], dtype=schema_dtype)])
Expand Down
20 changes: 10 additions & 10 deletions databento/common/publishers.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ class Dataset(StringyMixin, str, Enum):
XCIS_TRADES
NYSE National Trades.
MEMX_MEMOIR
MEMX Memoir Depth.
MEMX MEMOIR Depth.
EPRL_DOM
MIAX Pearl Depth.
FINN_NLS
Expand Down Expand Up @@ -603,7 +603,7 @@ class Dataset(StringyMixin, str, Enum):
XEEE_EOBI
European Energy Exchange EOBI.
XCBF_PITCH
Cboe Futures Exchange PITCH.
CFE Depth.
OCEA_MEMOIR
Blue Ocean ATS MEMOIR Depth.

Expand Down Expand Up @@ -862,7 +862,7 @@ def description(self) -> str:
if self == Dataset.XCIS_TRADES:
return "NYSE National Trades"
if self == Dataset.MEMX_MEMOIR:
return "MEMX Memoir Depth"
return "MEMX MEMOIR Depth"
if self == Dataset.EPRL_DOM:
return "MIAX Pearl Depth"
if self == Dataset.FINN_NLS:
Expand Down Expand Up @@ -912,7 +912,7 @@ def description(self) -> str:
if self == Dataset.XEEE_EOBI:
return "European Energy Exchange EOBI"
if self == Dataset.XCBF_PITCH:
return "Cboe Futures Exchange PITCH"
return "CFE Depth"
if self == Dataset.OCEA_MEMOIR:
return "Blue Ocean ATS MEMOIR Depth"
raise ValueError("Unexpected Dataset value")
Expand Down Expand Up @@ -953,7 +953,7 @@ class Publisher(StringyMixin, str, Enum):
XCIS_TRADES_XCIS
NYSE National Trades.
MEMX_MEMOIR_MEMX
MEMX Memoir Depth.
MEMX MEMOIR Depth.
EPRL_DOM_EPRL
MIAX Pearl Depth.
XNAS_NLS_FINN
Expand Down Expand Up @@ -1133,9 +1133,9 @@ class Publisher(StringyMixin, str, Enum):
XEEE_EOBI_XOFF
European Energy Exchange EOBI - Off-Market Trades.
XCBF_PITCH_XCBF
Cboe Futures Exchange.
Cboe Futures Exchange (CFE).
XCBF_PITCH_XOFF
Cboe Futures Exchange - Off-Market Trades.
Cboe Futures Exchange (CFE) - Off-Market Trades.
OCEA_MEMOIR_OCEA
Blue Ocean ATS MEMOIR.

Expand Down Expand Up @@ -2166,7 +2166,7 @@ def description(self) -> str:
if self == Publisher.XCIS_TRADES_XCIS:
return "NYSE National Trades"
if self == Publisher.MEMX_MEMOIR_MEMX:
return "MEMX Memoir Depth"
return "MEMX MEMOIR Depth"
if self == Publisher.EPRL_DOM_EPRL:
return "MIAX Pearl Depth"
if self == Publisher.XNAS_NLS_FINN:
Expand Down Expand Up @@ -2346,9 +2346,9 @@ def description(self) -> str:
if self == Publisher.XEEE_EOBI_XOFF:
return "European Energy Exchange EOBI - Off-Market Trades"
if self == Publisher.XCBF_PITCH_XCBF:
return "Cboe Futures Exchange"
return "Cboe Futures Exchange (CFE)"
if self == Publisher.XCBF_PITCH_XOFF:
return "Cboe Futures Exchange - Off-Market Trades"
return "Cboe Futures Exchange (CFE) - Off-Market Trades"
if self == Publisher.OCEA_MEMOIR_OCEA:
return "Blue Ocean ATS MEMOIR"
raise ValueError("Unexpected Publisher value")
5 changes: 1 addition & 4 deletions databento/live/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import logging
import math
import queue
import struct
import threading
from collections.abc import Iterable
from functools import partial
Expand Down Expand Up @@ -267,16 +266,14 @@ def _dispatch_callbacks(self, record: DBNRecord) -> None:

def _dispatch_writes(self, record: DBNRecord) -> None:
record_bytes = bytes(record)
ts_out_bytes = struct.pack("Q", record.ts_out) if self._metadata.has_ts_out else b""
for stream in self._user_streams:
try:
stream.write(record_bytes)
stream.write(ts_out_bytes)
except Exception as exc:
logger.error(
"error writing %s record (%d bytes) to `%s` stream",
type(record).__name__,
len(record_bytes) + len(ts_out_bytes),
len(record_bytes),
stream.stream_name,
exc_info=exc,
)
Expand Down
2 changes: 1 addition & 1 deletion databento/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.74.1"
__version__ = "0.75.0"
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "databento"
version = "0.74.1"
version = "0.75.0"
description = "Official Python client library for Databento"
readme = "README.md"
requires-python = ">=3.10"
Expand All @@ -10,7 +10,7 @@ dynamic = [ "classifiers" ]
dependencies = [
"aiohttp>=3.8.3,<4.0.0; python_version < '3.12'",
"aiohttp>=3.9.0,<4.0.0; python_version >= '3.12'",
"databento-dbn~=0.52.1",
"databento-dbn~=0.53.0",
"numpy>=1.23.5; python_version < '3.12'",
"numpy>=1.26.0; python_version >= '3.12'",
"pandas>=1.5.3,<4.0.0",
Expand Down
7 changes: 7 additions & 0 deletions tests/test_historical_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def test_mbo_fields() -> None:
fields.remove("record_size")
fields.remove("size_hint")
fields.remove("ts_index")
fields.remove("ts_out")

# Act
difference = fields.symmetric_difference(struct._ordered_fields)
Expand Down Expand Up @@ -45,6 +46,7 @@ def test_mbp_fields(
fields.remove("record_size")
fields.remove("size_hint")
fields.remove("ts_index")
fields.remove("ts_out")

# Act
difference = fields.symmetric_difference(struct._ordered_fields)
Expand Down Expand Up @@ -78,6 +80,7 @@ def test_ohlcv_fields(
fields.remove("record_size")
fields.remove("size_hint")
fields.remove("ts_index")
fields.remove("ts_out")

# Act
difference = fields.symmetric_difference(struct._ordered_fields)
Expand All @@ -97,6 +100,7 @@ def test_trades_struct() -> None:
fields.remove("record_size")
fields.remove("size_hint")
fields.remove("ts_index")
fields.remove("ts_out")

# Act
difference = fields.symmetric_difference(struct._ordered_fields)
Expand All @@ -116,6 +120,7 @@ def test_definition_struct() -> None:
fields.remove("record_size")
fields.remove("size_hint")
fields.remove("ts_index")
fields.remove("ts_out")

# Act
difference = fields.symmetric_difference(struct._ordered_fields)
Expand All @@ -135,6 +140,7 @@ def test_imbalance_struct() -> None:
fields.remove("record_size")
fields.remove("size_hint")
fields.remove("ts_index")
fields.remove("ts_out")

# Act
difference = fields.symmetric_difference(struct._ordered_fields)
Expand All @@ -154,6 +160,7 @@ def test_statistics_struct() -> None:
fields.remove("record_size")
fields.remove("size_hint")
fields.remove("ts_index")
fields.remove("ts_out")

# Act
difference = fields.symmetric_difference(struct._ordered_fields)
Expand Down
Loading