diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 6bf0a7270..6c5933a51 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -426,7 +426,9 @@ class Backtesting: pair=trade.pair, trade=trade, current_time=sell_candle_time, proposed_rate=closerate, current_profit=current_profit) - + # We can't place orders lower than current low. + # freqtrade does not support this in live, and the order would fill immediately + closerate = max(closerate, sell_row[LOW_IDX]) # Confirm trade exit: time_in_force = self.strategy.order_time_in_force['sell'] @@ -515,7 +517,10 @@ class Backtesting: propose_rate = strategy_safe_wrapper(self.strategy.custom_entry_price, default_retval=row[OPEN_IDX])( pair=pair, current_time=current_time, - proposed_rate=row[OPEN_IDX], entry_tag=entry_tag) # default value is the open rate + proposed_rate=propose_rate, entry_tag=entry_tag) # default value is the open rate + # We can't place orders higher than current high (otherwise it'd be a stop limit buy) + # which freqtrade does not support in live. + propose_rate = min(propose_rate, row[HIGH_IDX]) min_stake_amount = self.exchange.get_min_pair_stake_amount(pair, propose_rate, -0.05) or 0 max_stake_amount = self.wallets.get_available_stake_amount() diff --git a/tests/optimize/test_backtest_detail.py b/tests/optimize/test_backtest_detail.py index 42d68593a..3164e11b9 100644 --- a/tests/optimize/test_backtest_detail.py +++ b/tests/optimize/test_backtest_detail.py @@ -547,7 +547,7 @@ tc34 = BTContainer(data=[ custom_entry_price=4200, trades=[] ) -# Test 35: Custom-entry-price above all candles should timeout - so no trade happens. +# Test 35: Custom-entry-price above all candles should have rate adjusted to "entry candle high" tc35 = BTContainer(data=[ # D O H L C V B S [0, 5000, 5050, 4950, 5000, 6172, 1, 0], @@ -555,8 +555,10 @@ tc35 = BTContainer(data=[ [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.01, roi={"0": 0.10}, profit_perc=0.0, - custom_entry_price=7200, trades=[] + stop_loss=-0.01, roi={"0": 0.10}, profit_perc=-0.01, + custom_entry_price=7200, trades=[ + BTrade(sell_reason=SellType.STOP_LOSS, open_tick=1, close_tick=1) + ] ) # Test 36: Custom-entry-price around candle low @@ -577,7 +579,7 @@ tc36 = BTContainer(data=[ # Test 37: Custom exit price below all candles -# causes sell signal timeout +# Price adjusted to candle Low. tc37 = BTContainer(data=[ # D O H L C V B S BT [0, 5000, 5050, 4950, 5000, 6172, 1, 0], @@ -585,10 +587,10 @@ tc37 = BTContainer(data=[ [2, 4900, 5250, 4900, 5100, 6172, 0, 1], # exit - but timeout [3, 5100, 5100, 4950, 4950, 6172, 0, 0], [4, 5000, 5100, 4950, 4950, 6172, 0, 0]], - stop_loss=-0.10, roi={"0": 0.10}, profit_perc=0.0, + stop_loss=-0.10, roi={"0": 0.10}, profit_perc=-0.01, use_sell_signal=True, custom_exit_price=4552, - trades=[BTrade(sell_reason=SellType.FORCE_SELL, open_tick=1, close_tick=4)] + trades=[BTrade(sell_reason=SellType.SELL_SIGNAL, open_tick=1, close_tick=3)] ) # Test 38: Custom exit price above all candles