use update_trade_state also for closed stoploss orders

This commit is contained in:
Matthias 2020-05-13 20:25:32 +02:00
parent 0c3bdd66ac
commit 60f26ba501
3 changed files with 36 additions and 30 deletions

View File

@ -752,7 +752,7 @@ class FreqtradeBot:
# We check if stoploss order is fulfilled
if stoploss_order and stoploss_order['status'] == 'closed':
trade.sell_reason = SellType.STOPLOSS_ON_EXCHANGE.value
trade.update(stoploss_order)
self.update_trade_state(trade, stoploss_order, sl_order=True)
# Lock pair for one candle to prevent immediate rebuys
self.strategy.lock_pair(trade.pair,
timeframe_to_next_date(self.config['ticker_interval']))
@ -1123,7 +1123,7 @@ class FreqtradeBot:
#
def update_trade_state(self, trade: Trade, action_order: dict = None,
order_amount: float = None) -> bool:
order_amount: float = None, sl_order: bool = False) -> bool:
"""
Checks trades with open orders and updates the amount if necessary
Handles closing both buy and sell orders.
@ -1131,34 +1131,37 @@ class FreqtradeBot:
"""
# Get order details for actual price per unit
if trade.open_order_id:
# Update trade with order values
logger.info('Found open order for %s', trade)
try:
order = action_order or self.exchange.get_order(trade.open_order_id, trade.pair)
except InvalidOrderException as exception:
logger.warning('Unable to fetch order %s: %s', trade.open_order_id, exception)
return False
# Try update amount (binance-fix)
try:
new_amount = self.get_real_amount(trade, order, order_amount)
if not isclose(order['amount'], new_amount, abs_tol=constants.MATH_CLOSE_PREC):
order['amount'] = new_amount
order.pop('filled', None)
trade.recalc_open_trade_price()
except DependencyException as exception:
logger.warning("Could not update trade amount: %s", exception)
order_id = trade.open_order_id
elif trade.stoploss_order_id and sl_order:
order_id = trade.stoploss_order_id
else:
return False
# Update trade with order values
logger.info('Found open order for %s', trade)
try:
order = action_order or self.exchange.get_order(order_id, trade.pair)
except InvalidOrderException as exception:
logger.warning('Unable to fetch order %s: %s', order_id, exception)
return False
# Try update amount (binance-fix)
try:
new_amount = self.get_real_amount(trade, order, order_amount)
if not isclose(order['amount'], new_amount, abs_tol=constants.MATH_CLOSE_PREC):
order['amount'] = new_amount
order.pop('filled', None)
trade.recalc_open_trade_price()
except DependencyException as exception:
logger.warning("Could not update trade amount: %s", exception)
if self.exchange.check_order_canceled_empty(order):
# Trade has been cancelled on exchange
# Handling of this will happen in check_handle_timeout.
return True
trade.update(order)
if self.exchange.check_order_canceled_empty(order):
# Trade has been cancelled on exchange
# Handling of this will happen in check_handle_timeout.
return True
trade.update(order)
# Updating wallets when order is closed
if not trade.is_open:
self.wallets.update()
return False
# Updating wallets when order is closed
if not trade.is_open:
self.wallets.update()
def apply_fee_conditional(self, trade: Trade, trade_base_currency: str,
amount: float, fee_abs: float) -> float:

View File

@ -1140,7 +1140,8 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog,
'status': 'closed',
'type': 'stop_loss_limit',
'price': 3,
'average': 2
'average': 2,
'amount': limit_buy_order['amount'],
})
mocker.patch('freqtrade.exchange.Exchange.get_order', stoploss_order_hit)
assert freqtrade.handle_stoploss_on_exchange(trade) is True

View File

@ -44,6 +44,8 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee,
}
stoploss_order_closed = stoploss_order_open.copy()
stoploss_order_closed['status'] = 'closed'
stoploss_order_closed['filled'] = stoploss_order_closed['amount']
# Sell first trade based on stoploss, keep 2nd and 3rd trade open
stoploss_order_mock = MagicMock(
side_effect=[stoploss_order_closed, stoploss_order_open, stoploss_order_open])
@ -98,7 +100,7 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee,
assert cancel_order_mock.call_count == 1
# Wallets must be updated between stoploss cancellation and selling, and will be updated again
# during update_trade_state
assert wallets_mock.call_count == 3
assert wallets_mock.call_count == 4
trade = trades[0]
assert trade.sell_reason == SellType.STOPLOSS_ON_EXCHANGE.value