Implement most pessimistic handling of trailing stoploss.
This commit is contained in:
parent
0af9bcef60
commit
6d5fc96714
@ -225,6 +225,22 @@ class Backtesting:
|
|||||||
# sell at open price.
|
# sell at open price.
|
||||||
return sell_row[OPEN_IDX]
|
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
|
# Set close_rate to stoploss
|
||||||
return trade.stop_loss
|
return trade.stop_loss
|
||||||
elif sell.sell_type == (SellType.ROI):
|
elif sell.sell_type == (SellType.ROI):
|
||||||
|
@ -610,7 +610,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
# Initiate stoploss with open_rate. Does nothing if stoploss is already set.
|
# Initiate stoploss with open_rate. Does nothing if stoploss is already set.
|
||||||
trade.adjust_stop_loss(trade.open_rate, stop_loss_value, initial=True)
|
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
|
stop_loss_value = strategy_safe_wrapper(self.custom_stoploss, default_retval=None
|
||||||
)(pair=trade.pair, trade=trade,
|
)(pair=trade.pair, trade=trade,
|
||||||
current_time=current_time,
|
current_time=current_time,
|
||||||
@ -623,7 +623,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
else:
|
else:
|
||||||
logger.warning("CustomStoploss function did not return valid stoploss")
|
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
|
# trailing stoploss handling
|
||||||
sl_offset = self.trailing_stop_positive_offset
|
sl_offset = self.trailing_stop_positive_offset
|
||||||
|
|
||||||
|
@ -457,6 +457,50 @@ tc28 = BTContainer(data=[
|
|||||||
trades=[BTrade(sell_reason=SellType.TRAILING_STOP_LOSS, open_tick=1, close_tick=3)]
|
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 = [
|
TESTS = [
|
||||||
tc0,
|
tc0,
|
||||||
tc1,
|
tc1,
|
||||||
@ -487,6 +531,9 @@ TESTS = [
|
|||||||
tc26,
|
tc26,
|
||||||
tc27,
|
tc27,
|
||||||
tc28,
|
tc28,
|
||||||
|
tc29,
|
||||||
|
tc30,
|
||||||
|
tc31,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user