freqtrade/freqtrade · error · OperationalException

No pair in whitelist.

Error message

No pair in whitelist.

What it means

Thrown in Backtesting.init_backtest right after `self.pairlists.refresh_pairlist(...)` when the resulting whitelist is empty. It means the pairlist chain (whitelist plus any filters) removed every candidate pair before the backtest could start. The exchange object and fee are already initialized at this point, so the failure is purely about pair selection.

Source

Thrown at freqtrade/optimize/backtesting.py:212

                "Timeframe needs to be set in either "
                "configuration or as cli argument `--timeframe 5m`"
            )
        self.timeframe = str(self.config.get("timeframe"))
        self.timeframe_secs = timeframe_to_seconds(self.timeframe)
        self.timeframe_min = self.timeframe_secs // 60
        self.timeframe_td = timedelta(seconds=self.timeframe_secs)
        self._is_backtest_runmode = self.dataprovider.runmode == RunMode.BACKTEST
        self.disable_database_use()
        self.init_backtest_detail()
        self.pairlists = PairListManager(self.exchange, self.config, self.dataprovider)
        self._validate_pairlists_for_backtesting()

        self.dataprovider.add_pairlisthandler(self.pairlists)
        self.dynamic_pairlist: bool = self.config.get("enable_dynamic_pairlist", False)
        self.pairlists.refresh_pairlist(only_first=self.dynamic_pairlist)

        if len(self.pairlists.whitelist) == 0:
            raise OperationalException("No pair in whitelist.")
        self.set_fee()
        self.precision_mode = self.exchange.precisionMode
        self.precision_mode_price = self.exchange.precision_mode_price

        if self.config.get("freqai_backtest_live_models", False):
            from freqtrade.freqai.utils import get_timerange_backtest_live_models

            self.config["timerange"] = get_timerange_backtest_live_models(self.config)

        self.timerange = TimeRange.parse_timerange(
            None if self.config.get("timerange") is None else str(self.config.get("timerange"))
        )

        # Get maximum required startup period
        self.required_startup = max([strat.startup_candle_count for strat in self.strategylist])
        self.exchange.validate_required_startup_candles(self.required_startup, self.timeframe)

        # Add maximum startup candle count to configuration for informative pairs support

View on GitHub (pinned to 1c8edfe4d1)

Solutions

  1. Check `pair_whitelist` in the active config is non-empty and uses exact exchange symbols (e.g. "BTC/USDT", "ETH/USDT:USDT" for futures).
  2. Temporarily remove pairlist filters (PriceFilter, SpreadFilter, ...) to identify which one removes all pairs.
  3. Run `freqtrade test-pairlist` to inspect what the pairlist chain produces.
  4. For futures, verify trading_mode/futures_pair_whitelist consistency and that the pairs exist on the exchange.

Example fix

# before
"pairlists": [{"method": "StaticPairList"}, {"method": "PriceFilter", "low_price_ratio": 0.5}],
"exchange": {"pair_whitelist": ["BTC/USDT"]}
# after
"pairlists": [{"method": "StaticPairList"}],
"exchange": {"pair_whitelist": ["BTC/USDT", "ETH/USDT"]}
Defensive patterns

Strategy: validation

Validate before calling

def validate_whitelist(config) -> bool:
    chain = [p["method"] for p in config.get("pairlists", [])]
    pairs = config.get("exchange", {}).get("pair_whitelist", [])
    return bool(pairs) and "StaticPairList" in chain  # dynamic chains may still empty out

Prevention

When it happens

Trigger: Backtesting with an empty `pair_whitelist`, or with filters (PriceFilter, SpreadFilter, AgeFilter, etc.) or a malformed StaticPairList/VolumepairList chain that filters out all pairs; also a whitelist of pairs that all fail validation against the exchange markets.

Common situations: Copy-pasted config with pair symbols that don't match the exchange's format (e.g. 'BTC/USDT' on an exchange quoted differently), a pair_whitelist emptied by an aggressive PercentOfVolumeFilter, or futures configs listing spot-only pairs.

Related errors


AI-assisted analysis of freqtrade/freqtrade@1c8edfe4d1 (2026-08-15). Data as JSON: /api/errors/87d354b0e2b5a322. Report an issue: GitHub.