Add leverage adjustment to "stoploss_from_absolute"
This commit is contained in:
@@ -927,13 +927,14 @@ In some situations it may be confusing to deal with stops relative to current ra
|
|||||||
|
|
||||||
??? Example "Returning a stoploss using absolute price from the custom stoploss function"
|
??? Example "Returning a stoploss using absolute price from the custom stoploss function"
|
||||||
|
|
||||||
If we want to trail a stop price at 2xATR below current price we can call `stoploss_from_absolute(current_rate - (candle['atr'] * 2), current_rate, is_short=trade.is_short)`.
|
If we want to trail a stop price at 2xATR below current price we can call `stoploss_from_absolute(current_rate + (side * candle['atr'] * 2), current_rate, is_short=trade.is_short, leverage=trade.leverage)`.
|
||||||
|
For futures, we need to adjust the direction (up or down), as well as adjust for leverage, since the [`custom_stoploss`](strategy-callbacks.md#custom-stoploss) callback returns the ["risk for this trade"](stoploss.md#stoploss-and-leverage) - not the relative price movement.
|
||||||
|
|
||||||
``` python
|
``` python
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.strategy import IStrategy, stoploss_from_absolute
|
from freqtrade.strategy import IStrategy, stoploss_from_absolute, timeframe_to_prev_date
|
||||||
|
|
||||||
class AwesomeStrategy(IStrategy):
|
class AwesomeStrategy(IStrategy):
|
||||||
|
|
||||||
@@ -947,8 +948,12 @@ In some situations it may be confusing to deal with stops relative to current ra
|
|||||||
current_rate: float, current_profit: float, after_fill: bool,
|
current_rate: float, current_profit: float, after_fill: bool,
|
||||||
**kwargs) -> Optional[float]:
|
**kwargs) -> Optional[float]:
|
||||||
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
||||||
|
trade_date = timeframe_to_prev_date(self.timeframe, trade.open_date_utc)
|
||||||
candle = dataframe.iloc[-1].squeeze()
|
candle = dataframe.iloc[-1].squeeze()
|
||||||
return stoploss_from_absolute(current_rate - (candle['atr'] * 2), current_rate, is_short=trade.is_short)
|
sign = 1 if trade.is_short else -1
|
||||||
|
return stoploss_from_absolute(current_rate + (side * candle['atr'] * 2),
|
||||||
|
current_rate, is_short=trade.is_short,
|
||||||
|
leverage=trade.leverage)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ After:
|
|||||||
if current_profit > 0.10:
|
if current_profit > 0.10:
|
||||||
return stoploss_from_open(0.07, current_profit, is_short=trade.is_short)
|
return stoploss_from_open(0.07, current_profit, is_short=trade.is_short)
|
||||||
|
|
||||||
return stoploss_from_absolute(current_rate - (candle['atr'] * 2), current_rate, is_short=trade.is_short)
|
return stoploss_from_absolute(current_rate - (candle['atr'] * 2), current_rate, is_short=trade.is_short, leverage=trade.leverage)
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -123,7 +123,8 @@ def stoploss_from_open(
|
|||||||
return max(stoploss * leverage, 0.0)
|
return max(stoploss * leverage, 0.0)
|
||||||
|
|
||||||
|
|
||||||
def stoploss_from_absolute(stop_rate: float, current_rate: float, is_short: bool = False) -> float:
|
def stoploss_from_absolute(stop_rate: float, current_rate: float, is_short: bool = False,
|
||||||
|
leverage: float = 1.0) -> float:
|
||||||
"""
|
"""
|
||||||
Given current price and desired stop price, return a stop loss value that is relative to current
|
Given current price and desired stop price, return a stop loss value that is relative to current
|
||||||
price.
|
price.
|
||||||
@@ -136,6 +137,7 @@ def stoploss_from_absolute(stop_rate: float, current_rate: float, is_short: bool
|
|||||||
:param stop_rate: Stop loss price.
|
:param stop_rate: Stop loss price.
|
||||||
:param current_rate: Current asset price.
|
:param current_rate: Current asset price.
|
||||||
:param is_short: When true, perform the calculation for short instead of long
|
:param is_short: When true, perform the calculation for short instead of long
|
||||||
|
:param leverage: Leverage to use for the calculation
|
||||||
:return: Positive stop loss value relative to current price
|
:return: Positive stop loss value relative to current price
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -150,4 +152,4 @@ def stoploss_from_absolute(stop_rate: float, current_rate: float, is_short: bool
|
|||||||
# negative stoploss values indicate the requested stop price is higher/lower
|
# negative stoploss values indicate the requested stop price is higher/lower
|
||||||
# (long/short) than the current price
|
# (long/short) than the current price
|
||||||
# shorts can yield stoploss values higher than 1, so limit that as well
|
# shorts can yield stoploss values higher than 1, so limit that as well
|
||||||
return max(min(stoploss, 1.0), 0.0)
|
return max(min(stoploss, 1.0), 0.0) * leverage
|
||||||
|
|||||||
@@ -211,15 +211,18 @@ def test_stoploss_from_absolute():
|
|||||||
assert pytest.approx(stoploss_from_absolute(110, 100)) == 0
|
assert pytest.approx(stoploss_from_absolute(110, 100)) == 0
|
||||||
assert pytest.approx(stoploss_from_absolute(100, 0)) == 1
|
assert pytest.approx(stoploss_from_absolute(100, 0)) == 1
|
||||||
assert pytest.approx(stoploss_from_absolute(0, 100)) == 1
|
assert pytest.approx(stoploss_from_absolute(0, 100)) == 1
|
||||||
|
assert pytest.approx(stoploss_from_absolute(0, 100, False, leverage=5)) == 5
|
||||||
|
|
||||||
assert pytest.approx(stoploss_from_absolute(90, 100, True)) == 0
|
assert pytest.approx(stoploss_from_absolute(90, 100, True)) == 0
|
||||||
assert pytest.approx(stoploss_from_absolute(100, 100, True)) == 0
|
assert pytest.approx(stoploss_from_absolute(100, 100, True)) == 0
|
||||||
assert pytest.approx(stoploss_from_absolute(110, 100, True)) == -(1 - (110 / 100))
|
assert pytest.approx(stoploss_from_absolute(110, 100, True)) == -(1 - (110 / 100))
|
||||||
assert pytest.approx(stoploss_from_absolute(110, 100, True)) == 0.1
|
assert pytest.approx(stoploss_from_absolute(110, 100, True)) == 0.1
|
||||||
assert pytest.approx(stoploss_from_absolute(105, 100, True)) == 0.05
|
assert pytest.approx(stoploss_from_absolute(105, 100, True)) == 0.05
|
||||||
|
assert pytest.approx(stoploss_from_absolute(105, 100, True, 5)) == 0.05 * 5
|
||||||
assert pytest.approx(stoploss_from_absolute(100, 0, True)) == 1
|
assert pytest.approx(stoploss_from_absolute(100, 0, True)) == 1
|
||||||
assert pytest.approx(stoploss_from_absolute(0, 100, True)) == 0
|
assert pytest.approx(stoploss_from_absolute(0, 100, True)) == 0
|
||||||
assert pytest.approx(stoploss_from_absolute(100, 1, True)) == 1
|
assert pytest.approx(stoploss_from_absolute(100, 1, is_short=True)) == 1
|
||||||
|
assert pytest.approx(stoploss_from_absolute(100, 1, is_short=True, leverage=5)) == 5
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('trading_mode', ['futures', 'spot'])
|
@pytest.mark.parametrize('trading_mode', ['futures', 'spot'])
|
||||||
|
|||||||
Reference in New Issue
Block a user