Merge pull request #4992 from freqtrade/buy_partial_fill
Don't cancel low partial filled buy
This commit is contained in:
commit
df0928c8b5
@ -1045,6 +1045,16 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
|
|
||||||
# Cancelled orders may have the status of 'canceled' or 'closed'
|
# Cancelled orders may have the status of 'canceled' or 'closed'
|
||||||
if order['status'] not in ('cancelled', 'canceled', 'closed'):
|
if order['status'] not in ('cancelled', 'canceled', 'closed'):
|
||||||
|
filled_val = order.get('filled', 0.0) or 0.0
|
||||||
|
filled_stake = filled_val * trade.open_rate
|
||||||
|
minstake = self.exchange.get_min_pair_stake_amount(
|
||||||
|
trade.pair, trade.open_rate, self.strategy.stoploss)
|
||||||
|
|
||||||
|
if filled_val > 0 and filled_stake < minstake:
|
||||||
|
logger.warning(
|
||||||
|
f"Order {trade.open_order_id} for {trade.pair} not cancelled, "
|
||||||
|
f"as the filled amount of {filled_val} would result in an unsellable trade.")
|
||||||
|
return False
|
||||||
corder = self.exchange.cancel_order_with_result(trade.open_order_id, trade.pair,
|
corder = self.exchange.cancel_order_with_result(trade.open_order_id, trade.pair,
|
||||||
trade.amount)
|
trade.amount)
|
||||||
# Avoid race condition where the order could not be cancelled coz its already filled.
|
# Avoid race condition where the order could not be cancelled coz its already filled.
|
||||||
|
@ -2431,13 +2431,22 @@ def test_handle_cancel_buy(mocker, caplog, default_conf, limit_buy_order) -> Non
|
|||||||
freqtrade._notify_buy_cancel = MagicMock()
|
freqtrade._notify_buy_cancel = MagicMock()
|
||||||
|
|
||||||
trade = MagicMock()
|
trade = MagicMock()
|
||||||
trade.pair = 'LTC/ETH'
|
trade.pair = 'LTC/USDT'
|
||||||
|
trade.open_rate = 200
|
||||||
limit_buy_order['filled'] = 0.0
|
limit_buy_order['filled'] = 0.0
|
||||||
limit_buy_order['status'] = 'open'
|
limit_buy_order['status'] = 'open'
|
||||||
reason = CANCEL_REASON['TIMEOUT']
|
reason = CANCEL_REASON['TIMEOUT']
|
||||||
assert freqtrade.handle_cancel_buy(trade, limit_buy_order, reason)
|
assert freqtrade.handle_cancel_buy(trade, limit_buy_order, reason)
|
||||||
assert cancel_order_mock.call_count == 1
|
assert cancel_order_mock.call_count == 1
|
||||||
|
|
||||||
|
cancel_order_mock.reset_mock()
|
||||||
|
caplog.clear()
|
||||||
|
limit_buy_order['filled'] = 0.01
|
||||||
|
assert not freqtrade.handle_cancel_buy(trade, limit_buy_order, reason)
|
||||||
|
assert cancel_order_mock.call_count == 0
|
||||||
|
assert log_has_re("Order .* for .* not cancelled, as the filled amount.* unsellable.*", caplog)
|
||||||
|
|
||||||
|
caplog.clear()
|
||||||
cancel_order_mock.reset_mock()
|
cancel_order_mock.reset_mock()
|
||||||
limit_buy_order['filled'] = 2
|
limit_buy_order['filled'] = 2
|
||||||
assert not freqtrade.handle_cancel_buy(trade, limit_buy_order, reason)
|
assert not freqtrade.handle_cancel_buy(trade, limit_buy_order, reason)
|
||||||
@ -2492,7 +2501,8 @@ def test_handle_cancel_buy_corder_empty(mocker, default_conf, limit_buy_order,
|
|||||||
freqtrade._notify_buy_cancel = MagicMock()
|
freqtrade._notify_buy_cancel = MagicMock()
|
||||||
|
|
||||||
trade = MagicMock()
|
trade = MagicMock()
|
||||||
trade.pair = 'LTC/ETH'
|
trade.pair = 'LTC/USDT'
|
||||||
|
trade.open_rate = 200
|
||||||
limit_buy_order['filled'] = 0.0
|
limit_buy_order['filled'] = 0.0
|
||||||
limit_buy_order['status'] = 'open'
|
limit_buy_order['status'] = 'open'
|
||||||
reason = CANCEL_REASON['TIMEOUT']
|
reason = CANCEL_REASON['TIMEOUT']
|
||||||
|
Loading…
Reference in New Issue
Block a user