From c753bd0ddca98b56fdfb6efe7642140a34fecbe6 Mon Sep 17 00:00:00 2001 From: Sam Germain Date: Thu, 8 Jul 2021 05:37:54 -0600 Subject: [PATCH] updated ratio_calc_profit function --- freqtrade/persistence/models.py | 32 ++++++++----- tests/persistence/test_persistence.py | 47 +++++++++++++++---- .../persistence/test_persistence_leverage.py | 8 ++-- 3 files changed, 63 insertions(+), 24 deletions(-) diff --git a/freqtrade/persistence/models.py b/freqtrade/persistence/models.py index 2c9d9604f..85c908594 100644 --- a/freqtrade/persistence/models.py +++ b/freqtrade/persistence/models.py @@ -609,12 +609,14 @@ class LocalTrade(): def update_order(self, order: Dict) -> None: Order.update_orders(self.orders, order) - def _calc_open_trade_value(self) -> float: + def _calc_open_trade_value(self, amount: Optional[float] = None) -> float: """ Calculate the open_rate including open_fee. :return: Price in of the open trade incl. Fees """ - open_trade = Decimal(self.amount) * Decimal(self.open_rate) + if amount is None: + amount = self.amount + open_trade = Decimal(amount) * Decimal(self.open_rate) fees = open_trade * Decimal(self.fee_open) if self.is_short: return float(open_trade - fees) @@ -651,6 +653,7 @@ class LocalTrade(): return self.interest_mode(borrowed=borrowed, rate=rate, hours=hours) def calc_close_trade_value(self, rate: Optional[float] = None, + fee: Optional[float] = None, interest_rate: Optional[float] = None) -> float: """ @@ -718,23 +721,30 @@ class LocalTrade(): If interest_rate is not set self.interest_rate will be used :return: profit ratio as float """ + close_trade_value = self.calc_close_trade_value( rate=(rate or self.close_rate), fee=(fee or self.fee_close), interest_rate=(interest_rate or self.interest_rate) ) - if ((self.is_short and close_trade_value == 0.0) or - (not self.is_short and self.open_trade_value == 0.0)): + + if self.leverage is None: + leverage = 1.0 + else: + leverage = self.leverage + + stake_value = self._calc_open_trade_value(amount=(self.amount/leverage)) + + 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) + + if (short_close_zero or long_close_zero): return 0.0 else: - if self.has_no_leverage: - # TODO-mg: Use one profit_ratio calculation - profit_ratio = (close_trade_value/self.open_trade_value) - 1 + if self.is_short: + profit_ratio = ((self.open_trade_value - close_trade_value) / stake_value) else: - if self.is_short: - profit_ratio = ((self.open_trade_value - close_trade_value) / self.stake_amount) - else: - profit_ratio = ((close_trade_value - self.open_trade_value) / self.stake_amount) + profit_ratio = ((close_trade_value - self.open_trade_value) / stake_value) return float(f"{profit_ratio:.8f}") diff --git a/tests/persistence/test_persistence.py b/tests/persistence/test_persistence.py index 645947f76..de92139b4 100644 --- a/tests/persistence/test_persistence.py +++ b/tests/persistence/test_persistence.py @@ -114,20 +114,49 @@ def test_update_with_binance(limit_buy_order, limit_sell_order, fee, caplog): - Buy: 90.99181073 Crypto at 0.00001099 BTC (90.99181073*0.00001099 = 0.0009999 BTC) - Buying fee: 0.25% - - Total cost of buy trade: 0.001002500 BTC - ((90.99181073*0.00001099) + ((90.99181073*0.00001099)*0.0025)) + - open_trade_value: 0.0010024999999225066 BTC + (90.99181073*0.00001099) + ((90.99181073*0.00001099)*0.0025) Sell - Sell: 90.99181073 Crypto at 0.00001173 BTC - (90.99181073*0.00001173 = 0,00106733394 BTC) + (90.99181073*0.00001173 = 0.0010673339398629 BTC) - Selling fee: 0.25% - - Total cost of sell trade: 0.001064666 BTC - ((90.99181073*0.00001173) - ((90.99181073*0.00001173)*0.0025)) + - close_trade_value: 0.0010646656050132426 BTC + (90.99181073*0.00001173) - ((90.99181073*0.00001173)*0.0025) - Profit/Loss: +0.000062166 BTC - (Sell:0.001064666 - Buy:0.001002500) + Profit/Loss: +6.216560509073607e-05 BTC + (Sell:0.0010646656050132426 - Buy:0.0010024999999225066) Profit/Loss percentage: 0.0620 - ((0.001064666/0.001002500)-1 = 6.20%) + (0.0010646656050132426/0.0010024999999225066)-1 = 6.20% + = 0.062010578648919124 + 6.216560509073607e-05 / 0.0010024999999225066 + = 0.062010578648919186 + + amount = 90.99181073 Crypto + stake_amount = 0.0009999999999226999 + open_rate = 0.00001099 + close_rate = 0.00001173 + fee: 0.0025 (0.25%) + + open_trade_value = (amount * open_rate) + (amount * open_rate * fee) + = (90.99181073*0.00001099) + ((90.99181073*0.00001099)*0.0025) + = 0.0010024999999225066 + + close_trade_value = (amount * close_rate) - (amount * close_rate * fee) + = (90.99181073*0.00001173) - ((90.99181073*0.00001173)*0.0025) + = 0.0010646656050132426 + + #? ORIGINAL PROFIT RATIO CALCULATION + #? (close_trade_value/open_trade_value)-1 = original_answer + #? (0.0010646656050132426/0.0010024999999225066)-1 = 0.062010578648919 + + #? NEW PROFIT RATIO CALCULATION 1 + #? (close_trade_value - open_trade_value)/stake_amount = new_answer + #? (0.0010646656050132426 - 0.0010024999999225068)/0.0009999999999226999 = 0.06216560509554 + + #? NEW PROFIT RATIO CALCULATION 2 + #? (close_trade_value - open_trade_value)/open_trade_value = original_answer + #? (0.0010646656050132426 - 0.0010024999999225066)/0.0010024999999225066 = 0.062010578648919 :param limit_buy_order: :param limit_sell_order: @@ -137,7 +166,7 @@ def test_update_with_binance(limit_buy_order, limit_sell_order, fee, caplog): trade = Trade( id=2, pair='ETH/BTC', - stake_amount=0.001, + stake_amount=0.0009999999999226999, open_rate=0.01, amount=5, is_open=True, diff --git a/tests/persistence/test_persistence_leverage.py b/tests/persistence/test_persistence_leverage.py index 2326f92af..7aac986cb 100644 --- a/tests/persistence/test_persistence_leverage.py +++ b/tests/persistence/test_persistence_leverage.py @@ -231,9 +231,9 @@ def test_calc_open_close_trade_price_lev(limit_lev_buy_order, limit_lev_sell_ord total_profit = close_value - open_value = 0.003193788481706411 - 0.0030074999997675204 = 0.00018628848193889044 - total_profit_percentage = total_profit / stake_amount - = 0.00018628848193889054 / 0.0009999999999226999 - = 0.18628848195329067 + total_profit_percentage = total_profit / open_value + = 0.00018628848193889054 / 0.0030074999997675204 + = 0.06194130738264028 """ trade = Trade( pair='ETH/BTC', @@ -257,7 +257,7 @@ def test_calc_open_close_trade_price_lev(limit_lev_buy_order, limit_lev_sell_ord # Profit in BTC assert round(trade.calc_profit(), 8) == round(0.00018628848193889054, 8) # Profit in percent - assert round(trade.calc_profit_ratio(), 8) == round(0.18628848195329067, 8) + assert round(trade.calc_profit_ratio(), 8) == round(0.06194130738264028, 8) @pytest.mark.usefixtures("init_persistence")