Merge pull request #4962 from eschava/total_row
Total row for telegram "/status table" command
This commit is contained in:
commit
ccd705bfda
@ -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,
|
||||||
|
@ -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))
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user