2026-09-23 13:24:57 -04:00 | | | # run_tests.ps1 [-Expert WarriorGapFade -Prefix gapfade] - compile an EA, run one or more tester configs, keep each journal.
|
| | | #
|
| | | # .\run_tests.ps1 claude_dipz_4 claude_dipz_7
|
| | | #
|
| | | # Each name is an .ini in the fleet terminal's data dir. For each run this:
|
| | | # * closes any running terminal64 (a second launch on the same data dir is
|
| | | # silently swallowed by the running instance - the config never runs)
|
| | | # * launches with /config:<BACKSLASH path> (a forward-slash path falls back to cwd)
|
| | | # * checks the line after "launched with <ini>" is "automatic testing started"
|
| | | # (the process exit code says nothing about whether the test ran)
|
| | | # * waits for the EA's journal and copies it to dipz_trades_<name>.csv
|
| | | [CmdletBinding(PositionalBinding = $false)]
|
 feat(warrior): the vol-gated dip-buy book, ported into Warrior_EA
Warrior's defaults are now the validated book: DIP_ZSCORE alone, long only, H4,
risk 0.25%, one chart per index with a shared Magic.
- System/BarCache.mqh: whole-history closed bars, Wilder ATR, GK sigma and the
expanding vol percentile (no 1024-bar stdlib ceiling)
- System/AccountGuard.mqh: open-risk cap, kill switch, cross-chart lock and
Friday flat, shared through terminal globals by Magic
- CWarriorExpert: guard on every tick; a transient open failure retries the bar
- CWarriorSignal::SetupStop: the dip owns its 3 x Wilder ATR stop from the bid
- SignalDipBuy: no entry vote while holding (a still-dipping time exit never
closed, and Processing re-entered on the exit bar); no entry on a stop bar
- WarriorMoney sizes on equity; WARRIOR_RISK allows fractional risk
- TradeLog + research/compare_ea.py: trade-for-trade check vs WarriorDipZ -
SP500/US30/DAX40 identical to the cent, NAS100 96.9% (stale-quote timer fills)
- research/nn_cross_index.py: pre-registered cross-index NN meta-label - FAIL
(AUC 0.564, CI [0.498, 0.630]); DipMetaCut stays off
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 21:14:53 -04:00 | | | param([string]$Expert = 'WarriorDipZ', [string]$Prefix = 'dipz', [switch]$NoCompile,
|
2026-09-23 13:24:57 -04:00 | | | [Parameter(ValueFromRemainingArguments = $true)][string[]]$Configs)
|
| | |
|
| | | $ErrorActionPreference = 'Stop'
|
| | | $term = 'C:\Program Files\Five Percent Online MetaTrader 5'
|
| | | $data = 'C:\Users\admin\AppData\Roaming\MetaQuotes\Terminal\10CE948A1DFC9A8C27E56E827008EBD4'
|
| | | $common = 'C:\Users\admin\AppData\Roaming\MetaQuotes\Terminal\Common\Files'
|
| | | $src = Join-Path $PSScriptRoot "$Expert.mq5"
|
| | | $dst = Join-Path $data "MQL5\Experts\Warrior\$Expert.mq5"
|
| | |
|
 feat(warrior): the vol-gated dip-buy book, ported into Warrior_EA
