diff --git a/freqtrade/configuration/config_validation.py b/freqtrade/configuration/config_validation.py index df9f16f3e..b6029b6a5 100644 --- a/freqtrade/configuration/config_validation.py +++ b/freqtrade/configuration/config_validation.py @@ -74,6 +74,7 @@ def validate_config_consistency(conf: Dict[str, Any]) -> None: # validating trailing stoploss _validate_trailing_stoploss(conf) + _validate_price_config(conf) _validate_edge(conf) _validate_whitelist(conf) _validate_protections(conf) @@ -95,6 +96,19 @@ def _validate_unlimited_amount(conf: Dict[str, Any]) -> None: raise OperationalException("`max_open_trades` and `stake_amount` cannot both be unlimited.") +def _validate_price_config(conf: Dict[str, Any]) -> None: + """ + When using market orders, price sides must be using the "other" side of the price + """ + if (conf['order_types'].get('buy') == 'market' + and conf['bid_strategy'].get('price_side') != 'ask'): + raise OperationalException('Market buy orders require bid_strategy.price_side = "ask".') + + if (conf['order_types'].get('sell') == 'market' + and conf['ask_strategy'].get('price_side') != 'bid'): + raise OperationalException('Market sell orders require ask_strategy.price_side = "bid".') + + def _validate_trailing_stoploss(conf: Dict[str, Any]) -> None: if conf.get('stoploss') == 0.0: diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 6b3df392b..a0824e65c 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -790,6 +790,38 @@ def test_validate_max_open_trades(default_conf): validate_config_consistency(default_conf) +def test_validate_price_side(default_conf): + default_conf['order_types'] = { + "buy": "limit", + "sell": "limit", + "stoploss": "limit", + "stoploss_on_exchange": False, + } + # Default should pass + validate_config_consistency(default_conf) + + conf = deepcopy(default_conf) + conf['order_types']['buy'] = 'market' + with pytest.raises(OperationalException, + match='Market buy orders require bid_strategy.price_side = "ask".'): + validate_config_consistency(conf) + + conf = deepcopy(default_conf) + conf['order_types']['sell'] = 'market' + with pytest.raises(OperationalException, + match='Market sell orders require ask_strategy.price_side = "bid".'): + validate_config_consistency(conf) + + # Validate inversed case + conf = deepcopy(default_conf) + conf['order_types']['sell'] = 'market' + conf['order_types']['buy'] = 'market' + conf['ask_strategy']['price_side'] = 'bid' + conf['bid_strategy']['price_side'] = 'ask' + + validate_config_consistency(conf) + + def test_validate_tsl(default_conf): default_conf['stoploss'] = 0.0 with pytest.raises(OperationalException, match='The config stoploss needs to be different '