Update buy/sell fill telegram notifications
This commit is contained in:
parent
a237667bc9
commit
32e3376296
@ -219,6 +219,7 @@ class Telegram(RPCHandler):
|
||||
else:
|
||||
msg['stake_amount_fiat'] = 0
|
||||
|
||||
msg['currency'] = msg['pair'].split('/')[0]
|
||||
content = []
|
||||
content.append(
|
||||
f"\N{LARGE BLUE CIRCLE} *{msg['exchange']}:* Buying {msg['pair']}"
|
||||
@ -226,7 +227,7 @@ class Telegram(RPCHandler):
|
||||
)
|
||||
if msg.get('buy_tag', None):
|
||||
content.append(f"*Buy Tag:* `{msg['buy_tag']}`\n")
|
||||
content.append(f"*Amount:* `{msg['amount']:.8f} {msg['pair'].split('/')[0]}`\n")
|
||||
content.append(f"*Amount:* `{msg['amount']:.8f}` {msg['currency']}\n")
|
||||
content.append(f"*Open Rate:* `{msg['limit']:.8f}`\n")
|
||||
content.append(f"*Current Rate:* `{msg['current_rate']:.8f}`\n")
|
||||
content.append(
|
||||
@ -241,13 +242,14 @@ class Telegram(RPCHandler):
|
||||
message += ")`"
|
||||
return message
|
||||
|
||||
def _format_buy_msg_fill(self, msg: Dict[str, Any]) -> str:
|
||||
def _format_buy_fill_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
|
||||
|
||||
msg['currency'] = msg['pair'].split('/')[0]
|
||||
content = []
|
||||
content.append(
|
||||
f"\N{CHECK MARK} *{msg['exchange']}:* Bought {msg['pair']}"
|
||||
@ -255,7 +257,8 @@ class Telegram(RPCHandler):
|
||||
)
|
||||
if msg.get('buy_tag', None):
|
||||
content.append(f"*Buy Tag:* `{msg['buy_tag']}`\n")
|
||||
content.append(f"*Amount:* `{msg['amount']:.8f} {msg['pair'].split('/')[0]}`\n")
|
||||
content.append(f"*Amount:* `{msg['amount']:.8f}` {msg['currency']}\n")
|
||||
content.append(f"*Open Rate:* `{msg['open_rate']:.8f}`\n")
|
||||
content.append(
|
||||
f"*Total:* `({round_coin_value(msg['stake_amount'], msg['stake_currency'])}"
|
||||
)
|
||||
@ -269,38 +272,6 @@ class Telegram(RPCHandler):
|
||||
return message
|
||||
|
||||
def _format_sell_msg(self, msg: Dict[str, Any]) -> str:
|
||||
msg['amount'] = round(msg['amount'], 8)
|
||||
msg['duration'] = msg['close_date'].replace(
|
||||
microsecond=0) - msg['open_date'].replace(microsecond=0)
|
||||
msg['duration_min'] = msg['duration'].total_seconds() / 60
|
||||
msg['buy_tag'] = msg['buy_tag'] if "buy_tag" in msg.keys() else None
|
||||
|
||||
# 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'])
|
||||
msg['profit_extra'] = (' ({gain}: {profit_amount:.8f} {stake_currency}'
|
||||
' / {profit_fiat:.3f} {fiat_currency})').format(**msg)
|
||||
else:
|
||||
msg['profit_extra'] = ''
|
||||
|
||||
msg['currency'] = msg['pair'].split('/')[0]
|
||||
message = ("\N{LARGE RED CIRCLE} *{exchange}:* Selling {pair} (#{trade_id})\n"
|
||||
"*Unrealized Profit:* `{profit_ratio:.2%}{profit_extra}`\n"
|
||||
"*Buy Tag:* `{buy_tag}`\n"
|
||||
"*Sell Reason:* `{sell_reason}`\n"
|
||||
"*Duration:* `{duration} ({duration_min:.1f} min)`\n"
|
||||
"*Amount:* `{amount:.8f}` {currency}\n"
|
||||
"*Open Rate:* `{open_rate:.8f}`\n"
|
||||
"*Current Rate:* `{current_rate:.8f}`\n"
|
||||
"*Close Rate:* `{close_rate:.8f}`").format(
|
||||
**msg) # TODO: Updated from `limit`, confirm this is correct variable?
|
||||
|
||||
return message
|
||||
|
||||
def _format_sell_msg_fill(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(
|
||||
@ -320,18 +291,49 @@ class Telegram(RPCHandler):
|
||||
' / {profit_fiat:.3f} {fiat_currency})').format(**msg)
|
||||
else:
|
||||
msg['profit_extra'] = ''
|
||||
|
||||
msg['currency'] = msg['pair'].split('/')[0]
|
||||
message = ("{emoji} *{exchange}:* Selling {pair} (#{trade_id})\n"
|
||||
"*Unrealized Profit:* `{profit_ratio:.2%}{profit_extra}`\n"
|
||||
"*Buy Tag:* `{buy_tag}`\n"
|
||||
"*Sell Reason:* `{sell_reason}`\n"
|
||||
"*Duration:* `{duration} ({duration_min:.1f} min)`\n"
|
||||
"*Amount:* `{amount:.8f}` {currency}\n"
|
||||
"*Open Rate:* `{open_rate:.8f}`\n"
|
||||
"*Current Rate:* `{current_rate:.8f}`\n"
|
||||
"*Close Rate:* `{limit:.8f}`").format(**msg)
|
||||
|
||||
return message
|
||||
|
||||
def _format_sell_fill_msg(self, msg: Dict[str, Any]) -> str:
|
||||
import pprint
|
||||
pprint.pprint(msg)
|
||||
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['buy_tag'] = msg['buy_tag'] if "buy_tag" in msg.keys() else None
|
||||
msg['emoji'] = self._get_sell_emoji(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'])
|
||||
msg['profit_extra'] = (' ({gain}: {profit_amount:.8f} {stake_currency}'
|
||||
' / {profit_fiat:.3f} {fiat_currency})').format(**msg)
|
||||
else:
|
||||
msg['profit_extra'] = ''
|
||||
msg['currency'] = msg['pair'].split('/')[0]
|
||||
message = ("{emoji} *{exchange}:* Sold {pair} (#{trade_id})\n"
|
||||
"*Profit:* `{profit_ratio:.2%}{profit_extra}`\n"
|
||||
"*Buy Tag:* `{buy_tag}`\n"
|
||||
"*Sell Reason:* `{sell_reason}`\n"
|
||||
"*Duration:* `{duration} ({duration_min:.1f} min)`\n"
|
||||
"*Amount:* `{amount:.8f}` {currency}\n"
|
||||
"*Close Rate:* `{close_rate:.8f}`").format(
|
||||
**msg) # TODO: Updated from `limit`, confirm this is correct variable to use? Limit not in dict for _fill
|
||||
"*Close Rate:* `{close_rate:.8f}`").format(**msg)
|
||||
|
||||
return message
|
||||
|
||||
@ -347,10 +349,10 @@ class Telegram(RPCHandler):
|
||||
"Reason: {reason}.".format(**msg))
|
||||
|
||||
elif msg_type == RPCMessageType.BUY_FILL:
|
||||
message = self._format_buy_msg_fill(msg)
|
||||
message = self._format_buy_fill_msg(msg)
|
||||
|
||||
elif msg_type == RPCMessageType.SELL_FILL:
|
||||
message = self._format_sell_msg_fill(msg)
|
||||
message = self._format_sell_fill_msg(msg)
|
||||
|
||||
elif msg_type == RPCMessageType.SELL:
|
||||
message = self._format_sell_msg(msg)
|
||||
@ -360,11 +362,13 @@ class Telegram(RPCHandler):
|
||||
"*Protection* triggered due to {reason}. "
|
||||
"`{pair}` will be locked until `{lock_end_time}`."
|
||||
).format(**msg)
|
||||
|
||||
elif msg_type == RPCMessageType.PROTECTION_TRIGGER_GLOBAL:
|
||||
message = (
|
||||
"*Protection* triggered due to {reason}. "
|
||||
"*All pairs* will be locked until `{lock_end_time}`."
|
||||
).format(**msg)
|
||||
|
||||
elif msg_type == RPCMessageType.STATUS:
|
||||
message = '*Status:* `{status}`'.format(**msg)
|
||||
|
||||
|
@ -1613,7 +1613,7 @@ def test_send_msg_buy_notification(default_conf, mocker, caplog) -> None:
|
||||
assert msg_mock.call_args[0][0] \
|
||||
== '\N{LARGE BLUE CIRCLE} *Binance:* Buying ETH/BTC (#1)\n' \
|
||||
'*Buy Tag:* `buy_signal_01`\n' \
|
||||
'*Amount:* `1333.33333333`\n' \
|
||||
'*Amount:* `1333.33333333` ETH\n' \
|
||||
'*Open Rate:* `0.00001099`\n' \
|
||||
'*Current Rate:* `0.00001099`\n' \
|
||||
'*Total:* `(0.00100000 BTC, 12.345 USD)`'
|
||||
@ -1686,17 +1686,25 @@ def test_send_msg_buy_fill_notification(default_conf, mocker) -> None:
|
||||
|
||||
telegram.send_msg({
|
||||
'type': RPCMessageType.BUY_FILL,
|
||||
'buy_tag': 'buy_signal_01',
|
||||
'trade_id': 1,
|
||||
'buy_tag': 'buy_signal_01',
|
||||
'exchange': 'Binance',
|
||||
'pair': 'ETH/USDT',
|
||||
'open_rate': 200,
|
||||
'stake_amount': 100,
|
||||
'amount': 0.5,
|
||||
'open_date': arrow.utcnow().datetime
|
||||
'pair': 'ETH/BTC',
|
||||
'stake_amount': 0.001,
|
||||
# 'stake_amount_fiat': 0.0,
|
||||
'stake_currency': 'BTC',
|
||||
'fiat_currency': 'USD',
|
||||
'open_rate': 1.099e-05,
|
||||
'amount': 1333.3333333333335,
|
||||
'open_date': arrow.utcnow().shift(hours=-1)
|
||||
})
|
||||
assert (msg_mock.call_args[0][0] == '\N{LARGE CIRCLE} *Binance:* '
|
||||
'Buy order for ETH/USDT (#1) filled for 200.')
|
||||
|
||||
assert msg_mock.call_args[0][0] \
|
||||
== '\N{CHECK MARK} *Binance:* Bought ETH/BTC (#1)\n' \
|
||||
'*Buy Tag:* `buy_signal_01`\n' \
|
||||
'*Amount:* `1333.33333333` ETH\n' \
|
||||
'*Open Rate:* `0.00001099`\n' \
|
||||
'*Total:* `(0.00100000 BTC, 12.345 USD)`'
|
||||
|
||||
|
||||
def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
||||
@ -1727,11 +1735,11 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
||||
})
|
||||
assert msg_mock.call_args[0][0] \
|
||||
== ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH (#1)\n'
|
||||
'*Profit:* `-57.41% (loss: -0.05746268 ETH / -24.812 USD)`\n'
|
||||
'*Unrealized Profit:* `-57.41% (loss: -0.05746268 ETH / -24.812 USD)`\n'
|
||||
'*Buy Tag:* `buy_signal1`\n'
|
||||
'*Sell Reason:* `stop_loss`\n'
|
||||
'*Duration:* `1:00:00 (60.0 min)`\n'
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
'*Amount:* `1333.33333333` KEY\n'
|
||||
'*Open Rate:* `0.00007500`\n'
|
||||
'*Current Rate:* `0.00003201`\n'
|
||||
'*Close Rate:* `0.00003201`'
|
||||
@ -1759,11 +1767,11 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
||||
})
|
||||
assert msg_mock.call_args[0][0] \
|
||||
== ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH (#1)\n'
|
||||
'*Profit:* `-57.41%`\n'
|
||||
'*Unrealized Profit:* `-57.41%`\n'
|
||||
'*Buy Tag:* `buy_signal1`\n'
|
||||
'*Sell Reason:* `stop_loss`\n'
|
||||
'*Duration:* `1 day, 2:30:00 (1590.0 min)`\n'
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
'*Amount:* `1333.33333333` KEY\n'
|
||||
'*Open Rate:* `0.00007500`\n'
|
||||
'*Current Rate:* `0.00003201`\n'
|
||||
'*Close Rate:* `0.00003201`'
|
||||
@ -1813,25 +1821,30 @@ def test_send_msg_sell_fill_notification(default_conf, mocker) -> None:
|
||||
'type': RPCMessageType.SELL_FILL,
|
||||
'trade_id': 1,
|
||||
'exchange': 'Binance',
|
||||
'pair': 'ETH/USDT',
|
||||
'pair': 'KEY/ETH',
|
||||
'gain': 'loss',
|
||||
'limit': 3.201e-05,
|
||||
'amount': 0.1,
|
||||
'amount': 1333.3333333333335,
|
||||
'order_type': 'market',
|
||||
'open_rate': 500,
|
||||
'close_rate': 550,
|
||||
'current_rate': 3.201e-05,
|
||||
'open_rate': 7.5e-05,
|
||||
'close_rate': 3.201e-05,
|
||||
'profit_amount': -0.05746268,
|
||||
'profit_ratio': -0.57405275,
|
||||
'stake_currency': 'ETH',
|
||||
'fiat_currency': 'USD',
|
||||
'buy_tag': 'buy_signal1',
|
||||
'sell_reason': SellType.STOP_LOSS.value,
|
||||
'open_date': arrow.utcnow().shift(hours=-1),
|
||||
'open_date': arrow.utcnow().shift(days=-1, hours=-2, minutes=-30),
|
||||
'close_date': arrow.utcnow(),
|
||||
})
|
||||
assert msg_mock.call_args[0][0] \
|
||||
== ('\N{LARGE CIRCLE} *Binance:* Sell order for ETH/USDT (#1) filled for 550.')
|
||||
== ('\N{WARNING SIGN} *Binance:* Sold KEY/ETH (#1)\n'
|
||||
'*Profit:* `-57.41%`\n'
|
||||
'*Buy Tag:* `buy_signal1`\n'
|
||||
'*Sell Reason:* `stop_loss`\n'
|
||||
'*Duration:* `1 day, 2:30:00 (1590.0 min)`\n'
|
||||
'*Amount:* `1333.33333333` KEY\n'
|
||||
'*Close Rate:* `0.00003201`'
|
||||
)
|
||||
|
||||
|
||||
def test_send_msg_status_notification(default_conf, mocker) -> None:
|
||||
@ -1892,7 +1905,7 @@ def test_send_msg_buy_notification_no_fiat(default_conf, mocker) -> None:
|
||||
})
|
||||
assert msg_mock.call_args[0][0] == ('\N{LARGE BLUE CIRCLE} *Binance:* Buying ETH/BTC (#1)\n'
|
||||
'*Buy Tag:* `buy_signal_01`\n'
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
'*Amount:* `1333.33333333` ETH\n'
|
||||
'*Open Rate:* `0.00001099`\n'
|
||||
'*Current Rate:* `0.00001099`\n'
|
||||
'*Total:* `(0.00100000 BTC)`')
|
||||
@ -1923,11 +1936,11 @@ def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None:
|
||||
'close_date': arrow.utcnow(),
|
||||
})
|
||||
assert msg_mock.call_args[0][0] == ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH (#1)\n'
|
||||
'*Profit:* `-57.41%`\n'
|
||||
'*Unrealized Profit:* `-57.41%`\n'
|
||||
'*Buy Tag:* `buy_signal1`\n'
|
||||
'*Sell Reason:* `stop_loss`\n'
|
||||
'*Duration:* `2:35:03 (155.1 min)`\n'
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
'*Amount:* `1333.33333333` KEY\n'
|
||||
'*Open Rate:* `0.00007500`\n'
|
||||
'*Current Rate:* `0.00003201`\n'
|
||||
'*Close Rate:* `0.00003201`'
|
||||
|
Loading…
Reference in New Issue
Block a user