Add buy and sell fill notifications

closes #3542
This commit is contained in:
Matthias
2021-04-19 19:58:29 +02:00
parent 71b017e7c3
commit fecd5c582b
7 changed files with 136 additions and 5 deletions

View File

@@ -675,6 +675,21 @@ class FreqtradeBot(LoggingMixin):
# Send the message
self.rpc.send_msg(msg)
def _notify_buy_fill(self, trade: Trade) -> None:
msg = {
'trade_id': trade.id,
'type': RPCMessageType.BUY_FILL_NOTIFICATION,
'exchange': self.exchange.name.capitalize(),
'pair': trade.pair,
'open_rate': trade.open_rate,
'stake_amount': trade.stake_amount,
'stake_currency': self.config['stake_currency'],
'fiat_currency': self.config.get('fiat_display_currency', None),
'amount': trade.amount,
'open_date': trade.open_date,
}
self.rpc.send_msg(msg)
#
# SELL / exit positions / close trades logic and methods
#
@@ -1212,19 +1227,20 @@ class FreqtradeBot(LoggingMixin):
return True
def _notify_sell(self, trade: Trade, order_type: str) -> None:
def _notify_sell(self, trade: Trade, order_type: str, fill: bool = False) -> None:
"""
Sends rpc notification when a sell occured.
"""
profit_rate = trade.close_rate if trade.close_rate else trade.close_rate_requested
profit_trade = trade.calc_profit(rate=profit_rate)
# Use cached rates here - it was updated seconds ago.
current_rate = self.get_sell_rate(trade.pair, False)
current_rate = self.get_sell_rate(trade.pair, False) if not fill else None
profit_ratio = trade.calc_profit_ratio(profit_rate)
gain = "profit" if profit_ratio > 0 else "loss"
msg = {
'type': RPCMessageType.SELL_NOTIFICATION,
'type': (RPCMessageType.SELL_FILL_NOTIFICATION if fill
else RPCMessageType.SELL_NOTIFICATION),
'trade_id': trade.id,
'exchange': trade.exchange.capitalize(),
'pair': trade.pair,
@@ -1233,6 +1249,7 @@ class FreqtradeBot(LoggingMixin):
'order_type': order_type,
'amount': trade.amount,
'open_rate': trade.open_rate,
'close_rate': trade.close_rate,
'current_rate': current_rate,
'profit_amount': profit_trade,
'profit_ratio': profit_ratio,
@@ -1344,9 +1361,14 @@ class FreqtradeBot(LoggingMixin):
# Updating wallets when order is closed
if not trade.is_open:
self._notify_sell(trade, '', True)
self.protections.stop_per_pair(trade.pair)
self.protections.global_stop()
self.wallets.update()
elif trade.open_order_id is None:
# Buy fill
self._notify_buy_fill(trade)
return False
def apply_fee_conditional(self, trade: Trade, trade_base_currency: str,

View File

@@ -35,8 +35,10 @@ class RPCMessageType(Enum):
WARNING_NOTIFICATION = 'warning'
STARTUP_NOTIFICATION = 'startup'
BUY_NOTIFICATION = 'buy'
BUY_FILL_NOTIFICATION = 'buy_fill'
BUY_CANCEL_NOTIFICATION = 'buy_cancel'
SELL_NOTIFICATION = 'sell'
SELL_FILL_NOTIFICATION = 'sell_fill'
SELL_CANCEL_NOTIFICATION = 'sell_cancel'
def __repr__(self):

View File

@@ -209,6 +209,10 @@ class Telegram(RPCHandler):
"Cancelling open buy Order for {pair} (#{trade_id}). "
"Reason: {reason}.".format(**msg))
elif msg['type'] == RPCMessageType.BUY_FILL_NOTIFICATION:
message = ("\N{LARGE CIRCLE} *{exchange}:* "
"Buy order for {pair} (#{trade_id}) filled for {open_rate}.".format(**msg))
elif msg['type'] == RPCMessageType.SELL_NOTIFICATION:
msg['amount'] = round(msg['amount'], 8)
msg['profit_percent'] = round(msg['profit_ratio'] * 100, 2)
@@ -240,6 +244,10 @@ class Telegram(RPCHandler):
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)

View File

@@ -49,8 +49,12 @@ class Webhook(RPCHandler):
valuedict = self._config['webhook'].get('webhookbuy', None)
elif msg['type'] == RPCMessageType.BUY_CANCEL_NOTIFICATION:
valuedict = self._config['webhook'].get('webhookbuycancel', None)
elif msg['type'] == RPCMessageType.BUY_FILL_NOTIFICATION:
valuedict = self._config['webhook'].get('webhookbuyfill', None)
elif msg['type'] == RPCMessageType.SELL_NOTIFICATION:
valuedict = self._config['webhook'].get('webhooksell', None)
elif msg['type'] == RPCMessageType.SELL_FILL_NOTIFICATION:
valuedict = self._config['webhook'].get('webhooksellfill', None)
elif msg['type'] == RPCMessageType.SELL_CANCEL_NOTIFICATION:
valuedict = self._config['webhook'].get('webhooksellcancel', None)
elif msg['type'] in (RPCMessageType.STATUS_NOTIFICATION,