Implement most pessimistic handling of trailing stoploss.

This commit is contained in:
Rokas Kupstys 2021-06-12 10:16:30 +03:00
parent 0af9bcef60
commit 6d5fc96714
3 changed files with 65 additions and 2 deletions

View File

@ -225,6 +225,22 @@ class Backtesting:
# sell at open price.
return sell_row[OPEN_IDX]
# Special case: trailing triggers within same candle as trade opened. Assume most
# pessimistic price movement, which is moving just enough to arm stoploss and
# immediately going down to stop price.
if sell.sell_type == SellType.TRAILING_STOP_LOSS and trade_dur == 0 and \
self.strategy.trailing_stop_positive:
if self.strategy.trailing_only_offset_is_reached:
# Worst case: price reaches stop_positive_offset and dives down.
stop_rate = sell_row[OPEN_IDX] * \
(1 + abs(self.strategy.trailing_stop_positive_offset) -
abs(self.strategy.trailing_stop_positive))
else:
# Worst case: price ticks tiny bit above open and dives down.
stop_rate = sell_row[OPEN_IDX] * (1 - abs(self.strategy.trailing_stop_positive))
assert stop_rate < sell_row[HIGH_IDX]
return stop_rate
# Set close_rate to stoploss
return trade.stop_loss
elif sell.sell_type == (SellType.ROI):

View File

@ -610,7 +610,7 @@ class IStrategy(ABC, HyperStrategyMixin):
# Initiate stoploss with open_rate. Does nothing if stoploss is already set.
trade.adjust_stop_loss(trade.open_rate, stop_loss_value, initial=True)
if self.use_custom_stoploss:
if self.use_custom_stoploss and trade.stop_loss < current_rate:
stop_loss_value = strategy_safe_wrapper(self.custom_stoploss, default_retval=None
)(pair=trade.pair, trade=trade,
current_time=current_time,
@ -623,7 +623,7 @@ class IStrategy(ABC, HyperStrategyMixin):
else:
logger.warning("CustomStoploss function did not return valid stoploss")
if self.trailing_stop:
if self.trailing_stop and trade.stop_loss < current_rate:
# trailing stoploss handling
sl_offset = self.trailing_stop_positive_offset

View File

@ -457,6 +457,50 @@ tc28 = BTContainer(data=[
trades=[BTrade(sell_reason=SellType.TRAILING_STOP_LOSS, open_tick=1, close_tick=3)]
)
# Test 29: trailing_stop should be triggered by low of next candle, without adjusting stoploss using
# high of stoploss candle.
# stop-loss: 10%, ROI: 10% (should not apply)
tc29 = BTContainer(data=[
# D O H L C V B S
[0, 5000, 5050, 4950, 5000, 6172, 1, 0],
[1, 5000, 5050, 5000, 4900, 6172, 0, 0], # enter trade (signal on last candle)
[2, 4900, 5250, 4500, 5100, 6172, 0, 0], # Triggers trailing-stoploss
[3, 5100, 5100, 4650, 4750, 6172, 0, 0],
[4, 4750, 4950, 4350, 4750, 6172, 0, 0]],
stop_loss=-0.10, roi={"0": 0.10}, profit_perc=-0.02, trailing_stop=True,
trailing_stop_positive=0.03,
trades=[BTrade(sell_reason=SellType.TRAILING_STOP_LOSS, open_tick=1, close_tick=2)]
)
# Test 30: trailing_stop should be triggered immediately on trade open candle.
# stop-loss: 10%, ROI: 10% (should not apply)
tc30 = BTContainer(data=[
# D O H L C V B S
[0, 5000, 5050, 4950, 5000, 6172, 1, 0],
[1, 5000, 5500, 5000, 4900, 6172, 0, 0], # enter trade (signal on last candle) and stop
[2, 4900, 5250, 4500, 5100, 6172, 0, 0],
[3, 5100, 5100, 4650, 4750, 6172, 0, 0],
[4, 4750, 4950, 4350, 4750, 6172, 0, 0]],
stop_loss=-0.10, roi={"0": 0.10}, profit_perc=-0.01, trailing_stop=True,
trailing_stop_positive=0.01,
trades=[BTrade(sell_reason=SellType.TRAILING_STOP_LOSS, open_tick=1, close_tick=1)]
)
# Test 31: trailing_stop should be triggered immediately on trade open candle.
# stop-loss: 10%, ROI: 10% (should not apply)
tc31 = BTContainer(data=[
# D O H L C V B S
[0, 5000, 5050, 4950, 5000, 6172, 1, 0],
[1, 5000, 5500, 5000, 4900, 6172, 0, 0], # enter trade (signal on last candle) and stop
[2, 4900, 5250, 4500, 5100, 6172, 0, 0],
[3, 5100, 5100, 4650, 4750, 6172, 0, 0],
[4, 4750, 4950, 4350, 4750, 6172, 0, 0]],
stop_loss=-0.10, roi={"0": 0.10}, profit_perc=0.01, trailing_stop=True,
trailing_only_offset_is_reached=True, trailing_stop_positive_offset=0.02,
trailing_stop_positive=0.01,
trades=[BTrade(sell_reason=SellType.TRAILING_STOP_LOSS, open_tick=1, close_tick=1)]
)
TESTS = [
tc0,
tc1,
@ -487,6 +531,9 @@ TESTS = [
tc26,
tc27,
tc28,
tc29,
tc30,
tc31,
]