diff --git a/freqtrade/persistence/models.py b/freqtrade/persistence/models.py index 9e44b73e0..f6f079cd3 100644 --- a/freqtrade/persistence/models.py +++ b/freqtrade/persistence/models.py @@ -237,7 +237,7 @@ class LocalTrade(): close_profit: Optional[float] = None close_profit_abs: Optional[float] = None stake_amount: float = 0.0 - amount: float = 0.0 + _amount: float = 0.0 amount_requested: Optional[float] = None open_date: datetime close_date: Optional[datetime] = None @@ -278,6 +278,17 @@ class LocalTrade(): # raise OperationalException('LocalTrade.pair must be assigned') # return self.pair.split("/")[1] + @property + def amount(self) -> float: + if self.leverage is not None: + return self._amount * self.leverage + else: + return self._amount + + @amount.setter + def amount(self, value): + self._amount = value + @property def leverage(self) -> float: return self._leverage @@ -422,7 +433,10 @@ class LocalTrade(): def _set_new_stoploss(self, new_loss: float, stoploss: float): """Assign new stop value""" self.stop_loss = new_loss - self.stop_loss_pct = -1 * abs(stoploss) + if self.is_short: + self.stop_loss_pct = abs(stoploss) + else: + self.stop_loss_pct = -1 * abs(stoploss) self.stoploss_last_update = datetime.utcnow() def adjust_stop_loss(self, current_price: float, stoploss: float, @@ -438,17 +452,24 @@ class LocalTrade(): # Don't modify if called with initial and nothing to do return - new_loss = float(current_price * (1 - abs(stoploss))) - # TODO: Could maybe move this if into the new stoploss if branch - if (self.liquidation_price): # If trading on margin, don't set the stoploss below the liquidation price - new_loss = min(self.liquidation_price, new_loss) + if self.is_short: + new_loss = float(current_price * (1 + abs(stoploss))) + if self.liquidation_price: # If trading on margin, don't set the stoploss below the liquidation price + new_loss = min(self.liquidation_price, new_loss) + else: + new_loss = float(current_price * (1 - abs(stoploss))) + if self.liquidation_price: # If trading on margin, don't set the stoploss below the liquidation price + new_loss = max(self.liquidation_price, new_loss) # no stop loss assigned yet if not self.stop_loss: logger.debug(f"{self.pair} - Assigning new stoploss...") self._set_new_stoploss(new_loss, stoploss) self.initial_stop_loss = new_loss - self.initial_stop_loss_pct = -1 * abs(stoploss) + if self.is_short: + self.initial_stop_loss_pct = abs(stoploss) + else: + self.initial_stop_loss_pct = -1 * abs(stoploss) # evaluate if the stop loss needs to be updated else: diff --git a/tests/test_persistence_short.py b/tests/test_persistence_short.py index 0c3c842ff..eaede6fc7 100644 --- a/tests/test_persistence_short.py +++ b/tests/test_persistence_short.py @@ -611,50 +611,51 @@ def test_interest_binance(market_short_order, ten_minutes_ago, five_hours_ago, f trade.calculate_interest(interest_rate=0.00025))), 0.0047912401421875) -# def test_adjust_stop_loss(fee): -# trade = Trade( -# pair='ETH/BTC', -# stake_amount=0.001, -# amount=5, -# fee_open=fee.return_value, -# fee_close=fee.return_value, -# exchange='binance', -# open_rate=1, -# max_rate=1, -# ) -# trade.adjust_stop_loss(trade.open_rate, 0.05, True) -# assert trade.stop_loss == 0.95 -# assert trade.stop_loss_pct == -0.05 -# assert trade.initial_stop_loss == 0.95 -# assert trade.initial_stop_loss_pct == -0.05 -# # Get percent of profit with a lower rate -# trade.adjust_stop_loss(0.96, 0.05) -# assert trade.stop_loss == 0.95 -# assert trade.stop_loss_pct == -0.05 -# assert trade.initial_stop_loss == 0.95 -# assert trade.initial_stop_loss_pct == -0.05 -# # Get percent of profit with a custom rate (Higher than open rate) -# trade.adjust_stop_loss(1.3, -0.1) -# assert round(trade.stop_loss, 8) == 1.17 -# assert trade.stop_loss_pct == -0.1 -# assert trade.initial_stop_loss == 0.95 -# assert trade.initial_stop_loss_pct == -0.05 -# # current rate lower again ... should not change -# trade.adjust_stop_loss(1.2, 0.1) -# assert round(trade.stop_loss, 8) == 1.17 -# assert trade.initial_stop_loss == 0.95 -# assert trade.initial_stop_loss_pct == -0.05 -# # current rate higher... should raise stoploss -# trade.adjust_stop_loss(1.4, 0.1) -# assert round(trade.stop_loss, 8) == 1.26 -# assert trade.initial_stop_loss == 0.95 -# assert trade.initial_stop_loss_pct == -0.05 -# # Initial is true but stop_loss set - so doesn't do anything -# trade.adjust_stop_loss(1.7, 0.1, True) -# assert round(trade.stop_loss, 8) == 1.26 -# assert trade.initial_stop_loss == 0.95 -# assert trade.initial_stop_loss_pct == -0.05 -# assert trade.stop_loss_pct == -0.1 +def test_adjust_stop_loss(fee): + trade = Trade( + pair='ETH/BTC', + stake_amount=0.001, + amount=5, + fee_open=fee.return_value, + fee_close=fee.return_value, + exchange='binance', + open_rate=1, + max_rate=1, + is_short=True + ) + trade.adjust_stop_loss(trade.open_rate, 0.05, True) + assert trade.stop_loss == 1.05 + assert trade.stop_loss_pct == 0.05 + assert trade.initial_stop_loss == 1.05 + assert trade.initial_stop_loss_pct == 0.05 + # Get percent of profit with a lower rate + trade.adjust_stop_loss(1.04, 0.05) + assert trade.stop_loss == 1.05 + assert trade.stop_loss_pct == 0.05 + assert trade.initial_stop_loss == 1.05 + assert trade.initial_stop_loss_pct == 0.05 + # Get percent of profit with a custom rate (Higher than open rate) + trade.adjust_stop_loss(0.7, 0.1) + # assert round(trade.stop_loss, 8) == 1.17 #TODO: What is this test? + assert trade.stop_loss_pct == 0.1 + assert trade.initial_stop_loss == 1.05 + assert trade.initial_stop_loss_pct == 0.05 + # current rate lower again ... should not change + trade.adjust_stop_loss(0.8, -0.1) + # assert round(trade.stop_loss, 8) == 1.17 #TODO: What is this test? + assert trade.initial_stop_loss == 1.05 + assert trade.initial_stop_loss_pct == 0.05 + # current rate higher... should raise stoploss + trade.adjust_stop_loss(0.6, -0.1) + # assert round(trade.stop_loss, 8) == 1.26 #TODO: What is this test? + assert trade.initial_stop_loss == 1.05 + assert trade.initial_stop_loss_pct == 0.05 + # Initial is true but stop_loss set - so doesn't do anything + trade.adjust_stop_loss(0.3, -0.1, True) + # assert round(trade.stop_loss, 8) == 1.26 #TODO: What is this test? + assert trade.initial_stop_loss == 1.05 + assert trade.initial_stop_loss_pct == 0.05 + assert trade.stop_loss_pct == 0.1 # def test_adjust_min_max_rates(fee): # trade = Trade( @@ -742,42 +743,6 @@ def test_interest_binance(market_short_order, ten_minutes_ago, five_hours_ago, f # assert trade_adj.initial_stop_loss == 0.96 # assert trade_adj.initial_stop_loss_pct == -0.04 -# def test_update_fee(fee): -# trade = Trade( -# pair='ETH/BTC', -# stake_amount=0.001, -# fee_open=fee.return_value, -# open_date=arrow.utcnow().shift(hours=-2).datetime, -# amount=10, -# fee_close=fee.return_value, -# exchange='binance', -# open_rate=1, -# max_rate=1, -# ) -# fee_cost = 0.15 -# fee_currency = 'BTC' -# fee_rate = 0.0075 -# assert trade.fee_open_currency is None -# assert not trade.fee_updated('buy') -# assert not trade.fee_updated('sell') -# trade.update_fee(fee_cost, fee_currency, fee_rate, 'buy') -# assert trade.fee_updated('buy') -# assert not trade.fee_updated('sell') -# assert trade.fee_open_currency == fee_currency -# assert trade.fee_open_cost == fee_cost -# assert trade.fee_open == fee_rate -# # Setting buy rate should "guess" close rate -# assert trade.fee_close == fee_rate -# assert trade.fee_close_currency is None -# assert trade.fee_close_cost is None -# fee_rate = 0.0076 -# trade.update_fee(fee_cost, fee_currency, fee_rate, 'sell') -# assert trade.fee_updated('buy') -# assert trade.fee_updated('sell') -# assert trade.fee_close == 0.0076 -# assert trade.fee_close_cost == fee_cost -# assert trade.fee_close == fee_rate - # @pytest.mark.usefixtures("init_persistence") # @pytest.mark.parametrize('use_db', [True, False]) # def test_total_open_trades_stakes(fee, use_db):