From aee2591490b442a731c8efb039658e8230958cd5 Mon Sep 17 00:00:00 2001 From: Brook Miles Date: Wed, 17 Mar 2021 17:58:23 +0900 Subject: [PATCH] add stoploss_from_open() as a strategy_helper --- docs/strategy-customization.md | 36 +++++++++++++++++++++++++++ freqtrade/strategy/__init__.py | 1 + freqtrade/strategy/strategy_helper.py | 18 ++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index a1708a481..bf086bc0a 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -587,6 +587,42 @@ All columns of the informative dataframe will be available on the returning data *** +### *stoploss_from_open()* + +Stoploss values returned from `custom_stoploss` must specify a percentage relative to `current_rate`, but sometimes you may want to specify a stoploss relative to the open price instead. `stoploss_from_open()` is a helper function to calculate a stoploss value that can be returned from `custom_stoploss` which will be equivalent to the desired percentage above the open price. + +??? Example "Returning a stoploss relative to the open price from the custom stoploss function" + + Say the open price was $100, and `current_price` is $121 (`current_profit` will be `0.21`). + + If we want a stop price at 7% above the open price we can call `stoploss_from_open(0.07, current_profit)` which will return `0.1157024793`. 11.57% below $121 is $107, which is the same as 7% above $100. + + + ``` python + + from freqtrade.strategy import IStrategy, stoploss_from_open + from datetime import datetime + from freqtrade.persistence import Trade + + class AwesomeStrategy(IStrategy): + + # ... populate_* methods + + use_custom_stoploss = True + + def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime, + current_rate: float, current_profit: float, **kwargs) -> float: + + # once the profit has risin above 10%, keep the stoploss at 7% above the open price + if current_profit > 0.10: + return stoploss_from_open(0.07, current_profit) + + return 1 + + ``` + + + ## Additional data (Wallets) The strategy provides access to the `Wallets` object. This contains the current balances on the exchange. diff --git a/freqtrade/strategy/__init__.py b/freqtrade/strategy/__init__.py index 662156ae9..3de90666e 100644 --- a/freqtrade/strategy/__init__.py +++ b/freqtrade/strategy/__init__.py @@ -3,3 +3,4 @@ from freqtrade.exchange import (timeframe_to_minutes, timeframe_to_msecs, timefr timeframe_to_prev_date, timeframe_to_seconds) from freqtrade.strategy.interface import IStrategy from freqtrade.strategy.strategy_helper import merge_informative_pair +from freqtrade.strategy.strategy_helper import stoploss_from_open diff --git a/freqtrade/strategy/strategy_helper.py b/freqtrade/strategy/strategy_helper.py index d7b1327d9..f40fa285d 100644 --- a/freqtrade/strategy/strategy_helper.py +++ b/freqtrade/strategy/strategy_helper.py @@ -56,3 +56,21 @@ def merge_informative_pair(dataframe: pd.DataFrame, informative: pd.DataFrame, dataframe = dataframe.ffill() return dataframe + + +def stoploss_from_open(open_relative_stop: float, current_profit: float) -> float: + """ + + Given the current profit, and a desired stop loss value relative to the open price, + return a stop loss value that is relative to the current price, and which can be + returned from `custom_stoploss`. + + :param open_relative_stop: Desired stop loss value relative to open price + :param current_profit: The current profit percentage + :return: Stop loss value relative to current price + """ + + if current_profit == -1: + return 1 + + return 1-((1+open_relative_stop)/(1+current_profit))