From e67ffd2d879325af137d37863ee5abd6d065ba0e Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 6 Mar 2019 19:55:34 +0100 Subject: [PATCH] Fix issue that backtest is broken when stoploss_on_exchange is on --- freqtrade/optimize/backtesting.py | 11 +++++---- freqtrade/tests/optimize/test_backtesting.py | 24 +++++++++++++++++++- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index a8f4e530a..031b490c8 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -17,11 +17,10 @@ from freqtrade import optimize from freqtrade import DependencyException, constants from freqtrade.arguments import Arguments from freqtrade.configuration import Configuration -from freqtrade.exchange import Exchange from freqtrade.data import history from freqtrade.misc import file_dump_json from freqtrade.persistence import Trade -from freqtrade.resolvers import StrategyResolver +from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.state import RunMode from freqtrade.strategy.interface import SellType, IStrategy @@ -79,8 +78,8 @@ class Backtesting(object): self.strategylist.append(StrategyResolver(self.config).strategy) # Load one strategy self._set_strategy(self.strategylist[0]) - - self.exchange = Exchange(self.config) + exchange_name = self.config.get('exchange', {}).get('name', 'bittrex').title() + self.exchange = ExchangeResolver(exchange_name, self.config).exchange self.fee = self.exchange.get_fee() def _set_strategy(self, strategy): @@ -93,6 +92,10 @@ class Backtesting(object): self.tickerdata_to_dataframe = strategy.tickerdata_to_dataframe self.advise_buy = strategy.advise_buy self.advise_sell = strategy.advise_sell + # Set stoploss_on_exchange to false for backtesting, + # since a "perfect" stoploss-sell is assumed anyway + # And the regular "stoploss" function would not apply to that case + self.strategy.order_types['stoploss_on_exchange'] = False def _generate_text_table(self, data: Dict[str, Dict], results: DataFrame, skip_nan: bool = False) -> str: diff --git a/freqtrade/tests/optimize/test_backtesting.py b/freqtrade/tests/optimize/test_backtesting.py index e69b1374e..1d5fb1384 100644 --- a/freqtrade/tests/optimize/test_backtesting.py +++ b/freqtrade/tests/optimize/test_backtesting.py @@ -315,7 +315,28 @@ def test_start(mocker, fee, default_conf, caplog) -> None: assert start_mock.call_count == 1 -def test_backtesting_init(mocker, default_conf) -> None: +ORDER_TYPES = [ + { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'limit', + 'stoploss_on_exchange': False + }, + { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'limit', + 'stoploss_on_exchange': True + }] + + +@pytest.mark.parametrize("order_types", ORDER_TYPES) +def test_backtesting_init(mocker, default_conf, order_types) -> None: + """ + Check that stoploss_on_exchange is set to False while backtesting + since backtesting assumes a perfect stoploss anyway. + """ + default_conf["order_types"] = order_types patch_exchange(mocker) get_fee = mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.5)) backtesting = Backtesting(default_conf) @@ -326,6 +347,7 @@ def test_backtesting_init(mocker, default_conf) -> None: assert callable(backtesting.advise_sell) get_fee.assert_called() assert backtesting.fee == 0.5 + assert not backtesting.strategy.order_types["stoploss_on_exchange"] def test_tickerdata_to_dataframe_bt(default_conf, mocker) -> None: