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:
parent
7a22aaa111
commit
cf9331919f
@ -32,6 +32,13 @@ class Binance(Exchange):
|
|||||||
|
|
||||||
return super().get_order_book(pair, limit)
|
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:
|
def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict:
|
||||||
"""
|
"""
|
||||||
creates a stoploss limit order.
|
creates a stoploss limit order.
|
||||||
|
@ -519,6 +519,13 @@ class Exchange:
|
|||||||
|
|
||||||
return self.create_order(pair, ordertype, 'sell', amount, rate, params)
|
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:
|
def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict:
|
||||||
"""
|
"""
|
||||||
creates a stoploss order.
|
creates a stoploss order.
|
||||||
|
@ -51,6 +51,13 @@ class Kraken(Exchange):
|
|||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(e) from 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:
|
def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict:
|
||||||
"""
|
"""
|
||||||
Creates a stoploss market order.
|
Creates a stoploss market order.
|
||||||
|
@ -718,8 +718,7 @@ class FreqtradeBot:
|
|||||||
:param order: Current on exchange stoploss order
|
:param order: Current on exchange stoploss order
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
if self.exchange.stoploss_adjust(trade.stop_loss, order):
|
||||||
if trade.stop_loss > float(order['info']['stopPrice']):
|
|
||||||
# we check if the update is neccesary
|
# we check if the update is neccesary
|
||||||
update_beat = self.strategy.order_types.get('stoploss_on_exchange_interval', 60)
|
update_beat = self.strategy.order_types.get('stoploss_on_exchange_interval', 60)
|
||||||
if (datetime.utcnow() - trade.stoploss_last_update).total_seconds() >= update_beat:
|
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['type'] == order_type
|
||||||
assert order['price'] == 220
|
assert order['price'] == 220
|
||||||
assert order['amount'] == 1
|
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 .*"):
|
with pytest.raises(OperationalException, match=r"stoploss is not implemented .*"):
|
||||||
exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
|
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):
|
def test_merge_ft_has_dict(default_conf, mocker):
|
||||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
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['type'] == order_type
|
||||||
assert order['price'] == 220
|
assert order['price'] == 220
|
||||||
assert order['amount'] == 1
|
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user