Abstract creating stoploss-orders from stoploss-logic
This commit is contained in:
parent
a7e45c5a73
commit
f0c0f5618b
@ -617,6 +617,26 @@ class FreqtradeBot(object):
|
|||||||
logger.debug('Found no sell signal for %s.', trade)
|
logger.debug('Found no sell signal for %s.', trade)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def create_stoploss_order(self, trade: Trade, stop_price: float, rate: float) -> bool:
|
||||||
|
"""
|
||||||
|
Abstracts creating stoploss orders from the logic.
|
||||||
|
Handles errors and updates the trade database object.
|
||||||
|
:return: True if the order succeeded, and False in case of problems.
|
||||||
|
"""
|
||||||
|
# Limit price threshold: As limit price should always be below price
|
||||||
|
LIMIT_PRICE_PCT = 0.99
|
||||||
|
|
||||||
|
try:
|
||||||
|
stoploss_order = self.exchange.stoploss_limit(pair=trade.pair, amount=trade.amount,
|
||||||
|
stop_price=stop_price,
|
||||||
|
rate=rate * LIMIT_PRICE_PCT)
|
||||||
|
trade.stoploss_order_id = str(stoploss_order['id'])
|
||||||
|
return True
|
||||||
|
except DependencyException:
|
||||||
|
trade.stoploss_order_id = None
|
||||||
|
logger.exception('Unable to place a stoploss order on exchange.')
|
||||||
|
return False
|
||||||
|
|
||||||
def handle_stoploss_on_exchange(self, trade: Trade) -> bool:
|
def handle_stoploss_on_exchange(self, trade: Trade) -> bool:
|
||||||
"""
|
"""
|
||||||
Check if trade is fulfilled in which case the stoploss
|
Check if trade is fulfilled in which case the stoploss
|
||||||
@ -638,9 +658,6 @@ class FreqtradeBot(object):
|
|||||||
# If trade open order id does not exist: buy order is fulfilled
|
# If trade open order id does not exist: buy order is fulfilled
|
||||||
buy_order_fulfilled = not trade.open_order_id
|
buy_order_fulfilled = not trade.open_order_id
|
||||||
|
|
||||||
# Limit price threshold: As limit price should always be below price
|
|
||||||
limit_price_pct = 0.99
|
|
||||||
|
|
||||||
# If buy order is fulfilled but there is no stoploss, we add a stoploss on exchange
|
# If buy order is fulfilled but there is no stoploss, we add a stoploss on exchange
|
||||||
if (buy_order_fulfilled and not stoploss_order):
|
if (buy_order_fulfilled and not stoploss_order):
|
||||||
if self.edge:
|
if self.edge:
|
||||||
@ -650,34 +667,18 @@ class FreqtradeBot(object):
|
|||||||
|
|
||||||
stop_price = trade.open_rate * (1 + stoploss)
|
stop_price = trade.open_rate * (1 + stoploss)
|
||||||
|
|
||||||
# limit price should be less than stop price.
|
if self.create_stoploss_order(trade=trade, stop_price=stop_price, rate=stop_price):
|
||||||
limit_price = stop_price * limit_price_pct
|
|
||||||
|
|
||||||
try:
|
|
||||||
stoploss_order_id = self.exchange.stoploss_limit(
|
|
||||||
pair=trade.pair, amount=trade.amount, stop_price=stop_price, rate=limit_price
|
|
||||||
)['id']
|
|
||||||
trade.stoploss_order_id = str(stoploss_order_id)
|
|
||||||
trade.stoploss_last_update = datetime.now()
|
trade.stoploss_last_update = datetime.now()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
except DependencyException as exception:
|
|
||||||
trade.stoploss_order_id = None
|
|
||||||
logger.warning('Unable to place a stoploss order on exchange: %s', exception)
|
|
||||||
|
|
||||||
# If stoploss order is canceled for some reason we add it
|
# If stoploss order is canceled for some reason we add it
|
||||||
if stoploss_order and stoploss_order['status'] == 'canceled':
|
if stoploss_order and stoploss_order['status'] == 'canceled':
|
||||||
try:
|
if self.create_stoploss_order(trade=trade, stop_price=trade.stop_loss,
|
||||||
stoploss_order_id = self.exchange.stoploss_limit(
|
rate=trade.stop_loss):
|
||||||
pair=trade.pair, amount=trade.amount,
|
|
||||||
stop_price=trade.stop_loss, rate=trade.stop_loss * limit_price_pct
|
|
||||||
)['id']
|
|
||||||
trade.stoploss_order_id = str(stoploss_order_id)
|
|
||||||
return False
|
return False
|
||||||
except DependencyException as exception:
|
else:
|
||||||
trade.stoploss_order_id = None
|
trade.stoploss_order_id = None
|
||||||
logger.warning('Stoploss order was cancelled, '
|
logger.warning('Stoploss order was cancelled, but unable to recreate one.')
|
||||||
'but unable to recreate one: %s', exception)
|
|
||||||
|
|
||||||
# We check if stoploss order is fulfilled
|
# We check if stoploss order is fulfilled
|
||||||
if stoploss_order and stoploss_order['status'] == 'closed':
|
if stoploss_order and stoploss_order['status'] == 'closed':
|
||||||
@ -720,16 +721,12 @@ class FreqtradeBot(object):
|
|||||||
logger.exception(f"Could not cancel stoploss order {order['id']} "
|
logger.exception(f"Could not cancel stoploss order {order['id']} "
|
||||||
f"for pair {trade.pair}")
|
f"for pair {trade.pair}")
|
||||||
|
|
||||||
try:
|
# Create new stoploss order
|
||||||
# creating the new one
|
if self.create_stoploss_order(trade=trade, stop_price=trade.stop_loss,
|
||||||
stoploss_order_id = self.exchange.stoploss_limit(
|
rate=trade.stop_loss):
|
||||||
pair=trade.pair, amount=trade.amount,
|
return False
|
||||||
stop_price=trade.stop_loss, rate=trade.stop_loss * 0.99
|
else:
|
||||||
)['id']
|
logger.warning(f"Could not create trailing stoploss order "
|
||||||
trade.stoploss_order_id = str(stoploss_order_id)
|
|
||||||
except DependencyException:
|
|
||||||
trade.stoploss_order_id = None
|
|
||||||
logger.exception(f"Could not create trailing stoploss order "
|
|
||||||
f"for pair {trade.pair}.")
|
f"for pair {trade.pair}.")
|
||||||
|
|
||||||
def _check_and_execute_sell(self, trade: Trade, sell_rate: float,
|
def _check_and_execute_sell(self, trade: Trade, sell_rate: float,
|
||||||
|
@ -1153,7 +1153,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog,
|
|||||||
side_effect=DependencyException()
|
side_effect=DependencyException()
|
||||||
)
|
)
|
||||||
freqtrade.handle_stoploss_on_exchange(trade)
|
freqtrade.handle_stoploss_on_exchange(trade)
|
||||||
assert log_has('Unable to place a stoploss order on exchange: ', caplog)
|
assert log_has('Unable to place a stoploss order on exchange.', caplog)
|
||||||
assert trade.stoploss_order_id is None
|
assert trade.stoploss_order_id is None
|
||||||
|
|
||||||
# Fifth case: get_order returns InvalidOrder
|
# Fifth case: get_order returns InvalidOrder
|
||||||
|
Loading…
Reference in New Issue
Block a user