From 389feda65f6b25eb1344a3f37217793fc2a00129 Mon Sep 17 00:00:00 2001 From: Misagh Date: Tue, 2 Apr 2019 18:25:17 +0200 Subject: [PATCH 01/16] Invalid order exception added --- freqtrade/__init__.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/freqtrade/__init__.py b/freqtrade/__init__.py index 0d1ae9c26..30fed8c53 100644 --- a/freqtrade/__init__.py +++ b/freqtrade/__init__.py @@ -17,6 +17,14 @@ class OperationalException(BaseException): """ +class InvalidOrder(BaseException): + """ + This is returned when the order is not valid. Example: + If stoploss on exchange order is hit, then trying to cancel the order + should return this exception. + """ + + class TemporaryError(BaseException): """ Temporary network or exchange related error. From 99d256422e24fe39c7b3f0642dcec074b100daf3 Mon Sep 17 00:00:00 2001 From: Misagh Date: Tue, 2 Apr 2019 18:31:03 +0200 Subject: [PATCH 02/16] adding InvalidOrder to exchange --- freqtrade/exchange/exchange.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 011be58e5..2b7e41847 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -13,7 +13,8 @@ import ccxt import ccxt.async_support as ccxt_async from pandas import DataFrame -from freqtrade import constants, DependencyException, OperationalException, TemporaryError +from freqtrade import (constants, DependencyException, OperationalException, + TemporaryError, InvalidOrder) from freqtrade.data.converter import parse_ticker_dataframe logger = logging.getLogger(__name__) From 40df0dcf3d5653dc8aba3cf68f724480885b2a34 Mon Sep 17 00:00:00 2001 From: Misagh Date: Tue, 2 Apr 2019 18:45:18 +0200 Subject: [PATCH 03/16] tests fixed --- freqtrade/__init__.py | 2 +- freqtrade/exchange/exchange.py | 4 ++-- freqtrade/tests/exchange/test_exchange.py | 7 ++++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/freqtrade/__init__.py b/freqtrade/__init__.py index 30fed8c53..292613297 100644 --- a/freqtrade/__init__.py +++ b/freqtrade/__init__.py @@ -17,7 +17,7 @@ class OperationalException(BaseException): """ -class InvalidOrder(BaseException): +class InvalidOrderException(BaseException): """ This is returned when the order is not valid. Example: If stoploss on exchange order is hit, then trying to cancel the order diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 2b7e41847..7f4ab062c 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -14,7 +14,7 @@ import ccxt.async_support as ccxt_async from pandas import DataFrame from freqtrade import (constants, DependencyException, OperationalException, - TemporaryError, InvalidOrder) + TemporaryError, InvalidOrderException) from freqtrade.data.converter import parse_ticker_dataframe logger = logging.getLogger(__name__) @@ -608,7 +608,7 @@ class Exchange(object): try: return self._api.cancel_order(order_id, pair) except ccxt.InvalidOrder as e: - raise DependencyException( + raise InvalidOrderException( f'Could not cancel order. Message: {e}') except (ccxt.NetworkError, ccxt.ExchangeError) as e: raise TemporaryError( diff --git a/freqtrade/tests/exchange/test_exchange.py b/freqtrade/tests/exchange/test_exchange.py index eed16d39b..4deb74c67 100644 --- a/freqtrade/tests/exchange/test_exchange.py +++ b/freqtrade/tests/exchange/test_exchange.py @@ -11,7 +11,8 @@ import ccxt import pytest from pandas import DataFrame -from freqtrade import DependencyException, OperationalException, TemporaryError +from freqtrade import (DependencyException, OperationalException, + TemporaryError, InvalidOrderException) from freqtrade.exchange import Binance, Exchange, Kraken from freqtrade.exchange.exchange import API_RETRY_COUNT from freqtrade.resolvers.exchange_resolver import ExchangeResolver @@ -1233,11 +1234,11 @@ def test_cancel_order(default_conf, mocker, exchange_name): exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) assert exchange.cancel_order(order_id='_', pair='TKN/BTC') == 123 - with pytest.raises(DependencyException): + with pytest.raises(InvalidOrderException): api_mock.cancel_order = MagicMock(side_effect=ccxt.InvalidOrder) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) exchange.cancel_order(order_id='_', pair='TKN/BTC') - assert api_mock.cancel_order.call_count == API_RETRY_COUNT + 1 + assert api_mock.cancel_order.call_count == 1 ccxt_exceptionhandlers(mocker, default_conf, api_mock, exchange_name, "cancel_order", "cancel_order", From 54f11ad60388d5c9e3da5c90424174a914f1c00c Mon Sep 17 00:00:00 2001 From: Misagh Date: Tue, 2 Apr 2019 18:57:06 +0200 Subject: [PATCH 04/16] enriching TSL log --- freqtrade/freqtradebot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 55ef6f611..fca3e346d 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -745,8 +745,8 @@ class FreqtradeBot(object): update_beat = self.strategy.order_types.get('stoploss_on_exchange_interval', 60) if (datetime.utcnow() - trade.stoploss_last_update).total_seconds() > update_beat: # cancelling the current stoploss on exchange first - logger.info('Trailing stoploss: cancelling current stoploss on exchange ' - 'in order to add another one ...') + logger.info('Trailing stoploss: cancelling current stoploss on exchange (id:{%s})' + 'in order to add another one ...', order['id']) if self.exchange.cancel_order(order['id'], trade.pair): # creating the new one stoploss_order_id = self.exchange.stoploss_limit( From a363d443bfd38de6934e5d1d3beab020a9771d76 Mon Sep 17 00:00:00 2001 From: Misagh Date: Thu, 4 Apr 2019 17:13:54 +0200 Subject: [PATCH 05/16] stoploss on exchange canceled handled --- freqtrade/freqtradebot.py | 92 +++++++++++++++++++--------- freqtrade/tests/test_freqtradebot.py | 2 +- 2 files changed, 63 insertions(+), 31 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index fca3e346d..eeefaa6d8 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -690,46 +690,78 @@ class FreqtradeBot(object): is enabled. """ - result = False + logger.debug('Handling stoploss on exchange %s ...', trade) + try: - # If trade is open and the buy order is fulfilled but there is no stoploss, - # then we add a stoploss on exchange - if not trade.open_order_id and not trade.stoploss_order_id: - if self.edge: - stoploss = self.edge.stoploss(pair=trade.pair) - else: - stoploss = self.strategy.stoploss + # First we check if there is already a stoploss on exchange + stoploss_order = self.exchange.get_order(trade.stoploss_order_id, trade.pair) \ + if trade.stoploss_order_id else None + except DependencyException as exception: + logger.warning('Unable to fetch stoploss order: %s', exception) - stop_price = trade.open_rate * (1 + stoploss) - # limit price should be less than stop price. - # 0.99 is arbitrary here. - limit_price = stop_price * 0.99 + # If there open order id does not exist, + # it means buy order is fulfilled + buy_order_fulfilled = not trade.open_order_id + # Limit price threshold + # This is the limit price percentage below which you don't want to sell + # 0.99 is arbitrary here. + # As limit price should always be below price + limit_price_pct = 0.99 + + # If buy order is fulfilled but there is no stoploss, + # then we add a stoploss on exchange + if (buy_order_fulfilled and not stoploss_order): + if self.edge: + stoploss = self.edge.stoploss(pair=trade.pair) + else: + stoploss = self.strategy.stoploss + + stop_price = trade.open_rate * (1 + stoploss) + + # limit price should be less than stop price. + limit_price = stop_price * limit_price_pct + + try: stoploss_order_id = self.exchange.stoploss_limit( pair=trade.pair, amount=trade.amount, stop_price=stop_price, rate=limit_price )['id'] trade.stoploss_order_id = str(stoploss_order_id) trade.stoploss_last_update = datetime.now() + return False - # Or the trade open and there is already a stoploss on exchange. - # so we check if it is hit ... - elif trade.stoploss_order_id: - logger.debug('Handling stoploss on exchange %s ...', trade) - order = self.exchange.get_order(trade.stoploss_order_id, trade.pair) - if order['status'] == 'closed': - trade.sell_reason = SellType.STOPLOSS_ON_EXCHANGE.value - trade.update(order) - self.notify_sell(trade) - result = True - elif self.config.get('trailing_stop', False): - # if trailing stoploss is enabled we check if stoploss value has changed - # in which case we cancel stoploss order and put another one with new - # value immediately - self.handle_trailing_stoploss_on_exchange(trade, order) - except DependencyException as exception: - logger.warning('Unable to create stoploss order: %s', exception) - return result + except DependencyException as exception: + logger.warning('Unable to place a stoploss order on exchange: %s', exception) + + + # If stoploss order is canceled for some reason we add it + if stoploss_order and stoploss_order['status'] == 'canceled': + try: + stoploss_order_id = self.exchange.stoploss_limit( + pair=trade.pair, amount=trade.amount, + stop_price=trade.stop_loss, rate=trade.stop_loss * limit_price_pct + )['id'] + trade.stoploss_order_id = str(stoploss_order_id) + return False + except DependencyException as exception: + logger.warning('Stoploss order was cancelled, but unable to recreate one: %s', exception) + + # We check if stoploss order is fulfilled + if stoploss_order and stoploss_order['status'] == 'closed': + trade.sell_reason = SellType.STOPLOSS_ON_EXCHANGE.value + trade.update(stoploss_order) + self.notify_sell(trade) + return True + + # Finally we check if stoploss on exchange should be moved up because of trailing. + if stoploss_order and self.config.get('trailing_stop', False): + # if trailing stoploss is enabled we check if stoploss value has changed + # in which case we cancel stoploss order and put another one with new + # value immediately + self.handle_trailing_stoploss_on_exchange(trade, stoploss_order) + + return False def handle_trailing_stoploss_on_exchange(self, trade: Trade, order): """ diff --git a/freqtrade/tests/test_freqtradebot.py b/freqtrade/tests/test_freqtradebot.py index 416a085ad..3e8bdb001 100644 --- a/freqtrade/tests/test_freqtradebot.py +++ b/freqtrade/tests/test_freqtradebot.py @@ -1036,7 +1036,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, side_effect=DependencyException() ) freqtrade.handle_stoploss_on_exchange(trade) - assert log_has('Unable to create stoploss order: ', caplog.record_tuples) + assert log_has('Unable to place a stoploss order on exchange: ', caplog.record_tuples) def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, From 31fa857319e73fff1beb48c123f8f8a65edb25d0 Mon Sep 17 00:00:00 2001 From: Misagh Date: Thu, 4 Apr 2019 17:15:51 +0200 Subject: [PATCH 06/16] typo --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index eeefaa6d8..acff0761b 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -700,7 +700,7 @@ class FreqtradeBot(object): logger.warning('Unable to fetch stoploss order: %s', exception) - # If there open order id does not exist, + # If trade open order id does not exist, # it means buy order is fulfilled buy_order_fulfilled = not trade.open_order_id From 647534a4f81b42c0e5b944fc0aa992aea53b51c3 Mon Sep 17 00:00:00 2001 From: Misagh Date: Thu, 4 Apr 2019 17:17:21 +0200 Subject: [PATCH 07/16] flake8 --- freqtrade/freqtradebot.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index acff0761b..9bd3384fa 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -699,7 +699,6 @@ class FreqtradeBot(object): except DependencyException as exception: logger.warning('Unable to fetch stoploss order: %s', exception) - # If trade open order id does not exist, # it means buy order is fulfilled buy_order_fulfilled = not trade.open_order_id @@ -734,7 +733,6 @@ class FreqtradeBot(object): except DependencyException as exception: logger.warning('Unable to place a stoploss order on exchange: %s', exception) - # If stoploss order is canceled for some reason we add it if stoploss_order and stoploss_order['status'] == 'canceled': try: @@ -745,7 +743,8 @@ class FreqtradeBot(object): trade.stoploss_order_id = str(stoploss_order_id) return False except DependencyException as exception: - logger.warning('Stoploss order was cancelled, but unable to recreate one: %s', exception) + logger.warning('Stoploss order was cancelled, ' + 'but unable to recreate one: %s', exception) # We check if stoploss order is fulfilled if stoploss_order and stoploss_order['status'] == 'closed': From 7f4fd6168a272f190c4dcbf7ec65aae9a6e1ea98 Mon Sep 17 00:00:00 2001 From: Misagh Date: Thu, 4 Apr 2019 17:23:21 +0200 Subject: [PATCH 08/16] test for canceled SL on exchange added --- freqtrade/tests/test_freqtradebot.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/freqtrade/tests/test_freqtradebot.py b/freqtrade/tests/test_freqtradebot.py index 3e8bdb001..c854d99e8 100644 --- a/freqtrade/tests/test_freqtradebot.py +++ b/freqtrade/tests/test_freqtradebot.py @@ -1009,7 +1009,21 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, assert freqtrade.handle_stoploss_on_exchange(trade) is False assert trade.stoploss_order_id == 100 - # Third case: when stoploss is set and it is hit + # Third case: when stoploss was set but it was canceled for some reason + # should set a stoploss immediately and return False + trade.is_open = True + trade.open_order_id = None + trade.stoploss_order_id = 100 + + canceled_stoploss_order = MagicMock(return_value={'status': 'canceled'}) + mocker.patch('freqtrade.exchange.Exchange.get_order', canceled_stoploss_order) + stoploss_limit.reset_mock() + + assert freqtrade.handle_stoploss_on_exchange(trade) is False + assert stoploss_limit.call_count == 1 + assert trade.stoploss_order_id == "13434334" + + # Fourth case: when stoploss is set and it is hit # should unset stoploss_order_id and return true # as a trade actually happened freqtrade.create_trade() From 2b49a11b2add88895a3bd3f2f99189bd499b84a5 Mon Sep 17 00:00:00 2001 From: Misagh Date: Fri, 5 Apr 2019 19:46:43 +0200 Subject: [PATCH 09/16] returning InvalidOrder exception for get_order --- freqtrade/exchange/exchange.py | 4 ++-- freqtrade/tests/exchange/test_exchange.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 7f4ab062c..7880ce464 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -624,8 +624,8 @@ class Exchange(object): try: return self._api.fetch_order(order_id, pair) except ccxt.InvalidOrder as e: - raise DependencyException( - f'Could not get order. Message: {e}') + raise InvalidOrderException( + f'Tried to get an invalid order. Message: {e}') except (ccxt.NetworkError, ccxt.ExchangeError) as e: raise TemporaryError( f'Could not get order due to {e.__class__.__name__}. Message: {e}') diff --git a/freqtrade/tests/exchange/test_exchange.py b/freqtrade/tests/exchange/test_exchange.py index 4deb74c67..66bc47405 100644 --- a/freqtrade/tests/exchange/test_exchange.py +++ b/freqtrade/tests/exchange/test_exchange.py @@ -1261,11 +1261,11 @@ def test_get_order(default_conf, mocker, exchange_name): exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) assert exchange.get_order('X', 'TKN/BTC') == 456 - with pytest.raises(DependencyException): + with pytest.raises(InvalidOrderException): api_mock.fetch_order = MagicMock(side_effect=ccxt.InvalidOrder) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) exchange.get_order(order_id='_', pair='TKN/BTC') - assert api_mock.fetch_order.call_count == API_RETRY_COUNT + 1 + assert api_mock.fetch_order.call_count == 1 ccxt_exceptionhandlers(mocker, default_conf, api_mock, exchange_name, 'get_order', 'fetch_order', From 9712fb2d57669217523e797ec5ffd81796a02981 Mon Sep 17 00:00:00 2001 From: Misagh Date: Fri, 5 Apr 2019 19:49:02 +0200 Subject: [PATCH 10/16] removing unnecessary comment --- freqtrade/freqtradebot.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 9bd3384fa..a0725ad08 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -703,10 +703,7 @@ class FreqtradeBot(object): # it means buy order is fulfilled buy_order_fulfilled = not trade.open_order_id - # Limit price threshold - # This is the limit price percentage below which you don't want to sell - # 0.99 is arbitrary here. - # As limit price should always be below price + # Limit price threshold: As limit price should always be below price limit_price_pct = 0.99 # If buy order is fulfilled but there is no stoploss, From 25d8e93a90de924758d6298455b59e6facfb9e13 Mon Sep 17 00:00:00 2001 From: Misagh Date: Fri, 5 Apr 2019 19:53:15 +0200 Subject: [PATCH 11/16] remove unnecessary comment --- freqtrade/freqtradebot.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index a0725ad08..f04a39610 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -699,8 +699,7 @@ class FreqtradeBot(object): except DependencyException as exception: logger.warning('Unable to fetch stoploss order: %s', exception) - # If trade open order id does not exist, - # it means buy order is fulfilled + # If trade open order id does not exist: buy order is fulfilled buy_order_fulfilled = not trade.open_order_id # Limit price threshold: As limit price should always be below price From 54d068de44ce6a4bbb21a4ca08502d6dd1f77868 Mon Sep 17 00:00:00 2001 From: Misagh Date: Fri, 5 Apr 2019 20:20:16 +0200 Subject: [PATCH 12/16] missing test added --- freqtrade/freqtradebot.py | 9 +++++---- freqtrade/tests/test_freqtradebot.py | 11 ++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index f04a39610..3bab1758d 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -13,7 +13,7 @@ import arrow from requests.exceptions import RequestException import sdnotify -from freqtrade import (DependencyException, OperationalException, +from freqtrade import (DependencyException, OperationalException, InvalidOrderException, TemporaryError, __version__, constants, persistence) from freqtrade.data.converter import order_book_to_dataframe from freqtrade.data.dataprovider import DataProvider @@ -692,11 +692,13 @@ class FreqtradeBot(object): logger.debug('Handling stoploss on exchange %s ...', trade) + stoploss_order = None + try: # First we check if there is already a stoploss on exchange stoploss_order = self.exchange.get_order(trade.stoploss_order_id, trade.pair) \ if trade.stoploss_order_id else None - except DependencyException as exception: + except InvalidOrderException as exception: logger.warning('Unable to fetch stoploss order: %s', exception) # If trade open order id does not exist: buy order is fulfilled @@ -705,8 +707,7 @@ class FreqtradeBot(object): # Limit price threshold: As limit price should always be below price limit_price_pct = 0.99 - # If buy order is fulfilled but there is no stoploss, - # then we add a stoploss on exchange + # If buy order is fulfilled but there is no stoploss, we add a stoploss on exchange if (buy_order_fulfilled and not stoploss_order): if self.edge: stoploss = self.edge.stoploss(pair=trade.pair) diff --git a/freqtrade/tests/test_freqtradebot.py b/freqtrade/tests/test_freqtradebot.py index c854d99e8..5896e7cf9 100644 --- a/freqtrade/tests/test_freqtradebot.py +++ b/freqtrade/tests/test_freqtradebot.py @@ -12,7 +12,7 @@ import pytest import requests from freqtrade import (DependencyException, OperationalException, - TemporaryError, constants) + TemporaryError, InvalidOrderException, constants) from freqtrade.data.dataprovider import DataProvider from freqtrade.freqtradebot import FreqtradeBot from freqtrade.persistence import Trade @@ -1052,6 +1052,15 @@ 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.record_tuples) + #Fifth case: get_order returns InvalidOrder + # It should try to add stoploss order + trade.stoploss_order_id = 100 + stoploss_limit.reset_mock() + mocker.patch('freqtrade.exchange.Exchange.get_order', side_effect=InvalidOrderException()) + mocker.patch('freqtrade.exchange.Exchange.stoploss_limit', stoploss_limit) + freqtrade.handle_stoploss_on_exchange(trade) + assert stoploss_limit.call_count == 1 + def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, markets, limit_buy_order, limit_sell_order) -> None: From a505826ec92650af7d19a1d5a05f7fd09c82b956 Mon Sep 17 00:00:00 2001 From: Misagh Date: Fri, 5 Apr 2019 20:20:41 +0200 Subject: [PATCH 13/16] flake8 --- freqtrade/tests/test_freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/tests/test_freqtradebot.py b/freqtrade/tests/test_freqtradebot.py index 5896e7cf9..9687fe903 100644 --- a/freqtrade/tests/test_freqtradebot.py +++ b/freqtrade/tests/test_freqtradebot.py @@ -1052,7 +1052,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.record_tuples) - #Fifth case: get_order returns InvalidOrder + # Fifth case: get_order returns InvalidOrder # It should try to add stoploss order trade.stoploss_order_id = 100 stoploss_limit.reset_mock() From acb99a03e3f3e936865f16adb56657aeb8183ae1 Mon Sep 17 00:00:00 2001 From: Misagh Date: Fri, 5 Apr 2019 20:30:54 +0200 Subject: [PATCH 14/16] adding stoploss on exchange manual cancel note --- docs/configuration.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/configuration.md b/docs/configuration.md index 75843ef4a..f7e2a07f3 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -212,6 +212,10 @@ The below is the default which is used if this is not configured in either strat unsure of what you are doing. For more information about how stoploss works please read [the stoploss documentation](stoploss.md). +!!! Note + In case of stoploss on exchange if the stoploss is cancelled manually then + the bot would recreate one. + ### Understand order_time_in_force The `order_time_in_force` configuration parameter defines the policy by which the order is executed on the exchange. Three commonly used time in force are: From 41ff2a927650347a78f386abc57e387dadf15185 Mon Sep 17 00:00:00 2001 From: Misagh Date: Fri, 5 Apr 2019 20:40:44 +0200 Subject: [PATCH 15/16] TemporaryError removed --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 346bcfce3..009e039b3 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -12,7 +12,7 @@ import arrow from requests.exceptions import RequestException from freqtrade import (DependencyException, OperationalException, InvalidOrderException, - TemporaryError, __version__, constants, persistence) + __version__, constants, persistence) from freqtrade.data.converter import order_book_to_dataframe from freqtrade.data.dataprovider import DataProvider from freqtrade.edge import Edge From d294cab933ddaa49a00ae47ac33ae87d32754648 Mon Sep 17 00:00:00 2001 From: Misagh Date: Sat, 6 Apr 2019 20:27:03 +0200 Subject: [PATCH 16/16] adding order id to invalidorder exception message --- freqtrade/exchange/exchange.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 7880ce464..275b2123f 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -625,7 +625,7 @@ class Exchange(object): return self._api.fetch_order(order_id, pair) except ccxt.InvalidOrder as e: raise InvalidOrderException( - f'Tried to get an invalid order. Message: {e}') + f'Tried to get an invalid order (id: {order_id}). Message: {e}') except (ccxt.NetworkError, ccxt.ExchangeError) as e: raise TemporaryError( f'Could not get order due to {e.__class__.__name__}. Message: {e}')