Merge pull request #4962 from eschava/total_row

Total row for telegram "/status table" command
This commit is contained in:
Matthias 2021-05-21 08:02:30 +02:00 committed by GitHub
commit ccd705bfda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 9 deletions

View File

@ -220,12 +220,13 @@ class RPC:
return results return results
def _rpc_status_table(self, stake_currency: str, def _rpc_status_table(self, stake_currency: str,
fiat_display_currency: str) -> Tuple[List, List]: fiat_display_currency: str) -> Tuple[List, List, float]:
trades = Trade.get_open_trades() trades = Trade.get_open_trades()
if not trades: if not trades:
raise RPCException('no active trade') raise RPCException('no active trade')
else: else:
trades_list = [] trades_list = []
fiat_profit_sum = NAN
for trade in trades: for trade in trades:
# calculate profit and send message to user # calculate profit and send message to user
try: try:
@ -243,6 +244,8 @@ class RPC:
) )
if fiat_profit and not isnan(fiat_profit): if fiat_profit and not isnan(fiat_profit):
profit_str += f" ({fiat_profit:.2f})" profit_str += f" ({fiat_profit:.2f})"
fiat_profit_sum = fiat_profit if isnan(fiat_profit_sum) \
else fiat_profit_sum + fiat_profit
trades_list.append([ trades_list.append([
trade.id, trade.id,
trade.pair + ('*' if (trade.open_order_id is not None trade.pair + ('*' if (trade.open_order_id is not None
@ -256,7 +259,7 @@ class RPC:
profitcol += " (" + fiat_display_currency + ")" profitcol += " (" + fiat_display_currency + ")"
columns = ['ID', 'Pair', 'Since', profitcol] columns = ['ID', 'Pair', 'Since', profitcol]
return trades_list, columns return trades_list, columns, fiat_profit_sum
def _rpc_daily_profit( def _rpc_daily_profit(
self, timescale: int, self, timescale: int,

View File

@ -8,6 +8,7 @@ import logging
from datetime import timedelta from datetime import timedelta
from html import escape from html import escape
from itertools import chain from itertools import chain
from math import isnan
from typing import Any, Callable, Dict, List, Union from typing import Any, Callable, Dict, List, Union
import arrow import arrow
@ -354,19 +355,31 @@ class Telegram(RPCHandler):
:return: None :return: None
""" """
try: try:
statlist, head = self._rpc._rpc_status_table( fiat_currency = self._config.get('fiat_display_currency', '')
self._config['stake_currency'], self._config.get('fiat_display_currency', '')) statlist, head, fiat_profit_sum = self._rpc._rpc_status_table(
self._config['stake_currency'], fiat_currency)
show_total = not isnan(fiat_profit_sum) and len(statlist) > 1
max_trades_per_msg = 50 max_trades_per_msg = 50
""" """
Calculate the number of messages of 50 trades per message Calculate the number of messages of 50 trades per message
0.99 is used to make sure that there are no extra (empty) messages 0.99 is used to make sure that there are no extra (empty) messages
As an example with 50 trades, there will be int(50/50 + 0.99) = 1 message As an example with 50 trades, there will be int(50/50 + 0.99) = 1 message
""" """
for i in range(0, max(int(len(statlist) / max_trades_per_msg + 0.99), 1)): messages_count = max(int(len(statlist) / max_trades_per_msg + 0.99), 1)
message = tabulate(statlist[i * max_trades_per_msg:(i + 1) * max_trades_per_msg], for i in range(0, messages_count):
trades = statlist[i * max_trades_per_msg:(i + 1) * max_trades_per_msg]
if show_total and i == messages_count - 1:
# append total line
trades.append(["Total", "", "", f"{fiat_profit_sum:.2f} {fiat_currency}"])
message = tabulate(trades,
headers=head, headers=head,
tablefmt='simple') tablefmt='simple')
if show_total and i == messages_count - 1:
# insert separators line between Total
lines = message.split("\n")
message = "\n".join(lines[:-1] + [lines[1]] + [lines[-1]])
self._send_msg(f"<pre>{message}</pre>", parse_mode=ParseMode.HTML) self._send_msg(f"<pre>{message}</pre>", parse_mode=ParseMode.HTML)
except RPCException as e: except RPCException as e:
self._send_msg(str(e)) self._send_msg(str(e))

View File

@ -199,28 +199,31 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
freqtradebot.enter_positions() freqtradebot.enter_positions()
result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD') result, headers, fiat_profit_sum = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
assert "Since" in headers assert "Since" in headers
assert "Pair" in headers assert "Pair" in headers
assert 'instantly' == result[0][2] assert 'instantly' == result[0][2]
assert 'ETH/BTC' in result[0][1] assert 'ETH/BTC' in result[0][1]
assert '-0.41%' == result[0][3] assert '-0.41%' == result[0][3]
assert isnan(fiat_profit_sum)
# Test with fiatconvert # Test with fiatconvert
rpc._fiat_converter = CryptoToFiatConverter() rpc._fiat_converter = CryptoToFiatConverter()
result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD') result, headers, fiat_profit_sum = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
assert "Since" in headers assert "Since" in headers
assert "Pair" in headers assert "Pair" in headers
assert 'instantly' == result[0][2] assert 'instantly' == result[0][2]
assert 'ETH/BTC' in result[0][1] assert 'ETH/BTC' in result[0][1]
assert '-0.41% (-0.06)' == result[0][3] assert '-0.41% (-0.06)' == result[0][3]
assert '-0.06' == f'{fiat_profit_sum:.2f}'
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_sell_rate', mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_sell_rate',
MagicMock(side_effect=ExchangeError("Pair 'ETH/BTC' not available"))) MagicMock(side_effect=ExchangeError("Pair 'ETH/BTC' not available")))
result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD') result, headers, fiat_profit_sum = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
assert 'instantly' == result[0][2] assert 'instantly' == result[0][2]
assert 'ETH/BTC' in result[0][1] assert 'ETH/BTC' in result[0][1]
assert 'nan%' == result[0][3] assert 'nan%' == result[0][3]
assert isnan(fiat_profit_sum)
def test_rpc_daily_profit(default_conf, update, ticker, fee, def test_rpc_daily_profit(default_conf, update, ticker, fee,