From e2bcaa4d7586228cb95a6358f73ebd0b8c254e78 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 12 Mar 2019 21:46:35 +0100 Subject: [PATCH 1/5] Set Requested_close_rate to stoploss when stoploss_on_exchange was hit --- freqtrade/persistence.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index f603b139f..10aff72ec 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -266,6 +266,7 @@ class Trade(_DECL_BASE): logger.info('%s_SELL has been fulfilled for %s.', order_type.upper(), self) elif order_type == 'stop_loss_limit': self.stoploss_order_id = None + self.close_rate_requested = self.stop_loss logger.info('STOP_LOSS_LIMIT is hit for %s.', self) self.close(order['average']) else: From 11cc33a982cbe801c564676b5082e6ec409bdf7d Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 12 Mar 2019 21:49:08 +0100 Subject: [PATCH 2/5] Refactor notify_sell to rpc_manager * Call sell_notify also when stoploss_on_exchange is hit fix #1653 --- freqtrade/freqtradebot.py | 34 +++------------------------------- freqtrade/rpc/rpc_manager.py | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index dce3136df..58888a4f8 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -512,6 +512,7 @@ class FreqtradeBot(object): except OperationalException as exception: logger.warning("Could not update trade amount: %s", exception) + # This handles both buy and sell orders! trade.update(order) if self.strategy.order_types.get('stoploss_on_exchange') and trade.is_open: @@ -657,6 +658,7 @@ class FreqtradeBot(object): if order['status'] == 'closed': trade.sell_reason = SellType.STOPLOSS_ON_EXCHANGE.value trade.update(order) + self.rpc.notify_sell(trade, self.config, trade.close_rate) result = True elif self.config.get('trailing_stop', False): # if trailing stoploss is enabled we check if stoploss value has changed @@ -846,35 +848,5 @@ class FreqtradeBot(object): trade.open_order_id = order_id trade.close_rate_requested = limit trade.sell_reason = sell_reason.value - - profit_trade = trade.calc_profit(rate=limit) - current_rate = self.exchange.get_ticker(trade.pair)['bid'] - profit_percent = trade.calc_profit_percent(limit) - gain = "profit" if profit_percent > 0 else "loss" - - msg = { - 'type': RPCMessageType.SELL_NOTIFICATION, - 'exchange': trade.exchange.capitalize(), - 'pair': trade.pair, - 'gain': gain, - 'limit': limit, - 'amount': trade.amount, - 'open_rate': trade.open_rate, - 'current_rate': current_rate, - 'profit_amount': profit_trade, - 'profit_percent': profit_percent, - 'sell_reason': sell_reason.value - } - - # For regular case, when the configuration exists - if 'stake_currency' in self.config and 'fiat_display_currency' in self.config: - stake_currency = self.config['stake_currency'] - fiat_currency = self.config['fiat_display_currency'] - msg.update({ - 'stake_currency': stake_currency, - 'fiat_currency': fiat_currency, - }) - - # Send the message - self.rpc.send_msg(msg) Trade.session.flush() + self.rpc.notify_sell(trade, self.config, self.exchange.get_ticker(trade.pair)['bid']) diff --git a/freqtrade/rpc/rpc_manager.py b/freqtrade/rpc/rpc_manager.py index bc69c97ad..7a3971356 100644 --- a/freqtrade/rpc/rpc_manager.py +++ b/freqtrade/rpc/rpc_manager.py @@ -2,8 +2,9 @@ This module contains class to manage RPC communications (Telegram, Slack, ...) """ import logging -from typing import List, Dict, Any +from typing import Any, Dict, List +from freqtrade.persistence import Trade from freqtrade.rpc import RPC, RPCMessageType logger = logging.getLogger(__name__) @@ -80,3 +81,35 @@ class RPCManager(object): 'status': f'Searching for {stake_currency} pairs to buy and sell ' f'based on {pairlist.short_desc()}' }) + + def notify_sell(self, trade: Trade, config, current_rate: float): + profit_trade = trade.calc_profit(rate=trade.close_rate_requested) + + profit_percent = trade.calc_profit_percent(trade.close_rate_requested) + gain = "profit" if profit_percent > 0 else "loss" + + msg = { + 'type': RPCMessageType.SELL_NOTIFICATION, + 'exchange': trade.exchange.capitalize(), + 'pair': trade.pair, + 'gain': gain, + 'limit': trade.close_rate_requested, + 'amount': trade.amount, + 'open_rate': trade.open_rate, + 'current_rate': current_rate, + 'profit_amount': profit_trade, + 'profit_percent': profit_percent, + 'sell_reason': trade.sell_reason + } + + # For regular case, when the configuration exists + if 'stake_currency' in config and 'fiat_display_currency' in config: + stake_currency = config['stake_currency'] + fiat_currency = config['fiat_display_currency'] + msg.update({ + 'stake_currency': stake_currency, + 'fiat_currency': fiat_currency, + }) + + # Send the message + self.send_msg(msg) From 9054165e8accf6339008e75a0dec56507e0a2585 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 12 Mar 2019 21:50:57 +0100 Subject: [PATCH 3/5] Adjust test, since rpc_message is now called on buy and sel --- 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 2f66a5153..bd40a063f 100644 --- a/freqtrade/tests/test_freqtradebot.py +++ b/freqtrade/tests/test_freqtradebot.py @@ -2105,7 +2105,7 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, assert trade.is_open is False print(trade.sell_reason) assert trade.sell_reason == SellType.STOPLOSS_ON_EXCHANGE.value - assert rpc_mock.call_count == 1 + assert rpc_mock.call_count == 2 def test_execute_sell_without_conf_sell_up(default_conf, ticker, fee, From 6b948cfc7eed65da52c24037ff4e12db04849e8a Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 12 Mar 2019 22:01:19 +0100 Subject: [PATCH 4/5] Don't move notify_sell to rpc_manager - it needs exchange stuff --- freqtrade/freqtradebot.py | 39 ++++++++++++++++++++++++++++++++++-- freqtrade/rpc/rpc_manager.py | 33 ------------------------------ 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 58888a4f8..f6662e062 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -658,7 +658,7 @@ class FreqtradeBot(object): if order['status'] == 'closed': trade.sell_reason = SellType.STOPLOSS_ON_EXCHANGE.value trade.update(order) - self.rpc.notify_sell(trade, self.config, trade.close_rate) + 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 @@ -849,4 +849,39 @@ class FreqtradeBot(object): trade.close_rate_requested = limit trade.sell_reason = sell_reason.value Trade.session.flush() - self.rpc.notify_sell(trade, self.config, self.exchange.get_ticker(trade.pair)['bid']) + self.notify_sell(trade) + + def notify_sell(self, trade: Trade): + """ + Sends rpc notification when a sell occured. + """ + profit_trade = trade.calc_profit(rate=trade.close_rate_requested) + current_rate = self.exchange.get_ticker(trade.pair)['bid'] + profit_percent = trade.calc_profit_percent(trade.close_rate_requested) + gain = "profit" if profit_percent > 0 else "loss" + + msg = { + 'type': RPCMessageType.SELL_NOTIFICATION, + 'exchange': trade.exchange.capitalize(), + 'pair': trade.pair, + 'gain': gain, + 'limit': trade.close_rate_requested, + 'amount': trade.amount, + 'open_rate': trade.open_rate, + 'current_rate': current_rate, + 'profit_amount': profit_trade, + 'profit_percent': profit_percent, + 'sell_reason': trade.sell_reason + } + + # For regular case, when the configuration exists + if 'stake_currency' in self.config and 'fiat_display_currency' in self.config: + stake_currency = self.config['stake_currency'] + fiat_currency = self.config['fiat_display_currency'] + msg.update({ + 'stake_currency': stake_currency, + 'fiat_currency': fiat_currency, + }) + + # Send the message + self.rpc.send_msg(msg) diff --git a/freqtrade/rpc/rpc_manager.py b/freqtrade/rpc/rpc_manager.py index 7a3971356..7f0d0a5d4 100644 --- a/freqtrade/rpc/rpc_manager.py +++ b/freqtrade/rpc/rpc_manager.py @@ -4,7 +4,6 @@ This module contains class to manage RPC communications (Telegram, Slack, ...) import logging from typing import Any, Dict, List -from freqtrade.persistence import Trade from freqtrade.rpc import RPC, RPCMessageType logger = logging.getLogger(__name__) @@ -81,35 +80,3 @@ class RPCManager(object): 'status': f'Searching for {stake_currency} pairs to buy and sell ' f'based on {pairlist.short_desc()}' }) - - def notify_sell(self, trade: Trade, config, current_rate: float): - profit_trade = trade.calc_profit(rate=trade.close_rate_requested) - - profit_percent = trade.calc_profit_percent(trade.close_rate_requested) - gain = "profit" if profit_percent > 0 else "loss" - - msg = { - 'type': RPCMessageType.SELL_NOTIFICATION, - 'exchange': trade.exchange.capitalize(), - 'pair': trade.pair, - 'gain': gain, - 'limit': trade.close_rate_requested, - 'amount': trade.amount, - 'open_rate': trade.open_rate, - 'current_rate': current_rate, - 'profit_amount': profit_trade, - 'profit_percent': profit_percent, - 'sell_reason': trade.sell_reason - } - - # For regular case, when the configuration exists - if 'stake_currency' in config and 'fiat_display_currency' in config: - stake_currency = config['stake_currency'] - fiat_currency = config['fiat_display_currency'] - msg.update({ - 'stake_currency': stake_currency, - 'fiat_currency': fiat_currency, - }) - - # Send the message - self.send_msg(msg) From 2bf5a3843da848d45669bd98b764991d62d476e3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 13 Mar 2019 19:41:58 +0100 Subject: [PATCH 5/5] Use close_rate for notification if available --- freqtrade/freqtradebot.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index f6662e062..2eecb5802 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -855,9 +855,10 @@ class FreqtradeBot(object): """ Sends rpc notification when a sell occured. """ - profit_trade = trade.calc_profit(rate=trade.close_rate_requested) + profit_rate = trade.close_rate if trade.close_rate else trade.close_rate_requested + profit_trade = trade.calc_profit(rate=profit_rate) current_rate = self.exchange.get_ticker(trade.pair)['bid'] - profit_percent = trade.calc_profit_percent(trade.close_rate_requested) + profit_percent = trade.calc_profit_percent(profit_rate) gain = "profit" if profit_percent > 0 else "loss" msg = {