Skip to content

Commit

Permalink
Fix data requests when end is specified
Browse files Browse the repository at this point in the history
Bug only triggers when `last_timestamp` is None and comparing with `end`.
Fixed by adding truthiness checks in timestamp comparisons.
  • Loading branch information
cjdsellers committed Nov 29, 2024
1 parent c0dc294 commit 444b4cf
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 18 deletions.
18 changes: 18 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
# NautilusTrader 1.208.0 Beta

Released on TBD (UTC).

### Enhancements
None

### Internal Improvements
None

### Breaking Changes
None

### Fixes
- Fixed data requests when specifying `end` with no catalog registered (comparison between `pd.Timestamp` and `NoneType`)

---

# NautilusTrader 1.207.0 Beta

Released on 29th November 2024 (UTC).
Expand Down
40 changes: 22 additions & 18 deletions nautilus_trader/data/engine.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1304,13 +1304,13 @@ cdef class DataEngine(Component):
if client is not None:
Condition.is_true(isinstance(client, MarketDataClient), "client was not a MarketDataClient")

metadata = request.data_type.metadata
aggregated_bars_market_data_type = metadata.get("market_data_type", "")
update_catalog = metadata.get("update_catalog", False)
cdef dict[str, object] metadata = request.data_type.metadata
cdef str aggregated_bars_market_data_type = metadata.get("market_data_type", "")
cdef bint update_catalog = metadata.get("update_catalog", False)

now = self._clock.utc_now()
start = time_object_to_dt(metadata.get("start"))
end = time_object_to_dt(metadata.get("end"))
cdef datetime now = self._clock.utc_now()
cdef datetime start = time_object_to_dt(metadata.get("start")) # Can be None
cdef datetime end = time_object_to_dt(metadata.get("end")) # Can be None

if request.data_type.type == Instrument:
instrument_id = request.data_type.metadata.get("instrument_id")
Expand Down Expand Up @@ -1378,9 +1378,10 @@ cdef class DataEngine(Component):
instrument_id,
)

if last_timestamp and now <= last_timestamp or end and end <= last_timestamp:
self._query_catalog(request)
return
if last_timestamp:
if (now <= last_timestamp) or (end and end <= last_timestamp):
self._query_catalog(request)
return

if client is None:
self._log.error(
Expand Down Expand Up @@ -1409,9 +1410,10 @@ cdef class DataEngine(Component):
instrument_id,
)

if last_timestamp and now <= last_timestamp or end and end <= last_timestamp:
self._query_catalog(request)
return
if last_timestamp:
if (now <= last_timestamp) or (end and end <= last_timestamp):
self._query_catalog(request)
return

if client is None:
self._log.error(
Expand Down Expand Up @@ -1440,9 +1442,10 @@ cdef class DataEngine(Component):
bar_type=bar_type,
)

if last_timestamp and now <= last_timestamp or end and end <= last_timestamp:
self._query_catalog(request)
return
if last_timestamp:
if (now <= last_timestamp) or (end and end <= last_timestamp):
self._query_catalog(request)
return

if client is None:
self._log.error(
Expand All @@ -1468,9 +1471,10 @@ cdef class DataEngine(Component):
request.data_type.type,
)

if last_timestamp and now <= last_timestamp or end and end <= last_timestamp:
self._query_catalog(request)
return
if last_timestamp:
if (now <= last_timestamp) or (end and end <= last_timestamp):
self._query_catalog(request)
return

if client is None:
self._log.error(
Expand Down
43 changes: 43 additions & 0 deletions tests/unit_tests/data/test_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -2295,6 +2295,49 @@ def test_request_bars_reaches_client(self):
assert len(handler) == 1
assert handler[0].data == [bar]

def test_request_bars_with_start_and_end(self):
# Arrange
self.data_engine.register_client(self.mock_market_data_client)
bar_spec = BarSpecification(1000, BarAggregation.TICK, PriceType.MID)
bar_type = BarType(ETHUSDT_BINANCE.id, bar_spec)
bar = Bar(
bar_type,
Price.from_str("1051.00000"),
Price.from_str("1055.00000"),
Price.from_str("1050.00000"),
Price.from_str("1052.00000"),
Quantity.from_int(100),
0,
0,
)
self.mock_market_data_client.bars = [bar]

handler = []
request = DataRequest(
client_id=None,
venue=bar_type.instrument_id.venue,
data_type=DataType(
Bar,
metadata={
"bar_type": bar_type,
"start": pd.Timestamp("2024-10-01"),
"end": pd.Timestamp("2024-10-31"),
"update_catalog": False,
},
),
callback=handler.append,
request_id=UUID4(),
ts_init=self.clock.timestamp_ns(),
)

# Act
self.msgbus.request(endpoint="DataEngine.request", request=request)

# Assert
assert self.data_engine.request_count == 1
assert len(handler) == 1
assert handler[0].data == [bar]

def test_request_bars_when_catalog_registered(self):
# Arrange
catalog = setup_catalog(protocol="file")
Expand Down

0 comments on commit 444b4cf

Please sign in to comment.