From c9403eb9464543d4b1ea50485b4c4f70c3c5914a Mon Sep 17 00:00:00 2001 From: Stefano Date: Fri, 22 Aug 2025 08:40:14 +0900 Subject: [PATCH 1/3] fix calc_profit_ratio to correctly fallback to available values when amount or open_rate is None --- freqtrade/persistence/trade_model.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index ee1f9d9ff..a60ecbf34 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -1181,15 +1181,19 @@ class LocalTrade: """ Calculates the profit as ratio (including fee). :param rate: rate to compare with. - :param amount: Amount to use for the calculation. Falls back to trade.amount if not set. + :param amount: Amount to use for the calculation. Falls back to self.amount if not set. :param open_rate: open_rate to use. Defaults to self.open_rate if not provided. :return: profit ratio as float """ close_trade_value = self.calc_close_trade_value(rate, amount) - if amount is None or open_rate is None: + if (amount is None) and (open_rate is None): open_trade_value = self.open_trade_value else: + if amount is None: + amount = self.amount + if open_rate is None: + open_rate = self.open_rate open_trade_value = self._calc_open_trade_value(amount, open_rate) if open_trade_value == 0.0: From 24f5096ec6f8c199d0ff54e70c5bf0c21f0be8e3 Mon Sep 17 00:00:00 2001 From: Stefano Date: Sat, 23 Aug 2025 17:23:56 +0900 Subject: [PATCH 2/3] modify test_handle_trade to test several cases of calc_profit_ratio --- freqtrade/persistence/trade_model.py | 2 +- tests/freqtradebot/test_freqtradebot.py | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index a60ecbf34..9760f6ff7 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -1181,7 +1181,7 @@ class LocalTrade: """ Calculates the profit as ratio (including fee). :param rate: rate to compare with. - :param amount: Amount to use for the calculation. Falls back to self.amount if not set. + :param amount: Amount to use for the calculation. Falls back to trade.amount if not set. :param open_rate: open_rate to use. Defaults to self.open_rate if not provided. :return: profit ratio as float """ diff --git a/tests/freqtradebot/test_freqtradebot.py b/tests/freqtradebot/test_freqtradebot.py index 7edf30d2d..2db24cdb9 100644 --- a/tests/freqtradebot/test_freqtradebot.py +++ b/tests/freqtradebot/test_freqtradebot.py @@ -1528,6 +1528,25 @@ def test_handle_trade( assert trade.close_date is not None assert trade.exit_reason == "sell_signal1" + correct_profit_ratio = trade.calc_profit_ratio( + rate=trade.close_rate, amount=trade.amount, open_rate=trade.open_rate + ) + profit_ratio_1 = trade.calc_profit_ratio(rate=trade.close_rate, open_rate=trade.open_rate) + profit_ratio_2 = trade.calc_profit_ratio( + rate=trade.close_rate, open_rate=trade.open_rate * 1.02 + ) + profit_ratio_3 = trade.calc_profit_ratio(rate=trade.close_rate, amount=trade.amount) + profit_ratio_4 = trade.calc_profit_ratio(rate=trade.close_rate) + profit_ratio_5 = trade.calc_profit_ratio( + rate=trade.close_rate, amount=trade.amount, open_rate=trade.open_rate * 1.02 + ) + assert correct_profit_ratio == close_profit + assert correct_profit_ratio == profit_ratio_1 + assert correct_profit_ratio != profit_ratio_2 + assert correct_profit_ratio == profit_ratio_3 + assert correct_profit_ratio == profit_ratio_4 + assert correct_profit_ratio != profit_ratio_5 + @pytest.mark.parametrize("is_short", [False, True]) def test_handle_overlapping_signals( @@ -5729,7 +5748,7 @@ def test_position_adjust2(mocker, default_conf_usdt, fee) -> None: @pytest.mark.parametrize( "data", [ - # tuple 1 - side amount, price + # tuple 1 - side, amount, price # tuple 2 - amount, open_rate, stake_amount, cumulative_profit, realized_profit, rel_profit ( (("buy", 100, 10), (100.0, 10.0, 1000.0, 0.0, None, None)), From ec4767acd521b8dd2ff12ff3fe0339e685d5f48f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 24 Aug 2025 14:44:22 +0200 Subject: [PATCH 3/3] chore: Simplify code slightly --- freqtrade/persistence/trade_model.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index 9760f6ff7..d898ea55e 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -1190,11 +1190,10 @@ class LocalTrade: if (amount is None) and (open_rate is None): open_trade_value = self.open_trade_value else: - if amount is None: - amount = self.amount - if open_rate is None: - open_rate = self.open_rate - open_trade_value = self._calc_open_trade_value(amount, open_rate) + # Fall back to trade.amount and self.open_rate if necessary + open_trade_value = self._calc_open_trade_value( + amount or self.amount, open_rate or self.open_rate + ) if open_trade_value == 0.0: return 0.0