mirror of
https://github.com/freqtrade/freqtrade.git
synced 2025-12-17 13:21:15 +00:00
chore: show "total" profit if necessary
This commit is contained in:
@@ -287,7 +287,7 @@ class RPC:
|
|||||||
|
|
||||||
def _rpc_status_table(
|
def _rpc_status_table(
|
||||||
self, stake_currency: str, fiat_display_currency: str
|
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
|
:return: list of trades, list of columns, sum of fiat profit
|
||||||
"""
|
"""
|
||||||
@@ -297,17 +297,27 @@ class RPC:
|
|||||||
|
|
||||||
trades_list = []
|
trades_list = []
|
||||||
fiat_profit_sum = nan
|
fiat_profit_sum = nan
|
||||||
|
fiat_total_profit_sum = nan
|
||||||
for trade in self._rpc_trade_status():
|
for trade in self._rpc_trade_status():
|
||||||
# Format profit as a string with the right sign
|
# Format profit as a string with the right sign
|
||||||
profit = f"{trade['profit_ratio']:.2%}"
|
profit = f"{trade['profit_ratio']:.2%}"
|
||||||
fiat_profit = trade.get("profit_fiat", None)
|
fiat_profit = trade.get("profit_fiat", None)
|
||||||
if fiat_profit is None or isnan(fiat_profit):
|
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):
|
if not isnan(fiat_profit):
|
||||||
profit += f" ({fiat_profit:.2f})"
|
profit += f" ({fiat_profit:.2f})"
|
||||||
fiat_profit_sum = (
|
fiat_profit_sum = (
|
||||||
fiat_profit if isnan(fiat_profit_sum) else fiat_profit_sum + fiat_profit
|
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
|
# Format the active order side symbols
|
||||||
active_order_side = ""
|
active_order_side = ""
|
||||||
@@ -352,7 +362,7 @@ class RPC:
|
|||||||
if self._config.get("position_adjustment_enable", False):
|
if self._config.get("position_adjustment_enable", False):
|
||||||
columns.append("# Entries")
|
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(
|
def _rpc_timeunit_profit(
|
||||||
self,
|
self,
|
||||||
|
|||||||
@@ -858,11 +858,14 @@ class Telegram(RPCHandler):
|
|||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
fiat_currency = self._config.get("fiat_display_currency", "")
|
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
|
self._config["stake_currency"], fiat_currency
|
||||||
)
|
)
|
||||||
|
|
||||||
show_total = not isnan(fiat_profit_sum) and len(statlist) > 1
|
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
|
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
|
||||||
@@ -875,12 +878,22 @@ class Telegram(RPCHandler):
|
|||||||
if show_total and i == messages_count - 1:
|
if show_total and i == messages_count - 1:
|
||||||
# append total line
|
# append total line
|
||||||
trades.append(["Total", "", "", f"{fiat_profit_sum:.2f} {fiat_currency}"])
|
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")
|
message = tabulate(trades, headers=head, tablefmt="simple")
|
||||||
if show_total and i == messages_count - 1:
|
if show_total and i == messages_count - 1:
|
||||||
# insert separators line between Total
|
# insert separators line between Total
|
||||||
lines = message.split("\n")
|
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(
|
await self._send_msg(
|
||||||
f"<pre>{message}</pre>",
|
f"<pre>{message}</pre>",
|
||||||
parse_mode=ParseMode.HTML,
|
parse_mode=ParseMode.HTML,
|
||||||
@@ -1287,7 +1300,7 @@ class Telegram(RPCHandler):
|
|||||||
else:
|
else:
|
||||||
fiat_currency = self._config.get("fiat_display_currency", "")
|
fiat_currency = self._config.get("fiat_display_currency", "")
|
||||||
try:
|
try:
|
||||||
statlist, _, _ = self._rpc._rpc_status_table(
|
statlist, _, _, _ = self._rpc._rpc_status_table(
|
||||||
self._config["stake_currency"], fiat_currency
|
self._config["stake_currency"], fiat_currency
|
||||||
)
|
)
|
||||||
except RPCException:
|
except RPCException:
|
||||||
|
|||||||
@@ -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)
|
mocker.patch(f"{EXMS}._dry_is_price_crossed", return_value=False)
|
||||||
freqtradebot.enter_positions()
|
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 "Since" in headers
|
||||||
assert "Pair" in headers
|
assert "Pair" in headers
|
||||||
assert "now" == result[0][2]
|
assert "now" == result[0][2]
|
||||||
assert "ETH/BTC" in result[0][1]
|
assert "ETH/BTC" in result[0][1]
|
||||||
assert "0.00% (0.00)" == result[0][3]
|
assert "0.00% (0.00)" == result[0][3]
|
||||||
assert "0.00" == f"{fiat_profit_sum:.2f}"
|
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)
|
mocker.patch(f"{EXMS}._dry_is_price_crossed", return_value=True)
|
||||||
freqtradebot.process()
|
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 "Since" in headers
|
||||||
assert "Pair" in headers
|
assert "Pair" in headers
|
||||||
assert "now" == result[0][2]
|
assert "now" == result[0][2]
|
||||||
@@ -273,7 +278,9 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
|
|||||||
# Test with fiat convert
|
# Test with fiat convert
|
||||||
rpc._config["fiat_display_currency"] = "USD"
|
rpc._config["fiat_display_currency"] = "USD"
|
||||||
rpc._fiat_converter = CryptoToFiatConverter({})
|
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 "Since" in headers
|
||||||
assert "Pair" in headers
|
assert "Pair" in headers
|
||||||
assert len(result[0]) == 4
|
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 "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}"
|
assert "-0.06" == f"{fiat_profit_sum:.2f}"
|
||||||
|
assert "-0.06" == f"{total_sum:.2f}"
|
||||||
|
|
||||||
rpc._config["position_adjustment_enable"] = True
|
rpc._config["position_adjustment_enable"] = True
|
||||||
rpc._config["max_entry_position_adjustment"] = 3
|
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 "# Entries" in headers
|
||||||
assert len(result[0]) == 5
|
assert len(result[0]) == 5
|
||||||
# 4th column should be 1/4 - as 1 order filled (a total of 4 is possible)
|
# 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(
|
mocker.patch(
|
||||||
f"{EXMS}.get_rate", MagicMock(side_effect=ExchangeError("Pair 'ETH/BTC' not available"))
|
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 "now" == 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]
|
||||||
|
|||||||
Reference in New Issue
Block a user