Store pair datafrmes in dataprovider for backtesting.

This commit is contained in:
Rokas Kupstys 2021-05-02 12:20:54 +03:00
parent dc6e702fec
commit cdfa6adbe5
3 changed files with 18 additions and 9 deletions

View File

@ -173,3 +173,6 @@ class DataProvider:
return self._pairlists.whitelist.copy()
else:
raise OperationalException("Dataprovider was not initialized with a pairlist provider.")
def clear_cache(self):
self.__cached_pairs = {}

View File

@ -64,8 +64,8 @@ class Backtesting:
self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config)
dataprovider = DataProvider(self.config, self.exchange)
IStrategy.dp = dataprovider
self.dataprovider = DataProvider(self.config, self.exchange)
IStrategy.dp = self.dataprovider
if self.config.get('strategy_list', None):
for strat in list(self.config['strategy_list']):
@ -96,7 +96,7 @@ class Backtesting:
"PrecisionFilter not allowed for backtesting multiple strategies."
)
dataprovider.add_pairlisthandler(self.pairlists)
self.dataprovider.add_pairlisthandler(self.pairlists)
self.pairlists.refresh_pairlist()
if len(self.pairlists.whitelist) == 0:
@ -176,6 +176,7 @@ class Backtesting:
Trade.use_db = False
PairLocks.reset_locks()
Trade.reset_trades()
self.dataprovider.clear_cache()
def _get_ohlcv_as_lists(self, processed: Dict[str, DataFrame]) -> Dict[str, Tuple]:
"""
@ -266,7 +267,8 @@ class Backtesting:
pair=trade.pair, trade=trade, order_type='limit', amount=trade.amount,
rate=closerate,
time_in_force=time_in_force,
sell_reason=sell.sell_reason):
sell_reason=sell.sell_reason,
current_time=sell_row[DATE_IDX].to_pydatetime()):
return None
trade.close(closerate, show_msg=False)
@ -286,7 +288,7 @@ class Backtesting:
# Confirm trade entry:
if not strategy_safe_wrapper(self.strategy.confirm_trade_entry, default_retval=True)(
pair=pair, order_type=order_type, amount=stake_amount, rate=row[OPEN_IDX],
time_in_force=time_in_force):
time_in_force=time_in_force, current_time=row[DATE_IDX].to_pydatetime()):
return None
if stake_amount and (not min_stake_amount or stake_amount > min_stake_amount):
@ -348,6 +350,10 @@ class Backtesting:
trades: List[LocalTrade] = []
self.prepare_backtest(enable_protections)
# Update dataprovider cache
for pair, dataframe in processed.items():
self.dataprovider._set_cached_df(pair, self.timeframe, dataframe)
# Use dict of lists with data for performance
# (looping lists is a lot faster than pandas DataFrames)
data: Dict = self._get_ohlcv_as_lists(processed)

View File

@ -399,27 +399,27 @@ def test_custom_sell(default_conf, fee, caplog) -> None:
)
now = arrow.utcnow().datetime
res = strategy.should_sell(None, trade, 1, now, False, False, None, None, 0)
res = strategy.should_sell(trade, 1, now, False, False, None, None, 0)
assert res.sell_flag is False
assert res.sell_type == SellType.NONE
strategy.custom_sell = MagicMock(return_value=True)
res = strategy.should_sell(None, trade, 1, now, False, False, None, None, 0)
res = strategy.should_sell(trade, 1, now, False, False, None, None, 0)
assert res.sell_flag is True
assert res.sell_type == SellType.CUSTOM_SELL
assert res.sell_reason == 'custom_sell'
strategy.custom_sell = MagicMock(return_value='hello world')
res = strategy.should_sell(None, trade, 1, now, False, False, None, None, 0)
res = strategy.should_sell(trade, 1, now, False, False, None, None, 0)
assert res.sell_type == SellType.CUSTOM_SELL
assert res.sell_flag is True
assert res.sell_reason == 'hello world'
caplog.clear()
strategy.custom_sell = MagicMock(return_value='h' * 100)
res = strategy.should_sell(None, trade, 1, now, False, False, None, None, 0)
res = strategy.should_sell(trade, 1, now, False, False, None, None, 0)
assert res.sell_type == SellType.CUSTOM_SELL
assert res.sell_flag is True
assert res.sell_reason == 'h' * 64