Merge pull request #1631 from freqtrade/fix/backtest_sloe

Fix issue that backtest is broken when stoploss_on_exchange is on
This commit is contained in:
Misagh 2019-03-07 10:05:46 +01:00 committed by GitHub
commit bc7688a69f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 5 deletions

View File

@ -17,11 +17,10 @@ from freqtrade import optimize
from freqtrade import DependencyException, constants from freqtrade import DependencyException, constants
from freqtrade.arguments import Arguments from freqtrade.arguments import Arguments
from freqtrade.configuration import Configuration from freqtrade.configuration import Configuration
from freqtrade.exchange import Exchange
from freqtrade.data import history from freqtrade.data import history
from freqtrade.misc import file_dump_json from freqtrade.misc import file_dump_json
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
from freqtrade.resolvers import StrategyResolver from freqtrade.resolvers import ExchangeResolver, StrategyResolver
from freqtrade.state import RunMode from freqtrade.state import RunMode
from freqtrade.strategy.interface import SellType, IStrategy from freqtrade.strategy.interface import SellType, IStrategy
@ -79,8 +78,8 @@ class Backtesting(object):
self.strategylist.append(StrategyResolver(self.config).strategy) self.strategylist.append(StrategyResolver(self.config).strategy)
# Load one strategy # Load one strategy
self._set_strategy(self.strategylist[0]) self._set_strategy(self.strategylist[0])
exchange_name = self.config.get('exchange', {}).get('name', 'bittrex').title()
self.exchange = Exchange(self.config) self.exchange = ExchangeResolver(exchange_name, self.config).exchange
self.fee = self.exchange.get_fee() self.fee = self.exchange.get_fee()
def _set_strategy(self, strategy): def _set_strategy(self, strategy):
@ -93,6 +92,10 @@ class Backtesting(object):
self.tickerdata_to_dataframe = strategy.tickerdata_to_dataframe self.tickerdata_to_dataframe = strategy.tickerdata_to_dataframe
self.advise_buy = strategy.advise_buy self.advise_buy = strategy.advise_buy
self.advise_sell = strategy.advise_sell 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, def _generate_text_table(self, data: Dict[str, Dict], results: DataFrame,
skip_nan: bool = False) -> str: skip_nan: bool = False) -> str:

View File

@ -315,7 +315,28 @@ def test_start(mocker, fee, default_conf, caplog) -> None:
assert start_mock.call_count == 1 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) patch_exchange(mocker)
get_fee = mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.5)) get_fee = mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.5))
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
@ -326,6 +347,7 @@ def test_backtesting_init(mocker, default_conf) -> None:
assert callable(backtesting.advise_sell) assert callable(backtesting.advise_sell)
get_fee.assert_called() get_fee.assert_called()
assert backtesting.fee == 0.5 assert backtesting.fee == 0.5
assert not backtesting.strategy.order_types["stoploss_on_exchange"]
def test_tickerdata_to_dataframe_bt(default_conf, mocker) -> None: def test_tickerdata_to_dataframe_bt(default_conf, mocker) -> None: