diff --git a/docs/backtesting.md b/docs/backtesting.md index b4d9aef80..76718d206 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -530,8 +530,9 @@ Since backtesting lacks some detailed information about what happens within a ca - Exit-reason does not explain if a trade was positive or negative, just what triggered the exit (this can look odd if negative ROI values are used) - Evaluation sequence (if multiple signals happen on the same candle) - Exit-signal - - ROI (if not stoploss) - Stoploss + - ROI + - Trailing stoploss Taking these assumptions, backtesting tries to mirror real trading as closely as possible. However, backtesting will **never** replace running a strategy in dry-run mode. Also, keep in mind that past results don't guarantee future success. diff --git a/docs/strategy-callbacks.md b/docs/strategy-callbacks.md index ab67a3c26..7f3249c88 100644 --- a/docs/strategy-callbacks.md +++ b/docs/strategy-callbacks.md @@ -563,6 +563,14 @@ class AwesomeStrategy(IStrategy): `confirm_trade_exit()` can be used to abort a trade exit (sell) at the latest second (maybe because the price is not what we expect). +`confirm_trade_exit()` may be called multiple times within one iteration for the same trade if different exit-reasons apply. +The exit-reasons (if applicable) will be in the following sequence: + +* `exit_signal` / `custom_exit` +* `stop_loss` +* `roi` +* `trailing_stop_loss` + ``` python from freqtrade.persistence import Trade @@ -605,6 +613,9 @@ class AwesomeStrategy(IStrategy): ``` +!!! Warning + `confirm_trade_exit()` can prevent stoploss exits, causing significant losses as this would ignore stoploss exits. + ## Adjust trade position The `position_adjustment_enable` strategy property enables the usage of `adjust_trade_position()` callback in the strategy. diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 4ae55e31c..08f5474fd 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1117,7 +1117,7 @@ class FreqtradeBot(LoggingMixin): for should_exit in exits: if should_exit.exit_flag: 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'{f" Tag: {exit_tag}" if exit_tag is not None else ""}') exited = self.execute_trade_exit(trade, exit_rate, should_exit, exit_tag=exit_tag) if exited: return True @@ -1407,7 +1407,7 @@ class FreqtradeBot(LoggingMixin): :param trade: Trade instance :param limit: limit rate for the sell order :param exit_check: CheckTuple with signal and reason - :return: True if it succeeds (supported) False (not supported) + :return: True if it succeeds False """ trade.funding_fees = self.exchange.get_funding_fees( pair=trade.pair, @@ -1454,7 +1454,7 @@ class FreqtradeBot(LoggingMixin): time_in_force=time_in_force, exit_reason=exit_reason, sell_reason=exit_reason, # sellreason -> compatibility current_time=datetime.now(timezone.utc)): - logger.info(f"User requested abortion of exiting {trade.pair}") + logger.info(f"User requested abortion of {trade.pair} exit.") return False try: