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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## 0.77.0 - 2026-04-28

#### Enhancements
- Added new publisher values for Cboe Titanium Cboe Global Indices Feed
- Added `YEAR` to `SplitDuration` enum to support yearly historical batch job submission
- Upgraded `databento-dbn` to 0.56.0:
- Improved Python `DBNDecoder.decode()` performance with pre-allocated output buffers
- Added `DBNDecoder.write_and_decode()` to combine write and decode in a single call

## 0.76.0 - 2026-04-21

#### 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.55.0"
- databento-dbn = "~0.56.0"
- numpy = ">=1.23.5"
- pandas = ">=1.5.3"
- pip-system-certs = ">=4.0" (Windows only)
Expand Down
3 changes: 1 addition & 2 deletions databento/common/dbnstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,7 @@ def __iter__(self) -> Generator[DBNRecord, None, None]:
while True:
raw = reader.read(DBNStore.DBN_READ_SIZE)
if raw:
decoder.write(raw)
records = decoder.decode()
records = decoder.write_and_decode(raw)
for record in records:
if isinstance(record, databento_dbn.Metadata):
continue
Expand Down
1 change: 1 addition & 0 deletions databento/common/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class SplitDuration(StringyMixin, str, Enum):
DAY = "day"
WEEK = "week"
MONTH = "month"
YEAR = "year"
NONE = "none"


Expand Down
31 changes: 31 additions & 0 deletions databento/common/publishers.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ class Venue(StringyMixin, str, Enum):
MX2 Options.
IEXO
IEX Options LLC.
CGIF
Cboe Global Indices Feed.

"""

Expand Down Expand Up @@ -184,6 +186,7 @@ class Venue(StringyMixin, str, Enum):
OCEA = "OCEA"
MXTO = "MXTO"
IEXO = "IEXO"
CGIF = "CGIF"

@classmethod
def from_int(cls, value: int) -> Venue:
Expand Down Expand Up @@ -300,6 +303,8 @@ def from_int(cls, value: int) -> Venue:
return Venue.MXTO
if value == 55:
return Venue.IEXO
if value == 56:
return Venue.CGIF
raise ValueError(f"Integer value {value} does not correspond with any Venue variant")

def to_int(self) -> int:
Expand Down Expand Up @@ -416,6 +421,8 @@ def to_int(self) -> int:
return 54
if self == Venue.IEXO:
return 55
if self == Venue.CGIF:
return 56
raise ValueError("Invalid Venue")

@property
Expand Down Expand Up @@ -533,6 +540,8 @@ def description(self) -> str:
return "MX2 Options"
if self == Venue.IEXO:
return "IEX Options LLC"
if self == Venue.CGIF:
return "Cboe Global Indices Feed"
raise ValueError("Unexpected Venue value")


Expand Down Expand Up @@ -624,6 +633,8 @@ class Dataset(StringyMixin, str, Enum):
CFE Depth.
OCEA_MEMOIR
Blue Ocean ATS MEMOIR Depth.
CGIF_TITANIUM
Cboe Titanium Cboe Global Indices Feed.

"""

Expand Down Expand Up @@ -668,6 +679,7 @@ class Dataset(StringyMixin, str, Enum):
XEEE_EOBI = "XEEE.EOBI"
XCBF_PITCH = "XCBF.PITCH"
OCEA_MEMOIR = "OCEA.MEMOIR"
CGIF_TITANIUM = "CGIF.TITANIUM"

@classmethod
def from_int(cls, value: int) -> Dataset:
Expand Down Expand Up @@ -756,6 +768,8 @@ def from_int(cls, value: int) -> Dataset:
return Dataset.XCBF_PITCH
if value == 41:
return Dataset.OCEA_MEMOIR
if value == 42:
return Dataset.CGIF_TITANIUM
raise ValueError(f"Integer value {value} does not correspond with any Dataset variant")

def to_int(self) -> int:
Expand Down Expand Up @@ -844,6 +858,8 @@ def to_int(self) -> int:
return 40
if self == Dataset.OCEA_MEMOIR:
return 41
if self == Dataset.CGIF_TITANIUM:
return 42
raise ValueError("Invalid Dataset")

@property
Expand Down Expand Up @@ -933,6 +949,8 @@ def description(self) -> str:
return "CFE Depth"
if self == Dataset.OCEA_MEMOIR:
return "Blue Ocean ATS MEMOIR Depth"
if self == Dataset.CGIF_TITANIUM:
return "Cboe Titanium Cboe Global Indices Feed"
raise ValueError("Unexpected Dataset value")


