From one sentence to a tested strategy: AI scripting, bar replay and a grid optimizer in the browser
Describe a strategy in English, get runnable code, replay it bar by bar, then sweep every input the way the Strategy Tester sweeps an input block. Three engineering notes from building it: keeping the AI from inventing functions, resolving same-bar stop/target ties from finer timeframes, and why the optimizer has no combination cap.
1. AI scripting
The demo is easy — chat column, English in, code out. The hard part is that a model asked for a small DSL confidently writes functions that don't exist; it has read a lot of Pine and MQL5 and none of your language.
Two things fixed it. The spec in the system prompt is generated from the engine, not hand-written, and a test asserts both directions — nothing documented the engine lacks, nothing the engine offers left undocumented. It states the closed world explicitly: "THERE ARE NO OTHER INDICATORS. No ta.vwap, no ta.supertrend." And the script is parse-checked on arrival, not on Run, with a FIX IT button that sends the error back. Plus an Undo, because a feature that silently replaces forty lines of your work is one people stop using.
2. The backtest
The engine has no indicator math of its own — ta.ema calls the same function the chart draws with, P&L calls the same routine manual trading uses. That's the MQL5 iMA() guarantee: chart and test can't disagree.
Look-ahead is proven, not promised: truncate 2,000 bars off the end and re-run — no trade that closed before the cut may move. Steal that test.
Unresolvable ties assume the stop filled first — biased against the trader — and the count is reported, because that assumption can manufacture an entire edge. Measured: 43.6% of trades hit an ambiguous candle, and 50.5% of them had actually reached the target first. Win rate 26.0% → 47.5%. Not a rounding difference — a different strategy.
3. The optimizer
Tick the inputs, give min/max/step, every combination runs and ranks. No combination cap, because we measured instead of guessing: 12,000 bars costs ~22 ms per combo, so 500 combos is ~11 seconds. The panel times two real runs of your script on your bars and shows the estimate.
Single thread, so it's time-sliced at 45 ms and yields through MessageChannel (nested setTimeout(0) gets clamped to 4 ms and would cap a light sweep at ~200 combos/sec). One combo is the granularity and slicing can't change that — a worker would fix it, but the engine binds to the chart's own functions on the main thread, and that binding is the no-drift guarantee.
MT5 wins here and it's worth saying: local agents, cloud network, genetic algorithm. We enumerate a full grid on one thread.
Reporting rules: zero-trade rows shown dimmed, never hidden ("this range never fires" is the answer people came for); a combo that throws becomes an error row and the sweep continues; APPLY BEST takes the top of the current sort, not the default score. And the standing note — a wide grid always has a best row, and it may be luck.
Try it out: https://fxbacktest.app/
Describe a strategy in English, get runnable code, replay it bar by bar, then sweep every input the way the Strategy Tester sweeps an input block. Three engineering notes from building it: keeping the AI from inventing functions, resolving same-bar stop/target ties from finer timeframes, and why the optimizer has no combination cap.
1. AI scripting
The demo is easy — chat column, English in, code out. The hard part is that a model asked for a small DSL confidently writes functions that don't exist; it has read a lot of Pine and MQL5 and none of your language.
Two things fixed it. The spec in the system prompt is generated from the engine, not hand-written, and a test asserts both directions — nothing documented the engine lacks, nothing the engine offers left undocumented. It states the closed world explicitly: "THERE ARE NO OTHER INDICATORS. No ta.vwap, no ta.supertrend." And the script is parse-checked on arrival, not on Run, with a FIX IT button that sends the error back. Plus an Undo, because a feature that silently replaces forty lines of your work is one people stop using.
2. The backtest
The engine has no indicator math of its own — ta.ema calls the same function the chart draws with, P&L calls the same routine manual trading uses. That's the MQL5 iMA() guarantee: chart and test can't disagree.
Look-ahead is proven, not promised: truncate 2,000 bars off the end and re-run — no trade that closed before the cut may move. Steal that test.
Unresolvable ties assume the stop filled first — biased against the trader — and the count is reported, because that assumption can manufacture an entire edge. Measured: 43.6% of trades hit an ambiguous candle, and 50.5% of them had actually reached the target first. Win rate 26.0% → 47.5%. Not a rounding difference — a different strategy.
3. The optimizer
Tick the inputs, give min/max/step, every combination runs and ranks. No combination cap, because we measured instead of guessing: 12,000 bars costs ~22 ms per combo, so 500 combos is ~11 seconds. The panel times two real runs of your script on your bars and shows the estimate.
Single thread, so it's time-sliced at 45 ms and yields through MessageChannel (nested setTimeout(0) gets clamped to 4 ms and would cap a light sweep at ~200 combos/sec). One combo is the granularity and slicing can't change that — a worker would fix it, but the engine binds to the chart's own functions on the main thread, and that binding is the no-drift guarantee.
MT5 wins here and it's worth saying: local agents, cloud network, genetic algorithm. We enumerate a full grid on one thread.
Reporting rules: zero-trade rows shown dimmed, never hidden ("this range never fires" is the answer people came for); a combo that throws becomes an error row and the sweep continues; APPLY BEST takes the top of the current sort, not the default score. And the standing note — a wide grid always has a best row, and it may be luck.
Try it out: https://fxbacktest.app/