feat: remove "open_trade_count_start" workaround

Due to the updated pair ordering logic, we can open trades on
different pairs during the same candle without
superating the max_open_trades limit
This commit is contained in:
Matthias 2024-08-12 13:19:53 +02:00
parent 08c10c1f9b
commit 70f3018e67

View File

@ -1332,10 +1332,9 @@ class Backtesting:
pair: str,
current_time: datetime,
end_date: datetime,
open_trade_count_start: int,
trade_dir: Optional[LongShort],
is_first: bool = True,
) -> int:
) -> None:
"""
NOTE: This method is used by Hyperopt at each iteration. Please keep it optimized.
@ -1345,7 +1344,6 @@ class Backtesting:
# 1. Manage currently open orders of active trades
if self.manage_open_orders(t, current_time, row):
# Close trade
open_trade_count_start -= 1
LocalTrade.remove_bt_trade(t)
self.wallets.update()
@ -1361,13 +1359,9 @@ class Backtesting:
and trade_dir is not None
and not PairLocks.is_pair_locked(pair, row[DATE_IDX], trade_dir)
):
if self.trade_slot_available(open_trade_count_start):
if self.trade_slot_available(LocalTrade.bt_open_open_trade_count):
trade = self._enter_trade(pair, row, trade_dir)
if trade:
# TODO: hacky workaround to avoid opening > max_open_trades
# This emulates previous behavior - not sure if this is correct
# Prevents entering if the trade-slot was freed in this candle
open_trade_count_start += 1
self.wallets.update()
else:
self._collate_rejected(pair, row)
@ -1386,7 +1380,6 @@ class Backtesting:
order = trade.select_order(trade.exit_side, is_open=True)
if order:
self._process_exit_order(order, trade, current_time, row, pair)
return open_trade_count_start
def time_pair_generator(
self, start_date: datetime, end_date: datetime, increment: timedelta, pairs: List[str]
@ -1439,7 +1432,6 @@ class Backtesting:
start_date, end_date, self.timeframe_td, list(data.keys())
):
if is_first:
open_trade_count_start = LocalTrade.bt_open_open_trade_count
self.check_abort()
strategy_safe_wrapper(self.strategy.bot_loop_start, supress_error=True)(
current_time=current_time
@ -1473,9 +1465,7 @@ class Backtesting:
].copy()
if len(detail_data) == 0:
# Fall back to "regular" data if no detail data was found for this candle
open_trade_count_start = self.backtest_loop(
row, pair, current_time, end_date, open_trade_count_start, trade_dir
)
self.backtest_loop(row, pair, current_time, end_date, trade_dir)
continue
detail_data.loc[:, "enter_long"] = row[LONG_IDX]
detail_data.loc[:, "exit_long"] = row[ELONG_IDX]
@ -1487,12 +1477,11 @@ class Backtesting:
current_time_det = current_time
for det_row in detail_data[HEADERS].values.tolist():
self.dataprovider._set_dataframe_max_date(current_time_det)
open_trade_count_start = self.backtest_loop(
self.backtest_loop(
det_row,
pair,
current_time_det,
end_date,
open_trade_count_start,
trade_dir,
is_first,
)
@ -1500,9 +1489,7 @@ class Backtesting:
is_first = False
else:
self.dataprovider._set_dataframe_max_date(current_time)
open_trade_count_start = self.backtest_loop(
row, pair, current_time, end_date, open_trade_count_start, trade_dir
)
self.backtest_loop(row, pair, current_time, end_date, trade_dir)
self.handle_left_open(LocalTrade.bt_trades_open_pp, data=data)
self.wallets.update()