Liquidation should be a separate exit type
This commit is contained in:
parent
d70650b074
commit
995be90f91
@ -9,6 +9,7 @@ class ExitType(Enum):
|
|||||||
STOP_LOSS = "stop_loss"
|
STOP_LOSS = "stop_loss"
|
||||||
STOPLOSS_ON_EXCHANGE = "stoploss_on_exchange"
|
STOPLOSS_ON_EXCHANGE = "stoploss_on_exchange"
|
||||||
TRAILING_STOP_LOSS = "trailing_stop_loss"
|
TRAILING_STOP_LOSS = "trailing_stop_loss"
|
||||||
|
LIQUIDATION = "liquidation"
|
||||||
EXIT_SIGNAL = "exit_signal"
|
EXIT_SIGNAL = "exit_signal"
|
||||||
FORCE_EXIT = "force_exit"
|
FORCE_EXIT = "force_exit"
|
||||||
EMERGENCY_EXIT = "emergency_exit"
|
EMERGENCY_EXIT = "emergency_exit"
|
||||||
|
@ -381,7 +381,8 @@ class Backtesting:
|
|||||||
Get close rate for backtesting result
|
Get close rate for backtesting result
|
||||||
"""
|
"""
|
||||||
# Special handling if high or low hit STOP_LOSS or ROI
|
# Special handling if high or low hit STOP_LOSS or ROI
|
||||||
if exit.exit_type in (ExitType.STOP_LOSS, ExitType.TRAILING_STOP_LOSS):
|
if exit.exit_type in (
|
||||||
|
ExitType.STOP_LOSS, ExitType.TRAILING_STOP_LOSS, ExitType.LIQUIDATION):
|
||||||
return self._get_close_rate_for_stoploss(row, trade, exit, trade_dur)
|
return self._get_close_rate_for_stoploss(row, trade, exit, trade_dur)
|
||||||
elif exit.exit_type == (ExitType.ROI):
|
elif exit.exit_type == (ExitType.ROI):
|
||||||
return self._get_close_rate_for_roi(row, trade, exit, trade_dur)
|
return self._get_close_rate_for_roi(row, trade, exit, trade_dur)
|
||||||
@ -396,11 +397,16 @@ class Backtesting:
|
|||||||
is_short = trade.is_short or False
|
is_short = trade.is_short or False
|
||||||
leverage = trade.leverage or 1.0
|
leverage = trade.leverage or 1.0
|
||||||
side_1 = -1 if is_short else 1
|
side_1 = -1 if is_short else 1
|
||||||
|
if exit.exit_type == ExitType.LIQUIDATION and trade.liquidation_price:
|
||||||
|
stoploss_value = trade.liquidation_price
|
||||||
|
else:
|
||||||
|
stoploss_value = trade.stop_loss
|
||||||
|
|
||||||
if is_short:
|
if is_short:
|
||||||
if trade.stop_loss < row[LOW_IDX]:
|
if stoploss_value < row[LOW_IDX]:
|
||||||
return row[OPEN_IDX]
|
return row[OPEN_IDX]
|
||||||
else:
|
else:
|
||||||
if trade.stop_loss > row[HIGH_IDX]:
|
if stoploss_value > row[HIGH_IDX]:
|
||||||
return row[OPEN_IDX]
|
return row[OPEN_IDX]
|
||||||
|
|
||||||
# Special case: trailing triggers within same candle as trade opened. Assume most
|
# Special case: trailing triggers within same candle as trade opened. Assume most
|
||||||
@ -433,7 +439,7 @@ class Backtesting:
|
|||||||
return max(row[LOW_IDX], stop_rate)
|
return max(row[LOW_IDX], stop_rate)
|
||||||
|
|
||||||
# Set close_rate to stoploss
|
# Set close_rate to stoploss
|
||||||
return trade.stop_loss
|
return stoploss_value
|
||||||
|
|
||||||
def _get_close_rate_for_roi(self, row: Tuple, trade: LocalTrade, exit: ExitCheckTuple,
|
def _get_close_rate_for_roi(self, row: Tuple, trade: LocalTrade, exit: ExitCheckTuple,
|
||||||
trade_dur: int) -> float:
|
trade_dur: int) -> float:
|
||||||
|
@ -511,17 +511,9 @@ class LocalTrade():
|
|||||||
Method you should use to set self.stop_loss.
|
Method you should use to set self.stop_loss.
|
||||||
Assures stop_loss is not passed the liquidation price
|
Assures stop_loss is not passed the liquidation price
|
||||||
"""
|
"""
|
||||||
if self.liquidation_price is not None:
|
|
||||||
if self.is_short:
|
|
||||||
sl = min(stop_loss, self.liquidation_price)
|
|
||||||
else:
|
|
||||||
sl = max(stop_loss, self.liquidation_price)
|
|
||||||
else:
|
|
||||||
sl = stop_loss
|
|
||||||
|
|
||||||
if not self.stop_loss:
|
if not self.stop_loss:
|
||||||
self.initial_stop_loss = sl
|
self.initial_stop_loss = stop_loss
|
||||||
self.stop_loss = sl
|
self.stop_loss = stop_loss
|
||||||
|
|
||||||
self.stop_loss_pct = -1 * abs(percent)
|
self.stop_loss_pct = -1 * abs(percent)
|
||||||
self.stoploss_last_update = datetime.utcnow()
|
self.stoploss_last_update = datetime.utcnow()
|
||||||
|
@ -49,7 +49,7 @@ class StoplossGuard(IProtection):
|
|||||||
trades1 = Trade.get_trades_proxy(pair=pair, is_open=False, close_date=look_back_until)
|
trades1 = Trade.get_trades_proxy(pair=pair, is_open=False, close_date=look_back_until)
|
||||||
trades = [trade for trade in trades1 if (str(trade.exit_reason) in (
|
trades = [trade for trade in trades1 if (str(trade.exit_reason) in (
|
||||||
ExitType.TRAILING_STOP_LOSS.value, ExitType.STOP_LOSS.value,
|
ExitType.TRAILING_STOP_LOSS.value, ExitType.STOP_LOSS.value,
|
||||||
ExitType.STOPLOSS_ON_EXCHANGE.value)
|
ExitType.STOPLOSS_ON_EXCHANGE.value, ExitType.LIQUIDATION.value)
|
||||||
and trade.close_profit and trade.close_profit < self._profit_limit)]
|
and trade.close_profit and trade.close_profit < self._profit_limit)]
|
||||||
|
|
||||||
if self._only_per_side:
|
if self._only_per_side:
|
||||||
|
@ -963,7 +963,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
# ROI
|
# ROI
|
||||||
# Trailing stoploss
|
# Trailing stoploss
|
||||||
|
|
||||||
if stoplossflag.exit_type == ExitType.STOP_LOSS:
|
if stoplossflag.exit_type in (ExitType.STOP_LOSS, ExitType.LIQUIDATION):
|
||||||
|
|
||||||
logger.debug(f"{trade.pair} - Stoploss hit. exit_type={stoplossflag.exit_type}")
|
logger.debug(f"{trade.pair} - Stoploss hit. exit_type={stoplossflag.exit_type}")
|
||||||
exits.append(stoplossflag)
|
exits.append(stoplossflag)
|
||||||
@ -1035,6 +1035,17 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
|
|
||||||
sl_higher_long = (trade.stop_loss >= (low or current_rate) and not trade.is_short)
|
sl_higher_long = (trade.stop_loss >= (low or current_rate) and not trade.is_short)
|
||||||
sl_lower_short = (trade.stop_loss <= (high or current_rate) and trade.is_short)
|
sl_lower_short = (trade.stop_loss <= (high or current_rate) and trade.is_short)
|
||||||
|
liq_higher_long = (trade.liquidation_price
|
||||||
|
and trade.liquidation_price >= (low or current_rate)
|
||||||
|
and not trade.is_short)
|
||||||
|
liq_lower_short = (trade.liquidation_price
|
||||||
|
and trade.liquidation_price <= (high or current_rate)
|
||||||
|
and trade.is_short)
|
||||||
|
|
||||||
|
if (liq_higher_long or liq_lower_short):
|
||||||
|
logger.debug(f"{trade.pair} - Liquidation price hit. exit_type=ExitType.LIQUIDATION")
|
||||||
|
return ExitCheckTuple(exit_type=ExitType.LIQUIDATION)
|
||||||
|
|
||||||
# evaluate if the stoploss was hit if stoploss is not on exchange
|
# evaluate if the stoploss was hit if stoploss is not on exchange
|
||||||
# in Dry-Run, this handles stoploss logic as well, as the logic will not be different to
|
# in Dry-Run, this handles stoploss logic as well, as the logic will not be different to
|
||||||
# regular stoploss handling.
|
# regular stoploss handling.
|
||||||
|
Loading…
Reference in New Issue
Block a user