Merge pull request #6603 from adrianceding/fix_timeout

Fix using future data to fill when use timeout
This commit is contained in:
Matthias 2022-03-29 19:50:34 +02:00 committed by GitHub
commit 7def1398c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 12 deletions

View File

@ -57,6 +57,8 @@ This loop will be repeated again and again until the bot is stopped.
* Calculate indicators (calls `populate_indicators()` once per pair). * Calculate indicators (calls `populate_indicators()` once per pair).
* Calculate entry / exit signals (calls `populate_entry_trend()` and `populate_exit_trend()` once per pair). * Calculate entry / exit signals (calls `populate_entry_trend()` and `populate_exit_trend()` once per pair).
* Loops per candle simulating entry and exit points. * Loops per candle simulating entry and exit points.
* Check for Order timeouts, either via the `unfilledtimeout` configuration, or via `check_entry_timeout()` / `check_exit_timeout()` strategy callbacks.
* Check for trade entry signals (`enter_long` / `enter_short` columns).
* Confirm trade entry / exits (calls `confirm_trade_entry()` and `confirm_trade_exit()` if implemented in the strategy). * Confirm trade entry / exits (calls `confirm_trade_entry()` and `confirm_trade_exit()` if implemented in the strategy).
* Call `custom_entry_price()` (if implemented in the strategy) to determine entry price (Prices are moved to be within the opening candle). * Call `custom_entry_price()` (if implemented in the strategy) to determine entry price (Prices are moved to be within the opening candle).
* In Margin and Futures mode, `leverage()` strategy callback is called to determine the desired leverage. * In Margin and Futures mode, `leverage()` strategy callback is called to determine the desired leverage.
@ -64,7 +66,6 @@ This loop will be repeated again and again until the bot is stopped.
* Check position adjustments for open trades if enabled and call `adjust_trade_position()` to determine if an additional order is requested. * Check position adjustments for open trades if enabled and call `adjust_trade_position()` to determine if an additional order is requested.
* Call `custom_stoploss()` and `custom_exit()` to find custom exit points. * Call `custom_stoploss()` and `custom_exit()` to find custom exit points.
* For exits based on exit-signal and custom-exit: Call `custom_exit_price()` to determine exit price (Prices are moved to be within the closing candle). * For exits based on exit-signal and custom-exit: Call `custom_exit_price()` to determine exit price (Prices are moved to be within the closing candle).
* Check for Order timeouts, either via the `unfilledtimeout` configuration, or via `check_entry_timeout()` / `check_exit_timeout()` strategy callbacks.
* Generate backtest report output * Generate backtest report output
!!! Note !!! Note

View File

@ -938,7 +938,15 @@ class Backtesting:
indexes[pair] = row_index indexes[pair] = row_index
self.dataprovider._set_dataframe_max_index(row_index) self.dataprovider._set_dataframe_max_index(row_index)
# 1. Process buys. for t in list(open_trades[pair]):
# 1. Cancel expired buy/sell orders.
if self.check_order_cancel(t, current_time):
# Close trade due to buy timeout expiration.
open_trade_count -= 1
open_trades[pair].remove(t)
self.wallets.update()
# 2. Process buys.
# without positionstacking, we can only have one open trade per pair. # without positionstacking, we can only have one open trade per pair.
# max_open_trades must be respected # max_open_trades must be respected
# don't open on the last row # don't open on the last row
@ -961,7 +969,7 @@ class Backtesting:
open_trades[pair].append(trade) open_trades[pair].append(trade)
for trade in list(open_trades[pair]): for trade in list(open_trades[pair]):
# 2. Process entry orders. # 3. Process entry orders.
order = trade.select_order(trade.enter_side, is_open=True) order = trade.select_order(trade.enter_side, is_open=True)
if order and self._get_order_filled(order.price, row): if order and self._get_order_filled(order.price, row):
order.close_bt_order(current_time) order.close_bt_order(current_time)
@ -969,11 +977,11 @@ class Backtesting:
LocalTrade.add_bt_trade(trade) LocalTrade.add_bt_trade(trade)
self.wallets.update() self.wallets.update()
# 3. Create sell orders (if any) # 4. Create sell orders (if any)
if not trade.open_order_id: if not trade.open_order_id:
self._get_sell_trade_entry(trade, row) # Place sell order if necessary self._get_sell_trade_entry(trade, row) # Place sell order if necessary
# 4. Process sell orders. # 5. Process sell orders.
order = trade.select_order(trade.exit_side, is_open=True) order = trade.select_order(trade.exit_side, is_open=True)
if order and self._get_order_filled(order.price, row): if order and self._get_order_filled(order.price, row):
trade.open_order_id = None trade.open_order_id = None
@ -988,13 +996,6 @@ class Backtesting:
self.wallets.update() self.wallets.update()
self.run_protections(enable_protections, pair, current_time) self.run_protections(enable_protections, pair, current_time)
# 5. Cancel expired buy/sell orders.
if self.check_order_cancel(trade, current_time):
# Close trade due to buy timeout expiration.
open_trade_count -= 1
open_trades[pair].remove(trade)
self.wallets.update()
# Move time one configured time_interval ahead. # Move time one configured time_interval ahead.
self.progress.increment() self.progress.increment()
current_time += timedelta(minutes=self.timeframe_min) current_time += timedelta(minutes=self.timeframe_min)