| """Developer helper: drive Tick_Forge headless on a TESTING terminal install and report.
|
|
|
| usage: tf_run.py SRC NAME FROM TO MODE OFFSET_HOURS FUNCTION [SCREENSHOT.png]
|
| Set TF_DATA / TF_EXE for your own install. Defaults point at the OANDA testing install used in development.
|
| Never point this at a live-money terminal.
|
| """
|
| import os, subprocess, sys, time
|
| from pathlib import Path
|
|
|
| D = Path(os.environ.get("TF_DATA", r"C:\Users\gebruiker\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075"))
|
| EXE = os.environ.get("TF_EXE", r"C:\Program Files\MetaTrader 5\terminal64.exe")
|
|
|
|
|
| def w16(p, s):
|
| Path(p).write_bytes(b"\xff\xfe" + s.replace("\n", "\r\n").encode("utf-16-le"))
|
|
|
|
|
| def kill():
|
| subprocess.run(["powershell", "-NoProfile", "-Command",
|
| "Get-Process terminal64 -EA SilentlyContinue | Where-Object {$_.Path -eq '%s'} | Stop-Process -Force" % EXE])
|
|
|
|
|
| sym, name, fr, to, mode, off, fn = sys.argv[1:8]
|
| shot = sys.argv[8] if len(sys.argv) > 8 else ""
|
| guirun = os.environ.get("TF_GUIRUN") == "1" # drive the real window: fill the form and press GENERATE
|
| guiaudit = os.environ.get("TF_GUIAUDIT") == "1" # same, but press "Audit set" (7 symbols)
|
| auto = "false" if (shot or guirun or guiaudit) else "true"
|
| w16(D / "MQL5/Presets/tf_auto.set",
|
| "InpAuto=%s\nInpScreenshot=%s\nInpSource=%s\nInpTarget=%s\nInpFromDate=%s\nInpToDate=%s\nInpDataMode=%s\n"
|
| "InpOffsetHours=%s\nInpFunction=%s\nInpScaleSpread=true\nInpOverwrite=true\nInpCloseTerminal=true\nInpGuiRun=%s\nInpGuiAudit=%s\n" % (auto, shot, sym, name, fr, to, mode, off, fn, "true" if guirun else "false", "true" if guiaudit else "false"))
|
| import shutil
|
| (D / "MQL5/Profiles/Tester").mkdir(parents=True, exist_ok=True)
|
| shutil.copy2(D / "MQL5/Presets/tf_auto.set", D / "MQL5/Profiles/Tester/tf_auto.set")
|
| ini = Path(os.environ["TEMP"]) / "tf_auto.ini"
|
| w16(ini, "[StartUp]\nExpert=Tick_Forge\\TF_Dev\nExpertParameters=tf_auto.set\nSymbol=%s\nPeriod=M1\n" % sym)
|
| kill()
|
| time.sleep(2)
|
| for l in (D / "MQL5/Logs").glob("*.log"):
|
| try:
|
| l.rename(l.with_suffix(".bak%d" % int(time.time())))
|
| except OSError:
|
| pass
|
| subprocess.Popen([EXE, "/config:%s" % ini])
|
| key = "TICKFORGE_SHOT" if shot else "TICKFORGE_RESULT"
|
| t0 = time.time()
|
| lines = []
|
| while time.time() - t0 < 900:
|
| time.sleep(4)
|
| logs = sorted((D / "MQL5/Logs").glob("*.log"))
|
| if logs:
|
| lines = logs[-1].read_bytes().decode("utf-16-le", "ignore").splitlines()
|
| if any(key in x for x in lines):
|
| break
|
| time.sleep(8)
|
| for x in lines:
|
| if "TICKFORGE" in x or "TickForge" in x:
|
| print(x.encode("ascii", "ignore").decode()[:300])
|
| kill() if shot else None # headless generation closes the terminal itself (graceful, flushes the symbol list)
|