Reference

CLI Reference

Every script the pipeline runs, with its complete argument list, defaults, inputs, outputs and exit behaviour. All paths are relative to the repository root and every script is launched with that root as its working directory.

These are the scripts, not the app The GUI runs exactly these commands. Anything here can be run by hand, and the app will pick up the resulting artefacts on its next refresh.

Common conventions

Working directory
The repository root. Scripts insert their own directory into sys.path so sibling imports work.
Default data file
data/<SYMBOL>_<TF>.csv
Default output root
strategies_lr_<tf> for XAUUSD, else strategies_<symbol>_<tf>
Default cores
os.cpu_count() or 4 — the GUI passes cpu_count − 2
Encoding
Stdout is UTF-8, unbuffered, so progress lines arrive live

Data

check_ohlc_csv.py

Validates an OHLC CSV before the pipeline trusts it.

ArgumentRequiredDefaultControls
pathsyesOne or more CSV paths. Parses symbol and TF from the filename.
--quietnooffSuppress informational ok notes; print only errors and warnings.
Reads
Whatever paths are given. No repo-relative default.
Writes
Nothing — stdout report only.
Exit codes
0 = no errors (warnings allowed). 1 = at least one error.
check_ohlc_csv.py data/XAUUSD_M5.csv
check_ohlc_csv.py data/*.csv --quiet

Full validator details →

download_ohlc_all.py

Fetches the last N bars through the MetaTrader5 Python API. Needs a Windows Python.

ArgumentDefaultControls
--symbolXAUUSDSymbol to download. Must exist on the server.
--bars10000Number of most recent bars per timeframe.
--offset3.0Server-time offset in hours added to the API's UTC timestamps. 0 keeps UTC.
--tfM1 M2 M5 M10 M15 H1One or more timeframes (nargs="+"), restricted to the supported set.
--out<cwd>/dataOutput folder — not a file.
--loginMT5 account login.
--passwordAccount password.
--serverBroker server name.
Reads
The live terminal. Must be running and logged in.
Writes
<out>/<SYMBOL>_<TF>.csv — one per timeframe, in pipeline format.
Exit codes
2 if the MetaTrader5 module is missing; 1 if the terminal will not initialise or the symbol is not on the server.
Files are named after the raw --symbol Passing the broker's decorated symbol writes a decorated filename — XAUUSDb_M5.csv. Every later stage looks for the clean XAUUSD_M5.csv. The GUI passes a folder and renames the result afterwards.
A single timeframe returning no data prints FAILED and continues — it does not exit non-zero. Check the output list rather than the exit code when downloading several timeframes at once.

Optimisation

feature_search.py

The two-stage grid search. The CPU-heavy stage.

ArgumentRequiredDefaultControls
--enginenolrOnly lr is valid.
--symbolnoXAUUSDDrives the default data path, output root and lot multiplier.
--tfyesTimeframe, used for naming and the magic-number offset.
--setnoallA single set name, or the literal all. Anything else is a hard error.
--datanodata/<SYMBOL>_<TF>.csvThe CSV to search over.
--outnostrategies_lr_<tf>Output root.
--coresnocpu_countProcessPoolExecutor worker count.
Reads
data/<SYMBOL>_<TF>.csv — twice, once per worker and once in the parent to derive max_spread.
Writes
<out>/<set>/{summary.json, configs.json, slots.txt, equity_<magic>.csv}
Exit codes
1 if the data file is missing or the set name is unknown. A calibration mismatch raises SystemExit.
# all 11 sets, one process
feature_search.py --engine lr --symbol XAUUSD --tf M5 --set all --cores 14

# one set
feature_search.py --engine lr --symbol XAUUSD --tf M5 --set base9 --cores 14

Full detail →

build_allstar.py

Combines per-set winners into a portfolio.

ArgumentDefaultControls
--enginelrOnly lr is valid.
--symbolXAUUSDDefault data path and output root.
--tfrequiredTimeframe.
--all6offBuild the all6 folder — six slots.
--all9offBuild the all9 folder — the canonical nine.
--setsAn explicit set list (nargs="*"). Overrides the mode flags; folder becomes custom.
--topNThe N best-scoring sets on disk; folder becomes topN.
--excludeDrop the named sets; folder becomes best5.
--datadata/<SYMBOL>_<TF>.csvData CSV (only its bar count is read).
--outstrategies_lr_<tf>Output root.
--corescpu_countWorker count.
With no mode flag, the default is allstar Not all6. Resolution order: --topN--sets--exclude--all9--all6 → else allstar (5 slots, at most one per set).
Reads
Each participating set's summary.json and configs.json, plus the data CSV for its bar count.
Writes
<out>/<folder>/{summary.json, configs.json, equity_combined.csv, equity_<magic>.csv}
Exit codes
1 if the data file is missing, if no per-set outputs exist, or if nothing could be selected.

A set with missing outputs prints skip <set> and continues — non-fatal, but note the shortened book.

best_hours.py

Finds each set's best contiguous server-hour window.

ArgumentDefaultControls
--enginelrLabel stored in the JSON only.
--symbolXAUUSDData path and output root.
--tfrequiredTimeframe.
--datadata/<SYMBOL>_<TF>.csvData CSV.
--outstrategies_lr_<tf>Root to read summaries from and write best_hours.json to.
--corescpu_countAccepted but not used in the current implementation.
Reads
Every <root>/<set>/summary.json, plus the data CSV.
Writes
<root>/best_hours.json and <root>/<set>/trades.csv per set.
Exit codes
No explicit non-zero exits. Missing per-set summaries are skipped; a missing data CSV produces an uncaught pandas exception.

Full detail →

Evaluation

holdout_tail.py

Re-simulates frozen configurations on the last N bars.

ArgumentDefaultControls
--symbolXAUUSDSymbol.
--tfM5Timeframe.
--folderall6The portfolio folder to read — all9, all6, top6, etc.
--tail2500Number of trailing bars forming the unseen tail.
--modewarmwarm or cold.
--corescpu_countWorker count.
--outstrategies_lr_<tf>Root to read the portfolio from.
--datafrom the summaryData CSV override.
--fulloffAlso re-run the whole window and print the original numbers. Only when there are 4 or fewer slots.
Reads
<root>/<folder>/summary.json and the data CSV named inside it.
Writes
<root>/<folder>/tail<tail>_<mode>/{tail_report.json, equity_combined_tail.csv, trades_<magic>.csv}
Exit codes
1 if the portfolio summary.json is missing, or if tail_start would fall below 1000 bars.
holdout_tail.py --symbol XAUUSD --tf M5 --folder all9 --mode warm --tail 2500 --cores 14
holdout_tail.py --symbol XAUUSD --tf M5 --folder all9 --mode cold --tail 2500 --cores 14

Full detail →

Generation

gen_ea.py

Emits MQL5 source that mirrors the Python engine.

ArgumentDefaultControls
--enginelrlr (binary sigmoid) or softmax (3-class).
--symbolXAUUSDOutput root, EA header and filename suffix.
--tfM5Timeframe baked into the EA.
--setA set name, or all for every per-set EA.
--outstrategies_lr_<tf>Output root — also sets where best_hours.json is looked for.
--all6offEmit the all6 portfolio EA.
--all9offEmit the all9 portfolio EA.
--per-setoffEmit one EA per feature set.
--no-hoursoffForce InpSlot<N>Hours = "" on every slot. Precedes best_hours.json and the fallback table.
--tagBuild tag inserted before the TF suffix, e.g. 24X.
--prefixLiteral filename and header prefix identifying a dataset, e.g. FU_.
Reads
Portfolio and per-set summary.json + configs.json, and best_hours.json.
Writes
…/FxMath_AST_allstar_ALL9_M5.mq5 (portfolio) or …/FxMath_BAS_base9_LR_M5.mq5 (per set).
Exit codes
None. Missing inputs are skipped with a message; if nothing was emitted it prints Nothing generated. and returns successfully.
No non-zero exit is possible gen_ea.py never calls sys.exit. A run that produced nothing still looks successful. Always confirm the .mq5 file exists.

Full detail →

Reports

report_m5.py

ArgumentDefaultControls
--symbolXAUUSDSymbol.
--tfM5Timeframe.
--portautoPortfolio folder to feature in the headline. Auto order: all9all6allstar.
--outstrategies_lr_<tf>Output root.
--datafrom the summaryData CSV to describe.

Writes: <root>/report.html

report_tail.py

ArgumentDefaultControls
--symbolXAUUSDSymbol.
--tfM5Timeframe.
--tail2500Which tail folder to read.
--outstrategies_lr_<tf>Output root.
--labelDataset label for the title and filename, e.g. FU. Produces tail_holdout_report_FU.html.

Writes: <root>/tail_holdout_report.html

broker_run_report.py

ArgumentDefaultControls
--symbolXAUUSDSymbol.
--tfM5Timeframe; also names the output file.
--tail2500Which tail result to include.
--jsonAlso write the statistics as JSON to this path.

Writes: <root>/report_<tf>_performance.html — for M5, report_m5_performance.html. Prints the output path and the summary statistics to stdout.

Full detail →

Supporting modules

Not normally invoked directly, but useful to know about.

ModuleRole
backtest_lr.py The simulation engine. Imported by the search, the portfolio build, the hours search and the holdout. Provides LRBacktester and the _stats metric computation.
feature_sets.py The 11 feature-set definitions, the primitive library (compute_primitives), the MQL5 expression mirrors, parse_hours, and build_feature_matrix.
lr_hours_engine.py Exact hour-subset replay without re-running the model. Has a __main__ self-validation that compares replay against real hour-filtered backtests and prints EXACT MATCH or *** MISMATCH — do not use ***.
ml_models.py Alternative model implementations used by the comparison studies.
ExportOHLC_MQL5.mq5 The broker-side OHLC exporter. Compiled and attached to a chart inside MetaTrader; writes a pipeline-compatible CSV plus a .summary.txt sidecar.

Study scripts

The repository also contains a set of analysis scripts that are not part of the main chain. They answer secondary questions and are not driven by the GUI.

ScriptQuestion
hour_window_report.pyIs a tight ~2-hour entry window a real risk reduction?
hours_vs_24h_report.py24 hours versus the compiled windows, full metrics.
best_hours_report.pyExhaustive best-N-hour search with profit, drawdown and a nested out-of-sample.
best_single_hour.pyIf only one hour may be traded per timeframe, which hour, and is it real?
best_hour_per_slot.pyIs the best hour portfolio-wide, or does each slot want its own?
one_hour_ea_report.pyOne-hour-per-slot EA: built, compiled and judged against 24h.
mixed9_ea_report.pyCan nine slots picked across M5/M10/M15 beat one timeframe's book?
compare_models.py, compare_symbols_report.py, compare_tf_report.pyHead-to-head comparisons of models, symbols and timeframes.
select_slots.py, compare_slot_corr.pySlot selection and correlation diagnostics.
sizing_report.pyLot sizing for a drawdown limit.
cold_subset_check.pyValidates the cold-mode subset behaviour.
sim_dayguard.py, ea_hourly_profit_report.pyDay-of-week guard simulation and per-hour profit for generated EAs.

The app's own CLI

# resolve the environment and print a full report
run_studio.bat --check
py FxMath_LR_Studio\run.py --check
py -m FxMath_LR_Studio --check

# override the repo for one run
py FxMath_LR_Studio\run.py --repo C:\LR-EA

# start on a given target
py FxMath_LR_Studio\run.py --symbol XAUUSD --tf M5

# the frozen exe takes the same flags
"FxMath LR Studio.exe" --check
--check, --self-test
Resolve and print everything, open no window.
--repo
Override the repository path for this run.
--symbol
Start on a given symbol.
--tf
Start on a given timeframe.
Exit codes
0 when a valid repo was resolved, 2 otherwise — so --check can gate a build script.

Because a windowed executable has no console, --check on the frozen exe writes fxmath_lr_studio_check.txt beside the executable and shows the report in a dialog.

The bundled runner

FxMathLRStudioRunner.exe accepts the same argv shape as python.exe, which is what lets the GUI invoke it as a drop-in interpreter. It is also usable directly, for reproducing exactly what the GUI ran.

FxMathLRStudioRunner.exe scripts\feature_search.py --engine lr --symbol XAUUSD --tf M5 --set all
FxMathLRStudioRunner.exe -c "import numpy, pandas; print(numpy.__version__)"
FxMathLRStudioRunner.exe
# ^ with no arguments, prints its own usage
It is windowed, so it has no visible stdout The runner is built with console=False so a console window does not flash on every pipeline stage. Its output is only visible when the GUI pipes it. To inspect it directly, redirect to a file from a shell — FxMathLRStudioRunner.exe -c "..." > out.txt — or have the code write its result to a file.