From fdfa94bcc31b5fc751873ccfa943dc962a24a030 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Jun 2022 17:30:56 +0200 Subject: [PATCH] make discord notifications fully configurable. --- docs/assets/discord_notification.png | Bin 0 -> 48861 bytes docs/webhook-config.md | 49 +++++++++++++++++++++++ freqtrade/constants.py | 41 +++++++++++++++++++ freqtrade/rpc/discord.py | 57 +++++++++------------------ 4 files changed, 108 insertions(+), 39 deletions(-) create mode 100644 docs/assets/discord_notification.png diff --git a/docs/assets/discord_notification.png b/docs/assets/discord_notification.png new file mode 100644 index 0000000000000000000000000000000000000000..05a7705d7f599de625de31782344f98d93ccb17b GIT binary patch literal 48861 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 V+b%kpPX|ChQeyI=72gei{tsZlJYoO< literal 0 HcmV?d00001 diff --git a/docs/webhook-config.md b/docs/webhook-config.md index 5f5933b47..3677ebe89 100644 --- a/docs/webhook-config.md +++ b/docs/webhook-config.md @@ -239,3 +239,52 @@ Possible parameters are: The fields in `webhook.webhookstatus` are used for regular status messages (Started / Stopped / ...). Parameters are filled using string.format. The only possible value here is `{status}`. + +## Discord + +A special form of webhooks is available for discord. +You can configure this as follows: + +```json +"discord": { + "enabled": true, + "webhook_url": "https://discord.com/api/webhooks/", + "exit_fill": [ + {"Trade ID": "{trade_id}"}, + {"Exchange": "{exchange}"}, + {"Pair": "{pair}"}, + {"Direction": "{direction}"}, + {"Open rate": "{open_rate}"}, + {"Close rate": "{close_rate}"}, + {"Amount": "{amount}"}, + {"Open date": "{open_date:%Y-%m-%d %H:%M:%S}"}, + {"Close date": "{close_date:%Y-%m-%d %H:%M:%S}"}, + {"Profit": "{profit_amount} {stake_currency}"}, + {"Profitability": "{profit_ratio:.2%}"}, + {"Enter tag": "{enter_tag}"}, + {"Exit Reason": "{exit_reason}"}, + {"Strategy": "{strategy}"}, + {"Timeframe": "{timeframe}"}, + ], + "entry_fill": [ + {"Trade ID": "{trade_id}"}, + {"Exchange": "{exchange}"}, + {"Pair": "{pair}"}, + {"Direction": "{direction}"}, + {"Open rate": "{open_rate}"}, + {"Amount": "{amount}"}, + {"Open date": "{open_date:%Y-%m-%d %H:%M:%S}"}, + {"Enter tag": "{enter_tag}"}, + {"Strategy": "{strategy} {timeframe}"}, + ] +} +``` + + +The above represents the default (`exit_fill` and `entry_fill` are optional and will default to the above configuration) - modifications are obviously possible. + +Available fields correspond to the fields for webhooks and are documented in the corresponding webhook sections. + +The notifications will look as follows by default. + +![discord-notification](assets/discord_notification.png) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 9fbd70e42..18dbea259 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -336,6 +336,47 @@ CONF_SCHEMA = { 'webhookstatus': {'type': 'object'}, }, }, + 'discord': { + 'type': 'object', + 'properties': { + 'enabled': {'type': 'boolean'}, + 'webhook_url': {'type': 'string'}, + "exit_fill": { + 'type': 'array', 'items': {'type': 'object'}, + 'default': [ + {"Trade ID": "{trade_id}"}, + {"Exchange": "{exchange}"}, + {"Pair": "{pair}"}, + {"Direction": "{direction}"}, + {"Open rate": "{open_rate}"}, + {"Close rate": "{close_rate}"}, + {"Amount": "{amount}"}, + {"Open date": "{open_date:%Y-%m-%d %H:%M:%S}"}, + {"Close date": "{close_date:%Y-%m-%d %H:%M:%S}"}, + {"Profit": "{profit_amount} {stake_currency}"}, + {"Profitability": "{profit_ratio:.2%}"}, + {"Enter tag": "{enter_tag}"}, + {"Exit Reason": "{exit_reason}"}, + {"Strategy": "{strategy}"}, + {"Timeframe": "{timeframe}"}, + ] + }, + "entry_fill": { + 'type': 'array', 'items': {'type': 'object'}, + 'default': [ + {"Trade ID": "{trade_id}"}, + {"Exchange": "{exchange}"}, + {"Pair": "{pair}"}, + {"Direction": "{direction}"}, + {"Open rate": "{open_rate}"}, + {"Amount": "{amount}"}, + {"Open date": "{open_date:%Y-%m-%d %H:%M:%S}"}, + {"Enter tag": "{enter_tag}"}, + {"Strategy": "{strategy} {timeframe}"}, + ] + }, + } + }, 'api_server': { 'type': 'object', 'properties': { diff --git a/freqtrade/rpc/discord.py b/freqtrade/rpc/discord.py index 41185a090..9509b4f23 100644 --- a/freqtrade/rpc/discord.py +++ b/freqtrade/rpc/discord.py @@ -1,8 +1,7 @@ import logging from typing import Any, Dict -from freqtrade.constants import DATETIME_PRINT_FORMAT -from freqtrade.enums import RPCMessageType +from freqtrade.enums.rpcmessagetype import RPCMessageType from freqtrade.rpc import RPC from freqtrade.rpc.webhook import Webhook @@ -33,46 +32,26 @@ class Discord(Webhook): def send_msg(self, msg) -> None: logger.info(f"Sending discord message: {msg}") - # TODO: handle other message types - if msg['type'] == RPCMessageType.EXIT_FILL: - profit_ratio = msg.get('profit_ratio') - open_date = msg.get('open_date').strftime(DATETIME_PRINT_FORMAT) - close_date = msg.get('close_date').strftime( - DATETIME_PRINT_FORMAT) if msg.get('close_date') else '' + if msg['type'].value in self.config['discord']: + + msg['strategy'] = self.strategy + msg['timeframe'] = self.timeframe + fields = self.config['discord'].get(msg['type'].value) + color = 0x0000FF + if msg['type'] in (RPCMessageType.EXIT, RPCMessageType.EXIT_FILL): + profit_ratio = msg.get('profit_ratio') + color = (0x00FF00 if profit_ratio > 0 else 0xFF0000) embeds = [{ - 'title': '{} Trade: {}'.format( - 'Profit' if profit_ratio > 0 else 'Loss', - msg.get('pair')), - 'color': (0x00FF00 if profit_ratio > 0 else 0xFF0000), - 'fields': [ - {'name': 'Trade ID', 'value': msg.get('trade_id'), 'inline': True}, - {'name': 'Exchange', 'value': msg.get('exchange').capitalize(), 'inline': True}, - {'name': 'Pair', 'value': msg.get('pair'), 'inline': True}, - {'name': 'Direction', 'value': 'Short' if msg.get( - 'is_short') else 'Long', 'inline': True}, - {'name': 'Open rate', 'value': msg.get('open_rate'), 'inline': True}, - {'name': 'Close rate', 'value': msg.get('close_rate'), 'inline': True}, - {'name': 'Amount', 'value': msg.get('amount'), 'inline': True}, - {'name': 'Open order', 'value': msg.get('open_order_id'), 'inline': True}, - {'name': 'Open date', 'value': open_date, 'inline': True}, - {'name': 'Close date', 'value': close_date, 'inline': True}, - {'name': 'Profit', 'value': msg.get('profit_amount'), 'inline': True}, - {'name': 'Profitability', 'value': f'{profit_ratio:.2%}', 'inline': True}, - {'name': 'Stake currency', 'value': msg.get('stake_currency'), 'inline': True}, - {'name': 'Fiat currency', 'value': msg.get('fiat_display_currency'), - 'inline': True}, - {'name': 'Buy Tag', 'value': msg.get('enter_tag'), 'inline': True}, - {'name': 'Sell Reason', 'value': msg.get('exit_reason'), 'inline': True}, - {'name': 'Strategy', 'value': self.strategy, 'inline': True}, - {'name': 'Timeframe', 'value': self.timeframe, 'inline': True}, - ], - }] + 'title': f"Trade: {msg['pair']} {msg['type'].value}", + 'color': color, + 'fields': [], - # convert all value in fields to string for discord - for embed in embeds: - for field in embed['fields']: # type: ignore - field['value'] = str(field['value']) + }] + for f in fields: + for k, v in f.items(): + v = v.format(**msg) + embeds[0]['fields'].append({'name': k, 'value': v, 'inline': True}) # Send the message to discord channel payload = {'embeds': embeds}