Warrior's defaults are now the validated book: DIP_ZSCORE alone, long only, H4,
risk 0.25%, one chart per index with a shared Magic.
- System/BarCache.mqh: whole-history closed bars, Wilder ATR, GK sigma and the
expanding vol percentile (no 1024-bar stdlib ceiling)
- System/AccountGuard.mqh: open-risk cap, kill switch, cross-chart lock and
Friday flat, shared through terminal globals by Magic
- CWarriorExpert: guard on every tick; a transient open failure retries the bar
- CWarriorSignal::SetupStop: the dip owns its 3 x Wilder ATR stop from the bid
- SignalDipBuy: no entry vote while holding (a still-dipping time exit never
closed, and Processing re-entered on the exit bar); no entry on a stop bar
- WarriorMoney sizes on equity; WARRIOR_RISK allows fractional risk
- TradeLog + research/compare_ea.py: trade-for-trade check vs WarriorDipZ -
SP500/US30/DAX40 identical to the cent, NAS100 96.9% (stale-quote timer fills)
- research/nn_cross_index.py: pre-registered cross-index NN meta-label - FAIL
(AUC 0.564, CI [0.498, 0.630]); DipMetaCut stays off
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 21:14:53 -04:00 | | | # -NoCompile: the ini's Expert= is already built (Warrior_EA is compiled from a staged copy of the
|
| | | # whole repo, not from mql5/).
|
| | | if (-not $NoCompile) {
|
| | | Copy-Item $src $dst -Force
|
| | | $clog = Join-Path $env:TEMP 'dipz_compile.log'
|
| | | & (Join-Path $term 'MetaEditor64.exe') /compile:"$dst" /log:"$clog" | Out-Null
|
| | | Start-Sleep -Milliseconds 1500
|
| | | $res = (Get-Content $clog -Encoding Unicode | Select-String 'Result:').ToString()
|
| | | Write-Output "compile: $res"
|
| | | if ($res -notmatch ' 0 errors') { throw 'compile failed' }
|
| | | }
|
2026-09-23 13:24:57 -04:00 | | |
|
| | | foreach ($name in $Configs) {
|
 feat(warrior): the vol-gated dip-buy book, ported into Warrior_EA
Warrior's defaults are now the validated book: DIP_ZSCORE alone, long only, H4,
risk 0.25%, one chart per index with a shared Magic.
- System/BarCache.mqh: whole-history closed bars, Wilder ATR, GK sigma and the
expanding vol percentile (no 1024-bar stdlib ceiling)
- System/AccountGuard.mqh: open-risk cap, kill switch, cross-chart lock and
Friday flat, shared through terminal globals by Magic
- CWarriorExpert: guard on every tick; a transient open failure retries the bar
- CWarriorSignal::SetupStop: the dip owns its 3 x Wilder ATR stop from the bid
- SignalDipBuy: no entry vote while holding (a still-dipping time exit never
closed, and Processing re-entered on the exit bar); no entry on a stop bar
- WarriorMoney sizes on equity; WARRIOR_RISK allows fractional risk
- TradeLog + research/compare_ea.py: trade-for-trade check vs WarriorDipZ -
SP500/US30/DAX40 identical to the cent, NAS100 96.9% (stale-quote timer fills)
- research/nn_cross_index.py: pre-registered cross-index NN meta-label - FAIL
(AUC 0.564, CI [0.498, 0.630]); DipMetaCut stays off
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 21:14:53 -04:00 | | | # ONLY the fleet terminal - never the portable one under Documents\Workspaces.
|
| | | Get-Process terminal64 -ErrorAction SilentlyContinue |
|
| | | Where-Object { $_.Path -eq (Join-Path $term 'terminal64.exe') } | Stop-Process -Force
|
2026-09-23 13:24:57 -04:00 | | | Start-Sleep -Seconds 4
|
| | |
|
| | | $ini = Join-Path $data "$name.ini"
|
| | | $started = Get-Date
|
| | | Start-Process -FilePath (Join-Path $term 'terminal64.exe') -ArgumentList "/config:$ini"
|
| | |
|
| | | # confirm the test actually started
|
| | | $ok = $false
|
| | | for ($i = 0; $i -lt 30 -and -not $ok; $i++) {
|
| | | Start-Sleep -Seconds 2
|
| | | $log = Get-ChildItem (Join-Path $data 'logs') -Filter '2*.log' | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
| | | $lines = Get-Content $log.FullName -Encoding Unicode
|
| | | $idx = -1
|
| | | for ($k = $lines.Count - 1; $k -ge 0; $k--) { if ($lines[$k] -match 'launched with' -and ($lines[$k] + $lines[[math]::Min($k+1,$lines.Count-1)]) -match [regex]::Escape("$name.ini")) { $idx = $k; break } }
|
| | | if ($idx -ge 0) { $ok = ($lines[$idx..($lines.Count - 1)] -match 'automatic testing started').Count -gt 0 }
|
| | | }
|
| | | if (-not $ok) { Write-Output "$name : testing did NOT start"; continue }
|
| | |
|
| | | # the EA writes dipz_trades_<SYMBOL>.csv (and dipz_eq_<SYMBOL>.csv) on deinit
|
| | | $journal = $null
|
| | | for ($i = 0; $i -lt 180 -and -not $journal; $i++) {
|
| | | Start-Sleep -Seconds 5
|
| | | $journal = Get-ChildItem $common -Filter "$($Prefix)_trades_*.csv" |
|
| | | Where-Object { $_.LastWriteTime -gt $started -and $_.Name -notmatch 'claude_' } |
|
| | | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
| | | }
|
| | | if (-not $journal) { Write-Output "$name : no journal after 15 min"; continue }
|
| | | Start-Sleep -Seconds 2
|
| | | Copy-Item $journal.FullName (Join-Path $common "$($Prefix)_trades_$name.csv") -Force
|
| | | $eq = Get-ChildItem $common -Filter "$($Prefix)_eq_*.csv" | Where-Object { $_.LastWriteTime -gt $started -and $_.Name -notmatch 'claude_' } | Select-Object -First 1
|
| | | if ($eq) { Copy-Item $eq.FullName (Join-Path $common "$($Prefix)_eq_$name.csv") -Force }
|
| | | $rows = (Get-Content $journal.FullName).Count - 1
|
| | | Write-Output ("{0} : {1} trades, {2:n0}s" -f $name, $rows, ((Get-Date) - $started).TotalSeconds)
|
| | | }
|