Step 6 of 7

EA Generate & Compile

Turns the finished run into compile-ready MQL5 that mirrors the Python engine expression for expression, compiles it with MetaEditor, and copies the binary into the terminal.

What this stage does

gen_ea.py --engine lr --symbol XAUUSD --tf M5 --all9

# the 24-hour variant, tagged so it cannot overwrite the above
gen_ea.py --engine lr --symbol XAUUSD --tf M5 --all9 --no-hours --tag 24X
Read the portfolio
<root>/<folder>/summary.json and configs.json — the slot parameters, features and magic numbers.
Resolve each slot's hours
From best_hours.json, or empty if --no-hours was given. The resolution order is strict — see below.
Emit MQL5
Feature expressions, structs, the LR implementation, hour parsing, per-slot inputs and the trading loop — all mirroring the Python engine.
Compile with MetaEditor
Driven directly, not through a shell. Success is decided from the artefact and the log, never from the exit code.
Deploy
Copies the .ex5 into the selected terminal's MQL5\Experts folder.

Choosing what to emit

FlagEmitsSlots
--all9One portfolio EA for the canonical nine sets9
--all6One portfolio EA for the first six sets6
--per-setOne EA per feature set5 each
--set <name>One EA for a single set5
--set allAn EA for every per-set result on disk5 each

Filenames

# portfolio EA
strategies_lr_m5/all9/FxMath_AST_allstar_ALL9_M5.mq5

# per-set EA
strategies_lr_m5/base9/FxMath_BAS_base9_LR_M5.mq5

# with a tag
strategies_lr_m5/all9/FxMath_AST_allstar_ALL9_24X_M5.mq5

# non-XAUUSD symbols get the symbol in the suffix
strategies_dowjones30_m5/all9/FxMath_AST_allstar_ALL9_DOWJONES30_M5.mq5

AST stands for the allstar build; the per-set name uses the set's abbreviation. For XAUUSD the timeframe suffix is just _M5; for any other symbol it is _<SYMBOL>_<TF> so files from different instruments cannot collide.

Always use --tag for a variant The tag is inserted before the timeframe suffix. Without it, a second build of the same portfolio overwrites the first — and you lose the ability to compare a hours-baked EA against a 24-hour one, or to A/B two configurations.

The hours resolution order

Each slot's InpSlot<N>Hours value is resolved in this strict order, first match wins:

HOURS_DISABLE
Set by --no-hours. Forces every slot to "" (24 hours). Checked first, so a stale hours file cannot defeat it.
An explicit override
A programmatic (tf, set) → spec map, used by the study scripts to test specific windows.
<OUT_ROOT>/best_hours.json
The output of Step 4. Takes best_windows[0].spec — the top-ranked window.
A hardcoded fallback table
Built-in windows for XAUUSD across several timeframes and the six original sets — for the case where best_hours.json is absent but a known-good default exists.
Empty string
24 hours — no session filter. This is what non-XAUUSD symbols get when there is no hours file.
Watch for a silently-applied fallback If best_hours.json is missing, an XAUUSD build will quietly use the hardcoded table rather than 24 hours. That is usually fine, but it means the file you generated does not reflect the run you just completed. Confirm best_hours.json exists before generating, or use --no-hours to be explicit.

What the generated EA contains

SectionPurpose
Header blockCopyright, version, description, and a //| Data: <file> | line recording which CSV the run was built from.
Compile-time constantsN_FEATURES, FEATURE_LOOKBACK, MAX_TRAIN, MAX_SLOTS, TRADE_TF, and #define LAM 0.001 — the last one annotated as needing to match the Python engine.
SlotConfig structMagic, slMult, rr, trainingBars, retrainInterval, lookaheadBars, learning rates, maxIter, thresholds.
SlotState structWeights, bias, feature mean/std, the training buffer, model-trained flag, bars-since-train, last probability and signal, and the 24-entry hourOk[] array.
ParseHours()An exact MQL5 mirror of the Python parser, including wrap-around ranges.
Per-slot inputsInpSlot<N>Enable, InpSlot<N>Lot, InpSlot<N>Hours.
ComputeFeaturesAt()The feature primitives, emitted as MQL5 expressions that mirror feature_sets.py. For a portfolio EA this is a switch dispatching into each set's own expression block.
The LR implementationSigmoid, standardisation, batch gradient descent with L2, and the online momentum step — matching the engine's update rules.
Trading loopPer-bar feature computation, hour gate, per-slot probability and signal, position management with SL/TP, and magic+symbol-matched position scanning.

Two details worth knowing

The EA ignores the chart timeframe TRADE_TF is compiled in as a constant, so the EA reads its own timeframe's bars regardless of which chart it is attached to. Attaching an M5 EA to an H1 chart does not change its behaviour — which is convenient, but means a casual look at the chart tells you nothing about what the EA is actually reading.
The training buffer is fixed at compile time MAX_TRAIN = 1800, sized to cover the largest searched training_bars (1500) plus the largest lookahead (8) plus FEATURE_LOOKBACK (51) = 1559, with headroom. The same 51-bar lookback is mirrored in the data validator's trainability check.

MetaEditor's two traps

1 — MetaEditor returns exit code 1 even on a clean compile Success is therefore judged from the artefact: the .ex5 must exist, be newer than the previous build, and the log must report 0 errors.

The subtle half: when a build fails outright, MetaEditor still writes a fresh 0 errors log next to the old .ex5. A log-only check would report success. That is why mtime is checked as well as the log contents.
2 — The log is UTF-16LE Sometimes with a byte-order mark, sometimes without. It is decoded defensively, and the N errors, M warnings summary is taken from the last match in the file — because included header files can print their own summary before the final one, and reading the first would report the wrong count.

The compile log is shown verbatim on the EA page, with the real diagnostics also extracted into a table of severity / code / file / line / message. The raw log is what you want when something fails for an unexpected reason.

Deployment

Deployment copies the compiled .ex5 into the selected terminal's MQL5\Experts folder. Getting the right folder is the whole difficulty, because two MetaTrader installs on the same machine keep entirely separate %APPDATA% data directories.

The Settings page pairs each install with its data directory by reading that directory's origin.txt and shows the exact MQL5\Experts path that deployment will target. That path is the thing to verify when an EA compiles successfully but does not appear.

A compiled EA does not appear in MT5 Almost always one of two things: the deploy went to a different terminal's data directory than the one you are looking at, or you simply need to refresh the Navigator in MetaTrader. Check the Settings card's MQL5 path first, then right-click the Navigator and refresh.

The staleness check on the EA page

The EA page is the one place where staleness is treated as an error, not a warning. There are two reasons, and both are about accidentally trading something you did not test.

ConditionVerdict
.ex5 older than its .mq5 stale — the binary does not correspond to the source. You are looking at a build of older code.
An .ex5 with the same name exists elsewhere at a different size warning naming both paths — identically-named binaries from earlier runs are the single easiest way to backtest the wrong EA.

Progress output

hours filter DISABLED: every slot gets InpSlot<N>Hours = "" (trade 24x)
  EA: strategies_lr_m5/all9/FxMath_AST_allstar_ALL9_M5.mq5
  EA: strategies_lr_m5/base9/FxMath_BAS_base9_LR_M5.mq5  (3921 lines)
skip all6: no summary under strategies_lr_m5/all6

compiling with MetaEditor ...
  0 errors, 0 warnings
  -> strategies_lr_m5/all9/FxMath_AST_allstar_ALL9_M5.ex5

deploying to MQL5\Experts ...
  copied to C:\Users\...\MetaQuotes\Terminal\D0694EE...CE8\MQL5\Experts
Nothing generated. is not an error If no portfolio folder was found, the generator prints Nothing generated. and returns successfully. So a green-looking run with no output is possible. Check that the folder you asked for actually exists and has a summary.json.

The Expert Advisor page

Slots
ALL9, ALL6, or per-set — which portfolio to emit.
Session filter
Hours-baked (from best_hours.json) or 24-hour. The 24-hour option emits InpSlot<N>Hours = "" on every slot and tags the file 24X so both variants coexist.
Generate
Writes the .mq5 and shows the line count.
Compile
Drives MetaEditor, shows the verbatim log and a diagnostics table, and decides success from the artefact.
Compile existing .mq5
Compiles a file already on disk — the quickest way to exercise the MetaEditor path on a new machine.
Deploy
Copies the .ex5 into the selected terminal's MQL5\Experts.
Colliding binaries
A list of every .ex5 elsewhere in the repository whose name collides with a local one.

Checkpoint

Before moving to Step 7
  • The compile reported 0 errors, 0 warnings.
  • The .ex5 exists and is newer than the .mq5 — no STALE badge.
  • No colliding binaries are listed, or you know which one is which.
  • The deploy target is the MQL5\Experts path of the terminal you actually use.
  • You generated the 24-hour variant too, if you plan to compare it.
SymptomCauseFix
"MetaEditor64.exe not found" The selected terminal folder is wrong or the terminal is not installed. Settings → MetaTrader 5 → Browse to the folder containing metaeditor64.exe.
Compile reports failure but the log says "0 errors" Old log, old .ex5, or a stale build detected by the mtime check. Delete the .ex5 and the log, then recompile.
Compiled EA not visible in MT5 Deployed to a different terminal's data directory, or the Navigator is not refreshed. Verify the MQL5 path in Settings, then refresh the MT5 Navigator.
Nothing generated. No portfolio folder with a summary.json was found. Confirm Step 3 wrote the folder you are asking for.
STALE badge on the EA The .mq5 is newer than the .ex5. Recompile. The binary does not correspond to the current source.
Unexpected hours in the EA The generator fell back to the hardcoded table because best_hours.json was missing. Run Step 4, or regenerate with --no-hours to be explicit about 24-hour trading.

Full troubleshooting catalogue →