From 3f6eeda3f0e76627e9b62b672d59e7be46ef64f5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 24 Aug 2019 18:06:14 +0200 Subject: [PATCH 1/2] Reset stoploss_order_id when recreating fails --- freqtrade/freqtradebot.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e5ecef8bf..e88b9db6a 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -662,6 +662,7 @@ class FreqtradeBot(object): return False except DependencyException as exception: + trade.stoploss_order_id = None logger.warning('Unable to place a stoploss order on exchange: %s', exception) # If stoploss order is canceled for some reason we add it @@ -674,6 +675,7 @@ class FreqtradeBot(object): trade.stoploss_order_id = str(stoploss_order_id) return False except DependencyException as exception: + trade.stoploss_order_id = None logger.warning('Stoploss order was cancelled, ' 'but unable to recreate one: %s', exception) @@ -726,7 +728,8 @@ class FreqtradeBot(object): )['id'] trade.stoploss_order_id = str(stoploss_order_id) except DependencyException: - logger.exception(f"Could create trailing stoploss order " + trade.stoploss_order_id = None + logger.exception(f"Could not create trailing stoploss order " f"for pair {trade.pair}.") def _check_and_execute_sell(self, trade: Trade, sell_rate: float, From 365b9c3e9c0f74de5a2ad7eacabd1c325396788a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 24 Aug 2019 18:06:33 +0200 Subject: [PATCH 2/2] Add test to correctly handle unsuccessfull ordercreation --- freqtrade/tests/test_freqtradebot.py | 40 +++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/freqtrade/tests/test_freqtradebot.py b/freqtrade/tests/test_freqtradebot.py index 24d070d2d..dab7a9ff7 100644 --- a/freqtrade/tests/test_freqtradebot.py +++ b/freqtrade/tests/test_freqtradebot.py @@ -1112,6 +1112,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, # Third case: when stoploss was set but it was canceled for some reason # should set a stoploss immediately and return False + caplog.clear() trade.is_open = True trade.open_order_id = None trade.stoploss_order_id = 100 @@ -1127,6 +1128,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, # Fourth case: when stoploss is set and it is hit # should unset stoploss_order_id and return true # as a trade actually happened + caplog.clear() freqtrade.create_trades() trade = Trade.query.first() trade.is_open = True @@ -1152,6 +1154,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, ) freqtrade.handle_stoploss_on_exchange(trade) assert log_has('Unable to place a stoploss order on exchange: ', caplog) + assert trade.stoploss_order_id is None # Fifth case: get_order returns InvalidOrder # It should try to add stoploss order @@ -1163,6 +1166,41 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, assert stoploss_limit.call_count == 1 +def test_handle_sle_cancel_cant_recreate(mocker, default_conf, fee, caplog, + markets, limit_buy_order, limit_sell_order) -> None: + # Sixth case: stoploss order was cancelled but couldn't create new one + patch_RPCManager(mocker) + patch_exchange(mocker) + mocker.patch.multiple( + 'freqtrade.exchange.Exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.00001172, + 'ask': 0.00001173, + 'last': 0.00001172 + }), + buy=MagicMock(return_value={'id': limit_buy_order['id']}), + sell=MagicMock(return_value={'id': limit_sell_order['id']}), + get_fee=fee, + markets=PropertyMock(return_value=markets), + get_order=MagicMock(return_value={'status': 'canceled'}), + stoploss_limit=MagicMock(side_effect=DependencyException()), + ) + freqtrade = FreqtradeBot(default_conf) + patch_get_signal(freqtrade) + + freqtrade.create_trades() + trade = Trade.query.first() + trade.is_open = True + trade.open_order_id = '12345' + trade.stoploss_order_id = 100 + assert trade + + assert freqtrade.handle_stoploss_on_exchange(trade) is False + assert log_has_re(r'Stoploss order was cancelled, but unable to recreate one.*', caplog) + assert trade.stoploss_order_id is None + assert trade.is_open is True + + def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, markets, limit_buy_order, limit_sell_order) -> None: # When trailing stoploss is set @@ -1324,7 +1362,7 @@ def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, c mocker.patch("freqtrade.exchange.Exchange.stoploss_limit", side_effect=DependencyException()) freqtrade.handle_trailing_stoploss_on_exchange(trade, stoploss_order_hanging) assert cancel_mock.call_count == 1 - assert log_has_re(r"Could create trailing stoploss order for pair ETH/BTC\..*", caplog) + assert log_has_re(r"Could not create trailing stoploss order for pair ETH/BTC\..*", caplog) def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,