From 8d182768f94fb0d26225a7218fbcaa63f43bc738 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 17 Aug 2022 09:51:28 +0200 Subject: [PATCH] stoploss should also use trimmed prices --- freqtrade/persistence/trade_model.py | 10 ++++++---- tests/rpc/test_rpc.py | 22 +++++++++++----------- tests/test_freqtradebot.py | 16 ++++++---------- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index 1c96d9b76..b954fee20 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -14,7 +14,7 @@ from freqtrade.constants import (DATETIME_PRINT_FORMAT, MATH_CLOSE_PREC, NON_OPE BuySell, LongShort) from freqtrade.enums import ExitType, TradingMode from freqtrade.exceptions import DependencyException, OperationalException -from freqtrade.exchange import amount_to_precision +from freqtrade.exchange import amount_to_precision, price_to_precision from freqtrade.leverage import interest from freqtrade.persistence.base import _DECL_BASE from freqtrade.util import FtPrecise @@ -527,9 +527,10 @@ class LocalTrade(): """ Method used internally to set self.stop_loss. """ + stop_loss_norm = price_to_precision(stop_loss, self.price_precision, self.precision_mode) if not self.stop_loss: - self.initial_stop_loss = stop_loss - self.stop_loss = stop_loss + self.initial_stop_loss = stop_loss_norm + self.stop_loss = stop_loss_norm self.stop_loss_pct = -1 * abs(percent) self.stoploss_last_update = datetime.utcnow() @@ -557,7 +558,8 @@ class LocalTrade(): # no stop loss assigned yet if self.initial_stop_loss_pct is None or refresh: self.__set_stop_loss(new_loss, stoploss) - self.initial_stop_loss = new_loss + self.initial_stop_loss = price_to_precision( + new_loss, self.price_precision, self.precision_mode) self.initial_stop_loss_pct = -1 * abs(stoploss) # evaluate if the stop loss needs to be updated diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index e28f6510d..7b42bf083 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -96,20 +96,20 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'profit_pct': -0.41, 'profit_abs': -4.09e-06, 'profit_fiat': ANY, - 'stop_loss_abs': 9.882e-06, + 'stop_loss_abs': 9.89e-06, 'stop_loss_pct': -10.0, 'stop_loss_ratio': -0.1, 'stoploss_order_id': None, 'stoploss_last_update': ANY, 'stoploss_last_update_timestamp': ANY, - 'initial_stop_loss_abs': 9.882e-06, + 'initial_stop_loss_abs': 9.89e-06, 'initial_stop_loss_pct': -10.0, 'initial_stop_loss_ratio': -0.1, - 'stoploss_current_dist': -1.1080000000000002e-06, - 'stoploss_current_dist_ratio': -0.10081893, - 'stoploss_current_dist_pct': -10.08, - 'stoploss_entry_dist': -0.00010475, - 'stoploss_entry_dist_ratio': -0.10448878, + 'stoploss_current_dist': pytest.approx(-1.0999999e-06), + 'stoploss_current_dist_ratio': -0.10009099, + 'stoploss_current_dist_pct': -10.01, + 'stoploss_entry_dist': -0.00010402, + 'stoploss_entry_dist_ratio': -0.10376381, 'open_order': None, 'realized_profit': 0.0, 'exchange': 'binance', @@ -181,20 +181,20 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'profit_pct': ANY, 'profit_abs': ANY, 'profit_fiat': ANY, - 'stop_loss_abs': 9.882e-06, + 'stop_loss_abs': 9.89e-06, 'stop_loss_pct': -10.0, 'stop_loss_ratio': -0.1, 'stoploss_order_id': None, 'stoploss_last_update': ANY, 'stoploss_last_update_timestamp': ANY, - 'initial_stop_loss_abs': 9.882e-06, + 'initial_stop_loss_abs': 9.89e-06, 'initial_stop_loss_pct': -10.0, 'initial_stop_loss_ratio': -0.1, 'stoploss_current_dist': ANY, 'stoploss_current_dist_ratio': ANY, 'stoploss_current_dist_pct': ANY, - 'stoploss_entry_dist': -0.00010475, - 'stoploss_entry_dist_ratio': -0.10448878, + 'stoploss_entry_dist': -0.00010402, + 'stoploss_entry_dist_ratio': -0.10376381, 'open_order': None, 'exchange': 'binance', 'realized_profit': 0.0, diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 0be469b75..c3d738075 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -4,7 +4,6 @@ import logging import time from copy import deepcopy -from math import isclose from typing import List from unittest.mock import ANY, MagicMock, PropertyMock, patch @@ -12,7 +11,7 @@ import arrow import pytest from pandas import DataFrame -from freqtrade.constants import CANCEL_REASON, MATH_CLOSE_PREC, UNLIMITED_STAKE_AMOUNT +from freqtrade.constants import CANCEL_REASON, UNLIMITED_STAKE_AMOUNT from freqtrade.enums import (CandleType, ExitCheckTuple, ExitType, RPCMessageType, RunMode, SignalDirection, State) from freqtrade.exceptions import (DependencyException, ExchangeError, InsufficientFundsError, @@ -569,7 +568,7 @@ def test_process_trade_creation(default_conf_usdt, ticker_usdt, limit_order, lim assert trade.open_date is not None assert trade.exchange == 'binance' assert trade.open_rate == ticker_usdt.return_value[ticker_side] - assert isclose(trade.amount, 60 / ticker_usdt.return_value[ticker_side]) + assert pytest.approx(trade.amount) == 60 / ticker_usdt.return_value[ticker_side] assert log_has( f'{"Short" if is_short else "Long"} signal found: about create a new trade for ETH/USDT ' @@ -1801,7 +1800,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, # stoploss initially at 20% as edge dictated it. assert freqtrade.handle_trade(trade) is False assert freqtrade.handle_stoploss_on_exchange(trade) is False - assert isclose(trade.stop_loss, 1.76) + assert pytest.approx(trade.stop_loss) == 1.76 cancel_order_mock = MagicMock() stoploss_order_mock = MagicMock() @@ -1818,7 +1817,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, assert freqtrade.handle_stoploss_on_exchange(trade) is False # stoploss should remain the same - assert isclose(trade.stop_loss, 1.76) + assert pytest.approx(trade.stop_loss) == 1.76 # stoploss on exchange should not be canceled cancel_order_mock.assert_not_called() @@ -4524,11 +4523,8 @@ def test_get_real_amount_wrong_amount_rounding(default_conf_usdt, trades_for_ord order_obj = Order.parse_from_ccxt_object(buy_order_fee, 'LTC/ETH', 'buy') # Amount changes by fee amount. - assert isclose( - freqtrade.get_real_amount(trade, limit_buy_order_usdt, order_obj), - amount - (amount * 0.001), - abs_tol=MATH_CLOSE_PREC, - ) + assert pytest.approx(freqtrade.get_real_amount( + trade, limit_buy_order_usdt, order_obj)) == amount - (amount * 0.001) def test_get_real_amount_open_trade_usdt(default_conf_usdt, fee, mocker):