Skip to content

Commit 486e405

Browse files
authored
VER: Release 0.10.0
See release notes.
2 parents d439038 + 625b6b4 commit 486e405

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+767
-479
lines changed

.github/workflows/test.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
fail-fast: false
1313
matrix:
1414
os: [ubuntu-latest, macos-latest, windows-latest]
15-
python-version: ["3.7", "3.8", "3.9", "3.10"]
15+
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
1616
name: build - Python ${{ matrix.python-version }} (${{ matrix.os }})
1717
runs-on: ${{ matrix.os }}
1818

@@ -31,5 +31,9 @@ jobs:
3131
scripts/build.sh
3232
3333
# Run tests
34+
- name: Run tests in release mode
35+
if: ${{ github.ref == 'refs/heads/main' }}
36+
run: scripts/test.sh --release
3437
- name: Run tests
38+
if: ${{ github.ref != 'refs/heads/main' }}
3539
run: scripts/test.sh

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
# Changelog
22

3-
## 0.8.2 - 2023-03-10
3+
## 0.10.0 - 2023-04-07
4+
- Upgraded `databento-dbn` to 0.4.3
5+
- Renamed `Bento` class to `DBNStore`
6+
- Removed `metadata.list_compressions` (redundant with docs)
7+
- Removed `metadata.list_encodings` (redundant with docs)
8+
- Removed optional `start` and `end` params from `metadata.list_schemas` (redundant)
9+
- Removed `related` and `related_security_id` from definition schema
10+
- Added `instrument_class`, `strike_price`, and `strike_price_currency` to definition
11+
schema
12+
- Added support for `imbalance` schema
13+
- Improved exception messages for server and client timeouts
14+
15+
## 0.9.0 - 2023-03-10
416
- Removed `record_count` property from Bento class
517
- Fixed bug in `Bento` where invalid metadata would prevent iteration
618
- Improved use of the logging module

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ The library is fully compatible with the latest distribution of Anaconda 3.7 and
3131
The minimum dependencies as found in the `requirements.txt` are also listed below:
3232
- Python (>=3.7)
3333
- aiohttp (>=3.7.2)
34-
- databento-dbn (>=0.3.2)
34+
- databento-dbn (==0.4.3)
3535
- numpy (>=1.17.0)
3636
- pandas (>=1.1.3)
3737
- requests (>=2.24.0)

databento/__init__.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22

33
from databento.common import utility
4-
from databento.common.bento import Bento
4+
from databento.common.dbnstore import DBNStore
55
from databento.common.enums import (
66
Compression,
77
Dataset,
@@ -18,20 +18,20 @@
1818
SType,
1919
SymbologyResolution,
2020
)
21-
from databento.historical.api import API_VERSION
22-
from databento.historical.client import Historical
23-
from databento.historical.error import (
21+
from databento.common.error import (
2422
BentoClientError,
2523
BentoError,
2624
BentoHttpError,
2725
BentoServerError,
2826
)
27+
from databento.historical.api import API_VERSION
28+
from databento.historical.client import Historical
2929
from databento.version import __version__ # noqa
3030

3131

3232
__all__ = [
3333
"API_VERSION",
34-
"Bento",
34+
"DBNStore",
3535
"BentoClientError",
3636
"BentoError",
3737
"BentoHttpError",
@@ -58,4 +58,4 @@
5858

5959
# Convenience imports
6060
enable_logging = utility.enable_logging
61-
from_dbn = Bento.from_file
61+
from_dbn = DBNStore.from_file

databento/common/data.py

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def get_deriv_ba_types(level: int) -> List[Tuple[str, Union[type, str]]]:
114114
("contract_multiplier", np.int32),
115115
("decay_quantity", np.int32),
116116
("original_contract_size", np.int32),
117-
("related_security_id", np.uint32),
117+
("reserved1", "S4"),
118118
("trading_reference_date", np.uint16),
119119
("appl_id", np.int16),
120120
("maturity_year", np.uint16),
@@ -131,7 +131,11 @@ def get_deriv_ba_types(level: int) -> List[Tuple[str, Union[type, str]]]:
131131
("security_type", "S7"), # 7 byte chararray
132132
("unit_of_measure", "S31"), # 31 byte chararray
133133
("underlying", "S21"), # 21 byte chararray
134-
("related", "S21"), # 21 byte chararray
134+
("strike_price_currency", "S4"),
135+
("instrument_class", "S1"),
136+
("reserved2", "S2"),
137+
("strike_price", np.int64),
138+
("reserved3", "S6"),
135139
("match_algorithm", "S1"), # 1 byte chararray
136140
("md_security_trading_status", np.uint8),
137141
("main_fraction", np.uint8),
@@ -150,6 +154,30 @@ def get_deriv_ba_types(level: int) -> List[Tuple[str, Union[type, str]]]:
150154
("dummy", "S3"), # 3 byte chararray (Adjustment filler for 8-bytes alignment)
151155
]
152156

157+
IMBALANCE_MSG: List[Tuple[str, Union[type, str]]] = RECORD_HEADER + [
158+
("ts_recv", np.uint64),
159+
("ref_price", np.int64),
160+
("auction_time", np.uint64),
161+
("cont_book_clr_price", np.int64),
162+
("auct_interest_clr_price", np.int64),
163+
("ssr_filling_price", np.int64),
164+
("ind_match_price", np.int64),
165+
("upper_collar", np.int64),
166+
("lower_collar", np.int64),
167+
("paired_qty", np.uint32),
168+
("total_imbalance_qty", np.uint32),
169+
("market_imbalance_qty", np.uint32),
170+
("unpaired_qty", np.uint32),
171+
("auction_type", "S1"),
172+
("side", "S1"),
173+
("auction_status", np.uint8),
174+
("freeze_status", np.uint8),
175+
("num_extensions", np.uint8),
176+
("unpaired_side", "S1"),
177+
("significant_imbalance", "S1"),
178+
("dummy", "S1"),
179+
]
180+
153181

154182
STRUCT_MAP: Dict[Schema, List[Tuple[str, Union[type, str]]]] = {
155183
Schema.MBO: MBO_MSG,
@@ -173,6 +201,7 @@ def get_deriv_ba_types(level: int) -> List[Tuple[str, Union[type, str]]]:
173201
Schema.OHLCV_1D: OHLCV_MSG,
174202
Schema.STATUS: STATUS_MSG,
175203
Schema.DEFINITION: DEFINITION_MSG,
204+
Schema.IMBALANCE: IMBALANCE_MSG,
176205
Schema.GATEWAY_ERROR: RECORD_HEADER
177206
+ [
178207
("error", "S64"),
@@ -199,10 +228,10 @@ def get_deriv_ba_types(level: int) -> List[Tuple[str, Union[type, str]]]:
199228
"security_type",
200229
"unit_of_measure",
201230
"underlying",
202-
"related",
203231
"match_algorithm",
204232
"security_update_action",
205233
"user_defined_instrument",
234+
"strike_price_currency",
206235
]
207236

208237
DEFINITION_PRICE_COLUMNS = [
@@ -213,6 +242,7 @@ def get_deriv_ba_types(level: int) -> List[Tuple[str, Union[type, str]]]:
213242
"max_price_variation",
214243
"trading_reference_price",
215244
"min_price_increment_amount",
245+
"strike_price",
216246
]
217247

218248
DEFINITION_TYPE_MAX_MAP = {
@@ -261,14 +291,37 @@ def get_deriv_ba_fields(level: int) -> List[str]:
261291
"volume",
262292
]
263293

264-
STATUS_COLUMNS = [x for x in np.dtype(STATUS_MSG).names or ()]
265-
STATUS_COLUMNS.remove("ts_recv") # Index
294+
STATUS_DROP_COLUMNS = ["ts_recv"]
295+
DEFINITION_DROP_COLUMNS = [
296+
"ts_recv",
297+
"length",
298+
"rtype",
299+
"reserved1",
300+
"reserved2",
301+
"reserved3",
302+
"dummy",
303+
]
304+
305+
IMBALANCE_DROP_COLUMNS = [
306+
"ts_recv",
307+
"length",
308+
"rtype",
309+
"dummy",
310+
]
266311

267-
DEFINITION_COLUMNS = [x for x in np.dtype(DEFINITION_MSG).names or ()]
268-
DEFINITION_COLUMNS.remove("ts_recv") # Index
269-
DEFINITION_COLUMNS.remove("length")
270-
DEFINITION_COLUMNS.remove("rtype")
271-
DEFINITION_COLUMNS.remove("dummy")
312+
STATUS_COLUMNS = [
313+
x for x in (np.dtype(STATUS_MSG).names or ()) if x not in STATUS_DROP_COLUMNS
314+
]
315+
316+
DEFINITION_COLUMNS = [
317+
x
318+
for x in (np.dtype(DEFINITION_MSG).names or ())
319+
if x not in DEFINITION_DROP_COLUMNS
320+
]
321+
322+
IMBALANCE_COLUMNS = [
323+
x for x in (np.dtype(IMBALANCE_MSG).names or ()) if x not in IMBALANCE_DROP_COLUMNS
324+
]
272325

273326

274327
COLUMNS = {
@@ -306,4 +359,5 @@ def get_deriv_ba_fields(level: int) -> List[str]:
306359
Schema.OHLCV_1D: OHLCV_HEADER_COLUMNS,
307360
Schema.STATUS: STATUS_COLUMNS,
308361
Schema.DEFINITION: DEFINITION_COLUMNS,
362+
Schema.IMBALANCE: IMBALANCE_COLUMNS,
309363
}

databento/common/bento.py renamed to databento/common/dbnstore.py

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
STRUCT_MAP,
3131
)
3232
from databento.common.enums import Compression, Schema, SType
33+
from databento.common.error import BentoError
3334
from databento.common.metadata import MetadataDecoder
3435
from databento.common.symbology import ProductIdMappingInterval
3536

@@ -83,7 +84,7 @@ def is_dbn(reader: IO[bytes]) -> bool:
8384

8485

8586
class DataSource(abc.ABC):
86-
"""Abstract base class for backing Bento classes with data."""
87+
"""Abstract base class for backing DBNStore instances with data."""
8788

8889
def __init__(self, source: object) -> None:
8990
...
@@ -103,7 +104,7 @@ def reader(self) -> IO[bytes]:
103104

104105
class FileDataSource(DataSource):
105106
"""
106-
A file-backed data source for a Bento object.
107+
A file-backed data source for a DBNStore object.
107108
108109
Attributes
109110
----------
@@ -181,7 +182,7 @@ def reader(self) -> IO[bytes]:
181182

182183
class MemoryDataSource(DataSource):
183184
"""
184-
A memory-backed data source for a Bento object.
185+
A memory-backed data source for a DBNStore object.
185186
186187
Attributes
187188
----------
@@ -243,7 +244,7 @@ def reader(self) -> IO[bytes]:
243244
return self.__buffer
244245

245246

246-
class Bento:
247+
class DBNStore:
247248
"""
248249
A container for Databento Binary Encoding (DBN) data.
249250
@@ -345,11 +346,18 @@ def __init__(self, data_source: DataSource) -> None:
345346

346347
def __iter__(self) -> Generator[np.void, None, None]:
347348
reader = self.reader
349+
dtype = STRUCT_MAP[self.schema]
348350
while True:
349351
raw = reader.read(self.record_size)
350352
if raw:
351-
rec = np.frombuffer(raw, dtype=STRUCT_MAP[self.schema])
352-
yield rec[0]
353+
try:
354+
rec = np.frombuffer(raw, dtype)
355+
except ValueError as value_error:
356+
raise BentoError(
357+
f"Error decoding {len(raw)} bytes for {self.schema} iteration",
358+
) from value_error
359+
else:
360+
yield rec[0]
353361
else:
354362
break
355363

@@ -576,7 +584,7 @@ def raw(self) -> bytes:
576584
577585
See Also
578586
--------
579-
Bento.reader
587+
DBNStore.reader
580588
581589
"""
582590
return self._data_source.reader.read()
@@ -592,7 +600,7 @@ def reader(self) -> IO[bytes]:
592600
593601
See Also
594602
--------
595-
Bento.raw
603+
DBNStore.raw
596604
597605
"""
598606
if self.compression == Compression.ZSTD:
@@ -704,7 +712,7 @@ def symbols(self) -> List[str]:
704712
return self._metadata["symbols"]
705713

706714
@classmethod
707-
def from_file(cls, path: Union[PathLike[str], str]) -> "Bento":
715+
def from_file(cls, path: Union[PathLike[str], str]) -> "DBNStore":
708716
"""
709717
Load the data from a DBN file at the given path.
710718
@@ -715,7 +723,7 @@ def from_file(cls, path: Union[PathLike[str], str]) -> "Bento":
715723
716724
Returns
717725
-------
718-
Bento
726+
DBNStore
719727
720728
Raises
721729
------
@@ -726,7 +734,7 @@ def from_file(cls, path: Union[PathLike[str], str]) -> "Bento":
726734
return cls(FileDataSource(path))
727735

728736
@classmethod
729-
def from_bytes(cls, data: bytes) -> "Bento":
737+
def from_bytes(cls, data: bytes) -> "DBNStore":
730738
"""
731739
Load the data from a raw bytes.
732740
@@ -737,7 +745,7 @@ def from_bytes(cls, data: bytes) -> "Bento":
737745
738746
Returns
739747
-------
740-
Bento
748+
DBNStore
741749
742750
Raises
743751
------
@@ -771,7 +779,7 @@ def request_full_definitions(
771779
self,
772780
client: "Historical",
773781
path: Optional[Union[Path, str]] = None,
774-
) -> "Bento":
782+
) -> "DBNStore":
775783
"""
776784
Request full instrument definitions based on the metadata properties.
777785
@@ -782,11 +790,11 @@ def request_full_definitions(
782790
client : Historical
783791
The historical client to use for the request (contains the API key).
784792
path : Path or str, optional
785-
The path to stream the data to on disk (will then return a `Bento`).
793+
The path to stream the data to on disk (will then return a `DBNStore`).
786794
787795
Returns
788796
-------
789-
Bento
797+
DBNStore
790798
791799
Warnings
792800
--------
@@ -971,4 +979,11 @@ def to_ndarray(self) -> np.ndarray[Any, Any]:
971979
972980
"""
973981
data: bytes = self.reader.read()
974-
return np.frombuffer(data, dtype=self.dtype)
982+
try:
983+
nd_array = np.frombuffer(data, dtype=self.dtype)
984+
except ValueError as value_error:
985+
raise BentoError(
986+
f"Error decoding {len(data)} bytes to {self.schema} `ndarray`",
987+
) from value_error
988+
else:
989+
return nd_array

databento/common/enums.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class Schema(StringyMixin, str, Enum):
149149
OHLCV_1H = "ohlcv-1h"
150150
OHLCV_1D = "ohlcv-1d"
151151
DEFINITION = "definition"
152+
IMBALANCE = "imbalance"
152153
STATISTICS = "statistics"
153154
STATUS = "status"
154155
GATEWAY_ERROR = "gateway_error"

databento/historical/error.py renamed to databento/common/error.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ class BentoError(Exception):
66
Represents a Databento specific error.
77
"""
88

9-
pass
10-
119

1210
class BentoHttpError(BentoError):
1311
"""
@@ -105,5 +103,3 @@ class BentoWarning(Warning):
105103
"""
106104
Represents a Databento specific warning.
107105
"""
108-
109-
pass

0 commit comments

Comments
 (0)