Use proper profit calculations
This commit is contained in:
parent
1250c0a32b
commit
1fdd2e52e7
@ -1553,8 +1553,8 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
# TODO: Need to get "prediction" here (without persisting)
|
# TODO: Need to get "prediction" here (without persisting)
|
||||||
# trade.process_exit_sub_trade(order, is_closed=False)
|
# trade.process_exit_sub_trade(order, is_closed=False)
|
||||||
pass
|
pass
|
||||||
profit_ratio = trade.close_profit or 0.0
|
profit = trade.calc_profit(rate=profit_rate, amount=amount, open_rate=trade.open_rate)
|
||||||
profit = trade.close_profit_abs or 0.0
|
profit_ratio = trade.calc_profit_ratio(profit_rate, amount, trade.open_rate)
|
||||||
else:
|
else:
|
||||||
profit_rate = trade.close_rate if trade.close_rate else trade.close_rate_requested
|
profit_rate = trade.close_rate if trade.close_rate else trade.close_rate_requested
|
||||||
profit = trade.calc_profit(rate=profit_rate) + trade.realized_profit
|
profit = trade.calc_profit(rate=profit_rate) + trade.realized_profit
|
||||||
|
@ -636,29 +636,6 @@ class LocalTrade():
|
|||||||
raise ValueError(f'Unknown order type: {order.order_type}')
|
raise ValueError(f'Unknown order type: {order.order_type}')
|
||||||
Trade.commit()
|
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:
|
def close(self, rate: float, *, show_msg: bool = True) -> None:
|
||||||
"""
|
"""
|
||||||
Sets close_rate to the given rate, calculates total profit
|
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:
|
if rate is None and not self.close_rate:
|
||||||
return 0.0
|
return 0.0
|
||||||
|
|
||||||
amount = Decimal(amount or self.amount)
|
amount1 = Decimal(amount or self.amount)
|
||||||
trading_mode = self.trading_mode or TradingMode.SPOT
|
trading_mode = self.trading_mode or TradingMode.SPOT
|
||||||
|
|
||||||
if trading_mode == 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):
|
elif (trading_mode == TradingMode.MARGIN):
|
||||||
|
|
||||||
total_interest = self.calculate_interest()
|
total_interest = self.calculate_interest()
|
||||||
|
|
||||||
if self.is_short:
|
if self.is_short:
|
||||||
amount = amount + total_interest
|
amount1 = amount1 + total_interest
|
||||||
return float(self._calc_base_close(amount, rate, self.fee_close))
|
return float(self._calc_base_close(amount1, rate, self.fee_close))
|
||||||
else:
|
else:
|
||||||
# Currency already owned for longs, no need to purchase
|
# 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):
|
elif (trading_mode == TradingMode.FUTURES):
|
||||||
funding_fees = self.funding_fees or 0.0
|
funding_fees = self.funding_fees or 0.0
|
||||||
# Positive funding_fees -> Trade has gained from fees.
|
# Positive funding_fees -> Trade has gained from fees.
|
||||||
# Negative funding_fees -> Trade had to pay the fees.
|
# Negative funding_fees -> Trade had to pay the fees.
|
||||||
if self.is_short:
|
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:
|
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:
|
else:
|
||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
f"{self.trading_mode.value} trading is not yet available using freqtrade")
|
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
|
profit = close_trade_value - open_trade_value
|
||||||
return float(f"{profit:.8f}")
|
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(
|
def calc_profit_ratio(
|
||||||
self, rate: float, amount: float = None, open_rate: float = None) -> float:
|
self, rate: float, amount: float = None, open_rate: float = None) -> float:
|
||||||
"""
|
"""
|
||||||
@ -890,7 +859,7 @@ class LocalTrade():
|
|||||||
exit_rate = o.safe_price
|
exit_rate = o.safe_price
|
||||||
exit_amount = o.safe_amount_after_fee
|
exit_amount = o.safe_amount_after_fee
|
||||||
exit_stake_amount = exit_rate * exit_amount * (1 - self.fee_close)
|
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:
|
if total_amount > 0:
|
||||||
# Exclude final (closing) trade
|
# Exclude final (closing) trade
|
||||||
close_profit_abs += profit
|
close_profit_abs += profit
|
||||||
|
@ -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, 1.9, 0.003, -3.3209999, -0.055211970, spot, 0),
|
||||||
('binance', False, 1, 2.2, 0.003, 5.6520000, 0.093965087, 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, 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', 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),
|
('binance', True, 1, 2.1, 0.0025, -2.3074999, -0.03855472, futures, 1),
|
||||||
|
Loading…
Reference in New Issue
Block a user