From 9887cb997ed18907995f60db8ee795d407a86ded Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 14 Jul 2019 14:17:09 +0200 Subject: [PATCH 1/3] Check if Price is needed for market orders This is currently the case for: cex, coinex, cointiger, fcoin, fcoinjp, hadax, huobipro, huobiru, uex, --- freqtrade/exchange/exchange.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index ec2832cbf..65f013a03 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -387,7 +387,9 @@ class Exchange(object): try: # Set the precision for amount and price(rate) as accepted by the exchange amount = self.symbol_amount_prec(pair, amount) - rate = self.symbol_price_prec(pair, rate) if ordertype != 'market' else None + needs_price = (ordertype != 'market' + or self._api.options.get("createMarketBuyOrderRequiresPrice", False)) + rate = self.symbol_price_prec(pair, rate) if needs_price else None return self._api.create_order(pair, ordertype, side, amount, rate, params) @@ -395,12 +397,12 @@ class Exchange(object): except ccxt.InsufficientFunds as e: raise DependencyException( f'Insufficient funds to create {ordertype} {side} order on market {pair}.' - f'Tried to {side} amount {amount} at rate {rate} (total {rate*amount}).' + f'Tried to {side} amount {amount} at rate {rate} (total {rate * amount}).' f'Message: {e}') except ccxt.InvalidOrder as e: raise DependencyException( f'Could not create {ordertype} {side} order on market {pair}.' - f'Tried to {side} amount {amount} at rate {rate} (total {rate*amount}).' + f'Tried to {side} amount {amount} at rate {rate} (total {rate * amount}).' f'Message: {e}') except (ccxt.NetworkError, ccxt.ExchangeError) as e: raise TemporaryError( From 25822d17177e73f8b3346e14d9d21c038e93b0ee Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 14 Jul 2019 14:18:30 +0200 Subject: [PATCH 2/3] Add empty options dict to all tests using create_order --- freqtrade/tests/exchange/test_exchange.py | 5 +++++ freqtrade/tests/exchange/test_kraken.py | 2 ++ 2 files changed, 7 insertions(+) diff --git a/freqtrade/tests/exchange/test_exchange.py b/freqtrade/tests/exchange/test_exchange.py index bc1e7912c..9de605ffd 100644 --- a/freqtrade/tests/exchange/test_exchange.py +++ b/freqtrade/tests/exchange/test_exchange.py @@ -552,6 +552,7 @@ def test_dry_run_order(default_conf, mocker, side, exchange_name): def test_create_order(default_conf, mocker, side, ordertype, rate, exchange_name): api_mock = MagicMock() order_id = 'test_prod_{}_{}'.format(side, randint(0, 10 ** 6)) + api_mock.options = {} api_mock.create_order = MagicMock(return_value={ 'id': order_id, 'info': { @@ -592,6 +593,7 @@ def test_buy_prod(default_conf, mocker, exchange_name): order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6)) order_type = 'market' time_in_force = 'gtc' + api_mock.options = {} api_mock.create_order = MagicMock(return_value={ 'id': order_id, 'info': { @@ -659,6 +661,7 @@ def test_buy_prod(default_conf, mocker, exchange_name): def test_buy_considers_time_in_force(default_conf, mocker, exchange_name): api_mock = MagicMock() order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6)) + api_mock.options = {} api_mock.create_order = MagicMock(return_value={ 'id': order_id, 'info': { @@ -719,6 +722,7 @@ def test_sell_prod(default_conf, mocker, exchange_name): api_mock = MagicMock() order_id = 'test_prod_sell_{}'.format(randint(0, 10 ** 6)) order_type = 'market' + api_mock.options = {} api_mock.create_order = MagicMock(return_value={ 'id': order_id, 'info': { @@ -783,6 +787,7 @@ def test_sell_considers_time_in_force(default_conf, mocker, exchange_name): 'foo': 'bar' } }) + api_mock.options = {} default_conf['dry_run'] = False mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y) mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y) diff --git a/freqtrade/tests/exchange/test_kraken.py b/freqtrade/tests/exchange/test_kraken.py index 8b81a08a9..8f476affb 100644 --- a/freqtrade/tests/exchange/test_kraken.py +++ b/freqtrade/tests/exchange/test_kraken.py @@ -11,6 +11,7 @@ def test_buy_kraken_trading_agreement(default_conf, mocker): order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6)) order_type = 'limit' time_in_force = 'ioc' + api_mock.options = {} api_mock.create_order = MagicMock(return_value={ 'id': order_id, 'info': { @@ -42,6 +43,7 @@ def test_sell_kraken_trading_agreement(default_conf, mocker): api_mock = MagicMock() order_id = 'test_prod_sell_{}'.format(randint(0, 10 ** 6)) order_type = 'market' + api_mock.options = {} api_mock.create_order = MagicMock(return_value={ 'id': order_id, 'info': { From a8f3f2bc1a85d56b360dead4dfba36082afe62dc Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 14 Jul 2019 14:23:23 +0200 Subject: [PATCH 3/3] Extend test to cover market orders with price too --- freqtrade/tests/exchange/test_exchange.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/freqtrade/tests/exchange/test_exchange.py b/freqtrade/tests/exchange/test_exchange.py index 9de605ffd..a4f1bca18 100644 --- a/freqtrade/tests/exchange/test_exchange.py +++ b/freqtrade/tests/exchange/test_exchange.py @@ -543,16 +543,17 @@ def test_dry_run_order(default_conf, mocker, side, exchange_name): ("buy"), ("sell") ]) -@pytest.mark.parametrize("ordertype,rate", [ - ("market", None), - ("limit", 200), - ("stop_loss_limit", 200) +@pytest.mark.parametrize("ordertype,rate,marketprice", [ + ("market", None, None), + ("market", 200, True), + ("limit", 200, None), + ("stop_loss_limit", 200, None) ]) @pytest.mark.parametrize("exchange_name", EXCHANGES) -def test_create_order(default_conf, mocker, side, ordertype, rate, exchange_name): +def test_create_order(default_conf, mocker, side, ordertype, rate, marketprice, exchange_name): api_mock = MagicMock() order_id = 'test_prod_{}_{}'.format(side, randint(0, 10 ** 6)) - api_mock.options = {} + api_mock.options = {} if not marketprice else {"createMarketBuyOrderRequiresPrice": True} api_mock.create_order = MagicMock(return_value={ 'id': order_id, 'info': {