Should_exit should return all sell signals

This commit is contained in:
Matthias 2022-05-22 10:15:58 +02:00
parent 1315d02437
commit bdb904e714
3 changed files with 26 additions and 19 deletions

View File

@ -1106,7 +1106,7 @@ class FreqtradeBot(LoggingMixin):
""" """
Check and execute trade exit Check and execute trade exit
""" """
should_exit: ExitCheckTuple = self.strategy.should_exit( exits: List[ExitCheckTuple] = self.strategy.should_exit(
trade, trade,
exit_rate, exit_rate,
datetime.now(timezone.utc), datetime.now(timezone.utc),
@ -1114,11 +1114,12 @@ class FreqtradeBot(LoggingMixin):
exit_=exit_, exit_=exit_,
force_stoploss=self.edge.stoploss(trade.pair) if self.edge else 0 force_stoploss=self.edge.stoploss(trade.pair) if self.edge else 0
) )
for should_exit in exits:
if should_exit.exit_flag: if should_exit.exit_flag:
logger.info(f'Exit for {trade.pair} detected. Reason: {should_exit.exit_type}' logger.info(f'Exit for {trade.pair} detected. Reason: {should_exit.exit_type}'
f'Tag: {exit_tag if exit_tag is not None else "None"}') f'Tag: {exit_tag if exit_tag is not None else "None"}')
self.execute_trade_exit(trade, exit_rate, should_exit, exit_tag=exit_tag) exited = self.execute_trade_exit(trade, exit_rate, should_exit, exit_tag=exit_tag)
if exited:
return True return True
return False return False

View File

@ -527,15 +527,23 @@ class Backtesting:
if check_adjust_entry: if check_adjust_entry:
trade = self._get_adjust_trade_entry_for_candle(trade, row) trade = self._get_adjust_trade_entry_for_candle(trade, row)
exit_candle_time: datetime = row[DATE_IDX].to_pydatetime()
enter = row[SHORT_IDX] if trade.is_short else row[LONG_IDX] enter = row[SHORT_IDX] if trade.is_short else row[LONG_IDX]
exit_sig = row[ESHORT_IDX] if trade.is_short else row[ELONG_IDX] exit_sig = row[ESHORT_IDX] if trade.is_short else row[ELONG_IDX]
exit_ = self.strategy.should_exit( exits = self.strategy.should_exit(
trade, row[OPEN_IDX], exit_candle_time, # type: ignore trade, row[OPEN_IDX], row[DATE_IDX].to_pydatetime(), # type: ignore
enter=enter, exit_=exit_sig, enter=enter, exit_=exit_sig,
low=row[LOW_IDX], high=row[HIGH_IDX] low=row[LOW_IDX], high=row[HIGH_IDX]
) )
for exit_ in exits:
t = self._get_exit_for_signal(trade, row, exit_)
if t:
return t
return None
def _get_exit_for_signal(self, trade: LocalTrade, row: Tuple,
exit_: ExitCheckTuple) -> Optional[LocalTrade]:
exit_candle_time: datetime = row[DATE_IDX].to_pydatetime()
if exit_.exit_flag: if exit_.exit_flag:
trade.close_date = exit_candle_time trade.close_date = exit_candle_time
exit_reason = exit_.exit_reason exit_reason = exit_.exit_reason

View File

@ -878,16 +878,16 @@ class IStrategy(ABC, HyperStrategyMixin):
def should_exit(self, trade: Trade, rate: float, current_time: datetime, *, def should_exit(self, trade: Trade, rate: float, current_time: datetime, *,
enter: bool, exit_: bool, enter: bool, exit_: bool,
low: float = None, high: float = None, low: float = None, high: float = None,
force_stoploss: float = 0) -> ExitCheckTuple: force_stoploss: float = 0) -> List[ExitCheckTuple]:
""" """
This function evaluates if one of the conditions required to trigger an exit order This function evaluates if one of the conditions required to trigger an exit order
has been reached, which can either be a stop-loss, ROI or exit-signal. has been reached, which can either be a stop-loss, ROI or exit-signal.
:param low: Only used during backtesting to simulate (long)stoploss/(short)ROI :param low: Only used during backtesting to simulate (long)stoploss/(short)ROI
:param high: Only used during backtesting, to simulate (short)stoploss/(long)ROI :param high: Only used during backtesting, to simulate (short)stoploss/(long)ROI
:param force_stoploss: Externally provided stoploss :param force_stoploss: Externally provided stoploss
:return: True if trade should be exited, False otherwise :return: List of exit reasons - or empty list.
""" """
exits: List[ExitCheckTuple] = []
current_rate = rate current_rate = rate
current_profit = trade.calc_profit_ratio(current_rate) current_profit = trade.calc_profit_ratio(current_rate)
@ -938,7 +938,7 @@ class IStrategy(ABC, HyperStrategyMixin):
logger.debug(f"{trade.pair} - Sell signal received. " logger.debug(f"{trade.pair} - Sell signal received. "
f"exit_type=ExitType.{exit_signal.name}" + f"exit_type=ExitType.{exit_signal.name}" +
(f", custom_reason={custom_reason}" if custom_reason else "")) (f", custom_reason={custom_reason}" if custom_reason else ""))
return ExitCheckTuple(exit_type=exit_signal, exit_reason=custom_reason) exits.append(ExitCheckTuple(exit_type=exit_signal, exit_reason=custom_reason))
# Sequence: # Sequence:
# Exit-signal # Exit-signal
@ -946,16 +946,14 @@ class IStrategy(ABC, HyperStrategyMixin):
# Stoploss # Stoploss
if roi_reached and stoplossflag.exit_type != ExitType.STOP_LOSS: if roi_reached and stoplossflag.exit_type != ExitType.STOP_LOSS:
logger.debug(f"{trade.pair} - Required profit reached. exit_type=ExitType.ROI") logger.debug(f"{trade.pair} - Required profit reached. exit_type=ExitType.ROI")
return ExitCheckTuple(exit_type=ExitType.ROI) exits.append(ExitCheckTuple(exit_type=ExitType.ROI))
if stoplossflag.exit_flag: if stoplossflag.exit_flag:
logger.debug(f"{trade.pair} - Stoploss hit. exit_type={stoplossflag.exit_type}") logger.debug(f"{trade.pair} - Stoploss hit. exit_type={stoplossflag.exit_type}")
return stoplossflag exits.append(stoplossflag)
# This one is noisy, commented out... return exits
# logger.debug(f"{trade.pair} - No exit signal.")
return ExitCheckTuple(exit_type=ExitType.NONE)
def stop_loss_reached(self, current_rate: float, trade: Trade, def stop_loss_reached(self, current_rate: float, trade: Trade,
current_time: datetime, current_profit: float, current_time: datetime, current_profit: float,