SniperGold_ML/docs/P3_S13_CANDIDATE_SETUP_REPAIR.md

14 KiB

P3-S.13 CANDIDATE SETUP LAYER — SNIPERGOLD_ML (F3)

Date       : 2026-08-22
Session    : P3-S.13 — F3 CANDIDATE SETUP LAYER (third implementation phase
             of the frozen canonical architecture, P3-S.10).
Status     : IMPLEMENTED — test-first, contract enforced, consumer audit done,
             regression green, compilation 0/0, Forge pushed.
Baseline   : P3_S12_CLOSE_SHA e8efab9e950d5f851d354061a7e862a95e20f018
Contract   : docs/SNIPERGOLD_CANONICAL_SETUP_CONTRACT_v1.md (frozen)
Adjudication: docs/P3_S10_OWNER_ADJUDICATION.md (OD-1..OD-5)
F1 report  : docs/P3_S11_EVENT_CONTRACT_REPAIR.md
F2 report  : docs/P3_S12_ZONE_CONTRACT_REPAIR.md
Test report: ml/p3/smc_semantic/output/p3_s13_candidate_setup_report.json
Human verification : CANCELLED. No AUC/PF/profit/backtest/optimization used.

A. Frozen Architecture (implemented)

H4 context gate (direction-compatible)
        -> M30 context gate (direction-compatible)
        -> fresh Liquidity EVENT (M15, W_sweep = 40)
        -> CHoCH/MSS EVENT after the sweep (M15, W_choch = 40, same direction)
        -> unmitigated OB OR FVG ZONE (M15, direction-compatible)
        -> M15 entry condition
        -> CANDIDATE_SETUP (direction = chain direction)
        -> [optional M3 confirmation -> M3_CONFIRMED]

Primitive roles (frozen §C): H4 = CONTEXT STATE (gate), M30 = CONTEXT STATE (gate), Liquidity Sweep = EVENT (required, W_sweep=40), CHoCH/MSS = STRUCTURAL EVENT (required, W_choch=40, after sweep, inside the sweep chain), OB = ZONE (alternative), FVG = ZONE (alternative), Displacement = OPTIONAL ATTRIBUTE (per-bar, no persistent state), M15 = ENTRY CONDITION / CHAIN CARRIER (required), M3 = OPTIONAL MICRO CONFIRMATION (no veto).

Semantic separation (frozen §A/§J): STATE != EVENT != ZONE != CONDITION != CANDIDATE_SETUP != SIGNAL != TRADE. A directional signal may exist without a setup; a Candidate Setup requires the complete canonical chain.


B. Implementation Scope

IN SCOPE  : Candidate Setup entity, identity, lifecycle state machine,
            H4/M30 gates, event-chain consumption (F1), zone consumption (F2),
            M15 entry condition validation, optional M3 confirmation,
            one-setup-one-identity, one-entry rule, score separation,
            deterministic dedup, regression + compilation.
OUT OF SCOPE (NOT modified): F4 MTF/training alignment, F5 display
            redesign, ML/training pipeline, FEATURE_CONTRACT, legacy v4.x
            restoration, primitive detection formulas (sweep/CHoCH/FVG/OB/
            displacement unchanged), the flat aggregator's arithmetic.

C. Candidate Setup Object

AFCandidateSetup (AF_Engine2_Setup.mqh, frozen §E):

  setup_id               : monotonic integer, assigned at CANDIDATE_SETUP
  direction              : +1 bullish / -1 bearish (chain direction)
  state                  : lifecycle enum (frozen §F)
  sweep_onset, sweep_dir : originating Liquidity EVENT reference
  choch_onset, choch_dir : structure EVENT reference
  zone_type              : OB | FVG
  zone_formation         : zone formation bar (causal identity)
  zone_dir               : zone direction
  zone_mit_at_creation   : F2 mitigation state when the chain consumed it
  creation_bar           : M15 bar when the chain completed
  m3_bar                 : M3 confirmation bar (-1 = none)
  reason                 : provenance / lifecycle reason
  entry_bound            : one-entry bookkeeping (frozen §H)

NO execution fields (lot/SL/TP/ticket) — those are outside F3 (frozen §A,
CS-31). The scoring layer may attach score/confidence/ranking AFTER setup
existence (frozen §I) but never creates one.

D. State Machine

NONE -> CONTEXT_VALID -> LIQUIDITY_TRIGGERED -> STRUCTURE_CONFIRMED ->
ZONE_READY -> ENTRY_ARMED -> CANDIDATE_SETUP -> [M3_CONFIRMED]
        -> EXPIRED | INVALIDATED | CONSUMED

Rules (frozen §F):
  - strict stage order; no skipping;
  - a lapsed stage BEFORE CANDIDATE_SETUP discards the forming setup;
  - CANDIDATE_SETUP / M3_CONFIRMED are the ACTIVE formation states;
  - EXPIRED / INVALIDATED / CONSUMED are terminal and NON-REVERSIBLE
    (no reactivation);
  - at most one entry signal per setup (CONSUMED);
  - M3_CONFIRMED is optional; a contrary/absent M3 does NOT invalidate.

E. H4/M30 Gate

OD-1: H4 and M30 are HARD direction-compatible gates for the setup layer.
  - H4_state(asof) and M30_state(asof) must each be non-zero and equal to
    the chain direction.
  - H4 <-> M30 conflict (opposite signs) -> BLOCKED (no chain).
  - A neutral (0) state fails the gate -> no chain.
  - M15 chain conflict with H4/M30 -> BLOCKED (OD-4).
The flat vote remains a scoring/signal layer (signal != setup, §J); the
gates apply to the SETUP LAYER ONLY (OD-1 override recorded).

F. Event Chain

Consumed via the F1 EVENT contract (P3-S.11):
  sweep : fresh event only — age <= W_sweep (40 M15 bars);
          onset <= decision bar <= onset + W_sweep.
  CHoCH : fresh event — age <= W_choch (40);
          AFTER the sweep (choch onset >= sweep onset);
          inside the sweep validity chain (choch onset - sweep onset <= 40);
          same direction as the sweep.
No raw historical detector state is read; the F3 layer consumes F1 events
(AF_DetectSweepEvent / AF_DetectChochEvent materialize the onset that the
stateless detectors already compute; geometry unchanged).

G. Zone Consumption

Consumed via the F2 ZONE contract (P3-S.12):
  Candidate Setup may use ACTIVE + UNMITIGATED OB (AF_SETUP_ZONE_OB) OR
  ACTIVE + UNMITIGATED FVG (AF_SETUP_ZONE_FVG) — direction-compatible.
  Fully mitigated / invalidated zones are NOT consumable (AFZoneState
  mit_state + invalidated; F2 semantics reused).
  Zone mitigation mid-chain invalidates the setup (frozen §F).
F3 does NOT reimplement FVG/OB mitigation — it consumes AFZoneState.

H. M15 Entry Condition

The canonical M15 entry semantics are the project's own E-rule (Definition A,
SMC_CANDIDATE_SETUP_SPEC_v1 CS-1), retained as the M15 entry-condition
predicate inside the chain (P3-S.9 D.1):
  m15_cond(d) = zone membership AND confirmation conjunction (sweep OR
  choch direction-compatible) AND premium/discount filter (not in premium
  for buy / not in discount for sell); displacement may boost.
In the canonical chain the confirmation legs are already validated as stages
(§F); the M15 entry condition is the final direction-compatible CONDITION.
It is consumed as a semantic input (m15) by the F3 layer — the layer
validates it, it does not recompute the E-rule arithmetic. The M15 layer
acts as ENTRY CONDITION / CHAIN CARRIER, NOT as a second scoring system.

I. M3 Confirmation

Optional (frozen §F/§N, OD-4):
  - M3 direction-compatible within W_m3 of creation -> M3_CONFIRMED.
  - M3 contrary or absent -> M3_CONFIRMED = FALSE.
  - The Candidate Setup REMAINS VALID (M3 is not a gate).
  - A contrary M3 reduces only the micro-score (never the setup existence).
W_m3 = OPEN NUMERIC PARAMETER; placeholder test boundary 2 M15 decision
bars (~10 M3 bars at the 5:1 M3:M15 ratio), documented, NOT optimized.

J. Identity / Deduplication

Frozen §E/§G:
  uniqueness = (direction, sweep onset, choch onset, zone formation ts,
                creation ts). CAUSAL identity — every component is a dated
  chain element; no random id; no per-bar regeneration.
  ONE CAUSAL SETUP = ONE SETUP IDENTITY. While the same chain remains
  active, the same setup_id persists across bars (F3-T14/T23/T24).
  A new setup exists only when a NEW chain completes (new sweep onset /
  new CHoCH / new zone reference), producing a distinct identity.
  Dedup BY CONSTRUCTION: the engine's identity registry rejects a second
  setup with the same chain key (F3-T23/T24).

K. Score Separation

Frozen §I/§J: SCORE != SETUP EXISTENCE.
  - The flat aggregator (weighted vote) remains a SCORING/RANKING layer.
  - A score can never create a Candidate Setup (F3-T13).
  - A Candidate Setup can exist with ANY score, including a low one
    (F3-T25).
  - The aggregated vote may still produce a DIRECTIONAL SIGNAL without a
    setup (F3-T12) — that is a bias, not an entry instruction.
  - Entry signals (actionable) may only be emitted when bound to a valid
    CANDIDATE_SETUP (frozen §J.2).
Consumer audit: AFAggOut carries NO setup field; AF_Engine2_Aggregator /
AF_Engine2_Display / AF_Engine3_Render have zero references to the F3 layer.

L. Tests

New suite: ml/p3/smc_semantic/spec_tests_candidate_setup_runtime.py
  F3-T01..T25 (all 25 required by the brief §15):

  F3-T01  Valid complete setup (OB)          -> ONE CANDIDATE_SETUP
  F3-T02  FVG alternative                    -> ONE CANDIDATE_SETUP
  F3-T03  No zone                            -> NO CANDIDATE_SETUP
  F3-T04  Stale sweep (age 41 > 40)          -> NO CANDIDATE_SETUP
  F3-T05  CHoCH before sweep                 -> NO CANDIDATE_SETUP
  F3-T06  CHoCH outside sweep window         -> NO CANDIDATE_SETUP
  F3-T07  Wrong direction (chain vs context) -> NO CANDIDATE_SETUP
  F3-T08  H4 conflict                        -> BLOCKED
  F3-T09  M30 conflict                       -> BLOCKED
  F3-T10  M15 conflict                       -> BLOCKED
  F3-T11  M3 opposite                        -> setup valid, M3=FALSE
  F3-T12  H4-only signal                     -> signal exists, setup NONE
  F3-T13  High score without setup           -> score exists, setup NONE
  F3-T14  Identity stability                 -> same setup_id across bars
  F3-T15  One entry per setup                -> max one entry binding
  F3-T16  Setup expiration (W_setup=40)      -> EXPIRED
  F3-T17  Setup invalidation (zone mitigated)-> INVALIDATED
  F3-T18  Setup consumption                  -> CONSUMED, no 2nd entry
  F3-T19  Two independent setups             -> two distinct setup_ids
  F3-T20  Future mutation                    -> historical setup unchanged
  F3-T21  Zone mitigation before M15 entry   -> NO CANDIDATE_SETUP
  F3-T22  Context change after formation     -> INVALIDATED (canonical §F)
  F3-T23  Repeated raw state                 -> one event chain, one setup
  F3-T24  Duplicate formation prevention     -> no duplicate setup
  F3-T25  Candidate vs score                 -> setup EXISTS with low score

Discipline: canonical oracle vs expected ASSERT; repaired port (the MQL5
setup engine) vs oracle ASSERT; legacy port (PRE-F3, P3-S.8 facts) REPORT;
invariance (future mutation) ASSERT. Report:
ml/p3/smc_semantic/output/p3_s13_candidate_setup_report.json.

M. Regression

P3-S.2  Liquidity Sweep     17/17  PASS
P3-S.3  CHoCH/MSS           20/20  PASS
P3-S.4  FVG                 20/20  PASS
P3-S.5  Order Block         20/20  PASS
P3-S.6  Displacement        20/20  PASS
P3-S.7  MTF Alignment       22/22  PASS
P3-S.8  Candidate Setup     25/25  PASS
F1      Event Contract       8/8   PASS
F2      Zone Contract       20/20  PASS
F3      Candidate Setup     25/25  PASS
No suite weakened; no oracle changed. P3-S.4/S.5 still assert the SPEC
oracle (immutable) and REPORT the legacy code port as historical evidence;
the repaired Engine-2 behavior is asserted by the F2/F3 suites.

N. Compilation

MetaEditor build 6140, target AVX512 + FMA3:
  MQL5\Experts\AlgoForge_Engine2_UnitTest.mq5  -> 0 errors, 0 warnings
  MQL5\Indicators\AlgoForge\AF_Engine3_Display.mq5 -> 0 errors, 0 warnings
  MQL5\Experts\AlgoForge_Engine3_UnitTest.mq5  -> 0 errors, 0 warnings
Engine-2 unit test (Strategy Tester, XAUUSD M15, every tick):
  PASS=35891 FAIL=0 — includes T7a..T7e synthetic setup-layer checks.
Repo and terminal copies of the modified headers are byte-identical (fc /b).

O. Explicitly Unchanged Areas

F4 MTF / Training     : H4/M30/M15/M3 model, as-of logic, conflict policy,
                        hierarchy, train_model.py, build_features.py,
                        FEATURE_CONTRACT — untouched.
F5 Display            : render logic untouched (no F5 redesign in F3).
ML                    : model, LSTM, regime, meta-label — untouched.
Legacy v4.3/v4.4/v4.5 : historical evidence only; NOT restored.
Primitive detection   : AF_DetectSweep / AF_DetectChoch / AF_FindFVG /
                        AF_FindOrderBlock / AF_DetectDisplacement geometry
                        UNCHANGED (F1/F2 repairs retained).
Flat aggregator       : AFAggregator arithmetic unchanged (scoring layer).
EA (AlgoForge_Backtest_Baseline.mq5) : untouched (its F1 event contract is
                        consumed conceptually; no EA edit in F3).

P. Remaining F4/F5 work

F4 (next gate, P3-S.14): H4/M30/M15/M3 canonical alignment,
    runtime/training MTF mismatch, D1/H4/H1/M15 legacy training path,
    FEATURE_CONTRACT implications. The F3 layer consumes semantic inputs;
    the MTF wiring (Engine-1 slots -> semantic inputs) and any runtime
    integration belong to F4. If F4 discovers the current MTF layer cannot
    provide the required data, that is documented as an F4 blocker — NOT
    modified inside F3.
F5: display the setup entity (id, stages, lifecycle) instead of the bare
    vote signal in the "TRADE SETUP" panel — deferred, NOT started.
Phase VI: setup dataset rebuild for training — after F3/F4 validation.

Q. Forge Commit(s)

1. test: define F3 candidate setup regression coverage
   - ml/p3/smc_semantic/spec_tests_candidate_setup_runtime.py
   - ml/p3/smc_semantic/output/p3_s13_candidate_setup_report.json
2. feat: implement canonical candidate setup layer
   - MQL5/Include/AlgoForge/AF_Engine2_Setup.mqh      (new — F3 layer)
   - MQL5/Include/AlgoForge/AF_Defines.mqh            (W_setup/W_m3)
   - MQL5/Include/AlgoForge/AF_Engine2_Agents.mqh     (F1 event helpers)
   - MQL5/Experts/AlgoForge_Engine2_UnitTest.mq5      (T7 setup checks)
3. docs: record P3-S.13 candidate setup implementation
   - docs/P3_S13_CANDIDATE_SETUP_REPAIR.md            (this report)

R. Final Forge HEAD

P3_S13_FINAL_SHA = (recorded after push; see session handover).

S. Working Tree

local HEAD == remote HEAD, working tree CLEAN (verified after push).

T. P3-S.14 Readiness

The canonical Candidate Setup entity now exists: one causal chain = one
setup_id, deterministic lifecycle, H4/M30 gates enforced, fresh sweep +
CHoCH-after-sweep + unmitigated OB|FVG + M15 entry required, M3 optional,
score separated from setup existence, future data cannot alter past setup.
Next gate: P3-S.14 = F4 MTF / Training Alignment. NOT started in this
session.

End of P3-S.13 F3 candidate setup layer record. No F4/F5/ML change.