update_trade_state should take the order id directly - not from the trade object

This commit is contained in:
Matthias 2020-08-21 07:17:52 +02:00
parent 838985f6a0
commit 0b6014fae3
2 changed files with 22 additions and 25 deletions

View File

@ -242,7 +242,7 @@ class FreqtradeBot:
else: else:
fo = self.exchange.fetch_order(order.order_id, order.ft_pair) fo = self.exchange.fetch_order(order.order_id, order.ft_pair)
self.update_trade_state(order.trade, fo, sl_order=order.ft_order_side == 'stoploss') self.update_trade_state(order.trade, order.order_id, fo)
except ExchangeError: except ExchangeError:
logger.warning(f"Error updating {order.order_id}") logger.warning(f"Error updating {order.order_id}")
@ -272,7 +272,7 @@ class FreqtradeBot:
# No action for buy orders ... # No action for buy orders ...
continue continue
if fo: if fo:
self.update_trade_state(trade, fo, sl_order=order.ft_order_side == 'stoploss') self.update_trade_state(trade, order.order_id, fo)
except ExchangeError: except ExchangeError:
logger.warning(f"Error updating {order.order_id}") logger.warning(f"Error updating {order.order_id}")
@ -634,7 +634,7 @@ class FreqtradeBot:
# Update fees if order is closed # Update fees if order is closed
if order_status == 'closed': if order_status == 'closed':
self.update_trade_state(trade, order) self.update_trade_state(trade, order_id, order)
Trade.session.add(trade) Trade.session.add(trade)
Trade.session.flush() Trade.session.flush()
@ -878,7 +878,7 @@ class FreqtradeBot:
# We check if stoploss order is fulfilled # We check if stoploss order is fulfilled
if stoploss_order and stoploss_order['status'] in ('closed', 'triggered'): if stoploss_order and stoploss_order['status'] in ('closed', 'triggered'):
trade.sell_reason = SellType.STOPLOSS_ON_EXCHANGE.value trade.sell_reason = SellType.STOPLOSS_ON_EXCHANGE.value
self.update_trade_state(trade, stoploss_order, sl_order=True) self.update_trade_state(trade, trade.stoploss_order_id, stoploss_order)
# Lock pair for one candle to prevent immediate rebuys # Lock pair for one candle to prevent immediate rebuys
self.strategy.lock_pair(trade.pair, self.strategy.lock_pair(trade.pair,
timeframe_to_next_date(self.config['timeframe'])) timeframe_to_next_date(self.config['timeframe']))
@ -989,7 +989,7 @@ class FreqtradeBot:
logger.info('Cannot query order for %s due to %s', trade, traceback.format_exc()) logger.info('Cannot query order for %s due to %s', trade, traceback.format_exc())
continue continue
fully_cancelled = self.update_trade_state(trade, order) fully_cancelled = self.update_trade_state(trade, trade.open_order_id, order)
if (order['side'] == 'buy' and (order['status'] == 'open' or fully_cancelled) and ( if (order['side'] == 'buy' and (order['status'] == 'open' or fully_cancelled) and (
fully_cancelled fully_cancelled
@ -1070,7 +1070,7 @@ class FreqtradeBot:
# we need to fall back to the values from order if corder does not contain these keys. # we need to fall back to the values from order if corder does not contain these keys.
trade.amount = filled_amount trade.amount = filled_amount
trade.stake_amount = trade.amount * trade.open_rate trade.stake_amount = trade.amount * trade.open_rate
self.update_trade_state(trade, corder, trade.amount) self.update_trade_state(trade, trade.open_order_id, corder, trade.amount)
trade.open_order_id = None trade.open_order_id = None
logger.info('Partial buy order timeout for %s.', trade) logger.info('Partial buy order timeout for %s.', trade)
@ -1208,7 +1208,7 @@ class FreqtradeBot:
trade.sell_reason = sell_reason.value trade.sell_reason = sell_reason.value
# In case of market sell orders the order can be closed immediately # In case of market sell orders the order can be closed immediately
if order.get('status', 'unknown') == 'closed': if order.get('status', 'unknown') == 'closed':
self.update_trade_state(trade, order) self.update_trade_state(trade, trade.open_order_id, order)
Trade.session.flush() Trade.session.flush()
# Lock pair for one candle to prevent immediate rebuys # Lock pair for one candle to prevent immediate rebuys
@ -1305,20 +1305,17 @@ class FreqtradeBot:
# Common update trade state methods # Common update trade state methods
# #
def update_trade_state(self, trade: Trade, action_order: dict = None, def update_trade_state(self, trade: Trade, order_id: str, action_order: dict = None,
order_amount: float = None, sl_order: bool = False) -> bool: order_amount: float = None) -> bool:
""" """
Checks trades with open orders and updates the amount if necessary Checks trades with open orders and updates the amount if necessary
Handles closing both buy and sell orders. Handles closing both buy and sell orders.
:return: True if order has been cancelled without being filled partially, False otherwise :return: True if order has been cancelled without being filled partially, False otherwise
""" """
# Get order details for actual price per unit if not order_id:
if trade.open_order_id: logger.warning(f'Orderid for trade {trade} is empty.')
order_id = trade.open_order_id False
elif trade.stoploss_order_id and sl_order:
order_id = trade.stoploss_order_id
else:
return False
# Update trade with order values # Update trade with order values
logger.info('Found open order for %s', trade) logger.info('Found open order for %s', trade)
try: try:

View File

@ -1699,7 +1699,7 @@ def test_update_trade_state(mocker, default_conf, limit_buy_order, caplog) -> No
amount=11, amount=11,
) )
# Add datetime explicitly since sqlalchemy defaults apply only once written to database # Add datetime explicitly since sqlalchemy defaults apply only once written to database
freqtrade.update_trade_state(trade) freqtrade.update_trade_state(trade, '123')
# Test amount not modified by fee-logic # Test amount not modified by fee-logic
assert not log_has_re(r'Applying fee to .*', caplog) assert not log_has_re(r'Applying fee to .*', caplog)
assert trade.open_order_id is None assert trade.open_order_id is None
@ -1709,14 +1709,14 @@ def test_update_trade_state(mocker, default_conf, limit_buy_order, caplog) -> No
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', return_value=90.81) mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', return_value=90.81)
assert trade.amount != 90.81 assert trade.amount != 90.81
# test amount modified by fee-logic # test amount modified by fee-logic
freqtrade.update_trade_state(trade) freqtrade.update_trade_state(trade, '123')
assert trade.amount == 90.81 assert trade.amount == 90.81
assert trade.open_order_id is None assert trade.open_order_id is None
trade.is_open = True trade.is_open = True
trade.open_order_id = None trade.open_order_id = None
# Assert we call handle_trade() if trade is feasible for execution # Assert we call handle_trade() if trade is feasible for execution
freqtrade.update_trade_state(trade) freqtrade.update_trade_state(trade, '123')
assert log_has_re('Found open order for.*', caplog) assert log_has_re('Found open order for.*', caplog)
@ -1741,7 +1741,7 @@ def test_update_trade_state_withorderdict(default_conf, trades_for_order, limit_
open_order_id="123456", open_order_id="123456",
is_open=True, is_open=True,
) )
freqtrade.update_trade_state(trade, limit_buy_order) freqtrade.update_trade_state(trade, '123456', limit_buy_order)
assert trade.amount != amount assert trade.amount != amount
assert trade.amount == limit_buy_order['amount'] assert trade.amount == limit_buy_order['amount']
@ -1763,11 +1763,11 @@ def test_update_trade_state_withorderdict_rounding_fee(default_conf, trades_for_
open_rate=0.245441, open_rate=0.245441,
fee_open=fee.return_value, fee_open=fee.return_value,
fee_close=fee.return_value, fee_close=fee.return_value,
open_order_id="123456", open_order_id='123456',
is_open=True, is_open=True,
open_date=arrow.utcnow().datetime, open_date=arrow.utcnow().datetime,
) )
freqtrade.update_trade_state(trade, limit_buy_order) freqtrade.update_trade_state(trade, '123456', limit_buy_order)
assert trade.amount != amount assert trade.amount != amount
assert trade.amount == limit_buy_order['amount'] assert trade.amount == limit_buy_order['amount']
assert log_has_re(r'Applying fee on amount for .*', caplog) assert log_has_re(r'Applying fee on amount for .*', caplog)
@ -1787,7 +1787,7 @@ def test_update_trade_state_exception(mocker, default_conf,
'freqtrade.freqtradebot.FreqtradeBot.get_real_amount', 'freqtrade.freqtradebot.FreqtradeBot.get_real_amount',
side_effect=DependencyException() side_effect=DependencyException()
) )
freqtrade.update_trade_state(trade) freqtrade.update_trade_state(trade, trade.open_order_id)
assert log_has('Could not update trade amount: ', caplog) assert log_has('Could not update trade amount: ', caplog)
@ -1802,7 +1802,7 @@ def test_update_trade_state_orderexception(mocker, default_conf, caplog) -> None
# Test raise of OperationalException exception # Test raise of OperationalException exception
grm_mock = mocker.patch("freqtrade.freqtradebot.FreqtradeBot.get_real_amount", MagicMock()) grm_mock = mocker.patch("freqtrade.freqtradebot.FreqtradeBot.get_real_amount", MagicMock())
freqtrade.update_trade_state(trade) freqtrade.update_trade_state(trade, trade.open_order_id)
assert grm_mock.call_count == 0 assert grm_mock.call_count == 0
assert log_has(f'Unable to fetch order {trade.open_order_id}: ', caplog) assert log_has(f'Unable to fetch order {trade.open_order_id}: ', caplog)
@ -1834,7 +1834,7 @@ def test_update_trade_state_sell(default_conf, trades_for_order, limit_sell_orde
order = Order.parse_from_ccxt_object(limit_sell_order_open, 'LTC/ETH', 'sell') order = Order.parse_from_ccxt_object(limit_sell_order_open, 'LTC/ETH', 'sell')
trade.orders.append(order) trade.orders.append(order)
assert order.status == 'open' assert order.status == 'open'
freqtrade.update_trade_state(trade, limit_sell_order) freqtrade.update_trade_state(trade, trade.open_order_id, limit_sell_order)
assert trade.amount == limit_sell_order['amount'] assert trade.amount == limit_sell_order['amount']
# Wallet needs to be updated after closing a limit-sell order to reenable buying # Wallet needs to be updated after closing a limit-sell order to reenable buying
assert wallet_mock.call_count == 1 assert wallet_mock.call_count == 1