freqtrade/freqtrade · error · ConfigurationError

`max_open_trades` and `stake_amount` cannot both be unlimite

Error message

`max_open_trades` and `stake_amount` cannot both be unlimited.

What it means

In _rpc_force_entry, when no trade exists for the pair but the count of open trades already meets config max_open_trades, entry is refused with 'Maximum number of trades is reached.' This mirrors the automatic entry path's slot limit for manual entries.

Source

Thrown at freqtrade/configuration/config_validation.py:110

    _validate_consumers(conf)
    validate_migrated_strategy_settings(conf)
    _validate_orderflow(conf)
    _validate_demo_trading(conf)

    # validate configuration before returning
    logger.info("Validating configuration ...")
    validate_config_schema(conf, preliminary=preliminary)


def _validate_unlimited_amount(conf: dict[str, Any]) -> None:
    """
    Either max_open_trades or stake_amount need to be set.
    :raise: ConfigurationError if config validation failed
    """
    if (
        conf.get("max_open_trades") == float("inf") or conf.get("max_open_trades") == -1
    ) and conf.get("stake_amount") == UNLIMITED_STAKE_AMOUNT:
        raise ConfigurationError("`max_open_trades` and `stake_amount` cannot both be unlimited.")


def _validate_price_config(conf: dict[str, Any]) -> None:
    """
    When using market orders, price sides must be using the "other" side of the price
    """
    if conf.get("order_types", {}).get("entry") == "market" and conf.get("entry_pricing", {}).get(
        "price_side"
    ) not in ("ask", "other"):
        raise ConfigurationError('Market entry orders require entry_pricing.price_side = "other".')

    if conf.get("order_types", {}).get("exit") == "market" and conf.get("exit_pricing", {}).get(
        "price_side"
    ) not in ("bid", "other"):
        raise ConfigurationError('Market exit orders require exit_pricing.price_side = "other".')


def _validate_trailing_stoploss(conf: dict[str, Any]) -> None:

View on GitHub (pinned to 1c8edfe4d1)

Solutions

  1. Exit an existing trade to free a slot, then retry.
  2. Raise max_open_trades in the active config and restart the bot.
  3. Check /api/v1/count to confirm used vs max slots before forceentry.

Example fix

# before: max_open_trades = 1, one trade open
client.post('/api/v1/forceenter', json={'pair': 'ETH/USDT'})  # max reached

# after: free a slot or raise the limit (config)
{ "max_open_trades": 3 }
# then restart and retry
Defensive patterns

Strategy: validation

Validate before calling

count = client.count()
if count['current_max'] and count['count'] >= count['current_max']:
    raise ValueError('All trade slots used; exit one or raise max_open_trades')

Type guard

def has_free_slot(count_resp: dict) -> bool:
    return count_resp['count'] < count_resp['current_max']

Try / catch

from freqtrade.rpc import RPCException
try:
    rpc._rpc_force_entry(pair, None)
except RPCException as e:
    if 'Maximum number of trades' in str(e):
        client.forceexit('oldest')  # or surface to user to free a slot
    else:
        raise

Prevention

When it happens

Trigger: max_open_trades=3 with 3 open trades and forceenter on a fresh pair; max_open_trades set low (e.g. 1) for testing; slots consumed by long-running positions.

Common situations: Test configs with max_open_trades=1; strong markets filling all slots then operator wants a manual position; raising max_open_trades in config but not restarting.

Related errors


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