Update Huobi stoploss to shared method
This commit is contained in:
parent
a1f2f6ddeb
commit
14d49e85af
@ -2,12 +2,7 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
import ccxt
|
|
||||||
|
|
||||||
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException,
|
|
||||||
OperationalException, TemporaryError)
|
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
from freqtrade.exchange.common import retrier
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -21,6 +16,7 @@ class Huobi(Exchange):
|
|||||||
|
|
||||||
_ft_has: Dict = {
|
_ft_has: Dict = {
|
||||||
"stoploss_on_exchange": True,
|
"stoploss_on_exchange": True,
|
||||||
|
"stoploss_order_types": {"limit": "stop-limit"},
|
||||||
"ohlcv_candle_limit": 1000,
|
"ohlcv_candle_limit": 1000,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,64 +27,11 @@ class Huobi(Exchange):
|
|||||||
"""
|
"""
|
||||||
return order['type'] == 'stop' and stop_loss > float(order['stopPrice'])
|
return order['type'] == 'stop' and stop_loss > float(order['stopPrice'])
|
||||||
|
|
||||||
@retrier(retries=0)
|
def _get_stop_params(self, ordertype: str, stop_price: float) -> Dict:
|
||||||
def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict:
|
|
||||||
"""
|
|
||||||
creates a stoploss limit order.
|
|
||||||
this stoploss-limit is huobi-specific.
|
|
||||||
TODO: Compare this with other stoploss implementations -
|
|
||||||
"""
|
|
||||||
# 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)
|
|
||||||
rate = stop_price * limit_price_pct
|
|
||||||
|
|
||||||
ordertype = "stop-limit"
|
params = self._params.copy()
|
||||||
|
params.update({
|
||||||
stop_price = self.price_to_precision(pair, stop_price)
|
"stopPrice": stop_price,
|
||||||
|
"operator": "lte",
|
||||||
# Ensure rate is less than stop price
|
})
|
||||||
if stop_price <= rate:
|
return params
|
||||||
raise OperationalException(
|
|
||||||
'In stoploss limit order, stop price should be more than limit price')
|
|
||||||
|
|
||||||
if self._config['dry_run']:
|
|
||||||
dry_order = self.create_dry_run_order(
|
|
||||||
pair, ordertype, "sell", amount, stop_price)
|
|
||||||
return dry_order
|
|
||||||
|
|
||||||
try:
|
|
||||||
params = self._params.copy()
|
|
||||||
params.update({
|
|
||||||
"stopPrice": stop_price,
|
|
||||||
"operator": "lte",
|
|
||||||
})
|
|
||||||
|
|
||||||
amount = self.amount_to_precision(pair, amount)
|
|
||||||
|
|
||||||
rate = self.price_to_precision(pair, rate)
|
|
||||||
|
|
||||||
order = self._api.create_order(symbol=pair, type=ordertype, side='sell',
|
|
||||||
amount=amount, price=rate, params=params)
|
|
||||||
logger.info('stoploss limit order added for %s. '
|
|
||||||
'stop price: %s. limit: %s', pair, stop_price, rate)
|
|
||||||
self._log_exchange_response('create_stoploss_order', order)
|
|
||||||
return order
|
|
||||||
except ccxt.InsufficientFunds as e:
|
|
||||||
raise InsufficientFundsError(
|
|
||||||
f'Insufficient funds to create {ordertype} sell order on market {pair}. '
|
|
||||||
f'Tried to sell amount {amount} at rate {rate}. '
|
|
||||||
f'Message: {e}') from e
|
|
||||||
except ccxt.InvalidOrder as e:
|
|
||||||
# Errors:
|
|
||||||
# `Order would trigger immediately.`
|
|
||||||
raise InvalidOrderException(
|
|
||||||
f'Could not create {ordertype} sell order on market {pair}. '
|
|
||||||
f'Tried to sell amount {amount} at rate {rate}. '
|
|
||||||
f'Message: {e}') from e
|
|
||||||
except ccxt.DDoSProtection as e:
|
|
||||||
raise DDosProtection(e) from e
|
|
||||||
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
|
||||||
raise TemporaryError(
|
|
||||||
f'Could not place sell order due to {e.__class__.__name__}. Message: {e}') from e
|
|
||||||
except ccxt.BaseError as e:
|
|
||||||
raise OperationalException(e) from e
|
|
||||||
|
@ -48,7 +48,7 @@ def test_stoploss_order_huobi(default_conf, mocker, limitratio, expected):
|
|||||||
assert api_mock.create_order.call_args_list[0][1]['amount'] == 1
|
assert api_mock.create_order.call_args_list[0][1]['amount'] == 1
|
||||||
# Price should be 1% below stopprice
|
# Price should be 1% below stopprice
|
||||||
assert api_mock.create_order.call_args_list[0][1]['price'] == expected
|
assert api_mock.create_order.call_args_list[0][1]['price'] == expected
|
||||||
assert api_mock.create_order.call_args_list[0][1]['params'] == {"stop-price": 220,
|
assert api_mock.create_order.call_args_list[0][1]['params'] == {"stopPrice": 220,
|
||||||
"operator": "lte",
|
"operator": "lte",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user