Don't send double-notifications for stoploss fills
This commit is contained in:
parent
fecd5c582b
commit
8800a09770
@ -1361,6 +1361,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
|
|
||||||
# Updating wallets when order is closed
|
# Updating wallets when order is closed
|
||||||
if not trade.is_open:
|
if not trade.is_open:
|
||||||
|
if not stoploss_order:
|
||||||
self._notify_sell(trade, '', True)
|
self._notify_sell(trade, '', True)
|
||||||
self.protections.stop_per_pair(trade.pair)
|
self.protections.stop_per_pair(trade.pair)
|
||||||
self.protections.global_stop()
|
self.protections.global_stop()
|
||||||
|
@ -683,7 +683,7 @@ def test_telegram_forcesell_handle(default_conf, update, ticker, fee,
|
|||||||
context.args = ["1"]
|
context.args = ["1"]
|
||||||
telegram._forcesell(update=update, context=context)
|
telegram._forcesell(update=update, context=context)
|
||||||
|
|
||||||
assert msg_mock.call_count == 3
|
assert msg_mock.call_count == 4
|
||||||
last_msg = msg_mock.call_args_list[-1][0][0]
|
last_msg = msg_mock.call_args_list[-1][0][0]
|
||||||
assert {
|
assert {
|
||||||
'type': RPCMessageType.SELL_NOTIFICATION,
|
'type': RPCMessageType.SELL_NOTIFICATION,
|
||||||
@ -703,6 +703,7 @@ def test_telegram_forcesell_handle(default_conf, update, ticker, fee,
|
|||||||
'sell_reason': SellType.FORCE_SELL.value,
|
'sell_reason': SellType.FORCE_SELL.value,
|
||||||
'open_date': ANY,
|
'open_date': ANY,
|
||||||
'close_date': ANY,
|
'close_date': ANY,
|
||||||
|
'close_rate': ANY,
|
||||||
} == last_msg
|
} == last_msg
|
||||||
|
|
||||||
|
|
||||||
@ -743,7 +744,7 @@ def test_telegram_forcesell_down_handle(default_conf, update, ticker, fee,
|
|||||||
context.args = ["1"]
|
context.args = ["1"]
|
||||||
telegram._forcesell(update=update, context=context)
|
telegram._forcesell(update=update, context=context)
|
||||||
|
|
||||||
assert msg_mock.call_count == 3
|
assert msg_mock.call_count == 4
|
||||||
|
|
||||||
last_msg = msg_mock.call_args_list[-1][0][0]
|
last_msg = msg_mock.call_args_list[-1][0][0]
|
||||||
assert {
|
assert {
|
||||||
@ -764,6 +765,7 @@ def test_telegram_forcesell_down_handle(default_conf, update, ticker, fee,
|
|||||||
'sell_reason': SellType.FORCE_SELL.value,
|
'sell_reason': SellType.FORCE_SELL.value,
|
||||||
'open_date': ANY,
|
'open_date': ANY,
|
||||||
'close_date': ANY,
|
'close_date': ANY,
|
||||||
|
'close_rate': ANY,
|
||||||
} == last_msg
|
} == last_msg
|
||||||
|
|
||||||
|
|
||||||
@ -794,9 +796,9 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None
|
|||||||
context.args = ["all"]
|
context.args = ["all"]
|
||||||
telegram._forcesell(update=update, context=context)
|
telegram._forcesell(update=update, context=context)
|
||||||
|
|
||||||
# Called for each trade 3 times
|
# Called for each trade 4 times
|
||||||
assert msg_mock.call_count == 8
|
assert msg_mock.call_count == 12
|
||||||
msg = msg_mock.call_args_list[1][0][0]
|
msg = msg_mock.call_args_list[2][0][0]
|
||||||
assert {
|
assert {
|
||||||
'type': RPCMessageType.SELL_NOTIFICATION,
|
'type': RPCMessageType.SELL_NOTIFICATION,
|
||||||
'trade_id': 1,
|
'trade_id': 1,
|
||||||
@ -815,6 +817,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None
|
|||||||
'sell_reason': SellType.FORCE_SELL.value,
|
'sell_reason': SellType.FORCE_SELL.value,
|
||||||
'open_date': ANY,
|
'open_date': ANY,
|
||||||
'close_date': ANY,
|
'close_date': ANY,
|
||||||
|
'close_rate': ANY,
|
||||||
} == msg
|
} == msg
|
||||||
|
|
||||||
|
|
||||||
|
@ -1710,6 +1710,7 @@ def test_update_trade_state(mocker, default_conf, limit_buy_order, caplog) -> No
|
|||||||
open_rate=0.01,
|
open_rate=0.01,
|
||||||
open_date=arrow.utcnow().datetime,
|
open_date=arrow.utcnow().datetime,
|
||||||
amount=11,
|
amount=11,
|
||||||
|
exchange="binance",
|
||||||
)
|
)
|
||||||
assert not freqtrade.update_trade_state(trade, None)
|
assert not freqtrade.update_trade_state(trade, None)
|
||||||
assert log_has_re(r'Orderid for trade .* is empty.', caplog)
|
assert log_has_re(r'Orderid for trade .* is empty.', caplog)
|
||||||
@ -2262,7 +2263,7 @@ def test_check_handle_timedout_sell(default_conf, ticker, limit_sell_order_old,
|
|||||||
# check it does cancel sell orders over the time limit
|
# check it does cancel sell orders over the time limit
|
||||||
freqtrade.check_handle_timedout()
|
freqtrade.check_handle_timedout()
|
||||||
assert cancel_order_mock.call_count == 1
|
assert cancel_order_mock.call_count == 1
|
||||||
assert rpc_mock.call_count == 1
|
assert rpc_mock.call_count == 2
|
||||||
assert open_trade.is_open is True
|
assert open_trade.is_open is True
|
||||||
# Custom user sell-timeout is never called
|
# Custom user sell-timeout is never called
|
||||||
assert freqtrade.strategy.check_sell_timeout.call_count == 0
|
assert freqtrade.strategy.check_sell_timeout.call_count == 0
|
||||||
@ -2319,7 +2320,7 @@ def test_check_handle_timedout_partial(default_conf, ticker, limit_buy_order_old
|
|||||||
# note this is for a partially-complete buy order
|
# note this is for a partially-complete buy order
|
||||||
freqtrade.check_handle_timedout()
|
freqtrade.check_handle_timedout()
|
||||||
assert cancel_order_mock.call_count == 1
|
assert cancel_order_mock.call_count == 1
|
||||||
assert rpc_mock.call_count == 1
|
assert rpc_mock.call_count == 2
|
||||||
trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all()
|
trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all()
|
||||||
assert len(trades) == 1
|
assert len(trades) == 1
|
||||||
assert trades[0].amount == 23.0
|
assert trades[0].amount == 23.0
|
||||||
@ -2354,7 +2355,7 @@ def test_check_handle_timedout_partial_fee(default_conf, ticker, open_trade, cap
|
|||||||
assert log_has_re(r"Applying fee on amount for Trade.*", caplog)
|
assert log_has_re(r"Applying fee on amount for Trade.*", caplog)
|
||||||
|
|
||||||
assert cancel_order_mock.call_count == 1
|
assert cancel_order_mock.call_count == 1
|
||||||
assert rpc_mock.call_count == 1
|
assert rpc_mock.call_count == 2
|
||||||
trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all()
|
trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all()
|
||||||
assert len(trades) == 1
|
assert len(trades) == 1
|
||||||
# Verify that trade has been updated
|
# Verify that trade has been updated
|
||||||
@ -2394,7 +2395,7 @@ def test_check_handle_timedout_partial_except(default_conf, ticker, open_trade,
|
|||||||
assert log_has_re(r"Could not update trade amount: .*", caplog)
|
assert log_has_re(r"Could not update trade amount: .*", caplog)
|
||||||
|
|
||||||
assert cancel_order_mock.call_count == 1
|
assert cancel_order_mock.call_count == 1
|
||||||
assert rpc_mock.call_count == 1
|
assert rpc_mock.call_count == 2
|
||||||
trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all()
|
trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all()
|
||||||
assert len(trades) == 1
|
assert len(trades) == 1
|
||||||
# Verify that trade has been updated
|
# Verify that trade has been updated
|
||||||
@ -2639,6 +2640,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> N
|
|||||||
'sell_reason': SellType.ROI.value,
|
'sell_reason': SellType.ROI.value,
|
||||||
'open_date': ANY,
|
'open_date': ANY,
|
||||||
'close_date': ANY,
|
'close_date': ANY,
|
||||||
|
'close_rate': ANY,
|
||||||
} == last_msg
|
} == last_msg
|
||||||
|
|
||||||
|
|
||||||
@ -2689,6 +2691,7 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker)
|
|||||||
'sell_reason': SellType.STOP_LOSS.value,
|
'sell_reason': SellType.STOP_LOSS.value,
|
||||||
'open_date': ANY,
|
'open_date': ANY,
|
||||||
'close_date': ANY,
|
'close_date': ANY,
|
||||||
|
'close_rate': ANY,
|
||||||
} == last_msg
|
} == last_msg
|
||||||
|
|
||||||
|
|
||||||
@ -2746,7 +2749,7 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe
|
|||||||
'sell_reason': SellType.STOP_LOSS.value,
|
'sell_reason': SellType.STOP_LOSS.value,
|
||||||
'open_date': ANY,
|
'open_date': ANY,
|
||||||
'close_date': ANY,
|
'close_date': ANY,
|
||||||
|
'close_rate': ANY,
|
||||||
} == last_msg
|
} == last_msg
|
||||||
|
|
||||||
|
|
||||||
@ -2830,7 +2833,7 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke
|
|||||||
trade = Trade.query.first()
|
trade = Trade.query.first()
|
||||||
assert trade
|
assert trade
|
||||||
assert cancel_order.call_count == 1
|
assert cancel_order.call_count == 1
|
||||||
assert rpc_mock.call_count == 2
|
assert rpc_mock.call_count == 3
|
||||||
|
|
||||||
|
|
||||||
def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, fee,
|
def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, fee,
|
||||||
@ -2898,7 +2901,10 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f
|
|||||||
assert trade.stoploss_order_id is None
|
assert trade.stoploss_order_id is None
|
||||||
assert trade.is_open is False
|
assert trade.is_open is False
|
||||||
assert trade.sell_reason == SellType.STOPLOSS_ON_EXCHANGE.value
|
assert trade.sell_reason == SellType.STOPLOSS_ON_EXCHANGE.value
|
||||||
assert rpc_mock.call_count == 2
|
assert rpc_mock.call_count == 3
|
||||||
|
assert rpc_mock.call_args_list[0][0][0]['type'] == RPCMessageType.BUY_NOTIFICATION
|
||||||
|
assert rpc_mock.call_args_list[1][0][0]['type'] == RPCMessageType.BUY_FILL_NOTIFICATION
|
||||||
|
assert rpc_mock.call_args_list[2][0][0]['type'] == RPCMessageType.SELL_NOTIFICATION
|
||||||
|
|
||||||
|
|
||||||
def test_execute_sell_market_order(default_conf, ticker, fee,
|
def test_execute_sell_market_order(default_conf, ticker, fee,
|
||||||
@ -2932,7 +2938,7 @@ def test_execute_sell_market_order(default_conf, ticker, fee,
|
|||||||
assert not trade.is_open
|
assert not trade.is_open
|
||||||
assert trade.close_profit == 0.0620716
|
assert trade.close_profit == 0.0620716
|
||||||
|
|
||||||
assert rpc_mock.call_count == 2
|
assert rpc_mock.call_count == 3
|
||||||
last_msg = rpc_mock.call_args_list[-1][0][0]
|
last_msg = rpc_mock.call_args_list[-1][0][0]
|
||||||
assert {
|
assert {
|
||||||
'type': RPCMessageType.SELL_NOTIFICATION,
|
'type': RPCMessageType.SELL_NOTIFICATION,
|
||||||
@ -2952,6 +2958,7 @@ def test_execute_sell_market_order(default_conf, ticker, fee,
|
|||||||
'sell_reason': SellType.ROI.value,
|
'sell_reason': SellType.ROI.value,
|
||||||
'open_date': ANY,
|
'open_date': ANY,
|
||||||
'close_date': ANY,
|
'close_date': ANY,
|
||||||
|
'close_rate': ANY,
|
||||||
|
|
||||||
} == last_msg
|
} == last_msg
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user