|
|
|
|
@ -926,12 +926,10 @@ def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog,
|
|
|
|
|
}),
|
|
|
|
|
create_order=MagicMock(side_effect=[
|
|
|
|
|
{'id': limit_buy_order_usdt['id']},
|
|
|
|
|
{'id': limit_sell_order_usdt['id']},
|
|
|
|
|
limit_sell_order_usdt,
|
|
|
|
|
# {'id': limit_sell_order_usdt['id']},
|
|
|
|
|
]),
|
|
|
|
|
get_fee=fee,
|
|
|
|
|
)
|
|
|
|
|
mocker.patch.multiple(
|
|
|
|
|
'freqtrade.exchange.Binance',
|
|
|
|
|
stoploss=stoploss
|
|
|
|
|
)
|
|
|
|
|
freqtrade = FreqtradeBot(default_conf_usdt)
|
|
|
|
|
@ -956,7 +954,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog,
|
|
|
|
|
trade.stoploss_order_id = 100
|
|
|
|
|
|
|
|
|
|
hanging_stoploss_order = MagicMock(return_value={'status': 'open'})
|
|
|
|
|
mocker.patch('freqtrade.exchange.Binance.fetch_stoploss_order', hanging_stoploss_order)
|
|
|
|
|
mocker.patch('freqtrade.exchange.Exchange.fetch_stoploss_order', hanging_stoploss_order)
|
|
|
|
|
|
|
|
|
|
assert freqtrade.handle_stoploss_on_exchange(trade) is False
|
|
|
|
|
assert trade.stoploss_order_id == 100
|
|
|
|
|
@ -969,7 +967,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog,
|
|
|
|
|
trade.stoploss_order_id = 100
|
|
|
|
|
|
|
|
|
|
canceled_stoploss_order = MagicMock(return_value={'status': 'canceled'})
|
|
|
|
|
mocker.patch('freqtrade.exchange.Binance.fetch_stoploss_order', canceled_stoploss_order)
|
|
|
|
|
mocker.patch('freqtrade.exchange.Exchange.fetch_stoploss_order', canceled_stoploss_order)
|
|
|
|
|
stoploss.reset_mock()
|
|
|
|
|
|
|
|
|
|
assert freqtrade.handle_stoploss_on_exchange(trade) is False
|
|
|
|
|
@ -1001,7 +999,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog,
|
|
|
|
|
'average': 2,
|
|
|
|
|
'amount': limit_buy_order_usdt['amount'],
|
|
|
|
|
})
|
|
|
|
|
mocker.patch('freqtrade.exchange.Binance.fetch_stoploss_order', stoploss_order_hit)
|
|
|
|
|
mocker.patch('freqtrade.exchange.Exchange.fetch_stoploss_order', stoploss_order_hit)
|
|
|
|
|
assert freqtrade.handle_stoploss_on_exchange(trade) is True
|
|
|
|
|
assert log_has_re(r'STOP_LOSS_LIMIT is hit for Trade\(id=1, .*\)\.', caplog)
|
|
|
|
|
assert trade.stoploss_order_id is None
|
|
|
|
|
@ -1009,7 +1007,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog,
|
|
|
|
|
caplog.clear()
|
|
|
|
|
|
|
|
|
|
mocker.patch(
|
|
|
|
|
'freqtrade.exchange.Binance.stoploss',
|
|
|
|
|
'freqtrade.exchange.Exchange.stoploss',
|
|
|
|
|
side_effect=ExchangeError()
|
|
|
|
|
)
|
|
|
|
|
trade.is_open = True
|
|
|
|
|
@ -1021,9 +1019,9 @@ def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog,
|
|
|
|
|
# It should try to add stoploss order
|
|
|
|
|
trade.stoploss_order_id = 100
|
|
|
|
|
stoploss.reset_mock()
|
|
|
|
|
mocker.patch('freqtrade.exchange.Binance.fetch_stoploss_order',
|
|
|
|
|
mocker.patch('freqtrade.exchange.Exchange.fetch_stoploss_order',
|
|
|
|
|
side_effect=InvalidOrderException())
|
|
|
|
|
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss)
|
|
|
|
|
mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss)
|
|
|
|
|
freqtrade.handle_stoploss_on_exchange(trade)
|
|
|
|
|
assert stoploss.call_count == 1
|
|
|
|
|
|
|
|
|
|
@ -1033,10 +1031,37 @@ def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog,
|
|
|
|
|
trade.is_open = False
|
|
|
|
|
stoploss.reset_mock()
|
|
|
|
|
mocker.patch('freqtrade.exchange.Exchange.fetch_order')
|
|
|
|
|
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss)
|
|
|
|
|
mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss)
|
|
|
|
|
assert freqtrade.handle_stoploss_on_exchange(trade) is False
|
|
|
|
|
assert stoploss.call_count == 0
|
|
|
|
|
|
|
|
|
|
# Seventh case: emergency exit triggered
|
|
|
|
|
# Trailing stop should not act anymore
|
|
|
|
|
stoploss_order_cancelled = MagicMock(side_effect=[{
|
|
|
|
|
'id': "100",
|
|
|
|
|
'status': 'canceled',
|
|
|
|
|
'type': 'stop_loss_limit',
|
|
|
|
|
'price': 3,
|
|
|
|
|
'average': 2,
|
|
|
|
|
'amount': limit_buy_order_usdt['amount'],
|
|
|
|
|
'info': {'stopPrice': 22},
|
|
|
|
|
}])
|
|
|
|
|
trade.stoploss_order_id = 100
|
|
|
|
|
trade.is_open = True
|
|
|
|
|
trade.stoploss_last_update = arrow.utcnow().shift(hours=-1).datetime
|
|
|
|
|
trade.stop_loss = 24
|
|
|
|
|
freqtrade.config['trailing_stop'] = True
|
|
|
|
|
stoploss = MagicMock(side_effect=InvalidOrderException())
|
|
|
|
|
|
|
|
|
|
mocker.patch('freqtrade.exchange.Exchange.cancel_stoploss_order_with_result',
|
|
|
|
|
side_effect=InvalidOrderException())
|
|
|
|
|
mocker.patch('freqtrade.exchange.Exchange.fetch_stoploss_order', stoploss_order_cancelled)
|
|
|
|
|
mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss)
|
|
|
|
|
assert freqtrade.handle_stoploss_on_exchange(trade) is False
|
|
|
|
|
assert trade.stoploss_order_id is None
|
|
|
|
|
assert trade.is_open is False
|
|
|
|
|
assert trade.sell_reason == str(SellType.EMERGENCY_SELL)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_handle_sle_cancel_cant_recreate(mocker, default_conf_usdt, fee, caplog,
|
|
|
|
|
limit_buy_order_usdt, limit_sell_order_usdt) -> None:
|
|
|
|
|
|