From c58a1649cb0d016cd3996e31d5ca582a7eb98424 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 29 Aug 2023 20:18:19 +0200 Subject: [PATCH] add calc_profit_combined call --- freqtrade/persistence/trade_model.py | 46 +++++++++++++++++++++++++++ tests/persistence/test_persistence.py | 15 +++++++++ 2 files changed, 61 insertions(+) diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index 6f31444d4..705fc5d7b 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -905,6 +905,52 @@ class LocalTrade: profit = close_trade_value - open_trade_value return float(f"{profit:.8f}") + def calc_profit_combined(self, rate: float, amount: Optional[float] = None, + open_rate: Optional[float] = None): + """ + Calculate profit metrics (absolute, ratio, total, total ratio). + All calculations include fees. + :param rate: close rate to compare with. + :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: TODO: fill me out + """ + + close_trade_value = self.calc_close_trade_value(rate, amount) + if amount is None or open_rate is None: + open_trade_value = self.open_trade_value + else: + open_trade_value = self._calc_open_trade_value(amount, open_rate) + + if self.is_short: + profit_abs = open_trade_value - close_trade_value + else: + profit_abs = close_trade_value - open_trade_value + + try: + if self.is_short: + profit_ratio = (1 - (close_trade_value / open_trade_value)) * self.leverage + else: + profit_ratio = ((close_trade_value / open_trade_value) - 1) * self.leverage + profit_ratio = float(f"{profit_ratio:.8f}") + except ZeroDivisionError: + profit_ratio = 0.0 + + total_profit_abs = profit_abs + self.realized_profit + total_profit_ratio = ( + (total_profit_abs / self.max_stake_amount) * self.leverage + if self.max_stake_amount else 0.0 + ) + total_profit_ratio = float(f"{total_profit_ratio:.8f}") + profit_abs = float(f"{profit_abs:.8f}") + res = { + 'profit_abs': profit_abs, + 'profit_ratio': profit_ratio, + 'total_profit': profit_abs + self.realized_profit, + 'total_profit_ratio': total_profit_ratio, + } + return res + def calc_profit_ratio( self, rate: float, amount: Optional[float] = None, open_rate: Optional[float] = None) -> float: diff --git a/tests/persistence/test_persistence.py b/tests/persistence/test_persistence.py index e4802da87..d69d986cc 100644 --- a/tests/persistence/test_persistence.py +++ b/tests/persistence/test_persistence.py @@ -1152,14 +1152,29 @@ def test_calc_profit( leverage=lev, fee_open=0.0025, fee_close=fee_close, + max_stake_amount=60.0, trading_mode=trading_mode, funding_fees=funding_fees ) trade.open_order_id = 'something' + profit_res = trade.calc_profit_combined(close_rate) + assert pytest.approx(profit_res['profit_abs']) == round(profit, 8) + assert pytest.approx(profit_res['profit_ratio']) == round(profit_ratio, 8) + + assert pytest.approx(profit_res['total_profit']) == round(profit, 8) + # assert pytest.approx(profit_res['total_profit_ratio']) == round(profit_ratio, 8) + assert pytest.approx(trade.calc_profit(rate=close_rate)) == round(profit, 8) assert pytest.approx(trade.calc_profit_ratio(rate=close_rate)) == round(profit_ratio, 8) + profit_res2 = trade.calc_profit_combined(close_rate, trade.amount, trade.open_rate) + assert pytest.approx(profit_res2['profit_abs']) == round(profit, 8) + assert pytest.approx(profit_res2['profit_ratio']) == round(profit_ratio, 8) + + assert pytest.approx(profit_res2['total_profit']) == round(profit, 8) + # assert pytest.approx(profit_res2['total_profit_ratio']) == round(profit_ratio, 8) + assert pytest.approx(trade.calc_profit(close_rate, trade.amount, trade.open_rate)) == round(profit, 8) assert pytest.approx(trade.calc_profit_ratio(close_rate, trade.amount,