Expand Down Expand Up @@ -1160,6 +1178,8 @@ class Publisher(StringyMixin, str, Enum):
OPRA - MEMX MX2 Options.
OPRA_PILLAR_IEXO
OPRA - IEX Options LLC.
CGIF_TITANIUM_CGIF
Cboe Global Indices Feed.

"""

Expand Down Expand Up @@ -1272,6 +1292,7 @@ class Publisher(StringyMixin, str, Enum):
OCEA_MEMOIR_OCEA = "OCEA.MEMOIR.OCEA"
OPRA_PILLAR_MXTO = "OPRA.PILLAR.MXTO"
OPRA_PILLAR_IEXO = "OPRA.PILLAR.IEXO"
CGIF_TITANIUM_CGIF = "CGIF.TITANIUM.CGIF"

@classmethod
def from_int(cls, value: int) -> Publisher:
Expand Down Expand Up @@ -1496,6 +1517,8 @@ def from_int(cls, value: int) -> Publisher:
return Publisher.OPRA_PILLAR_MXTO
if value == 109:
return Publisher.OPRA_PILLAR_IEXO
if value == 110:
return Publisher.CGIF_TITANIUM_CGIF
raise ValueError(f"Integer value {value} does not correspond with any Publisher variant")

def to_int(self) -> int:
Expand Down Expand Up @@ -1720,6 +1743,8 @@ def to_int(self) -> int:
return 108
if self == Publisher.OPRA_PILLAR_IEXO:
return 109
if self == Publisher.CGIF_TITANIUM_CGIF:
return 110
raise ValueError("Invalid Publisher")

@property
Expand Down Expand Up @@ -1945,6 +1970,8 @@ def venue(self) -> Venue:
return Venue.MXTO
if self == Publisher.OPRA_PILLAR_IEXO:
return Venue.IEXO
if self == Publisher.CGIF_TITANIUM_CGIF:
return Venue.CGIF
raise ValueError("Unexpected Publisher value")

@property
Expand Down Expand Up @@ -2170,6 +2197,8 @@ def dataset(self) -> Dataset:
return Dataset.OPRA_PILLAR
if self == Publisher.OPRA_PILLAR_IEXO:
return Dataset.OPRA_PILLAR
if self == Publisher.CGIF_TITANIUM_CGIF:
return Dataset.CGIF_TITANIUM
raise ValueError("Unexpected Publisher value")

@property
Expand Down Expand Up @@ -2395,4 +2424,6 @@ def description(self) -> str:
return "OPRA - MEMX MX2 Options"
if self == Publisher.OPRA_PILLAR_IEXO:
return "OPRA - IEX Options LLC"
if self == Publisher.CGIF_TITANIUM_CGIF:
return "Cboe Global Indices Feed"
raise ValueError("Unexpected Publisher value")
2 changes: 1 addition & 1 deletion databento/historical/api/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def submit_job(
`dbn`.
split_symbols : bool, default False
If files should be split by raw symbol. Cannot be requested with `'ALL_SYMBOLS'`.
split_duration : SplitDuration or str {'day', 'week', 'month', 'none'}, default 'day'
split_duration : SplitDuration or str {'day', 'week', 'month', 'year', 'none'}, default 'day'
The maximum time duration before batched data is split into multiple files.
A week starts on Sunday UTC.
split_size : int, optional
Expand Down
5 changes: 2 additions & 3 deletions databento/live/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ def buffer_updated(self, nbytes: int) -> None:

"""
logger.debug("read %d bytes from remote gateway", nbytes)
data = self.__buffer[:nbytes]
data = bytes(memoryview(self.__buffer)[:nbytes])

if self.authenticated.done():
self._process_dbn(data)
Expand Down Expand Up @@ -375,8 +375,7 @@ def _process_dbn(self, data: bytes) -> None:
raise ValueError("not connected")

try:
self._dbn_decoder.write(bytes(data))
records = self._dbn_decoder.decode()
records = self._dbn_decoder.write_and_decode(data)
except Exception:
logger.exception("error decoding DBN record")
self.__transport.close()
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.76.0"
__version__ = "0.77.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.76.0"
version = "0.77.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.55.0",
"databento-dbn~=0.56.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
Loading