@@ -1433,6 +1433,12 @@ def get_detail_data(self, pair: str, row: tuple) -> DataFrame | None:
14331433 detail_data .loc [:, "exit_tag" ] = row [EXIT_TAG_IDX ]
14341434 return detail_data
14351435
1436+ def time_generator (self , start_date : datetime , end_date : datetime ):
1437+ current_time = start_date + self .timeframe_td
1438+ while current_time <= end_date :
1439+ yield current_time
1440+ current_time += self .timeframe_td
1441+
14361442 def time_pair_generator (
14371443 self , start_date : datetime , end_date : datetime , increment : timedelta , pairs : list [str ]
14381444 ):
@@ -1445,14 +1451,23 @@ def time_pair_generator(
14451451 self .progress .init_step (
14461452 BacktestState .BACKTEST , int ((end_date - start_date ) / self .timeframe_td )
14471453 )
1448- while current_time <= end_date :
1449- is_first = True
1454+ for current_time in self .time_generator (start_date , end_date ):
1455+ # Loop for each time point.
1456+
1457+ self .check_abort ()
1458+ # Reset open trade count for this candle
1459+ # Critical to avoid exceeding max_open_trades in backtesting
1460+ # when timeframe-detail is used and trades close within the opening candle.
1461+ LocalTrade .bt_open_open_trade_count_candle = LocalTrade .bt_open_open_trade_count
1462+ strategy_safe_wrapper (self .strategy .bot_loop_start , supress_error = True )(
1463+ current_time = current_time
1464+ )
1465+
14501466 # Pairs that have open trades should be processed first
14511467 new_pairlist = list (dict .fromkeys ([t .pair for t in LocalTrade .bt_trades_open ] + pairs ))
14521468
14531469 for pair in new_pairlist :
1454- yield current_time , pair , is_first
1455- is_first = False
1470+ yield current_time , pair
14561471
14571472 self .progress .increment ()
14581473 current_time += increment
@@ -1482,18 +1497,9 @@ def backtest(self, processed: dict, start_date: datetime, end_date: datetime) ->
14821497 indexes : dict = defaultdict (int )
14831498
14841499 # Loop timerange and get candle for each pair at that point in time
1485- for current_time , pair , is_first_call in self .time_pair_generator (
1500+ for current_time , pair in self .time_pair_generator (
14861501 start_date , end_date , self .timeframe_td , list (data .keys ())
14871502 ):
1488- if is_first_call :
1489- self .check_abort ()
1490- # Reset open trade count for this candle
1491- # Critical to avoid exceeding max_open_trades in backtesting
1492- # when timeframe-detail is used and trades close within the opening candle.
1493- LocalTrade .bt_open_open_trade_count_candle = LocalTrade .bt_open_open_trade_count
1494- strategy_safe_wrapper (self .strategy .bot_loop_start , supress_error = True )(
1495- current_time = current_time
1496- )
14971503 row_index = indexes [pair ]
14981504 row = self .validate_row (data , pair , row_index , current_time )
14991505 if not row :
0 commit comments