From e4ca42faec580a3c336298d42402fec0d8e56f93 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Sat, 18 Sep 2021 10:18:33 +0300 Subject: [PATCH] [SQUASH] Update stoploss_from_absolute to behave more like stoploss_from_open and add a test for it. --- freqtrade/strategy/strategy_helper.py | 16 +++++++++++++++- tests/strategy/test_strategy_helpers.py | 11 ++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/freqtrade/strategy/strategy_helper.py b/freqtrade/strategy/strategy_helper.py index f813b39c5..175bcaccb 100644 --- a/freqtrade/strategy/strategy_helper.py +++ b/freqtrade/strategy/strategy_helper.py @@ -97,8 +97,22 @@ def stoploss_from_absolute(stop_rate: float, current_rate: float) -> float: """ Given current price and desired stop price, return a stop loss value that is relative to current price. + + The requested stop can be positive for a stop above the open price, or negative for + a stop below the open price. The return value is always >= 0. + + Returns 0 if the resulting stop price would be above the current price. + :param stop_rate: Stop loss price. :param current_rate: Current asset price. :return: Positive stop loss value relative to current price """ - return 1 - (stop_rate / current_rate) + + # formula is undefined for current_rate 0, return maximum value + if current_rate == 0: + return 1 + + stoploss = 1 - (stop_rate / current_rate) + + # negative stoploss values indicate the requested stop price is higher than the current price + return max(stoploss, 0.0) diff --git a/tests/strategy/test_strategy_helpers.py b/tests/strategy/test_strategy_helpers.py index d4206ba8c..9132382fa 100644 --- a/tests/strategy/test_strategy_helpers.py +++ b/tests/strategy/test_strategy_helpers.py @@ -5,7 +5,8 @@ import pandas as pd import pytest from freqtrade.data.dataprovider import DataProvider -from freqtrade.strategy import merge_informative_pair, stoploss_from_open, timeframe_to_minutes +from freqtrade.strategy import (merge_informative_pair, stoploss_from_open, timeframe_to_minutes, + stoploss_from_absolute) def generate_test_data(timeframe: str, size: int): @@ -135,6 +136,14 @@ def test_stoploss_from_open(): assert isclose(stop_price, expected_stop_price, rel_tol=0.00001) +def test_stoploss_from_absolute(): + assert stoploss_from_absolute(90, 100) == 1 - (90 / 100) + assert stoploss_from_absolute(100, 100) == 0 + assert stoploss_from_absolute(110, 100) == 0 + assert stoploss_from_absolute(100, 0) == 1 + assert stoploss_from_absolute(0, 100) == 1 + + def test_informative_decorator(mocker, default_conf): test_data_5m = generate_test_data('5m', 40) test_data_30m = generate_test_data('30m', 40)