**self.freqai_info.get("optuna_hyperopt", {}),
}
+ @cached_property
+ def _optuna_label_candle_pool_full(self) -> list[int]:
+ n_pairs = len(self.pairs)
+ label_frequency_candles = max(
+ 2, 2 * n_pairs, int(self.ft_params.get("label_frequency_candles", 12))
+ )
+ min_offset = -int(label_frequency_candles / 2)
+ max_offset = int(label_frequency_candles / 2)
+ return [
+ max(1, label_frequency_candles + offset)
+ for offset in range(min_offset, max_offset + 1)
+ ]
+
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.pairs = self.config.get("exchange", {}).get("pair_whitelist")
else:
raise ValueError(f"Invalid namespace: {namespace}")
- def build_optuna_label_candle_pool(self) -> list[int]:
- n_pairs = len(self.pairs)
- label_frequency_candles = max(
- 2, 2 * n_pairs, int(self.ft_params.get("label_frequency_candles", 12))
- )
- min_offset = -int(label_frequency_candles / 2)
- max_offset = int(label_frequency_candles / 2)
- return [
- max(1, label_frequency_candles + offset)
- for offset in range(min_offset, max_offset + 1)
- ]
-
def init_optuna_label_candle_pool(self) -> None:
- self._optuna_label_candle_pool = self.build_optuna_label_candle_pool()
+ self._optuna_label_candle_pool = self._optuna_label_candle_pool_full
random.shuffle(self._optuna_label_candle_pool)
if len(self._optuna_label_candle_pool) == 0:
raise RuntimeError("Failed to initialize optuna label candle pool")
logger.warning(
"Optuna label candle pool is empty, reinitializing it ("
f"{self._optuna_label_candle_pool=} ,"
- f"{self.build_optuna_label_candle_pool()=} ,"
+ f"{self._optuna_label_candle_pool_full=} ,"
f"{self._optuna_label_candle.values()=} ,"
f"{self._optuna_label_candles.values()=} ,"
f"{self._optuna_label_incremented_pairs=})"
self._optuna_label_candle[pair] = optuna_label_candle
self._optuna_label_candle_pool.remove(optuna_label_candle)
optuna_label_available_candles = (
- set(self.build_optuna_label_candle_pool())
+ set(self._optuna_label_candle_pool_full)
- set(self._optuna_label_candle_pool)
- set(self._optuna_label_candle.values())
)
# Match the predictions warmup period
return self.freqai_info.get("fit_live_predictions_candles", 100)
+ @cached_property
+ def max_open_trades_per_side(self) -> int:
+ max_open_trades = self.config.get("max_open_trades")
+ if max_open_trades < 0:
+ return -1
+ if self.is_short_allowed():
+ if max_open_trades % 2 == 1:
+ max_open_trades += 1
+ return int(max_open_trades / 2)
+ else:
+ return max_open_trades
+
def bot_start(self, **kwargs) -> None:
self.pairs = self.config.get("exchange", {}).get("pair_whitelist")
if not self.pairs:
) -> bool:
if Trade.get_open_trade_count() >= self.config.get("max_open_trades"):
return False
- max_open_trades_per_side = self.max_open_trades_per_side()
+ max_open_trades_per_side = self.max_open_trades_per_side
if max_open_trades_per_side >= 0:
open_trades = Trade.get_open_trades()
trades_per_side = sum(1 for trade in open_trades if trade.enter_tag == side)
)
return False
- def max_open_trades_per_side(self) -> int:
- max_open_trades = self.config.get("max_open_trades")
- if max_open_trades < 0:
- return -1
- if self.is_short_allowed():
- if max_open_trades % 2 == 1:
- max_open_trades += 1
- return int(max_open_trades / 2)
- else:
- return max_open_trades
-
def is_short_allowed(self) -> bool:
trading_mode = self.config.get("trading_mode")
if trading_mode == "margin" or trading_mode == "futures":