Repository: freqtrade/freqtrade

Issue:
Show the Trade ID in the Telegram message when an order is opened/closed.
## Describe the enhancement

Hi :)

I was thinking that it would be useful to have the Trade ID written somewhere in the Telegram message when a Trade is opened/closed.

The current message are something like that :

Buy :
```
Binance: Buying TFUEL/USDT
Amount: 1434.94033573
Open Rate: 0.08637600
Current Rate: 0.08637600
Total: (123.944406 USDT, 102.451 EUR)
```

Sell :
```
Binance: Selling TFUEL/USDT
Amount: 1434.94033573
Open Rate: 0.08637600
Current Rate: 0.08727900
Close Rate: 0.08727900
Sell Reason: trailing_stop_loss
Duration: 0:30:28 (30.5 min)
Profit: 0.84% (profit: 1.04656656 USDT / 0.865 EUR)
```

I think it's not needed to add a new line, so it probably makes sense to add it on the line of the symbol, like that :

Option 1:
```
Binance: Buying TFUEL/USDT (#14)
Binance: Selling TFUEL/USDT (#14)
```
Option 2:
```
Binance: Buying #14 - TFUEL/USDT
Binance: Selling #14 - TFUEL/USDT
```
Option 3:
```
Binance: Buying Trade ID 14 - TFUEL/USDT
Binance: Selling Trade ID 14 - TFUEL/USDT
```

Other ideas on how to write it ?

It should be easy to do, so I can make a PR for that, just let me know.

Thoughts ?



Discussion:
i'm personally not really convinced about the usefulness of this ... what difference does it make if it's trade id 14, or trade id 25 that's beeing bought currently?

if any, then the shortest (so 1 or 2) ... 

I don't see any useful case for this too.. adding this in every message would add in 99% of the cases useless information to the message. Whenever I want to remove a trade or forcesell I just use /status table to get the ID. And even if this was added I'd still use /status table since I'd probably have to scroll up in the chat to find the buy/sell message with the ID..
If it was useful I would gladly look in implementing this :D 
I understand that it might not be useful for most of the people, it's just that I had a specific case where I was trying to look at an historical data and I was trying to find what was the Trade ID of a specific trade that happened days ago.

How would you guys feel if we add an option in the telegram section of the config to allow user to eventually add more detail to the telegram messages ?

Like something like that :

```
    "telegram": {
        "enabled": false,
        "token": "your_telegram_token",
        "chat_id": "your_telegram_chat_id",
        "show_trades_ids": true
    },
```
:+1:  for this feature

It can be useful in some cases. For example, I wanted to query the database for a few interesting orders and then I realized there is no way to match an order from telegram to the database, unless you hit the /status button in the middle of the trade... 

Could also be useful for debugging and troubleshooting sometimes too.
> How would you guys feel if we add an option in the telegram section of the config to allow user to eventually add more detail to the telegram messages ?

as said, i'd prefer the "smallest" option (1 or 2).

Making it optional is ... kinda overengineered i'd think - while it might seem tempting at first (make everything optional ...), almost noone will care enough to actually change that setting, so it's probably time better spent elsewhere.

In the end, possibilities are quite high that you might change the default to disable this, only to regret it later should you EVER come across the need to use this - so while i'm not convinced about the need for this, i also don't think i'd change the default to disabled (simply because maybe it will come in handy at a later point).


Sounds good, then I will implement and test the option 1 on my side, and make a PR when ready :)

Resolving patch:
diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py
--- a/freqtrade/rpc/telegram.py
+++ b/freqtrade/rpc/telegram.py
@@ -193,7 +193,8 @@ def send_msg(self, msg: Dict[str, Any]) -> None:
             else:
                 msg['stake_amount_fiat'] = 0
 
