diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 923511341..7aab0cdc7 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1553,8 +1553,8 @@ class FreqtradeBot(LoggingMixin): # TODO: Need to get "prediction" here (without persisting) # trade.process_exit_sub_trade(order, is_closed=False) pass - profit_ratio = trade.close_profit or 0.0 - profit = trade.close_profit_abs or 0.0 + profit = trade.calc_profit(rate=profit_rate, amount=amount, open_rate=trade.open_rate) + profit_ratio = trade.calc_profit_ratio(profit_rate, amount, trade.open_rate) else: profit_rate = trade.close_rate if trade.close_rate else trade.close_rate_requested profit = trade.calc_profit(rate=profit_rate) + trade.realized_profit diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index e8dbc3504..a813d16b8 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -636,29 +636,6 @@ class LocalTrade(): raise ValueError(f'Unknown order type: {order.order_type}') Trade.commit() - def process_exit_sub_trade(self, order: Order, is_closed: bool = True) -> None: - """ - Recalculate trade amount and realized profit after partial exit - """ - exit_amount = order.safe_amount_after_fee - exit_rate = order.safe_price - exit_stake_amount = exit_rate * exit_amount * (1 - self.fee_close) - profit = self.calc_profit2(self.open_rate, exit_rate, exit_amount) * int(self.leverage) - if self.is_short: - profit *= -1 - if is_closed: - self.amount -= exit_amount - self.stake_amount = self.open_rate * self.amount - self.realized_profit += profit - # logger.info(f"Processed exit sub trade for {self}") - self.close_profit_abs = profit - if self.is_short: - self.close_profit = (exit_stake_amount - profit) / exit_stake_amount - 1 - else: - self.close_profit = exit_stake_amount / (exit_stake_amount - profit) - 1 - - self.recalc_open_trade_value() - def close(self, rate: float, *, show_msg: bool = True) -> None: """ Sets close_rate to the given rate, calculates total profit @@ -774,31 +751,31 @@ class LocalTrade(): if rate is None and not self.close_rate: return 0.0 - amount = Decimal(amount or self.amount) + amount1 = Decimal(amount or self.amount) trading_mode = self.trading_mode or TradingMode.SPOT if trading_mode == TradingMode.SPOT: - return float(self._calc_base_close(amount, rate, self.fee_close)) + return float(self._calc_base_close(amount1, rate, self.fee_close)) elif (trading_mode == TradingMode.MARGIN): total_interest = self.calculate_interest() if self.is_short: - amount = amount + total_interest - return float(self._calc_base_close(amount, rate, self.fee_close)) + amount1 = amount1 + total_interest + return float(self._calc_base_close(amount1, rate, self.fee_close)) else: # Currency already owned for longs, no need to purchase - return float(self._calc_base_close(amount, rate, self.fee_close) - total_interest) + return float(self._calc_base_close(amount1, rate, self.fee_close) - total_interest) elif (trading_mode == TradingMode.FUTURES): funding_fees = self.funding_fees or 0.0 # Positive funding_fees -> Trade has gained from fees. # Negative funding_fees -> Trade had to pay the fees. if self.is_short: - return float(self._calc_base_close(amount, rate, self.fee_close)) - funding_fees + return float(self._calc_base_close(amount1, rate, self.fee_close)) - funding_fees else: - return float(self._calc_base_close(amount, rate, self.fee_close)) + funding_fees + return float(self._calc_base_close(amount1, rate, self.fee_close)) + funding_fees else: raise OperationalException( f"{self.trading_mode.value} trading is not yet available using freqtrade") @@ -823,14 +800,6 @@ class LocalTrade(): profit = close_trade_value - open_trade_value return float(f"{profit:.8f}") - def calc_profit2(self, open_rate: float, close_rate: float, - amount: float) -> float: - # TODO: This is almost certainly wrong for margin/short scenarios. - # Needs investigation. - return float(Decimal(amount) - * (Decimal(1 - self.fee_close) * Decimal(close_rate) - - Decimal(1 + self.fee_open) * Decimal(open_rate))) - def calc_profit_ratio( self, rate: float, amount: float = None, open_rate: float = None) -> float: """ @@ -890,7 +859,7 @@ class LocalTrade(): exit_rate = o.safe_price exit_amount = o.safe_amount_after_fee exit_stake_amount = exit_rate * exit_amount * (1 - self.fee_close) - profit = self.calc_profit2(avg_price, exit_rate, exit_amount) * int(self.leverage) + profit = self.calc_profit(rate=exit_rate, amount=exit_amount, open_rate=avg_price) if total_amount > 0: # Exclude final (closing) trade close_profit_abs += profit diff --git a/tests/test_persistence.py b/tests/test_persistence.py index d344fde6a..abcdbb982 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -853,7 +853,7 @@ def test_calc_close_trade_price( ('binance', False, 1, 1.9, 0.003, -3.3209999, -0.055211970, spot, 0), ('binance', False, 1, 2.2, 0.003, 5.6520000, 0.093965087, spot, 0), - # # FUTURES, funding_fee=1 + # FUTURES, funding_fee=1 ('binance', False, 1, 2.1, 0.0025, 3.6925, 0.06138819, futures, 1), ('binance', False, 3, 2.1, 0.0025, 3.6925, 0.18416458, futures, 1), ('binance', True, 1, 2.1, 0.0025, -2.3074999, -0.03855472, futures, 1),