rename RPC message types

This commit is contained in:
Matthias 2021-04-20 06:41:58 +02:00
parent 8800a09770
commit 0341ac5a55
9 changed files with 128 additions and 125 deletions

View File

@ -113,7 +113,7 @@ class FreqtradeBot(LoggingMixin):
via RPC about changes in the bot status. via RPC about changes in the bot status.
""" """
self.rpc.send_msg({ self.rpc.send_msg({
'type': RPCMessageType.STATUS_NOTIFICATION, 'type': RPCMessageType.STATUS,
'status': msg 'status': msg
}) })
@ -205,7 +205,7 @@ class FreqtradeBot(LoggingMixin):
if len(open_trades) != 0: if len(open_trades) != 0:
msg = { msg = {
'type': RPCMessageType.WARNING_NOTIFICATION, 'type': RPCMessageType.WARNING,
'status': f"{len(open_trades)} open trades active.\n\n" 'status': f"{len(open_trades)} open trades active.\n\n"
f"Handle these trades manually on {self.exchange.name}, " f"Handle these trades manually on {self.exchange.name}, "
f"or '/start' the bot again and use '/stopbuy' " f"or '/start' the bot again and use '/stopbuy' "
@ -634,7 +634,7 @@ class FreqtradeBot(LoggingMixin):
""" """
msg = { msg = {
'trade_id': trade.id, 'trade_id': trade.id,
'type': RPCMessageType.BUY_NOTIFICATION, 'type': RPCMessageType.BUY,
'exchange': self.exchange.name.capitalize(), 'exchange': self.exchange.name.capitalize(),
'pair': trade.pair, 'pair': trade.pair,
'limit': trade.open_rate, 'limit': trade.open_rate,
@ -658,7 +658,7 @@ class FreqtradeBot(LoggingMixin):
msg = { msg = {
'trade_id': trade.id, 'trade_id': trade.id,
'type': RPCMessageType.BUY_CANCEL_NOTIFICATION, 'type': RPCMessageType.BUY_CANCEL,
'exchange': self.exchange.name.capitalize(), 'exchange': self.exchange.name.capitalize(),
'pair': trade.pair, 'pair': trade.pair,
'limit': trade.open_rate, 'limit': trade.open_rate,
@ -678,7 +678,7 @@ class FreqtradeBot(LoggingMixin):
def _notify_buy_fill(self, trade: Trade) -> None: def _notify_buy_fill(self, trade: Trade) -> None:
msg = { msg = {
'trade_id': trade.id, 'trade_id': trade.id,
'type': RPCMessageType.BUY_FILL_NOTIFICATION, 'type': RPCMessageType.BUY_FILL,
'exchange': self.exchange.name.capitalize(), 'exchange': self.exchange.name.capitalize(),
'pair': trade.pair, 'pair': trade.pair,
'open_rate': trade.open_rate, 'open_rate': trade.open_rate,
@ -1239,8 +1239,8 @@ class FreqtradeBot(LoggingMixin):
gain = "profit" if profit_ratio > 0 else "loss" gain = "profit" if profit_ratio > 0 else "loss"
msg = { msg = {
'type': (RPCMessageType.SELL_FILL_NOTIFICATION if fill 'type': (RPCMessageType.SELL_FILL if fill
else RPCMessageType.SELL_NOTIFICATION), else RPCMessageType.SELL),
'trade_id': trade.id, 'trade_id': trade.id,
'exchange': trade.exchange.capitalize(), 'exchange': trade.exchange.capitalize(),
'pair': trade.pair, 'pair': trade.pair,
@ -1284,7 +1284,7 @@ class FreqtradeBot(LoggingMixin):
gain = "profit" if profit_ratio > 0 else "loss" gain = "profit" if profit_ratio > 0 else "loss"
msg = { msg = {
'type': RPCMessageType.SELL_CANCEL_NOTIFICATION, 'type': RPCMessageType.SELL_CANCEL,
'trade_id': trade.id, 'trade_id': trade.id,
'exchange': trade.exchange.capitalize(), 'exchange': trade.exchange.capitalize(),
'pair': trade.pair, 'pair': trade.pair,

View File

@ -31,15 +31,15 @@ logger = logging.getLogger(__name__)
class RPCMessageType(Enum): class RPCMessageType(Enum):
STATUS_NOTIFICATION = 'status' STATUS = 'status'
WARNING_NOTIFICATION = 'warning' WARNING = 'warning'
STARTUP_NOTIFICATION = 'startup' STARTUP = 'startup'
BUY_NOTIFICATION = 'buy' BUY = 'buy'
BUY_FILL_NOTIFICATION = 'buy_fill' BUY_FILL = 'buy_fill'
BUY_CANCEL_NOTIFICATION = 'buy_cancel' BUY_CANCEL = 'buy_cancel'
SELL_NOTIFICATION = 'sell' SELL = 'sell'
SELL_FILL_NOTIFICATION = 'sell_fill' SELL_FILL = 'sell_fill'
SELL_CANCEL_NOTIFICATION = 'sell_cancel' SELL_CANCEL = 'sell_cancel'
def __repr__(self): def __repr__(self):
return self.value return self.value

View File

@ -67,7 +67,7 @@ class RPCManager:
def startup_messages(self, config: Dict[str, Any], pairlist, protections) -> None: def startup_messages(self, config: Dict[str, Any], pairlist, protections) -> None:
if config['dry_run']: if config['dry_run']:
self.send_msg({ self.send_msg({
'type': RPCMessageType.WARNING_NOTIFICATION, 'type': RPCMessageType.WARNING,
'status': 'Dry run is enabled. All trades are simulated.' 'status': 'Dry run is enabled. All trades are simulated.'
}) })
stake_currency = config['stake_currency'] stake_currency = config['stake_currency']
@ -79,7 +79,7 @@ class RPCManager:
exchange_name = config['exchange']['name'] exchange_name = config['exchange']['name']
strategy_name = config.get('strategy', '') strategy_name = config.get('strategy', '')
self.send_msg({ self.send_msg({
'type': RPCMessageType.STARTUP_NOTIFICATION, 'type': RPCMessageType.STARTUP,
'status': f'*Exchange:* `{exchange_name}`\n' 'status': f'*Exchange:* `{exchange_name}`\n'
f'*Stake per trade:* `{stake_amount} {stake_currency}`\n' f'*Stake per trade:* `{stake_amount} {stake_currency}`\n'
f'*Minimum ROI:* `{minimal_roi}`\n' f'*Minimum ROI:* `{minimal_roi}`\n'
@ -88,13 +88,13 @@ class RPCManager:
f'*Strategy:* `{strategy_name}`' f'*Strategy:* `{strategy_name}`'
}) })
self.send_msg({ self.send_msg({
'type': RPCMessageType.STARTUP_NOTIFICATION, 'type': RPCMessageType.STARTUP,
'status': f'Searching for {stake_currency} pairs to buy and sell ' 'status': f'Searching for {stake_currency} pairs to buy and sell '
f'based on {pairlist.short_desc()}' f'based on {pairlist.short_desc()}'
}) })
if len(protections.name_list) > 0: if len(protections.name_list) > 0:
prots = '\n'.join([p for prot in protections.short_desc() for k, p in prot.items()]) prots = '\n'.join([p for prot in protections.short_desc() for k, p in prot.items()])
self.send_msg({ self.send_msg({
'type': RPCMessageType.STARTUP_NOTIFICATION, 'type': RPCMessageType.STARTUP,
'status': f'Using Protections: \n{prots}' 'status': f'Using Protections: \n{prots}'
}) })

View File

@ -176,6 +176,53 @@ class Telegram(RPCHandler):
""" """
self._updater.stop() self._updater.stop()
def _format_buy_msg(self, msg: Dict[str, Any]) -> str:
if self._rpc._fiat_converter:
msg['stake_amount_fiat'] = self._rpc._fiat_converter.convert_amount(
msg['stake_amount'], msg['stake_currency'], msg['fiat_currency'])
else:
msg['stake_amount_fiat'] = 0
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"
f"*Total:* `({round_coin_value(msg['stake_amount'], msg['stake_currency'])}")
if msg.get('fiat_currency', None):
message += f", {round_coin_value(msg['stake_amount_fiat'], msg['fiat_currency'])}"
message += ")`"
return message
def _format_sell_msg(self, msg: Dict[str, Any]) -> str:
msg['amount'] = round(msg['amount'], 8)
msg['profit_percent'] = round(msg['profit_ratio'] * 100, 2)
msg['duration'] = msg['close_date'].replace(
microsecond=0) - msg['open_date'].replace(microsecond=0)
msg['duration_min'] = msg['duration'].total_seconds() / 60
msg['emoji'] = self._get_sell_emoji(msg)
message = ("{emoji} *{exchange}:* Selling {pair} (#{trade_id})\n"
"*Amount:* `{amount:.8f}`\n"
"*Open Rate:* `{open_rate:.8f}`\n"
"*Current Rate:* `{current_rate:.8f}`\n"
"*Close Rate:* `{limit:.8f}`\n"
"*Sell Reason:* `{sell_reason}`\n"
"*Duration:* `{duration} ({duration_min:.1f} min)`\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
if (all(prop in msg for prop in ['gain', 'fiat_currency', 'stake_currency'])
and self._rpc._fiat_converter):
msg['profit_fiat'] = self._rpc._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)
return message
def send_msg(self, msg: Dict[str, Any]) -> None: def send_msg(self, msg: Dict[str, Any]) -> None:
""" Send a message to telegram channel """ """ Send a message to telegram channel """
@ -186,75 +233,31 @@ class Telegram(RPCHandler):
# Notification disabled # Notification disabled
return return
if msg['type'] == RPCMessageType.BUY_NOTIFICATION: if msg['type'] == RPCMessageType.BUY:
if self._rpc._fiat_converter: message = self._format_buy_msg(msg)
msg['stake_amount_fiat'] = self._rpc._fiat_converter.convert_amount(
msg['stake_amount'], msg['stake_currency'], msg['fiat_currency'])
else:
msg['stake_amount_fiat'] = 0
message = (f"\N{LARGE BLUE CIRCLE} *{msg['exchange']}:* Buying {msg['pair']}" elif msg['type'] in (RPCMessageType.BUY_CANCEL, RPCMessageType.SELL_CANCEL):
f" (#{msg['trade_id']})\n" msg['message_side'] = 'buy' if msg['type'] == RPCMessageType.BUY_CANCEL else 'sell'
f"*Amount:* `{msg['amount']:.8f}`\n"
f"*Open Rate:* `{msg['limit']:.8f}`\n"
f"*Current Rate:* `{msg['current_rate']:.8f}`\n"
f"*Total:* `({round_coin_value(msg['stake_amount'], msg['stake_currency'])}")
if msg.get('fiat_currency', None):
message += f", {round_coin_value(msg['stake_amount_fiat'], msg['fiat_currency'])}"
message += ")`"
elif msg['type'] == RPCMessageType.BUY_CANCEL_NOTIFICATION:
message = ("\N{WARNING SIGN} *{exchange}:* " message = ("\N{WARNING SIGN} *{exchange}:* "
"Cancelling open buy Order for {pair} (#{trade_id}). " "Cancelling open {message_side} Order for {pair} (#{trade_id}). "
"Reason: {reason}.".format(**msg)) "Reason: {reason}.".format(**msg))
elif msg['type'] == RPCMessageType.BUY_FILL_NOTIFICATION: elif msg['type'] == (RPCMessageType.BUY_FILL, RPCMessageType.SELL_FILL):
msg['message_side'] = 'Buy' if msg['type'] == RPCMessageType.BUY_FILL else 'Sell'
message = ("\N{LARGE CIRCLE} *{exchange}:* " message = ("\N{LARGE CIRCLE} *{exchange}:* "
"Buy order for {pair} (#{trade_id}) filled for {open_rate}.".format(**msg)) "Buy order for {pair} (#{trade_id}) filled for {open_rate}.".format(**msg))
elif msg['type'] == RPCMessageType.SELL_NOTIFICATION: elif msg['type'] == RPCMessageType.SELL:
msg['amount'] = round(msg['amount'], 8) message = self._format_sell_msg(msg)
msg['profit_percent'] = round(msg['profit_ratio'] * 100, 2)
msg['duration'] = msg['close_date'].replace(
microsecond=0) - msg['open_date'].replace(microsecond=0)
msg['duration_min'] = msg['duration'].total_seconds() / 60
msg['emoji'] = self._get_sell_emoji(msg) elif msg['type'] == RPCMessageType.STATUS:
message = ("{emoji} *{exchange}:* Selling {pair} (#{trade_id})\n"
"*Amount:* `{amount:.8f}`\n"
"*Open Rate:* `{open_rate:.8f}`\n"
"*Current Rate:* `{current_rate:.8f}`\n"
"*Close Rate:* `{limit:.8f}`\n"
"*Sell Reason:* `{sell_reason}`\n"
"*Duration:* `{duration} ({duration_min:.1f} min)`\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
if (all(prop in msg for prop in ['gain', 'fiat_currency', 'stake_currency'])
and self._rpc._fiat_converter):
msg['profit_fiat'] = self._rpc._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)
elif msg['type'] == RPCMessageType.SELL_CANCEL_NOTIFICATION:
message = ("\N{WARNING SIGN} *{exchange}:* Cancelling Open Sell Order "
"for {pair} (#{trade_id}). Reason: {reason}").format(**msg)
elif msg['type'] == RPCMessageType.SELL_FILL_NOTIFICATION:
message = ("\N{LARGE CIRCLE} *{exchange}:* "
"Sell order for {pair} (#{trade_id}) filled at {close_rate}.".format(**msg))
elif msg['type'] == RPCMessageType.STATUS_NOTIFICATION:
message = '*Status:* `{status}`'.format(**msg) message = '*Status:* `{status}`'.format(**msg)
elif msg['type'] == RPCMessageType.WARNING_NOTIFICATION: elif msg['type'] == RPCMessageType.WARNING:
message = '\N{WARNING SIGN} *Warning:* `{status}`'.format(**msg) message = '\N{WARNING SIGN} *Warning:* `{status}`'.format(**msg)
elif msg['type'] == RPCMessageType.STARTUP_NOTIFICATION: elif msg['type'] == RPCMessageType.STARTUP:
message = '{status}'.format(**msg) message = '{status}'.format(**msg)
else: else:

View File

@ -45,21 +45,21 @@ class Webhook(RPCHandler):
""" Send a message to telegram channel """ """ Send a message to telegram channel """
try: try:
if msg['type'] == RPCMessageType.BUY_NOTIFICATION: if msg['type'] == RPCMessageType.BUY:
valuedict = self._config['webhook'].get('webhookbuy', None) valuedict = self._config['webhook'].get('webhookbuy', None)
elif msg['type'] == RPCMessageType.BUY_CANCEL_NOTIFICATION: elif msg['type'] == RPCMessageType.BUY_CANCEL:
valuedict = self._config['webhook'].get('webhookbuycancel', None) valuedict = self._config['webhook'].get('webhookbuycancel', None)
elif msg['type'] == RPCMessageType.BUY_FILL_NOTIFICATION: elif msg['type'] == RPCMessageType.BUY_FILL:
valuedict = self._config['webhook'].get('webhookbuyfill', None) valuedict = self._config['webhook'].get('webhookbuyfill', None)
elif msg['type'] == RPCMessageType.SELL_NOTIFICATION: elif msg['type'] == RPCMessageType.SELL:
valuedict = self._config['webhook'].get('webhooksell', None) valuedict = self._config['webhook'].get('webhooksell', None)
elif msg['type'] == RPCMessageType.SELL_FILL_NOTIFICATION: elif msg['type'] == RPCMessageType.SELL_FILL:
valuedict = self._config['webhook'].get('webhooksellfill', None) valuedict = self._config['webhook'].get('webhooksellfill', None)
elif msg['type'] == RPCMessageType.SELL_CANCEL_NOTIFICATION: elif msg['type'] == RPCMessageType.SELL_CANCEL:
valuedict = self._config['webhook'].get('webhooksellcancel', None) valuedict = self._config['webhook'].get('webhooksellcancel', None)
elif msg['type'] in (RPCMessageType.STATUS_NOTIFICATION, elif msg['type'] in (RPCMessageType.STATUS,
RPCMessageType.STARTUP_NOTIFICATION, RPCMessageType.STARTUP,
RPCMessageType.WARNING_NOTIFICATION): RPCMessageType.WARNING):
valuedict = self._config['webhook'].get('webhookstatus', None) valuedict = self._config['webhook'].get('webhookstatus', None)
else: else:
raise NotImplementedError('Unknown message type: {}'.format(msg['type'])) raise NotImplementedError('Unknown message type: {}'.format(msg['type']))

View File

@ -71,7 +71,7 @@ def test_send_msg_telegram_disabled(mocker, default_conf, caplog) -> None:
freqtradebot = get_patched_freqtradebot(mocker, default_conf) freqtradebot = get_patched_freqtradebot(mocker, default_conf)
rpc_manager = RPCManager(freqtradebot) rpc_manager = RPCManager(freqtradebot)
rpc_manager.send_msg({ rpc_manager.send_msg({
'type': RPCMessageType.STATUS_NOTIFICATION, 'type': RPCMessageType.STATUS,
'status': 'test' 'status': 'test'
}) })
@ -86,7 +86,7 @@ def test_send_msg_telegram_enabled(mocker, default_conf, caplog) -> None:
freqtradebot = get_patched_freqtradebot(mocker, default_conf) freqtradebot = get_patched_freqtradebot(mocker, default_conf)
rpc_manager = RPCManager(freqtradebot) rpc_manager = RPCManager(freqtradebot)
rpc_manager.send_msg({ rpc_manager.send_msg({
'type': RPCMessageType.STATUS_NOTIFICATION, 'type': RPCMessageType.STATUS,
'status': 'test' 'status': 'test'
}) })
@ -124,7 +124,7 @@ def test_send_msg_webhook_CustomMessagetype(mocker, default_conf, caplog) -> Non
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf)) rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
assert 'webhook' in [mod.name for mod in rpc_manager.registered_modules] assert 'webhook' in [mod.name for mod in rpc_manager.registered_modules]
rpc_manager.send_msg({'type': RPCMessageType.STARTUP_NOTIFICATION, rpc_manager.send_msg({'type': RPCMessageType.STARTUP,
'status': 'TestMessage'}) 'status': 'TestMessage'})
assert log_has( assert log_has(
"Message type 'startup' not implemented by handler webhook.", "Message type 'startup' not implemented by handler webhook.",

View File

@ -686,7 +686,7 @@ def test_telegram_forcesell_handle(default_conf, update, ticker, fee,
assert msg_mock.call_count == 4 assert msg_mock.call_count == 4
last_msg = msg_mock.call_args_list[-1][0][0] last_msg = msg_mock.call_args_list[-1][0][0]
assert { assert {
'type': RPCMessageType.SELL_NOTIFICATION, 'type': RPCMessageType.SELL,
'trade_id': 1, 'trade_id': 1,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
@ -748,7 +748,7 @@ def test_telegram_forcesell_down_handle(default_conf, update, ticker, fee,
last_msg = msg_mock.call_args_list[-1][0][0] last_msg = msg_mock.call_args_list[-1][0][0]
assert { assert {
'type': RPCMessageType.SELL_NOTIFICATION, 'type': RPCMessageType.SELL,
'trade_id': 1, 'trade_id': 1,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
@ -800,7 +800,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None
assert msg_mock.call_count == 12 assert msg_mock.call_count == 12
msg = msg_mock.call_args_list[2][0][0] msg = msg_mock.call_args_list[2][0][0]
assert { assert {
'type': RPCMessageType.SELL_NOTIFICATION, 'type': RPCMessageType.SELL,
'trade_id': 1, 'trade_id': 1,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
@ -1198,7 +1198,7 @@ def test_show_config_handle(default_conf, update, mocker) -> None:
def test_send_msg_buy_notification(default_conf, mocker, caplog) -> None: def test_send_msg_buy_notification(default_conf, mocker, caplog) -> None:
msg = { msg = {
'type': RPCMessageType.BUY_NOTIFICATION, 'type': RPCMessageType.BUY,
'trade_id': 1, 'trade_id': 1,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
@ -1243,7 +1243,7 @@ def test_send_msg_buy_cancel_notification(default_conf, mocker) -> None:
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf) telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
telegram.send_msg({ telegram.send_msg({
'type': RPCMessageType.BUY_CANCEL_NOTIFICATION, 'type': RPCMessageType.BUY_CANCEL,
'trade_id': 1, 'trade_id': 1,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
@ -1261,7 +1261,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
old_convamount = telegram._rpc._fiat_converter.convert_amount old_convamount = telegram._rpc._fiat_converter.convert_amount
telegram._rpc._fiat_converter.convert_amount = lambda a, b, c: -24.812 telegram._rpc._fiat_converter.convert_amount = lambda a, b, c: -24.812
telegram.send_msg({ telegram.send_msg({
'type': RPCMessageType.SELL_NOTIFICATION, 'type': RPCMessageType.SELL,
'trade_id': 1, 'trade_id': 1,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'KEY/ETH', 'pair': 'KEY/ETH',
@ -1291,7 +1291,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
msg_mock.reset_mock() msg_mock.reset_mock()
telegram.send_msg({ telegram.send_msg({
'type': RPCMessageType.SELL_NOTIFICATION, 'type': RPCMessageType.SELL,
'trade_id': 1, 'trade_id': 1,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'KEY/ETH', 'pair': 'KEY/ETH',
@ -1328,7 +1328,7 @@ def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None:
old_convamount = telegram._rpc._fiat_converter.convert_amount old_convamount = telegram._rpc._fiat_converter.convert_amount
telegram._rpc._fiat_converter.convert_amount = lambda a, b, c: -24.812 telegram._rpc._fiat_converter.convert_amount = lambda a, b, c: -24.812
telegram.send_msg({ telegram.send_msg({
'type': RPCMessageType.SELL_CANCEL_NOTIFICATION, 'type': RPCMessageType.SELL_CANCEL,
'trade_id': 1, 'trade_id': 1,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'KEY/ETH', 'pair': 'KEY/ETH',
@ -1340,7 +1340,7 @@ def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None:
msg_mock.reset_mock() msg_mock.reset_mock()
telegram.send_msg({ telegram.send_msg({
'type': RPCMessageType.SELL_CANCEL_NOTIFICATION, 'type': RPCMessageType.SELL_CANCEL,
'trade_id': 1, 'trade_id': 1,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'KEY/ETH', 'pair': 'KEY/ETH',
@ -1357,7 +1357,7 @@ def test_send_msg_status_notification(default_conf, mocker) -> None:
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf) telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
telegram.send_msg({ telegram.send_msg({
'type': RPCMessageType.STATUS_NOTIFICATION, 'type': RPCMessageType.STATUS,
'status': 'running' 'status': 'running'
}) })
assert msg_mock.call_args[0][0] == '*Status:* `running`' assert msg_mock.call_args[0][0] == '*Status:* `running`'
@ -1366,7 +1366,7 @@ def test_send_msg_status_notification(default_conf, mocker) -> None:
def test_warning_notification(default_conf, mocker) -> None: def test_warning_notification(default_conf, mocker) -> None:
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf) telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
telegram.send_msg({ telegram.send_msg({
'type': RPCMessageType.WARNING_NOTIFICATION, 'type': RPCMessageType.WARNING,
'status': 'message' 'status': 'message'
}) })
assert msg_mock.call_args[0][0] == '\N{WARNING SIGN} *Warning:* `message`' assert msg_mock.call_args[0][0] == '\N{WARNING SIGN} *Warning:* `message`'
@ -1375,7 +1375,7 @@ def test_warning_notification(default_conf, mocker) -> None:
def test_startup_notification(default_conf, mocker) -> None: def test_startup_notification(default_conf, mocker) -> None:
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf) telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
telegram.send_msg({ telegram.send_msg({
'type': RPCMessageType.STARTUP_NOTIFICATION, 'type': RPCMessageType.STARTUP,
'status': '*Custom:* `Hello World`' 'status': '*Custom:* `Hello World`'
}) })
assert msg_mock.call_args[0][0] == '*Custom:* `Hello World`' assert msg_mock.call_args[0][0] == '*Custom:* `Hello World`'
@ -1394,7 +1394,7 @@ def test_send_msg_buy_notification_no_fiat(default_conf, mocker) -> None:
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf) telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
telegram.send_msg({ telegram.send_msg({
'type': RPCMessageType.BUY_NOTIFICATION, 'type': RPCMessageType.BUY,
'trade_id': 1, 'trade_id': 1,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
@ -1420,7 +1420,7 @@ def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None:
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf) telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
telegram.send_msg({ telegram.send_msg({
'type': RPCMessageType.SELL_NOTIFICATION, 'type': RPCMessageType.SELL,
'trade_id': 1, 'trade_id': 1,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'KEY/ETH', 'pair': 'KEY/ETH',

View File

@ -68,7 +68,7 @@ def test_send_msg_webhook(default_conf, mocker):
msg_mock = MagicMock() msg_mock = MagicMock()
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
msg = { msg = {
'type': RPCMessageType.BUY_NOTIFICATION, 'type': RPCMessageType.BUY,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
'limit': 0.005, 'limit': 0.005,
@ -89,7 +89,7 @@ def test_send_msg_webhook(default_conf, mocker):
msg_mock.reset_mock() msg_mock.reset_mock()
msg = { msg = {
'type': RPCMessageType.BUY_CANCEL_NOTIFICATION, 'type': RPCMessageType.BUY_CANCEL,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
'limit': 0.005, 'limit': 0.005,
@ -110,8 +110,8 @@ def test_send_msg_webhook(default_conf, mocker):
msg_mock.reset_mock() msg_mock.reset_mock()
msg = { msg = {
'type': RPCMessageType.BUY_FILL_NOTIFICATION, 'type': RPCMessageType.BUY_FILL,
'exchange': 'Bittrex', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
'open_rate': 0.005, 'open_rate': 0.005,
'stake_amount': 0.8, 'stake_amount': 0.8,
@ -130,7 +130,7 @@ def test_send_msg_webhook(default_conf, mocker):
# Test sell # Test sell
msg_mock.reset_mock() msg_mock.reset_mock()
msg = { msg = {
'type': RPCMessageType.SELL_NOTIFICATION, 'type': RPCMessageType.SELL,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
'gain': "profit", 'gain': "profit",
@ -155,7 +155,7 @@ def test_send_msg_webhook(default_conf, mocker):
# Test sell cancel # Test sell cancel
msg_mock.reset_mock() msg_mock.reset_mock()
msg = { msg = {
'type': RPCMessageType.SELL_CANCEL_NOTIFICATION, 'type': RPCMessageType.SELL_CANCEL,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
'gain': "profit", 'gain': "profit",
@ -180,8 +180,8 @@ def test_send_msg_webhook(default_conf, mocker):
# Test Sell fill # Test Sell fill
msg_mock.reset_mock() msg_mock.reset_mock()
msg = { msg = {
'type': RPCMessageType.SELL_FILL_NOTIFICATION, 'type': RPCMessageType.SELL_FILL,
'exchange': 'Bittrex', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
'gain': "profit", 'gain': "profit",
'close_rate': 0.005, 'close_rate': 0.005,
@ -203,9 +203,9 @@ def test_send_msg_webhook(default_conf, mocker):
assert (msg_mock.call_args[0][0]["value3"] == assert (msg_mock.call_args[0][0]["value3"] ==
default_conf["webhook"]["webhooksellfill"]["value3"].format(**msg)) default_conf["webhook"]["webhooksellfill"]["value3"].format(**msg))
for msgtype in [RPCMessageType.STATUS_NOTIFICATION, for msgtype in [RPCMessageType.STATUS,
RPCMessageType.WARNING_NOTIFICATION, RPCMessageType.WARNING,
RPCMessageType.STARTUP_NOTIFICATION]: RPCMessageType.STARTUP]:
# Test notification # Test notification
msg = { msg = {
'type': msgtype, 'type': msgtype,
@ -228,8 +228,8 @@ def test_exception_send_msg(default_conf, mocker, caplog):
del default_conf["webhook"]["webhookbuy"] del default_conf["webhook"]["webhookbuy"]
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf) webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
webhook.send_msg({'type': RPCMessageType.BUY_NOTIFICATION}) webhook.send_msg({'type': RPCMessageType.BUY})
assert log_has(f"Message type '{RPCMessageType.BUY_NOTIFICATION}' not configured for webhooks", assert log_has(f"Message type '{RPCMessageType.BUY}' not configured for webhooks",
caplog) caplog)
default_conf["webhook"] = get_webhook_dict() default_conf["webhook"] = get_webhook_dict()
@ -238,7 +238,7 @@ def test_exception_send_msg(default_conf, mocker, caplog):
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf) webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
msg = { msg = {
'type': RPCMessageType.BUY_NOTIFICATION, 'type': RPCMessageType.BUY,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
'limit': 0.005, 'limit': 0.005,

View File

@ -2624,7 +2624,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> N
last_msg = rpc_mock.call_args_list[-1][0][0] last_msg = rpc_mock.call_args_list[-1][0][0]
assert { assert {
'trade_id': 1, 'trade_id': 1,
'type': RPCMessageType.SELL_NOTIFICATION, 'type': RPCMessageType.SELL,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
'gain': 'profit', 'gain': 'profit',
@ -2674,7 +2674,7 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker)
assert rpc_mock.call_count == 2 assert rpc_mock.call_count == 2
last_msg = rpc_mock.call_args_list[-1][0][0] last_msg = rpc_mock.call_args_list[-1][0][0]
assert { assert {
'type': RPCMessageType.SELL_NOTIFICATION, 'type': RPCMessageType.SELL,
'trade_id': 1, 'trade_id': 1,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
@ -2732,7 +2732,7 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe
last_msg = rpc_mock.call_args_list[-1][0][0] last_msg = rpc_mock.call_args_list[-1][0][0]
assert { assert {
'type': RPCMessageType.SELL_NOTIFICATION, 'type': RPCMessageType.SELL,
'trade_id': 1, 'trade_id': 1,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
@ -2902,9 +2902,9 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f
assert trade.is_open is False assert trade.is_open is False
assert trade.sell_reason == SellType.STOPLOSS_ON_EXCHANGE.value assert trade.sell_reason == SellType.STOPLOSS_ON_EXCHANGE.value
assert rpc_mock.call_count == 3 assert rpc_mock.call_count == 3
assert rpc_mock.call_args_list[0][0][0]['type'] == RPCMessageType.BUY_NOTIFICATION assert rpc_mock.call_args_list[0][0][0]['type'] == RPCMessageType.BUY
assert rpc_mock.call_args_list[1][0][0]['type'] == RPCMessageType.BUY_FILL_NOTIFICATION assert rpc_mock.call_args_list[1][0][0]['type'] == RPCMessageType.BUY_FILL
assert rpc_mock.call_args_list[2][0][0]['type'] == RPCMessageType.SELL_NOTIFICATION assert rpc_mock.call_args_list[2][0][0]['type'] == RPCMessageType.SELL
def test_execute_sell_market_order(default_conf, ticker, fee, def test_execute_sell_market_order(default_conf, ticker, fee,
@ -2941,7 +2941,7 @@ def test_execute_sell_market_order(default_conf, ticker, fee,
assert rpc_mock.call_count == 3 assert rpc_mock.call_count == 3
last_msg = rpc_mock.call_args_list[-1][0][0] last_msg = rpc_mock.call_args_list[-1][0][0]
assert { assert {
'type': RPCMessageType.SELL_NOTIFICATION, 'type': RPCMessageType.SELL,
'trade_id': 1, 'trade_id': 1,
'exchange': 'Binance', 'exchange': 'Binance',
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',