move exchange-specific order-parsing to exchange class
Related to stoploss_on_exchange in combination with trailing stoploss. Binance contains stopPrice in the info, while kraken returns the same value as "price".
This commit is contained in:
		| @@ -32,6 +32,13 @@ class Binance(Exchange): | ||||
|  | ||||
|         return super().get_order_book(pair, limit) | ||||
|  | ||||
|     def stoploss_adjust(self, stop_loss: float, order: Dict) -> bool: | ||||
|         """ | ||||
|         Verify stop_loss against stoploss-order value (limit or price) | ||||
|         Returns True if adjustment is necessary. | ||||
|         """ | ||||
|         return order['type'] == 'stop_loss_limit' and stop_loss > float(order['info']['stopPrice']) | ||||
|  | ||||
|     def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict: | ||||
|         """ | ||||
|         creates a stoploss limit order. | ||||
|   | ||||
| @@ -282,8 +282,8 @@ class Exchange: | ||||
|         quote_currencies = self.get_quote_currencies() | ||||
|         if stake_currency not in quote_currencies: | ||||
|             raise OperationalException( | ||||
|                     f"{stake_currency} is not available as stake on {self.name}. " | ||||
|                     f"Available currencies are: {', '.join(quote_currencies)}") | ||||
|                 f"{stake_currency} is not available as stake on {self.name}. " | ||||
|                 f"Available currencies are: {', '.join(quote_currencies)}") | ||||
|  | ||||
|     def validate_pairs(self, pairs: List[str]) -> None: | ||||
|         """ | ||||
| @@ -460,7 +460,7 @@ class Exchange: | ||||
|                 "status": "closed", | ||||
|                 "filled": closed_order["amount"], | ||||
|                 "remaining": 0 | ||||
|                 }) | ||||
|             }) | ||||
|         if closed_order["type"] in ["stop_loss_limit"]: | ||||
|             closed_order["info"].update({"stopPrice": closed_order["price"]}) | ||||
|         self._dry_run_open_orders[closed_order["id"]] = closed_order | ||||
| @@ -519,6 +519,13 @@ class Exchange: | ||||
|  | ||||
|         return self.create_order(pair, ordertype, 'sell', amount, rate, params) | ||||
|  | ||||
|     def stoploss_adjust(self, stop_loss: float, order: Dict) -> bool: | ||||
|         """ | ||||
|         Verify stop_loss against stoploss-order value (limit or price) | ||||
|         Returns True if adjustment is necessary. | ||||
|         """ | ||||
|         raise OperationalException(f"stoploss is not implemented for {self.name}.") | ||||
|  | ||||
|     def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict: | ||||
|         """ | ||||
|         creates a stoploss order. | ||||
|   | ||||
| @@ -51,6 +51,13 @@ class Kraken(Exchange): | ||||
|         except ccxt.BaseError as e: | ||||
|             raise OperationalException(e) from e | ||||
|  | ||||
|     def stoploss_adjust(self, stop_loss: float, order: Dict) -> bool: | ||||
|         """ | ||||
|         Verify stop_loss against stoploss-order value (limit or price) | ||||
|         Returns True if adjustment is necessary. | ||||
|         """ | ||||
|         return order['type'] == 'stop-loss' and stop_loss > float(order['price']) | ||||
|  | ||||
|     def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict: | ||||
|         """ | ||||
|         Creates a stoploss market order. | ||||
|   | ||||
| @@ -718,8 +718,7 @@ class FreqtradeBot: | ||||
|         :param order: Current on exchange stoploss order | ||||
|         :return: None | ||||
|         """ | ||||
|  | ||||
|         if trade.stop_loss > float(order['info']['stopPrice']): | ||||
|         if self.exchange.stoploss_adjust(trade.stop_loss, order): | ||||
|             # we check if the update is neccesary | ||||
|             update_beat = self.strategy.order_types.get('stoploss_on_exchange_interval', 60) | ||||
|             if (datetime.utcnow() - trade.stoploss_last_update).total_seconds() >= update_beat: | ||||
|   | ||||
| @@ -92,3 +92,17 @@ def test_stoploss_order_dry_run_binance(default_conf, mocker): | ||||
|     assert order['type'] == order_type | ||||
|     assert order['price'] == 220 | ||||
|     assert order['amount'] == 1 | ||||
|  | ||||
|  | ||||
| def test_stoploss_adjust_binance(mocker, default_conf): | ||||
|     exchange = get_patched_exchange(mocker, default_conf, id='binance') | ||||
|     order = { | ||||
|         'type': 'stop_loss_limit', | ||||
|         'price': 1500, | ||||
|         'info': {'stopPrice': 1500}, | ||||
|     } | ||||
|     assert exchange.stoploss_adjust(1501, order) | ||||
|     assert not exchange.stoploss_adjust(1499, order) | ||||
|     # Test with invalid order case | ||||
|     order['type'] = 'stop_loss' | ||||
|     assert not exchange.stoploss_adjust(1501, order) | ||||
|   | ||||
| @@ -1763,6 +1763,9 @@ def test_stoploss_order_unsupported_exchange(default_conf, mocker): | ||||
|     with pytest.raises(OperationalException, match=r"stoploss is not implemented .*"): | ||||
|         exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) | ||||
|  | ||||
|     with pytest.raises(OperationalException, match=r"stoploss is not implemented .*"): | ||||
|         exchange.stoploss_adjust(1, {}) | ||||
|  | ||||
|  | ||||
| def test_merge_ft_has_dict(default_conf, mocker): | ||||
|     mocker.patch.multiple('freqtrade.exchange.Exchange', | ||||
|   | ||||
| @@ -236,3 +236,16 @@ def test_stoploss_order_dry_run_kraken(default_conf, mocker): | ||||
|     assert order['type'] == order_type | ||||
|     assert order['price'] == 220 | ||||
|     assert order['amount'] == 1 | ||||
|  | ||||
|  | ||||
| def test_stoploss_adjust_kraken(mocker, default_conf): | ||||
|     exchange = get_patched_exchange(mocker, default_conf, id='kraken') | ||||
|     order = { | ||||
|         'type': 'stop-loss', | ||||
|         'price': 1500, | ||||
|     } | ||||
|     assert exchange.stoploss_adjust(1501, order) | ||||
|     assert not exchange.stoploss_adjust(1499, order) | ||||
|     # Test with invalid order case ... | ||||
|     order['type'] = 'stop_loss_limit' | ||||
|     assert not exchange.stoploss_adjust(1501, order) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user