"""Build the single-file MQL5 Market versions and compile them on a testing install. usage: build_market.py market/Tick_Forge.mq5 Expert (the utility product), TF_Gui / TF_Engine / TF_Expr inlined market/Tick_Forge_Indicator.mq5 indicator build of the same window (alternate) Each is compiled; errors / warnings are printed. The Market compiles the uploaded source server-side, so it must be ONE file with no custom includes (standard library includes are fine). Set TF_DATA / TF_EDITOR for your own install. """ import os, re, shutil, subprocess, sys from pathlib import Path HERE = Path(__file__).resolve().parent.parent D = Path(os.environ.get("TF_DATA", r"C:\Users\gebruiker\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075")) EDIT = os.environ.get("TF_EDITOR", r"C:\Program Files\MetaTrader 5\metaeditor64.exe") # (source in repo, output name in market/, MQL5 sub-folder it compiles in, file name there) BUILDS = (("Tick_Forge.mq5", "Tick_Forge.mq5", "Experts", "Tick_Forge_Market"), ("variants/Tick_Forge_Indicator.mq5", "Tick_Forge_Indicator.mq5", "Indicators", "Tick_Forge_Market")) def body(name): return (HERE / name).read_text(encoding="utf-8") def inline(text): def sub(m): inc = m.group(1) return "// ---- inlined from %s ----\n%s\n// ---- end %s ----" % (inc, inline(body(inc)), inc) return re.sub(r'^#include "([^"]+)"[ \t]*$', sub, text, flags=re.M) out = HERE / "market" out.mkdir(exist_ok=True) (HERE / "release").mkdir(exist_ok=True) status = 0 for src_rel, out_name, kind, folder in BUILDS: src = inline(body(src_rel)) first = src.find("#property strict") if first >= 0: # inlined headers may repeat it; keep the first src = src[:first + 17] + src[first + 17:].replace("#property strict\n", "") (out / out_name).write_text(src, encoding="utf-8", newline="\n") left = re.findall(r'^#include "[^"]+"', src, flags=re.M) if left: sys.exit("custom includes left in %s: %s" % (out_name, left)) dst = D / "MQL5" / kind / folder dst.mkdir(parents=True, exist_ok=True) shutil.copy2(out / out_name, dst / out_name) ex = dst / out_name.replace(".mq5", ".ex5") if ex.exists(): ex.unlink() log = dst / (out_name + ".log") subprocess.run([EDIT, "/compile:%s" % (dst / out_name), "/log:%s" % log], capture_output=True) txt = log.read_bytes().decode("utf-16", "ignore") if log.exists() else "" res = [l.strip() for l in txt.splitlines() if re.search(r"error|warning|Result", l, re.I)] print("%s (%d lines): %s | ex5 %s" % (out_name, len(src.splitlines()), res[-1] if res else "?", ex.exists())) if ex.exists(): shutil.copy2(ex, HERE / "release" / ex.name) else: status = 1 sys.exit(status)