From b0e05b92d3aa16404798edc2c657d904c2242c04 Mon Sep 17 00:00:00 2001 From: Sam Germain Date: Fri, 10 Sep 2021 13:39:42 -0600 Subject: [PATCH] Added minor changes from lev-exchange review --- freqtrade/exchange/binance.py | 15 ++++++++------- freqtrade/exchange/exchange.py | 7 +++++-- freqtrade/exchange/ftx.py | 10 +++++----- freqtrade/exchange/kraken.py | 15 +++++++++------ tests/exchange/test_binance.py | 17 ++++++++--------- tests/exchange/test_kraken.py | 25 ++++++++++++++++--------- 6 files changed, 51 insertions(+), 38 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 5680a7b47..f5a222d2d 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -41,8 +41,8 @@ class Binance(Exchange): """ return order['type'] == 'stop_loss_limit' and ( - side == "sell" and stop_loss > float(order['info']['stopPrice']) or - side == "buy" and stop_loss < float(order['info']['stopPrice']) + (side == "sell" and stop_loss > float(order['info']['stopPrice'])) or + (side == "buy" and stop_loss < float(order['info']['stopPrice'])) ) @retrier(retries=0) @@ -55,11 +55,12 @@ class Binance(Exchange): :param side: "buy" or "sell" """ # Limit price threshold: As limit price should always be below stop-price - limit_price_pct = order_types.get( - 'stoploss_on_exchange_limit_ratio', - 0.99 if side == 'sell' else 1.01 - ) - rate = stop_price * limit_price_pct + limit_price_pct = order_types.get('stoploss_on_exchange_limit_ratio', 0.99) + if side == "sell": + # TODO: Name limit_rate in other exchange subclasses + rate = stop_price * limit_price_pct + else: + rate = stop_price * (2 - limit_price_pct) ordertype = "stop_loss_limit" diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index b9da0cf7c..03ab281c9 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -1597,8 +1597,7 @@ class Exchange: :param pair: The base/quote currency pair being traded :nominal_value: The total value of the trade in quote currency (collateral + debt) """ - raise OperationalException( - f"{self.name.capitalize()}.get_max_leverage has not been implemented.") + return 1.0 @retrier def set_leverage(self, leverage: float, pair: Optional[str]): @@ -1606,6 +1605,10 @@ class Exchange: Set's the leverage before making a trade, in order to not have the same leverage on every trade """ + if not self.exchange_has("setLeverage"): + # Some exchanges only support one collateral type + return + try: self._api.set_leverage(symbol=pair, leverage=leverage) except ccxt.DDoSProtection as e: diff --git a/freqtrade/exchange/ftx.py b/freqtrade/exchange/ftx.py index 870791cf5..095d8eaa1 100644 --- a/freqtrade/exchange/ftx.py +++ b/freqtrade/exchange/ftx.py @@ -57,11 +57,11 @@ class Ftx(Exchange): Limit orders are defined by having orderPrice set, otherwise a market order is used. """ - limit_price_pct = order_types.get( - 'stoploss_on_exchange_limit_ratio', - 0.99 if side == "sell" else 1.01 - ) - limit_rate = stop_price * limit_price_pct + limit_price_pct = order_types.get('stoploss_on_exchange_limit_ratio', 0.99) + if side == "sell": + limit_rate = stop_price * limit_price_pct + else: + limit_rate = stop_price * (2 - limit_price_pct) ordertype = "stop" diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 861063b3f..b72a92070 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -55,8 +55,8 @@ class Kraken(Exchange): orders = self._api.fetch_open_orders() order_list = [(x["symbol"].split("/")[0 if x["side"] == "sell" else 1], - x["remaining"] if x["side"] == "sell" else x["remaining"] * x["price"], - # Don't remove the below comment, this can be important for debugging + x["remaining"] if x["side"] == "sell" else x["remaining"] * x["price"], + # Don't remove the below comment, this can be important for debugging # x["side"], x["amount"], ) for x in orders] for bal in balances: @@ -96,7 +96,10 @@ class Kraken(Exchange): if order_types.get('stoploss', 'market') == 'limit': ordertype = "stop-loss-limit" limit_price_pct = order_types.get('stoploss_on_exchange_limit_ratio', 0.99) - limit_rate = stop_price * limit_price_pct + if side == "sell": + limit_rate = stop_price * limit_price_pct + else: + limit_rate = stop_price * (2 - limit_price_pct) params['price2'] = self.price_to_precision(pair, limit_rate) else: ordertype = "stop-loss" @@ -144,13 +147,13 @@ class Kraken(Exchange): for pair, market in self.markets.items(): info = market['info'] - leverage_buy = info['leverage_buy'] if 'leverage_buy' in info else [] - leverage_sell = info['leverage_sell'] if 'leverage_sell' in info else [] + leverage_buy = info.get('leverage_buy', []) + leverage_sell = info.get('leverage_sell', []) if len(leverage_buy) > 0 or len(leverage_sell) > 0: if leverage_buy != leverage_sell: logger.warning( f"The buy({leverage_buy}) and sell({leverage_sell}) leverage are not equal" - "{pair}. Please let freqtrade know because this has never happened before" + "for {pair}. Please notify freqtrade because this has never happened before" ) if max(leverage_buy) < max(leverage_sell): leverages[pair] = leverage_buy diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index ad55ede9b..96287da44 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -9,19 +9,18 @@ from tests.conftest import get_patched_exchange from tests.exchange.test_exchange import ccxt_exceptionhandlers -@pytest.mark.parametrize('limitratio,exchangelimitratio,expected,side', [ - (None, 1.05, 220 * 0.99, "sell"), - (0.99, 1.05, 220 * 0.99, "sell"), - (0.98, 1.05, 220 * 0.98, "sell"), - (None, 0.95, 220 * 1.01, "buy"), - (1.01, 0.95, 220 * 1.01, "buy"), - (1.02, 0.95, 220 * 1.02, "buy"), +@pytest.mark.parametrize('limitratio,expected,side', [ + (None, 220 * 0.99, "sell"), + (0.99, 220 * 0.99, "sell"), + (0.98, 220 * 0.98, "sell"), + (None, 220 * 1.01, "buy"), + (0.99, 220 * 1.01, "buy"), + (0.98, 220 * 1.02, "buy"), ]) def test_stoploss_order_binance( default_conf, mocker, limitratio, - exchangelimitratio, expected, side ): @@ -47,7 +46,7 @@ def test_stoploss_order_binance( amount=1, stop_price=190, side=side, - order_types={'stoploss_on_exchange_limit_ratio': exchangelimitratio} + order_types={'stoploss_on_exchange_limit_ratio': 1.05} ) api_mock.create_order.reset_mock() diff --git a/tests/exchange/test_kraken.py b/tests/exchange/test_kraken.py index 01f27997c..66e7f4f0b 100644 --- a/tests/exchange/test_kraken.py +++ b/tests/exchange/test_kraken.py @@ -166,11 +166,11 @@ def test_get_balances_prod(default_conf, mocker): @pytest.mark.parametrize('ordertype', ['market', 'limit']) -@pytest.mark.parametrize('side,limitratio,adjustedprice', [ - ("buy", 0.99, 217.8), - ("sell", 1.01, 222.2), +@pytest.mark.parametrize('side,adjustedprice', [ + ("sell", 217.8), + ("buy", 222.2), ]) -def test_stoploss_order_kraken(default_conf, mocker, ordertype, side, limitratio, adjustedprice): +def test_stoploss_order_kraken(default_conf, mocker, ordertype, side, adjustedprice): api_mock = MagicMock() order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6)) @@ -187,10 +187,15 @@ def test_stoploss_order_kraken(default_conf, mocker, ordertype, side, limitratio exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken') - order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, side=side, - order_types={'stoploss': ordertype, - 'stoploss_on_exchange_limit_ratio': limitratio - }) + order = exchange.stoploss( + pair='ETH/BTC', + amount=1, + stop_price=220, + side=side, + order_types={ + 'stoploss': ordertype, + 'stoploss_on_exchange_limit_ratio': 0.99 + }) assert 'id' in order assert 'info' in order @@ -199,7 +204,9 @@ def test_stoploss_order_kraken(default_conf, mocker, ordertype, side, limitratio if ordertype == 'limit': assert api_mock.create_order.call_args_list[0][1]['type'] == STOPLOSS_LIMIT_ORDERTYPE assert api_mock.create_order.call_args_list[0][1]['params'] == { - 'trading_agreement': 'agree', 'price2': adjustedprice} + 'trading_agreement': 'agree', + 'price2': adjustedprice + } else: assert api_mock.create_order.call_args_list[0][1]['type'] == STOPLOSS_ORDERTYPE assert api_mock.create_order.call_args_list[0][1]['params'] == {