From 044b57a943e76cb9446ee774557710b1d49da9fb Mon Sep 17 00:00:00 2001 From: Mikko Ohtamaa Date: Sat, 20 Jul 2024 23:13:36 +0900 Subject: [PATCH] Add price_data_delay_tolerance hint --- tests/backtest/test_backtest_execution.py | 12 +++++++++++- tradeexecutor/backtest/backtest_runner.py | 5 ++++- tradeexecutor/strategy/trading_strategy_universe.py | 10 ++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/tests/backtest/test_backtest_execution.py b/tests/backtest/test_backtest_execution.py index 1c2228d32..11b9ed129 100644 --- a/tests/backtest/test_backtest_execution.py +++ b/tests/backtest/test_backtest_execution.py @@ -5,8 +5,10 @@ import logging from decimal import Decimal +import pandas as pd import pytest +from tradeexecutor.backtest.backtest_runner import guess_data_delay_tolerance from tradeexecutor.state.identifier import AssetIdentifier from tradeexecutor.state.trade import TradeStatus from tradeexecutor.strategy.reserve_currency import ReserveCurrency @@ -260,7 +262,7 @@ def test_buy_with_fee( logger: logging.Logger, state: State, wallet: SimulatedWallet, - strategy_universe, + strategy_universe, routing_model: BacktestRoutingModel, pricing_model: BacktestPricing, wbnb: AssetIdentifier, @@ -341,3 +343,11 @@ def test_buy_sell_backtest_with_fee( # Check our wallet was credited assert wallet.get_balance(busd.address) == pytest.approx(Decimal('9990.040840796019796453251579')) assert wallet.get_balance(wbnb.address) == 0 + + +def test_price_data_tolerance( + strategy_universe, +): + """Workaround for Uni v3 issues""" + strategy_universe.price_data_delay_tolerance = datetime.timedelta(days=365) + assert guess_data_delay_tolerance(strategy_universe) == pd.Timedelta(days=365) \ No newline at end of file diff --git a/tradeexecutor/backtest/backtest_runner.py b/tradeexecutor/backtest/backtest_runner.py index 493f57b97..f06b095eb 100644 --- a/tradeexecutor/backtest/backtest_runner.py +++ b/tradeexecutor/backtest/backtest_runner.py @@ -1025,7 +1025,10 @@ def guess_data_delay_tolerance(universe: TradingStrategyUniverse) -> pd.Timedelt This could work around some data quality issues or early historical data. """ - if universe.data_universe.time_bucket == TimeBucket.d7: + + if universe.price_data_delay_tolerance: + return pd.Timedelta(universe.price_data_delay_tolerance) + elif universe.data_universe.time_bucket == TimeBucket.d7: data_delay_tolerance = pd.Timedelta("9d") else: data_delay_tolerance = pd.Timedelta("2d") diff --git a/tradeexecutor/strategy/trading_strategy_universe.py b/tradeexecutor/strategy/trading_strategy_universe.py index d8a042b57..d5247713c 100644 --- a/tradeexecutor/strategy/trading_strategy_universe.py +++ b/tradeexecutor/strategy/trading_strategy_universe.py @@ -171,6 +171,16 @@ class TradingStrategyUniverse(StrategyExecutionUniverse): #: options: UniverseOptions | None = None + #: How much lag we allow in the price feed. + #: + #: This can be set for a very high value when working with open ended universes where the liquidity pools are + #: disappear when liquidity providers leave. + #: + #: TODO: Use carefully - this is mostly a workaround variable and + #: will have a more robust TVL/liquidity solution in the future. + #: + price_data_delay_tolerance: datetime.timedelta | None = None + def __repr__(self): pair_count = self.data_universe.pairs.get_count() if pair_count <= 3: