fix: restore ea: bridge in config + wire optimizer_loop to EARegistry
Root cause: Removing ea: from config.yaml broke 4 call sites in
optimizer_loop.py (_execute_run, _build_components) and main.py that
still read cfg['ea']. Server started but MT5 never launched.
Fixes:
config.yaml - Restored ea: block as bridge for legacy callers
optimizer_loop.py - _build_components: loads EARegistry, creates
IniBuilder(schema=schema) instead of manifest path
_execute_run: uses self._profile.{name,symbol,tf}
instead of cfg['ea']; passes profile to runner.run()
mt5/runner.py - Validation + TradeLog now use EAProfile data when
profile is provided (legacy fallback preserved)
Tested:
7/7 pre-flight checks pass (config, registry, schema, IniBuilder, runner,
MutationEngine, OptimizerLoop._build_components)
Live browser test: Start clicked → MT5 launched → logs appeared → Reports
page loaded (9 cards) → Back to dashboard navigated in-tab
System fully operational
This commit is contained in:
+45
-7
@@ -34,11 +34,13 @@ from reports.writer import ReportWriter
|
||||
import pandas as pd
|
||||
|
||||
BASE_DIR = Path(__file__).parent
|
||||
MANIFEST_PATH = BASE_DIR / "mutation" / "param_manifest.yaml"
|
||||
KB_PATH = BASE_DIR / "mutation" / "knowledge_base.yaml"
|
||||
DB_PATH = BASE_DIR / "optimizer.db"
|
||||
RUNS_DIR = BASE_DIR / "runs"
|
||||
|
||||
# Keep MANIFEST_PATH for MutationEngine (still uses it for advanced mode)
|
||||
MANIFEST_PATH = BASE_DIR / "mutation" / "param_manifest.yaml"
|
||||
|
||||
|
||||
class OptimizerLoop:
|
||||
"""
|
||||
@@ -394,11 +396,16 @@ class OptimizerLoop:
|
||||
run_id=run_id, params=params,
|
||||
period_start=period_start, period_end=period_end,
|
||||
output_dir=run_dir, phase=phase,
|
||||
ea_file=self._profile.ex5_file,
|
||||
ea_symbol=self._profile.symbol,
|
||||
ea_timeframe=self._profile.timeframe,
|
||||
)
|
||||
|
||||
run = Run(
|
||||
run_id=run_id, ea_name=cfg["ea"]["name"],
|
||||
symbol=cfg["ea"]["symbol"], timeframe=cfg["ea"]["timeframe"],
|
||||
run_id=run_id,
|
||||
ea_name=self._profile.name,
|
||||
symbol=self._profile.symbol,
|
||||
timeframe=self._profile.timeframe,
|
||||
period_start=period_start, period_end=period_end,
|
||||
params=params, phase=phase, hypothesis_id=hypothesis_id,
|
||||
tester_model=cfg["mt5"]["tester_model"],
|
||||
@@ -407,8 +414,11 @@ class OptimizerLoop:
|
||||
store.save_run(run)
|
||||
|
||||
self._emit("log", {"level": "info", "msg": f"⏳ MT5 running: {run_id}"})
|
||||
result = runner.run(run_id, ini_path, run_dir / "report",
|
||||
log_csv_search_dir=Path(cfg["mt5"]["mql5_files_path"]))
|
||||
result = runner.run(
|
||||
run_id, ini_path, run_dir / "report",
|
||||
log_csv_search_dir=Path(cfg["mt5"]["mql5_files_path"]),
|
||||
profile=self._profile,
|
||||
)
|
||||
|
||||
if not result.success:
|
||||
self._emit("run_failed", {"run_id": run_id, "error": result.error_message})
|
||||
@@ -492,8 +502,36 @@ class OptimizerLoop:
|
||||
|
||||
def _build_components(self):
|
||||
cfg = self.cfg
|
||||
store = DataStore(DB_PATH, RUNS_DIR)
|
||||
builder = IniBuilder(self.config_path, str(MANIFEST_PATH))
|
||||
|
||||
# ── EA Registry: load profile + schema ────────────────────────────────
|
||||
from ea.registry import EARegistry
|
||||
reg = EARegistry(self.config_path)
|
||||
ea_name = cfg.get("ea", {}).get("name", "LEGSTECH_EA_V2")
|
||||
try:
|
||||
self._profile = reg.get(ea_name)
|
||||
schema = reg.get_schema(self._profile)
|
||||
logger.info(f"Using EA profile from registry: {ea_name} (mode={self._profile.mode})")
|
||||
except KeyError:
|
||||
# Profile not in registry — fall back to legacy manifest
|
||||
logger.warning(f"EA {ea_name!r} not in registry, using legacy manifest")
|
||||
from ea.registry import EAProfile
|
||||
self._profile = EAProfile(
|
||||
name=ea_name,
|
||||
ex5_file=cfg["ea"]["file"],
|
||||
set_template="",
|
||||
symbol=cfg["ea"]["symbol"],
|
||||
timeframe=cfg["ea"]["timeframe"],
|
||||
)
|
||||
schema = None # builder will use manifest
|
||||
|
||||
# ── Component construction ─────────────────────────────────────────────
|
||||
store = DataStore(DB_PATH, RUNS_DIR)
|
||||
|
||||
if schema is not None:
|
||||
builder = IniBuilder(self.config_path, schema=schema)
|
||||
else:
|
||||
builder = IniBuilder(self.config_path, str(MANIFEST_PATH))
|
||||
|
||||
runner = MT5Runner(self.config_path)
|
||||
parser = ReportParser()
|
||||
log_rdr = TradeLogReader(
|
||||
|
||||
Reference in New Issue
Block a user