""" Summarise a set of WarriorDipZ tester runs: the report's MARK-TO-MARKET equity drawdown plus journal-derived cadence, swap drag and an IS/OOS split. python grid_summary.py claude_g4_c0 claude_g4_c10 ... Screen (the account's actual rule): cadence >= 2/mo, equity maxDD <= 5%, ret/DD >= 2 -- with ret/DD computed on the MARK-TO-MARKET drawdown, never the exit-based one, which understates concurrent losses. """ from __future__ import annotations import re import sys import numpy as np TERM = r"C:\Users\admin\AppData\Roaming\MetaQuotes\Terminal\10CE948A1DFC9A8C27E56E827008EBD4" COMMON = r"C:\Users\admin\AppData\Roaming\MetaQuotes\Terminal\Common\Files" DEPOSIT = 100000.0 def report(name): t = open(rf"{TERM}\{name}.htm", encoding="utf-16").read() cells = [re.sub(r"\s+", " ", re.sub(r"<[^>]+>", "", c)).strip() for c in re.findall(r"]*>(.*?)", t, flags=re.S)] out = {} for i, c in enumerate(cells): nxt = next((x for x in cells[i + 1:i + 4] if x), "") if c == "Total Net Profit:": out["net"] = float(nxt.replace(" ", "")) elif c == "Equity Drawdown Maximal:": out["eqdd"] = float(re.search(r"\(([\d.]+)%\)", nxt).group(1)) / 100 elif c == "Profit Factor:": out["pf"] = float(nxt) return out def journal(name): raw = np.genfromtxt(rf"{COMMON}\dipz_trades_{name}.csv", delimiter=",", skip_header=1, dtype=str, encoding="ansi") ts = lambda s: np.datetime64(s[:10].replace(".", "-") + "T" + s[11:] + ":00") # noqa: E731 return [dict(sym=r[1], t=ts(r[2]), x=ts(r[5]), net=float(r[7]), gross=float(r[9]), swap=float(r[10])) for r in raw] def seg_stats(rows): rows = sorted(rows, key=lambda r: r["x"]) q = DEPOSIT + np.concatenate([[0], np.cumsum([r["net"] for r in rows])]) dd = ((np.maximum.accumulate(q) - q) / np.maximum.accumulate(q)).max() return q[-1] / DEPOSIT - 1, dd if __name__ == "__main__": names = sys.argv[1:] print(f"{'run':<16}{'n':>5}{'/mo':>6}{'net':>8}{'CAGR':>7}{'eqDD':>7}{'ret/DD':>8}{'PF':>6}" f"{'swap':>8}{'swap%':>7} {'IS ret/DDx':>10}{'OOS ret/DDx':>12} screen") for nm in names: try: rp, js = report(nm), journal(nm) except Exception as e: # noqa: BLE001 print(f"{nm:<16} unreadable: {e}") continue yrs = (max(r["x"] for r in js) - min(r["t"] for r in js)) / np.timedelta64(365, "D") tot = rp["net"] / DEPOSIT cagr = (1 + tot) ** (1 / yrs) - 1 rdd = tot / rp["eqdd"] swap = sum(r["swap"] for r in js) gross = sum(r["gross"] for r in js) split = np.datetime64("2024-01-01") is_t, is_d = seg_stats([r for r in js if r["t"] < split]) oo_t, oo_d = seg_stats([r for r in js if r["t"] >= split]) permo = len(js) / (yrs * 12) fails = [k for k, bad in (("cadence", permo < 2), ("eqDD", rp["eqdd"] > 0.05), ("ret/DD", rdd < 2)) if bad] print(f"{nm:<16}{len(js):>5}{permo:>6.1f}{tot:>+8.1%}{cagr:>+7.1%}{rp['eqdd']:>7.2%}" f"{rdd:>8.2f}{rp['pf']:>6.2f}{swap:>8.0f}{swap / gross if gross else 0:>7.0%}" f" {is_t / is_d if is_d else float('nan'):>10.2f}{oo_t / oo_d if oo_d else float('nan'):>12.2f}" f" {'PASS' if not fails else 'fail:' + ','.join(fails)}") print("\nIS/OOS ret/DDx use the exit-based drawdown inside each window (split 2024-01-01);" " the headline ret/DD uses the tester's mark-to-market equity drawdown.")