diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index d52165e0a..603b0631f 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -20,7 +20,7 @@ from freqtrade.exchange import timeframe_to_minutes from freqtrade.persistence import Trade from freqtrade.rpc import RPCManager, RPCMessageType from freqtrade.resolvers import ExchangeResolver, StrategyResolver, PairListResolver -from freqtrade.state import State +from freqtrade.state import State, RunMode from freqtrade.strategy.interface import SellType, IStrategy from freqtrade.wallets import Wallets @@ -75,6 +75,12 @@ class FreqtradeBot(object): persistence.init(self.config.get('db_url', None), clean_open_orders=self.config.get('dry_run', False)) + # Stoploss on exchange does not make sense, therefore we need to disable that. + if (self.dataprovider.runmode == RunMode.DRY_RUN and + self.strategy.order_types.get('stoploss_on_exchange', False)): + logger.info("Disabling stoploss_on_exchange during dry-run.") + self.strategy.order_types['stoploss_on_exchange'] = False + config['order_types']['stoploss_on_exchange'] = False # Set initial bot state from config initial_state = self.config.get('initial_state') self.state = State[initial_state.upper()] if initial_state else State.STOPPED diff --git a/freqtrade/tests/strategy/test_strategy.py b/freqtrade/tests/strategy/test_strategy.py index df8c0f126..93c0a9e8a 100644 --- a/freqtrade/tests/strategy/test_strategy.py +++ b/freqtrade/tests/strategy/test_strategy.py @@ -15,7 +15,7 @@ from freqtrade.resolvers import StrategyResolver from freqtrade.strategy import import_strategy from freqtrade.strategy.default_strategy import DefaultStrategy from freqtrade.strategy.interface import IStrategy -from freqtrade.tests.conftest import log_has_re +from freqtrade.tests.conftest import log_has_re, log_has def test_import_strategy(caplog): @@ -257,12 +257,9 @@ def test_strategy_override_order_types(caplog): for method in ['buy', 'sell', 'stoploss', 'stoploss_on_exchange']: assert resolver.strategy.order_types[method] == order_types[method] - assert ('freqtrade.resolvers.strategy_resolver', - logging.INFO, - "Override strategy 'order_types' with value in config file:" - " {'buy': 'market', 'sell': 'limit', 'stoploss': 'limit'," - " 'stoploss_on_exchange': True}." - ) in caplog.record_tuples + assert log_has("Override strategy 'order_types' with value in config file:" + " {'buy': 'market', 'sell': 'limit', 'stoploss': 'limit'," + " 'stoploss_on_exchange': True}.", caplog.record_tuples) config = { 'strategy': 'DefaultStrategy', diff --git a/freqtrade/tests/test_freqtradebot.py b/freqtrade/tests/test_freqtradebot.py index 1a4c5159c..7ed918318 100644 --- a/freqtrade/tests/test_freqtradebot.py +++ b/freqtrade/tests/test_freqtradebot.py @@ -16,7 +16,7 @@ from freqtrade.data.dataprovider import DataProvider from freqtrade.freqtradebot import FreqtradeBot from freqtrade.persistence import Trade from freqtrade.rpc import RPCMessageType -from freqtrade.state import State +from freqtrade.state import State, RunMode from freqtrade.strategy.interface import SellCheckTuple, SellType from freqtrade.tests.conftest import (get_patched_freqtradebot, get_patched_worker, log_has, log_has_re, @@ -130,7 +130,77 @@ def test_throttle_with_assets(mocker, default_conf) -> None: assert result == -1 -def test_get_trade_stake_amount(default_conf, ticker, limit_buy_order, fee, mocker) -> None: +def test_order_dict_dry_run(default_conf, mocker, caplog) -> None: + patch_RPCManager(mocker) + patch_exchange(mocker) + mocker.patch.multiple( + 'freqtrade.exchange.Exchange', + get_balance=MagicMock(return_value=default_conf['stake_amount'] * 2) + ) + conf = default_conf.copy() + conf['runmode'] = RunMode.DRY_RUN + conf['order_types'] = { + 'buy': 'market', + 'sell': 'limit', + 'stoploss': 'limit', + 'stoploss_on_exchange': True, + } + + freqtrade = FreqtradeBot(conf) + assert log_has("Disabling stoploss_on_exchange during dry-run.", caplog.record_tuples) + assert not freqtrade.strategy.order_types['stoploss_on_exchange'] + + caplog.clear() + # is left untouched + conf = default_conf.copy() + conf['runmode'] = RunMode.DRY_RUN + conf['order_types'] = { + 'buy': 'market', + 'sell': 'limit', + 'stoploss': 'limit', + 'stoploss_on_exchange': False, + } + freqtrade = FreqtradeBot(conf) + assert not freqtrade.strategy.order_types['stoploss_on_exchange'] + assert not log_has_re(".*stoploss_on_exchange .* dry-run", caplog.record_tuples) + + +def test_order_dict_live(default_conf, mocker, caplog) -> None: + patch_RPCManager(mocker) + patch_exchange(mocker) + mocker.patch.multiple( + 'freqtrade.exchange.Exchange', + get_balance=MagicMock(return_value=default_conf['stake_amount'] * 2) + ) + conf = default_conf.copy() + conf['runmode'] = RunMode.LIVE + conf['order_types'] = { + 'buy': 'market', + 'sell': 'limit', + 'stoploss': 'limit', + 'stoploss_on_exchange': True, + } + + freqtrade = FreqtradeBot(conf) + assert not log_has_re(".*stoploss_on_exchange .* dry-run", caplog.record_tuples) + assert freqtrade.strategy.order_types['stoploss_on_exchange'] + + caplog.clear() + # is left untouched + conf = default_conf.copy() + conf['runmode'] = RunMode.LIVE + conf['order_types'] = { + 'buy': 'market', + 'sell': 'limit', + 'stoploss': 'limit', + 'stoploss_on_exchange': False, + } + freqtrade = FreqtradeBot(conf) + assert not freqtrade.strategy.order_types['stoploss_on_exchange'] + assert not log_has_re(".*stoploss_on_exchange .* dry-run", caplog.record_tuples) + + +def test_get_trade_stake_amount(default_conf, ticker, mocker) -> None: patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple(