WIP: 6+ weeks of uncommitted EA development and preset tuning

Confluence EA (v1.16 → v1.20):
- Per-EA realized P&L tracking via history deals
- Weekly drawdown protection
- Warmup bars, pivot cache, state persistence
- Point-scaled pivot thresholds, ranging ATR factor
- Market filling mode helper per symbol

Grid EA (v3.1 → v4.1):
- Adaptive filters, adaptive entry, spread filter
- Session filter, breakeven, correlation caps, range drift
- Profit protection (stop-after-profit, cycle reports)
- Edge cleanup v5.0 — close wrong-side positions outside grid
- Master one-shot shutdown, grid state persistence

Presets:
- Fix GetOut=Y shutdown bug on 4 grid presets
- Relax ADXMax 18→40, widen RSI 20/80 across grid presets
- Standardize daily drawdown 3%→5%, add weekly 10%
- Increase grid lots 0.01→0.03
- Normalize confluence ATR thresholds per pair
- Add XAGUSD, EURCHF, EURGBP, AUDNZD presets

Docs & DevOps:
- April 23 audit files (preset mismatch, code review, checklist)
- n8n workflow and validation infrastructure updates
- AI agent analyses in notes/

Known issues carried forward:
- Shared drawdown budget contamination (both EAs)
- Confluence ranging-market threshold inversion
- Older grid presets missing v4.1 safety controls
This commit is contained in:
2026-05-12 09:02:25 -04:00
parent b9b4e2b22b
commit 0894d18db4
72 changed files with 3869 additions and 1416 deletions
@@ -0,0 +1,56 @@
# 2026-04-23 OrdersEA Smart Grid - Read-Only Code Review
Reviewed current `OrdersEA_Smart_Grid.mq5` and `grid-*.set` files in the repo read-only. No code changes made.
## Findings
### High: several presets set `GetOut=Y`, which makes those charts effectively unable to run grids
`GetOut` only accepts `N/L/S/A/X`; `Y` is invalid per validation in `OrdersEA_Smart_Grid.mq5` lines 1150-1159. But `OnTick()` treats anything other than `N` as GetOut mode, calls `HandleGetOut()`, deletes pending orders, sets `gridPlaced=false`, and returns before trading in lines 1212-1215. The affected repo presets are:
- `grid-usdjpy.set:32`
- `grid-xauusd.set:32`
- `grid-gbpusd.set:32`
- `grid-gbpjpy.set:32`
The comments say "enable for safety", but the code interprets that as shutdown mode. This is the first thing to fix before judging live behavior.
### High: the grid monitoring logic cancels same-side pending limits after the first fill, despite the comment saying opposite-side limits
When a BUY position exists, it deletes remaining `ORDER_TYPE_BUY_LIMIT`; when a SELL exists, it deletes remaining `ORDER_TYPE_SELL_LIMIT` in `OrdersEA_Smart_Grid.mq5` lines 1312-1335. That means it does not behave like a classic multi-level averaging grid after the first level fills. This may be intentional risk reduction, but it contradicts the comment and likely user expectation.
### High: daily/weekly drawdown is only partially isolated per EA
The P&L numerator is filtered by symbol and magic, which is good, but the daily and weekly baselines still use whole-account `ACCOUNT_EQUITY` in `OrdersEA_Smart_Grid.mq5` lines 340 and 353. If Confluence or another EA has floating P&L at rollover, OrdersEA's limit is based on a contaminated account-level baseline. The same isolation problem affects cycle profit logic.
### High: cycle profit target and stop-after-profit can be triggered by other EAs' floating P&L
`CheckProfitTarget()` compares current whole-account equity to `cycleStartEquity` in `OrdersEA_Smart_Grid.mq5` line 835, and `InpStopAfterProfit` uses whole-account equity in line 1341. Since `cycleStartEquity` is also captured from whole-account equity at grid placement in line 1417, Confluence can make Grid think a cycle is profitable, or vice versa.
### Medium: breakeven is now broker-valid but not really breakeven/profit-locking
Current logic sets BUY SL to `open - buffer` and SELL SL to `open + buffer` in `OrdersEA_Smart_Grid.mq5` line 791. That avoids the invalid-stops flood noted in the vault, but it parks the stop on the loss side of entry, not at true breakeven or better. If the intent is "after one TP, protect the remaining basket from loss," this implementation does not do that.
### Medium: breakeven can still flood logs if a broker rejects modifications
`ApplyBreakeven()` retries every 5 seconds and logs every failed `PositionModify()` in `OrdersEA_Smart_Grid.mq5` lines 799-803. There is no freeze-level/stops-level precheck and no failure backoff per ticket. The Apr 23 invalid-stop issue is fixed directionally, but the retry architecture can still produce another large log flood under a different rejection condition.
### Medium: adaptive relaxation does not help symbols that have never traded
`UpdateFilterRelaxation()` returns immediately when `lastTradePlacedTime == 0` in `OrdersEA_Smart_Grid.mq5` lines 530-537. So a pair that has been blocked forever by filters never relaxes, even though the feature says "relax after N days with no trade." It only relaxes after at least one prior order placement.
### Medium: old presets do not carry the newer safety inputs, so they rely on risky defaults
The older `grid-eurusd/usdjpy/gbpusd/...` files do not define `InpUseSessionFilter`, `InpUseBreakeven`, correlation caps, or spread caps, so MT5 will use source defaults. Source default is `InpUseSessionFilter=false` in `OrdersEA_Smart_Grid.mq5` line 65, meaning most older pairs are not actually restricted to Asia hours. The new EURGBP/EURCHF/AUDNZD presets are much better aligned with v4.1.
## What Looks Good
The core v4.1 architecture is much improved versus the earlier vault history:
- Uses `_Symbol` plus `MagicNum` consistently for normal position/order handling.
- Pending orders use `ORDER_FILLING_RETURN`, avoiding the IOC pending-order issue.
- `IsBreakout()` no longer clobbers ATR-based grid bounds.
- Pivots recalc reliably once per broker day after the first tick.
- State is persisted through GlobalVariables.
- Master shutdown is one-shot instead of every tick.
- Range, spread, session, correlation, daily/weekly drawdown, cycle reports, and weekend close are all present.
## Bottom Line
The biggest practical problem is not the `.mq5` core, it is the mismatch between code semantics and presets: `GetOut=Y` is a shutdown setting in practice, not a safety enable. After that, the main code risks are equity contamination from other EAs, unclear same-side limit cancellation behavior, and breakeven not actually locking breakeven.
## Suggested Next Steps
1. Audit and normalize every live chart's loaded preset, especially `GetOut`, `MagicNum`, `InpUseSessionFilter`, and `InpUseBreakeven`.
2. Decide whether OrdersEA should be a true multi-level averaging grid or a one-fill-per-side range system, then align the cancellation logic and comments.
3. Make cycle P&L/profit-stop/drawdown baselines use OrdersEA-only P&L rather than whole-account equity.