diff --git a/docs/webhook-config.md b/docs/webhook-config.md index 71524187a..e5509d6c9 100644 --- a/docs/webhook-config.md +++ b/docs/webhook-config.md @@ -66,6 +66,7 @@ Possible parameters are: * profit_fiat * stake_currency * fiat_currency +* sell_reason ### Webhookstatus diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index a73a2e98f..53c012a17 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -834,6 +834,7 @@ class FreqtradeBot(object): 'current_rate': current_rate, 'profit_amount': profit_trade, 'profit_percent': profit_percent, + 'sell_reason': sell_reason.value } # For regular case, when the configuration exists diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 55c5abef2..032593e9e 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -125,9 +125,9 @@ class Telegram(RPC): else: msg['stake_amount_fiat'] = 0 - message = "*{exchange}:* Buying [{pair}]({market_url})\n" \ - "with limit `{limit:.8f}\n" \ - "({stake_amount:.6f} {stake_currency}".format(**msg) + message = ("*{exchange}:* Buying [{pair}]({market_url})\n" + "with limit `{limit:.8f}\n" + "({stake_amount:.6f} {stake_currency}").format(**msg) if msg.get('fiat_currency', None): message += ",{stake_amount_fiat:.3f} {fiat_currency}".format(**msg) @@ -137,12 +137,13 @@ class Telegram(RPC): msg['amount'] = round(msg['amount'], 8) msg['profit_percent'] = round(msg['profit_percent'] * 100, 2) - message = "*{exchange}:* Selling [{pair}]({market_url})\n" \ - "*Limit:* `{limit:.8f}`\n" \ - "*Amount:* `{amount:.8f}`\n" \ - "*Open Rate:* `{open_rate:.8f}`\n" \ - "*Current Rate:* `{current_rate:.8f}`\n" \ - "*Profit:* `{profit_percent:.2f}%`".format(**msg) + message = ("*{exchange}:* Selling [{pair}]({market_url})\n" + "*Limit:* `{limit:.8f}`\n" + "*Amount:* `{amount:.8f}`\n" + "*Open Rate:* `{open_rate:.8f}`\n" + "*Current Rate:* `{current_rate:.8f}`\n" + "*Sell Reason:* `{sell_reason}`\n" + "*Profit:* `{profit_percent:.2f}%`").format(**msg) # Check if all sell properties are available. # This might not be the case if the message origin is triggered by /forcesell @@ -150,8 +151,8 @@ class Telegram(RPC): and self._fiat_converter): msg['profit_fiat'] = self._fiat_converter.convert_amount( msg['profit_amount'], msg['stake_currency'], msg['fiat_currency']) - message += '` ({gain}: {profit_amount:.8f} {stake_currency}`' \ - '` / {profit_fiat:.3f} {fiat_currency})`'.format(**msg) + message += ('` ({gain}: {profit_amount:.8f} {stake_currency}`' + '` / {profit_fiat:.3f} {fiat_currency})`').format(**msg) elif msg['type'] == RPCMessageType.STATUS_NOTIFICATION: message = '*Status:* `{status}`'.format(**msg) diff --git a/freqtrade/tests/rpc/test_rpc_telegram.py b/freqtrade/tests/rpc/test_rpc_telegram.py index a8e8bf003..900f583eb 100644 --- a/freqtrade/tests/rpc/test_rpc_telegram.py +++ b/freqtrade/tests/rpc/test_rpc_telegram.py @@ -17,6 +17,7 @@ from freqtrade.freqtradebot import FreqtradeBot from freqtrade.persistence import Trade from freqtrade.rpc import RPCMessageType from freqtrade.rpc.telegram import Telegram, authorized_only +from freqtrade.strategy.interface import SellType from freqtrade.state import State from freqtrade.tests.conftest import (get_patched_freqtradebot, log_has, patch_exchange) @@ -729,6 +730,7 @@ def test_forcesell_handle(default_conf, update, ticker, fee, 'profit_percent': 0.0611052, 'stake_currency': 'BTC', 'fiat_currency': 'USD', + 'sell_reason': SellType.FORCE_SELL.value } == last_msg @@ -782,6 +784,7 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee, 'profit_percent': -0.05478342, 'stake_currency': 'BTC', 'fiat_currency': 'USD', + 'sell_reason': SellType.FORCE_SELL.value } == last_msg @@ -827,6 +830,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, markets, mocker 'profit_percent': -0.00589291, 'stake_currency': 'BTC', 'fiat_currency': 'USD', + 'sell_reason': SellType.FORCE_SELL.value } == msg @@ -1127,16 +1131,18 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None: 'profit_amount': -0.05746268, 'profit_percent': -0.57405275, 'stake_currency': 'ETH', - 'fiat_currency': 'USD' + 'fiat_currency': 'USD', + 'sell_reason': SellType.STOP_LOSS.value }) assert msg_mock.call_args[0][0] \ - == '*Binance:* Selling [KEY/ETH]' \ - '(https://www.binance.com/tradeDetail.html?symbol=KEY_ETH)\n' \ - '*Limit:* `0.00003201`\n' \ - '*Amount:* `1333.33333333`\n' \ - '*Open Rate:* `0.00007500`\n' \ - '*Current Rate:* `0.00003201`\n' \ - '*Profit:* `-57.41%`` (loss: -0.05746268 ETH`` / -24.812 USD)`' + == ('*Binance:* Selling [KEY/ETH]' + '(https://www.binance.com/tradeDetail.html?symbol=KEY_ETH)\n' + '*Limit:* `0.00003201`\n' + '*Amount:* `1333.33333333`\n' + '*Open Rate:* `0.00007500`\n' + '*Current Rate:* `0.00003201`\n' + '*Sell Reason:* `stop_loss`\n' + '*Profit:* `-57.41%`` (loss: -0.05746268 ETH`` / -24.812 USD)`') msg_mock.reset_mock() telegram.send_msg({ @@ -1152,15 +1158,17 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None: 'profit_amount': -0.05746268, 'profit_percent': -0.57405275, 'stake_currency': 'ETH', + 'sell_reason': SellType.STOP_LOSS.value }) assert msg_mock.call_args[0][0] \ - == '*Binance:* Selling [KEY/ETH]' \ - '(https://www.binance.com/tradeDetail.html?symbol=KEY_ETH)\n' \ - '*Limit:* `0.00003201`\n' \ - '*Amount:* `1333.33333333`\n' \ - '*Open Rate:* `0.00007500`\n' \ - '*Current Rate:* `0.00003201`\n' \ - '*Profit:* `-57.41%`' + == ('*Binance:* Selling [KEY/ETH]' + '(https://www.binance.com/tradeDetail.html?symbol=KEY_ETH)\n' + '*Limit:* `0.00003201`\n' + '*Amount:* `1333.33333333`\n' + '*Open Rate:* `0.00007500`\n' + '*Current Rate:* `0.00003201`\n' + '*Sell Reason:* `stop_loss`\n' + '*Profit:* `-57.41%`') # Reset singleton function to avoid random breaks telegram._fiat_converter.convert_amount = old_convamount @@ -1278,7 +1286,8 @@ def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None: 'profit_amount': -0.05746268, 'profit_percent': -0.57405275, 'stake_currency': 'ETH', - 'fiat_currency': 'USD' + 'fiat_currency': 'USD', + 'sell_reason': SellType.STOP_LOSS.value }) assert msg_mock.call_args[0][0] \ == '*Binance:* Selling [KEY/ETH]' \ @@ -1287,6 +1296,7 @@ def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None: '*Amount:* `1333.33333333`\n' \ '*Open Rate:* `0.00007500`\n' \ '*Current Rate:* `0.00003201`\n' \ + '*Sell Reason:* `stop_loss`\n' \ '*Profit:* `-57.41%`' diff --git a/freqtrade/tests/rpc/test_rpc_webhook.py b/freqtrade/tests/rpc/test_rpc_webhook.py index bfe0416b0..002308815 100644 --- a/freqtrade/tests/rpc/test_rpc_webhook.py +++ b/freqtrade/tests/rpc/test_rpc_webhook.py @@ -7,6 +7,7 @@ from requests import RequestException from freqtrade.rpc import RPCMessageType from freqtrade.rpc.webhook import Webhook +from freqtrade.strategy.interface import SellType from freqtrade.tests.conftest import get_patched_freqtradebot, log_has @@ -80,6 +81,7 @@ def test_send_msg(default_conf, mocker): 'profit_amount': 0.001, 'profit_percent': 0.20, 'stake_currency': 'BTC', + 'sell_reason': SellType.STOP_LOSS.value } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 diff --git a/freqtrade/tests/test_freqtradebot.py b/freqtrade/tests/test_freqtradebot.py index a9b3ffc5d..be84829e2 100644 --- a/freqtrade/tests/test_freqtradebot.py +++ b/freqtrade/tests/test_freqtradebot.py @@ -1513,6 +1513,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, markets, moc 'profit_percent': 0.0611052, 'stake_currency': 'BTC', 'fiat_currency': 'USD', + 'sell_reason': SellType.ROI.value } == last_msg @@ -1559,6 +1560,7 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, markets, 'profit_percent': -0.05478342, 'stake_currency': 'BTC', 'fiat_currency': 'USD', + 'sell_reason': SellType.STOP_LOSS.value } == last_msg @@ -1613,6 +1615,8 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe 'profit_percent': -0.01493766, 'stake_currency': 'BTC', 'fiat_currency': 'USD', + 'sell_reason': SellType.STOP_LOSS.value + } == last_msg @@ -1781,6 +1785,8 @@ def test_execute_sell_without_conf_sell_up(default_conf, ticker, fee, 'current_rate': 1.172e-05, 'profit_amount': 6.126e-05, 'profit_percent': 0.0611052, + 'sell_reason': SellType.ROI.value + } == last_msg @@ -1827,6 +1833,7 @@ def test_execute_sell_without_conf_sell_down(default_conf, ticker, fee, 'current_rate': 1.044e-05, 'profit_amount': -5.492e-05, 'profit_percent': -0.05478342, + 'sell_reason': SellType.STOP_LOSS.value } == last_msg