From b3adadb7a06aa49df9d461afb8af041b76ab4b76 Mon Sep 17 00:00:00 2001 From: Kyle Widmann Date: Thu, 13 Feb 2025 21:03:11 -0500 Subject: [PATCH 1/2] Adding support to preload candles for indicators --- poetry.lock | 2 +- pytradebacktest/broker.py | 5 +++++ pytradebacktest/data.py | 17 +++++++++++++++-- tests/unit/test_data.py | 28 ++++++++++++++++++++++++++-- 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5f5dc14..e5ca030 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1078,7 +1078,7 @@ pytest = "^8.1.1" type = "git" url = "https://github.com/kylewidmann/PyTrade/" reference = "v1.0.0" -resolved_reference = "2acf943b674cb414af3fa3fa8b0719ad6569ed69" +resolved_reference = "f54c77cb167295b88aab51227bcc099c6ae7344d" [[package]] name = "pytz" diff --git a/pytradebacktest/broker.py b/pytradebacktest/broker.py index 2e4f9b3..09683bf 100644 --- a/pytradebacktest/broker.py +++ b/pytradebacktest/broker.py @@ -65,6 +65,11 @@ def order(self, order: Order): self.orders.append(order) + def load_instrument_candles( + self, instrument: Instrument, granularity: Granularity, count: int + ): + self._data.load_instrument_candles(instrument, granularity, count) + def subscribe( self, instrument: Instrument, granularity: Granularity ) -> IInstrumentData: diff --git a/pytradebacktest/data.py b/pytradebacktest/data.py index 279d98f..3093545 100644 --- a/pytradebacktest/data.py +++ b/pytradebacktest/data.py @@ -117,6 +117,8 @@ def load(self) -> list[InstrumentData]: class MarketData(IDataContext): + _index: pd.Timestamp + def __init__(self, loader: MarketDataLoader): self._sources = loader.load() self._init_index() @@ -132,9 +134,17 @@ def universe(self): return self._sources @property - def index(self): + def index(self) -> pd.Timestamp: return self._index + def load_instrument_candles( + self, instrument: Instrument, granularity: Granularity, count: int + ): + _data = self.get(instrument, granularity) + _instrument_timestamp: pd.Timestamp = _data.df.index[count] + if _instrument_timestamp > self._index: + self._index = _instrument_timestamp + @property def i(self) -> int: return self._market_index.get_loc(self._index) @@ -163,7 +173,10 @@ def next(self): def __next(self): - for idx in self._market_index: + # Slice index incase some candles were loaded prior to starting + # the test run + _index = self._market_index[self.i :] + for idx in _index: self._index = idx for source in self._sources: source.index = idx diff --git a/tests/unit/test_data.py b/tests/unit/test_data.py index 317701a..c80fd63 100644 --- a/tests/unit/test_data.py +++ b/tests/unit/test_data.py @@ -1,4 +1,6 @@ -from datetime import datetime +from datetime import datetime, timezone + +from pytrade.instruments import FxInstrument, Granularity from pytradebacktest.data import MarketData @@ -11,7 +13,7 @@ def test_load_market_data(test_fx_universe): def test_init_index(test_fx_universe): data: MarketData = test_fx_universe - assert data._index == datetime(2024, 5, 1) + assert data.index == datetime(2024, 5, 1, tzinfo=timezone.utc) def test_fx_length(test_fx_universe): @@ -20,3 +22,25 @@ def test_fx_length(test_fx_universe): def test_stock_length(test_stock_universe): assert len(test_stock_universe) == 2148 + + +def test_preload_candles(test_fx_universe): + data: MarketData = test_fx_universe + + assert data.i == 0 + assert data.index == datetime(2024, 5, 1, tzinfo=timezone.utc) + + data.load_instrument_candles(FxInstrument.EURUSD, Granularity.M1, 5) + + assert data.i == 5 + assert data.index == datetime(2024, 5, 1, 0, 5, tzinfo=timezone.utc) + + data.load_instrument_candles(FxInstrument.EURUSD, Granularity.M1, 10) + + assert data.i == 10 + assert data.index == datetime(2024, 5, 1, 0, 10, tzinfo=timezone.utc) + + data.load_instrument_candles(FxInstrument.EURUSD, Granularity.M1, 7) + + assert data.i == 10 + assert data.index == datetime(2024, 5, 1, 0, 10, tzinfo=timezone.utc) From 1493dce740c1ff76dbf50bb9b5a5c61714473fee Mon Sep 17 00:00:00 2001 From: Kyle Widmann Date: Thu, 13 Feb 2025 21:24:57 -0500 Subject: [PATCH 2/2] Bump pytrade --- poetry.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index e5ca030..46272ea 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1078,7 +1078,7 @@ pytest = "^8.1.1" type = "git" url = "https://github.com/kylewidmann/PyTrade/" reference = "v1.0.0" -resolved_reference = "f54c77cb167295b88aab51227bcc099c6ae7344d" +resolved_reference = "7f1f4fd4879791b73048b31d081cbcf673a95ca2" [[package]] name = "pytz"