Allow None from custom_stop

This commit is contained in:
Matthias
2023-08-14 16:20:54 +02:00
parent 6e32f172be
commit 3ed682a9c6
4 changed files with 16 additions and 14 deletions

View File

@@ -164,6 +164,7 @@ E.g. If the `current_rate` is 200 USD, then returning `0.02` will set the stoplo
During backtesting, `current_rate` (and `current_profit`) are provided against the candle's high (or low for short trades) - while the resulting stoploss is evaluated against the candle's low (or high for short trades).
The absolute value of the return value is used (the sign is ignored), so returning `0.05` or `-0.05` have the same result, a stoploss 5% below the current price.
Returning None will be interpreted as "no desire to change", and is the only safe way to return when you'd like to not modify the stoploss.
To simulate a regular trailing stoploss of 4% (trailing 4% behind the maximum reached price) you would use the following very simple method:
@@ -180,7 +181,7 @@ class AwesomeStrategy(IStrategy):
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, after_fill: bool,
**kwargs) -> float:
**kwargs) -> Optional[float]:
"""
Custom stoploss logic, returning the new distance relative to current_rate (as ratio).
e.g. returning -0.05 would create a stoploss 5% below current_rate.
@@ -232,14 +233,14 @@ class AwesomeStrategy(IStrategy):
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, after_fill: bool,
**kwargs) -> float:
**kwargs) -> Optional[float]:
# Make sure you have the longest interval first - these conditions are evaluated from top to bottom.
if current_time - timedelta(minutes=120) > trade.open_date_utc:
return -0.05
elif current_time - timedelta(minutes=60) > trade.open_date_utc:
return -0.10
return 1
return None
```
#### Different stoploss per pair
@@ -259,7 +260,7 @@ class AwesomeStrategy(IStrategy):
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, after_fill: bool,
**kwargs) -> float:
**kwargs) -> Optional[float]:
if pair in ('ETH/BTC', 'XRP/BTC'):
return -0.10
@@ -286,7 +287,7 @@ class AwesomeStrategy(IStrategy):
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, after_fill: bool,
**kwargs) -> float:
**kwargs) -> Optional[float]:
if current_profit < 0.04:
return -1 # return a value bigger than the initial stoploss to keep using the initial stoploss
@@ -320,7 +321,7 @@ class AwesomeStrategy(IStrategy):
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, after_fill: bool,
**kwargs) -> float:
**kwargs) -> Optional[float]:
# evaluate highest to lowest, so that highest possible stop is used
if current_profit > 0.40:
@@ -331,7 +332,7 @@ class AwesomeStrategy(IStrategy):
return stoploss_from_open(0.07, current_profit, is_short=trade.is_short, leverage=trade.leverage)
# return maximum stoploss value, keeping current stoploss price unchanged
return 1
return None
```
#### Custom stoploss using an indicator from dataframe example
@@ -349,7 +350,7 @@ class AwesomeStrategy(IStrategy):
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, after_fill: bool,
**kwargs) -> float:
**kwargs) -> Optional[float]:
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
@@ -362,7 +363,7 @@ class AwesomeStrategy(IStrategy):
return stoploss_from_absolute(stoploss_price, current_rate, is_short=trade.is_short)
# return maximum stoploss value, keeping current stoploss price unchanged
return 1
return None
```
See [Dataframe access](strategy-advanced.md#dataframe-access) for more information about dataframe use in strategy callbacks.

View File

@@ -902,7 +902,7 @@ Stoploss values returned from `custom_stoploss` must specify a percentage relati
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, after_fill: bool,
**kwargs) -> float:
**kwargs) -> Optional[float]:
# once the profit has risen above 10%, keep the stoploss at 7% above the open price
if current_profit > 0.10:
@@ -945,7 +945,7 @@ In some situations it may be confusing to deal with stops relative to current ra
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, after_fill: bool,
**kwargs) -> float:
**kwargs) -> Optional[float]:
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
candle = dataframe.iloc[-1].squeeze()
return stoploss_from_absolute(current_rate - (candle['atr'] * 2), current_rate, is_short=trade.is_short)

View File

@@ -311,7 +311,8 @@ After:
``` python hl_lines="5 7"
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, after_fill: bool, **kwargs) -> float:
current_rate: float, current_profit: float, after_fill: bool,
**kwargs) -> Optional[float]:
# once the profit has risen above 10%, keep the stoploss at 7% above the open price
if current_profit > 0.10:
return stoploss_from_open(0.07, current_profit, is_short=trade.is_short)

View File

@@ -373,7 +373,7 @@ class IStrategy(ABC, HyperStrategyMixin):
return True
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime, current_rate: float,
current_profit: float, after_fill: bool, **kwargs) -> float:
current_profit: float, after_fill: bool, **kwargs) -> Optional[float]:
"""
Custom stoploss logic, returning the new distance relative to current_rate (as ratio).
e.g. returning -0.05 would create a stoploss 5% below current_rate.
@@ -1200,7 +1200,7 @@ class IStrategy(ABC, HyperStrategyMixin):
trade.adjust_stop_loss(bound or current_rate, stop_loss_value,
allow_refresh=after_fill)
else:
logger.warning("CustomStoploss function did not return valid stoploss")
logger.debug("CustomStoploss function did not return valid stoploss")
if self.trailing_stop and dir_correct:
# trailing stoploss handling