Skip to content

fix(pmm_mister): declare candles_config field required by backtest engine#149

Closed
gordonkoehn wants to merge 1 commit intohummingbot:mainfrom
gordonkoehn:fix/pmm_mister-candles-config-upstream
Closed

fix(pmm_mister): declare candles_config field required by backtest engine#149
gordonkoehn wants to merge 1 commit intohummingbot:mainfrom
gordonkoehn:fix/pmm_mister-candles-config-upstream

Conversation

@gordonkoehn
Copy link
Copy Markdown

@gordonkoehn gordonkoehn commented Apr 19, 2026

Summary

PMMisterConfig is missing the candles_config field. The backtest engine reads self.controller.config.candles_config unconditionally, so POST /backtesting/run-backtesting on any pmm_mister config fails with:

{"error": "'PMMisterConfig' object has no attribute 'candles_config'"}

Injecting the field via the request payload is rejected by extra="forbid", so the fix must live on the config class. Every other controller under bots/controllers/generic/ already declares this field (pmm.py:23, pmm_adjusted.py:23, lp_rebalancer.py:26) — pmm_mister.py is the anomaly.

Change

Two lines: import CandlesConfig, add candles_config: List[CandlesConfig] = [] to PMMisterConfig, mirroring pmm.py:23.

Suggestion (happy to adjust on feedback)

Since every generic controller declares this field with an identical empty-default, this is arguably better lifted to ControllerConfigBase so subclasses can't forget it — the current pattern is a footgun that this bug demonstrates. I scoped this PR to the minimal fix to keep it easy to merge, but happy to open a follow-up refactoring ControllerConfigBase if that approach is preferred.

Repro (pure Python, no network)

import sys; from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
from bots.controllers.generic.pmm_mister import PMMisterConfig

config = PMMisterConfig(
    id="x", controller_name="pmm_mister", controller_type="generic",
    connector_name="binance", trading_pair="BTC-USDT", total_amount_quote=100,
    buy_spreads=[0.003], sell_spreads=[0.003],
    buy_amounts_pct=[100], sell_amounts_pct=[100],
    target_base_pct=0.5, min_base_pct=0.3, max_base_pct=0.7,
    leverage=1, take_profit=0.001,
    open_order_type="LIMIT_MAKER", take_profit_order_type="LIMIT_MAKER",
    global_stop_loss=0.03, global_take_profit=0.03,
    max_active_executors_by_level=1,
)
print(f"OK: candles_config = {list(config.candles_config)!r}")

On main: AttributeError: 'PMMisterConfig' object has no attribute 'candles_config'. On this branch: OK: candles_config = [].

Test plan

  • Repro above fails on main, passes on this branch
  • POST /backtesting/run-backtesting with a real pmm_mister config + 44h window returns HTTP 200 on this branch; crashes on main
  • Existing test suite — did not run locally; relying on CI

Related

Splits #(fork PR) into two upstream PRs. This PR is the config-schema fix; the companion PR addresses an independent KeyError in should_effectivize_executor.

🤖 Generated with Claude Code

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes backtesting failures for the pmm_mister generic controller by adding the missing candles_config field to PMMisterConfig, matching the schema pattern used by other generic controllers.

Changes:

  • Import CandlesConfig in pmm_mister.py
  • Add candles_config: List[CandlesConfig] = [] to PMMisterConfig so the backtest engine can safely access config.candles_config

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…gine

PMMisterConfig is the only controller config under bots/controllers/generic/
that doesn't declare `candles_config: List[CandlesConfig] = []`. Every
sibling (pmm.py, pmm_adjusted.py, pmm_dynamic.py, quantum_grid_allocator.py,
etc.) declares it.

The HB backtest engine accesses `self.controller.config.candles_config`
unconditionally in BacktestingEngineBase.initialize_backtesting_data_provider
(hummingbot/strategy_v2/backtesting/backtesting_engine_base.py ~L117), so
calling POST /backtesting/run-backtesting with any pmm_mister config crashes
with:

    'PMMisterConfig' object has no attribute 'candles_config'

Attempting to pass `candles_config: []` in the request body is rejected by
Pydantic's `extra="forbid"` — the model has to declare the field itself.

This patch mirrors the exact placement used by pmm.py:23.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@cardosofede
Copy link
Copy Markdown
Contributor

hey @gordonkoehn I think that the new version that I uploaded was working can you verify?

@gordonkoehn
Copy link
Copy Markdown
Author

Hey @cardosofede, yes thanks for the heads up – just tested with main (8da18c2) without this patch. WORKS :)

/backtesting/run with a pmm_mister config now returns 200 OK.

I see you made a new controller.get_candles_config() path with ControllerBase's default makes this unnecessary.

Closing #149 as obsolete. Thank you for ppm_mister and continuously improving it all!

@gordonkoehn gordonkoehn closed this May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants