From 1ca594bbcbb7907c82989dcb74e2a7653eea088f Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2024 17:54:34 +0100 Subject: [PATCH] chore: show "total" profit if necessary --- freqtrade/rpc/rpc.py | 16 +++++++++++++--- freqtrade/rpc/telegram.py | 19 ++++++++++++++++--- tests/rpc/test_rpc.py | 22 +++++++++++++++++----- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 67edd3924..ce19299f9 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -287,7 +287,7 @@ class RPC: def _rpc_status_table( self, stake_currency: str, fiat_display_currency: str - ) -> tuple[list, list, float]: + ) -> tuple[list, list, float, float]: """ :return: list of trades, list of columns, sum of fiat profit """ @@ -297,17 +297,27 @@ class RPC: trades_list = [] fiat_profit_sum = nan + fiat_total_profit_sum = nan for trade in self._rpc_trade_status(): # Format profit as a string with the right sign profit = f"{trade['profit_ratio']:.2%}" fiat_profit = trade.get("profit_fiat", None) if fiat_profit is None or isnan(fiat_profit): - fiat_profit: float = trade.get("profit_abs", 0.0) + fiat_profit = trade.get("profit_abs", 0.0) if not isnan(fiat_profit): profit += f" ({fiat_profit:.2f})" fiat_profit_sum = ( fiat_profit if isnan(fiat_profit_sum) else fiat_profit_sum + fiat_profit ) + total_profit = trade.get("total_profit_fiat", None) + if total_profit is None or isnan(total_profit): + total_profit = trade.get("total_profit_abs", 0.0) + if not isnan(total_profit): + fiat_total_profit_sum = ( + total_profit + if isnan(fiat_total_profit_sum) + else fiat_total_profit_sum + total_profit + ) # Format the active order side symbols active_order_side = "" @@ -352,7 +362,7 @@ class RPC: if self._config.get("position_adjustment_enable", False): columns.append("# Entries") - return trades_list, columns, fiat_profit_sum + return trades_list, columns, fiat_profit_sum, fiat_total_profit_sum def _rpc_timeunit_profit( self, diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 70cf6fe72..e50771481 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -858,11 +858,14 @@ class Telegram(RPCHandler): :return: None """ fiat_currency = self._config.get("fiat_display_currency", "") - statlist, head, fiat_profit_sum = self._rpc._rpc_status_table( + statlist, head, fiat_profit_sum, fiat_total_profit_sum = self._rpc._rpc_status_table( self._config["stake_currency"], fiat_currency ) show_total = not isnan(fiat_profit_sum) and len(statlist) > 1 + show_total_realized = ( + not isnan(fiat_total_profit_sum) and len(statlist) > 1 and fiat_profit_sum + ) != fiat_total_profit_sum max_trades_per_msg = 50 """ Calculate the number of messages of 50 trades per message @@ -875,12 +878,22 @@ class Telegram(RPCHandler): if show_total and i == messages_count - 1: # append total line trades.append(["Total", "", "", f"{fiat_profit_sum:.2f} {fiat_currency}"]) + if show_total_realized: + trades.append( + [ + "Total", + "(incl. realized Profits)", + "", + f"{fiat_total_profit_sum:.2f} {fiat_currency}", + ] + ) message = tabulate(trades, headers=head, 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]]) + offset = 2 if show_total_realized else 1 + message = "\n".join(lines[:-offset] + [lines[1]] + lines[-offset:]) await self._send_msg( f"
{message}
", parse_mode=ParseMode.HTML, @@ -1287,7 +1300,7 @@ class Telegram(RPCHandler): else: fiat_currency = self._config.get("fiat_display_currency", "") try: - statlist, _, _ = self._rpc._rpc_status_table( + statlist, _, _, _ = self._rpc._rpc_status_table( self._config["stake_currency"], fiat_currency ) except RPCException: diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index b5e2c2bca..d0ec44061 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -251,18 +251,23 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: mocker.patch(f"{EXMS}._dry_is_price_crossed", return_value=False) freqtradebot.enter_positions() - result, headers, fiat_profit_sum = rpc._rpc_status_table(default_conf["stake_currency"], "USD") + result, headers, fiat_profit_sum, total_sum = rpc._rpc_status_table( + default_conf["stake_currency"], "USD" + ) assert "Since" in headers assert "Pair" in headers assert "now" == result[0][2] assert "ETH/BTC" in result[0][1] assert "0.00% (0.00)" == result[0][3] assert "0.00" == f"{fiat_profit_sum:.2f}" + assert "0.00" == f"{total_sum:.2f}" mocker.patch(f"{EXMS}._dry_is_price_crossed", return_value=True) freqtradebot.process() - result, headers, fiat_profit_sum = rpc._rpc_status_table(default_conf["stake_currency"], "USD") + result, headers, fiat_profit_sum, total_sum = rpc._rpc_status_table( + default_conf["stake_currency"], "USD" + ) assert "Since" in headers assert "Pair" in headers assert "now" == result[0][2] @@ -273,7 +278,9 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: # Test with fiat convert rpc._config["fiat_display_currency"] = "USD" rpc._fiat_converter = CryptoToFiatConverter({}) - result, headers, fiat_profit_sum = rpc._rpc_status_table(default_conf["stake_currency"], "USD") + result, headers, fiat_profit_sum, total_sum = rpc._rpc_status_table( + default_conf["stake_currency"], "USD" + ) assert "Since" in headers assert "Pair" in headers assert len(result[0]) == 4 @@ -281,10 +288,13 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: assert "ETH/BTC" in result[0][1] assert "-0.41% (-0.06)" == result[0][3] assert "-0.06" == f"{fiat_profit_sum:.2f}" + assert "-0.06" == f"{total_sum:.2f}" rpc._config["position_adjustment_enable"] = True rpc._config["max_entry_position_adjustment"] = 3 - result, headers, fiat_profit_sum = rpc._rpc_status_table(default_conf["stake_currency"], "USD") + result, headers, fiat_profit_sum, total_sum = rpc._rpc_status_table( + default_conf["stake_currency"], "USD" + ) assert "# Entries" in headers assert len(result[0]) == 5 # 4th column should be 1/4 - as 1 order filled (a total of 4 is possible) @@ -294,7 +304,9 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: mocker.patch( f"{EXMS}.get_rate", MagicMock(side_effect=ExchangeError("Pair 'ETH/BTC' not available")) ) - result, headers, fiat_profit_sum = rpc._rpc_status_table(default_conf["stake_currency"], "USD") + result, headers, fiat_profit_sum, total_sum = rpc._rpc_status_table( + default_conf["stake_currency"], "USD" + ) assert "now" == result[0][2] assert "ETH/BTC" in result[0][1] assert "nan%" == result[0][3]