calc_profits should allow custom open and amount parameters
This commit is contained in:
parent
6bdf9c2a94
commit
ade65fc274
@ -674,12 +674,12 @@ class LocalTrade():
|
|||||||
"""
|
"""
|
||||||
return len([o for o in self.orders if o.ft_order_side == self.exit_side])
|
return len([o for o in self.orders if o.ft_order_side == self.exit_side])
|
||||||
|
|
||||||
def _calc_open_trade_value(self) -> float:
|
def _calc_open_trade_value(self, amount: float, open_rate: float) -> float:
|
||||||
"""
|
"""
|
||||||
Calculate the open_rate including open_fee.
|
Calculate the open_rate including open_fee.
|
||||||
:return: Price in of the open trade incl. Fees
|
:return: Price in of the open trade incl. Fees
|
||||||
"""
|
"""
|
||||||
open_trade = Decimal(self.amount) * Decimal(self.open_rate)
|
open_trade = Decimal(amount) * Decimal(open_rate)
|
||||||
fees = open_trade * Decimal(self.fee_open)
|
fees = open_trade * Decimal(self.fee_open)
|
||||||
if self.is_short:
|
if self.is_short:
|
||||||
return float(open_trade - fees)
|
return float(open_trade - fees)
|
||||||
@ -691,7 +691,7 @@ class LocalTrade():
|
|||||||
Recalculate open_trade_value.
|
Recalculate open_trade_value.
|
||||||
Must be called whenever open_rate, fee_open is changed.
|
Must be called whenever open_rate, fee_open is changed.
|
||||||
"""
|
"""
|
||||||
self.open_trade_value = self._calc_open_trade_value()
|
self.open_trade_value = self._calc_open_trade_value(self.amount, self.open_rate)
|
||||||
|
|
||||||
def calculate_interest(self) -> Decimal:
|
def calculate_interest(self) -> Decimal:
|
||||||
"""
|
"""
|
||||||
@ -723,7 +723,7 @@ class LocalTrade():
|
|||||||
else:
|
else:
|
||||||
return close_trade - fees
|
return close_trade - fees
|
||||||
|
|
||||||
def calc_close_trade_value(self, rate: float) -> float:
|
def calc_close_trade_value(self, rate: float, amount: float = None) -> float:
|
||||||
"""
|
"""
|
||||||
Calculate the Trade's close value including fees
|
Calculate the Trade's close value including fees
|
||||||
:param rate: rate to compare with.
|
:param rate: rate to compare with.
|
||||||
@ -732,7 +732,7 @@ 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(self.amount)
|
amount = 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:
|
||||||
@ -761,39 +761,53 @@ class LocalTrade():
|
|||||||
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")
|
||||||
|
|
||||||
def calc_profit(self, rate: float) -> float:
|
def calc_profit(self, rate: float, amount: float = None, open_rate: float = None) -> float:
|
||||||
"""
|
"""
|
||||||
Calculate the absolute profit in stake currency between Close and Open trade
|
Calculate the absolute profit in stake currency between Close and Open trade
|
||||||
:param rate: close rate to compare with.
|
: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: profit in stake currency as float
|
:return: profit in stake currency as float
|
||||||
"""
|
"""
|
||||||
close_trade_value = self.calc_close_trade_value(rate)
|
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:
|
if self.is_short:
|
||||||
profit = self.open_trade_value - close_trade_value
|
profit = open_trade_value - close_trade_value
|
||||||
else:
|
else:
|
||||||
profit = close_trade_value - self.open_trade_value
|
profit = close_trade_value - open_trade_value
|
||||||
return float(f"{profit:.8f}")
|
return float(f"{profit:.8f}")
|
||||||
|
|
||||||
def calc_profit_ratio(self, rate: float) -> float:
|
def calc_profit_ratio(
|
||||||
|
self, rate: float, amount: float = None, open_rate: float = None) -> float:
|
||||||
"""
|
"""
|
||||||
Calculates the profit as ratio (including fee).
|
Calculates the profit as ratio (including fee).
|
||||||
:param rate: rate to compare with.
|
:param rate: 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: profit ratio as float
|
:return: profit ratio as float
|
||||||
"""
|
"""
|
||||||
close_trade_value = self.calc_close_trade_value(rate)
|
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)
|
||||||
|
|
||||||
short_close_zero = (self.is_short and close_trade_value == 0.0)
|
short_close_zero = (self.is_short and close_trade_value == 0.0)
|
||||||
long_close_zero = (not self.is_short and self.open_trade_value == 0.0)
|
long_close_zero = (not self.is_short and open_trade_value == 0.0)
|
||||||
leverage = self.leverage or 1.0
|
leverage = self.leverage or 1.0
|
||||||
|
|
||||||
if (short_close_zero or long_close_zero):
|
if (short_close_zero or long_close_zero):
|
||||||
return 0.0
|
return 0.0
|
||||||
else:
|
else:
|
||||||
if self.is_short:
|
if self.is_short:
|
||||||
profit_ratio = (1 - (close_trade_value / self.open_trade_value)) * leverage
|
profit_ratio = (1 - (close_trade_value / open_trade_value)) * leverage
|
||||||
else:
|
else:
|
||||||
profit_ratio = ((close_trade_value / self.open_trade_value) - 1) * leverage
|
profit_ratio = ((close_trade_value / open_trade_value) - 1) * leverage
|
||||||
|
|
||||||
return float(f"{profit_ratio:.8f}")
|
return float(f"{profit_ratio:.8f}")
|
||||||
|
|
||||||
|
@ -605,7 +605,7 @@ def test_calc_open_close_trade_price(
|
|||||||
trade.open_rate = 2.0
|
trade.open_rate = 2.0
|
||||||
trade.close_rate = 2.2
|
trade.close_rate = 2.2
|
||||||
trade.recalc_open_trade_value()
|
trade.recalc_open_trade_value()
|
||||||
assert isclose(trade._calc_open_trade_value(), open_value)
|
assert isclose(trade._calc_open_trade_value(trade.amount, trade.open_rate), open_value)
|
||||||
assert isclose(trade.calc_close_trade_value(trade.close_rate), close_value)
|
assert isclose(trade.calc_close_trade_value(trade.close_rate), close_value)
|
||||||
assert isclose(trade.calc_profit(trade.close_rate), round(profit, 8))
|
assert isclose(trade.calc_profit(trade.close_rate), round(profit, 8))
|
||||||
assert pytest.approx(trade.calc_profit_ratio(trade.close_rate)) == profit_ratio
|
assert pytest.approx(trade.calc_profit_ratio(trade.close_rate)) == profit_ratio
|
||||||
@ -763,7 +763,7 @@ def test_calc_open_trade_value(
|
|||||||
trade.update_trade(oobj) # Buy @ 2.0
|
trade.update_trade(oobj) # Buy @ 2.0
|
||||||
|
|
||||||
# Get the open rate price with the standard fee rate
|
# Get the open rate price with the standard fee rate
|
||||||
assert trade._calc_open_trade_value() == result
|
assert trade._calc_open_trade_value(trade.amount, trade.open_rate) == result
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
@ -1139,6 +1139,11 @@ def test_calc_profit(
|
|||||||
assert pytest.approx(trade.calc_profit(rate=close_rate)) == round(profit, 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)
|
assert pytest.approx(trade.calc_profit_ratio(rate=close_rate)) == 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,
|
||||||
|
trade.open_rate)) == round(profit_ratio, 8)
|
||||||
|
|
||||||
|
|
||||||
def test_migrate_new(mocker, default_conf, fee, caplog):
|
def test_migrate_new(mocker, default_conf, fee, caplog):
|
||||||
"""
|
"""
|
||||||
@ -1298,7 +1303,7 @@ def test_migrate_new(mocker, default_conf, fee, caplog):
|
|||||||
assert log_has("trying trades_bak2", caplog)
|
assert log_has("trying trades_bak2", caplog)
|
||||||
assert log_has("Running database migration for trades - backup: trades_bak2, orders_bak0",
|
assert log_has("Running database migration for trades - backup: trades_bak2, orders_bak0",
|
||||||
caplog)
|
caplog)
|
||||||
assert trade.open_trade_value == trade._calc_open_trade_value()
|
assert trade.open_trade_value == trade._calc_open_trade_value(trade.amount, trade.open_rate)
|
||||||
assert trade.close_profit_abs is None
|
assert trade.close_profit_abs is None
|
||||||
|
|
||||||
orders = trade.orders
|
orders = trade.orders
|
||||||
@ -2308,7 +2313,7 @@ def test_recalc_trade_from_orders(fee):
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert fee.return_value == 0.0025
|
assert fee.return_value == 0.0025
|
||||||
assert trade._calc_open_trade_value() == o1_trade_val
|
assert trade._calc_open_trade_value(trade.amount, trade.open_rate) == o1_trade_val
|
||||||
assert trade.amount == o1_amount
|
assert trade.amount == o1_amount
|
||||||
assert trade.stake_amount == o1_cost
|
assert trade.stake_amount == o1_cost
|
||||||
assert trade.open_rate == o1_rate
|
assert trade.open_rate == o1_rate
|
||||||
|
Loading…
Reference in New Issue
Block a user