-            message = (f"\N{LARGE BLUE CIRCLE} *{msg['exchange']}:* Buying {msg['pair']}\n"
+            message = (f"\N{LARGE BLUE CIRCLE} *{msg['exchange']}:* Buying {msg['pair']}"
+                       f" (#{msg['trade_id']})\n"
                        f"*Amount:* `{msg['amount']:.8f}`\n"
                        f"*Open Rate:* `{msg['limit']:.8f}`\n"
                        f"*Current Rate:* `{msg['current_rate']:.8f}`\n"
@@ -205,7 +206,8 @@ def send_msg(self, msg: Dict[str, Any]) -> None:
 
         elif msg['type'] == RPCMessageType.BUY_CANCEL_NOTIFICATION:
             message = ("\N{WARNING SIGN} *{exchange}:* "
-                       "Cancelling open buy Order for {pair}. Reason: {reason}.".format(**msg))
+                       "Cancelling open buy Order for {pair} (#{trade_id}). "
+                       "Reason: {reason}.".format(**msg))
 
         elif msg['type'] == RPCMessageType.SELL_NOTIFICATION:
             msg['amount'] = round(msg['amount'], 8)
@@ -216,7 +218,7 @@ def send_msg(self, msg: Dict[str, Any]) -> None:
 
             msg['emoji'] = self._get_sell_emoji(msg)
 
-            message = ("{emoji} *{exchange}:* Selling {pair}\n"
+            message = ("{emoji} *{exchange}:* Selling {pair} (#{trade_id})\n"
                        "*Amount:* `{amount:.8f}`\n"
                        "*Open Rate:* `{open_rate:.8f}`\n"
                        "*Current Rate:* `{current_rate:.8f}`\n"
@@ -236,7 +238,7 @@ def send_msg(self, msg: Dict[str, Any]) -> None:
 
         elif msg['type'] == RPCMessageType.SELL_CANCEL_NOTIFICATION:
             message = ("\N{WARNING SIGN} *{exchange}:* Cancelling Open Sell Order "
-                       "for {pair}. Reason: {reason}").format(**msg)
+                       "for {pair} (#{trade_id}). Reason: {reason}").format(**msg)
 
         elif msg['type'] == RPCMessageType.STATUS_NOTIFICATION:
             message = '*Status:* `{status}`'.format(**msg)


Test patch:
diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py
--- a/tests/rpc/test_rpc_telegram.py
+++ b/tests/rpc/test_rpc_telegram.py
@@ -1196,6 +1196,7 @@ def test_send_msg_buy_notification(default_conf, mocker, caplog) -> None:
 
     msg = {
         'type': RPCMessageType.BUY_NOTIFICATION,
+        'trade_id': 1,
         'exchange': 'Bittrex',
         'pair': 'ETH/BTC',
         'limit': 1.099e-05,
@@ -1212,7 +1213,7 @@ def test_send_msg_buy_notification(default_conf, mocker, caplog) -> None:
 
     telegram.send_msg(msg)
     assert msg_mock.call_args[0][0] \
-        == '\N{LARGE BLUE CIRCLE} *Bittrex:* Buying ETH/BTC\n' \
+        == '\N{LARGE BLUE CIRCLE} *Bittrex:* Buying ETH/BTC (#1)\n' \
            '*Amount:* `1333.33333333`\n' \
            '*Open Rate:* `0.00001099`\n' \
            '*Current Rate:* `0.00001099`\n' \
@@ -1240,12 +1241,14 @@ def test_send_msg_buy_cancel_notification(default_conf, mocker) -> None:
 
     telegram.send_msg({
         'type': RPCMessageType.BUY_CANCEL_NOTIFICATION,
+        'trade_id': 1,
         'exchange': 'Bittrex',
         'pair': 'ETH/BTC',
         'reason': CANCEL_REASON['TIMEOUT']
     })
     assert (msg_mock.call_args[0][0] == '\N{WARNING SIGN} *Bittrex:* '
-            'Cancelling open buy Order for ETH/BTC. Reason: cancelled due to timeout.')
+            'Cancelling open buy Order for ETH/BTC (#1). '
+            'Reason: cancelled due to timeout.')
 
 
 def test_send_msg_sell_notification(default_conf, mocker) -> None:
@@ -1256,6 +1259,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
     telegram._rpc._fiat_converter.convert_amount = lambda a, b, c: -24.812
     telegram.send_msg({
         'type': RPCMessageType.SELL_NOTIFICATION,
+        'trade_id': 1,
         'exchange': 'Binance',
         'pair': 'KEY/ETH',
         'gain': 'loss',
@@ -1273,7 +1277,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
         'close_date': arrow.utcnow(),
     })
     assert msg_mock.call_args[0][0] \
-        == ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH\n'
+        == ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH (#1)\n'
             '*Amount:* `1333.33333333`\n'
             '*Open Rate:* `0.00007500`\n'
             '*Current Rate:* `0.00003201`\n'
@@ -1285,6 +1289,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
     msg_mock.reset_mock()
     telegram.send_msg({
         'type': RPCMessageType.SELL_NOTIFICATION,
+        'trade_id': 1,
         'exchange': 'Binance',
         'pair': 'KEY/ETH',
         'gain': 'loss',
@@ -1301,7 +1306,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
         'close_date': arrow.utcnow(),
     })
     assert msg_mock.call_args[0][0] \
-        == ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH\n'
+        == ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH (#1)\n'
             '*Amount:* `1333.33333333`\n'
             '*Open Rate:* `0.00007500`\n'
             '*Current Rate:* `0.00003201`\n'
@@ -1321,23 +1326,26 @@ def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None:
     telegram._rpc._fiat_converter.convert_amount = lambda a, b, c: -24.812
     telegram.send_msg({
         'type': RPCMessageType.SELL_CANCEL_NOTIFICATION,
+        'trade_id': 1,
         'exchange': 'Binance',
         'pair': 'KEY/ETH',
         'reason': 'Cancelled on exchange'
     })
     assert msg_mock.call_args[0][0] \
-        == ('\N{WARNING SIGN} *Binance:* Cancelling Open Sell Order for KEY/ETH. '
-            'Reason: Cancelled on exchange')
+        == ('\N{WARNING SIGN} *Binance:* Cancelling Open Sell Order for KEY/ETH (#1).'
+            ' Reason: Cancelled on exchange')
 
     msg_mock.reset_mock()
     telegram.send_msg({
         'type': RPCMessageType.SELL_CANCEL_NOTIFICATION,
+        'trade_id': 1,
         'exchange': 'Binance',
         'pair': 'KEY/ETH',
         'reason': 'timeout'
     })
     assert msg_mock.call_args[0][0] \
-        == ('\N{WARNING SIGN} *Binance:* Cancelling Open Sell Order for KEY/ETH. Reason: timeout')
+        == ('\N{WARNING SIGN} *Binance:* Cancelling Open Sell Order for KEY/ETH (#1).'
+            ' Reason: timeout')
     # Reset singleton function to avoid random breaks
     telegram._rpc._fiat_converter.convert_amount = old_convamount
 
@@ -1384,6 +1392,7 @@ def test_send_msg_buy_notification_no_fiat(default_conf, mocker) -> None:
 
     telegram.send_msg({
         'type': RPCMessageType.BUY_NOTIFICATION,
+        'trade_id': 1,
         'exchange': 'Bittrex',
         'pair': 'ETH/BTC',
         'limit': 1.099e-05,
@@ -1396,7 +1405,7 @@ def test_send_msg_buy_notification_no_fiat(default_conf, mocker) -> None:
         'amount': 1333.3333333333335,
         'open_date': arrow.utcnow().shift(hours=-1)
     })
-    assert msg_mock.call_args[0][0] == ('\N{LARGE BLUE CIRCLE} *Bittrex:* Buying ETH/BTC\n'
+    assert msg_mock.call_args[0][0] == ('\N{LARGE BLUE CIRCLE} *Bittrex:* Buying ETH/BTC (#1)\n'
                                         '*Amount:* `1333.33333333`\n'
                                         '*Open Rate:* `0.00001099`\n'
                                         '*Current Rate:* `0.00001099`\n'
@@ -1409,6 +1418,7 @@ def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None:
 
     telegram.send_msg({
         'type': RPCMessageType.SELL_NOTIFICATION,
+        'trade_id': 1,
         'exchange': 'Binance',
         'pair': 'KEY/ETH',
         'gain': 'loss',
@@ -1425,7 +1435,7 @@ def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None:
         'open_date': arrow.utcnow().shift(hours=-2, minutes=-35, seconds=-3),
         'close_date': arrow.utcnow(),
     })
-    assert msg_mock.call_args[0][0] == ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH\n'
+    assert msg_mock.call_args[0][0] == ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH (#1)\n'
                                         '*Amount:* `1333.33333333`\n'
                                         '*Open Rate:* `0.00007500`\n'
                                         '*Current Rate:* `0.00003201`\n'