SniperGold_ML/docs/P3_S18A_LABEL_CONTRACT_REVIEW.md

19 KiB

P3-S18A LABEL CONTRACT REVIEW — SETUP-OUTCOME SEMANTIC AUDIT

Date       : 2026-08-23
Session    : P3-S.18A — OPTION A: LABEL CONTRACT REVIEW
Status     : COMPLETE
Verdict    : PRIMARY LABEL CONTRACT = APPROVED AS V1
             (with documented, additive v2 enrichment recommendations —
             NOT semantic corrections of a defect)
Scope      : RESEARCH / CONTRACT REVIEW ONLY. No ML training, no AUC/PF,
             no parameter optimization, no production/MQL5/Candidate Setup/
             FEATURE_CONTRACT changes, no Tickstory/Dukascopy.
Human verif: REMAINS CANCELLED (historical only). No performance experiment.
Contract   : docs/P3_S16_LABEL_CONTRACT.md (v1, immutable)
Baseline   : P3-S.17R.2 close ae81f15b18f3e8952e183353357ba02281b6f9e6
             VERIFIED (local == origin/main, branch main, working tree CLEAN).

A. Latest SESSION_HANDOVER used

docs/SESSION_HANDOVER_2026-08-23_P3_S17R2_VECTORIZE.md
  (committed at HEAD ae81f15 — the NEWEST authoritative handover by commit
   ancestry; read completely before any work.)

It records: P3-S.17R.2 = COMPLETE, verdict = FULL PARITY ACHIEVED,
CHoCH/OB/FVG vectorized == frozen reference (197,032/197,032 each),
Candidate Setup runtime==research 694==694 (identity 694/694, runtime-only 0,
research-only 0, per-bar mismatch 0), in-scope population 686 (594 leads /
92 follow-ons / 0 duplicates), P3-S.17 re-audit completed, label distribution
WIN 167 / LOSS 404 / UNRESOLVED 18 / AMBIGUOUS 5 (leads), production unchanged,
ML NOT TOUCHED, P3-S.18 NOT STARTED, next = NEW DECISION SESSION (OPTION A/B/C).
Verified against Git at session start (local HEAD == remote HEAD == ae81f15,
branch main, working tree CLEAN).

B. Checkpoint

Starting checkpoint (verified): ae81f15b18f3e8952e183353357ba02281b6f9e6
  local HEAD == origin/main == ae81f15
  branch      = main
  working tree = CLEAN
  origin      = https://forge.mql5.io/chiki2bum2/SniperGold_ML.git
P3-S.17R.2 parity-close : ff3202c8be59d9f1073b2f286e219c54f96eb44a

C. Verified Candidate Setup population

Full runtime/research computable population : 694
P3-S.17 authorized in-scope population      : 686
De-overlap (lead-per-episode, horizon 16)   : 594 leads / 92 follow-ons
Duplicate setup_ids rejected                : 0
De-overlap separation verified              : TRUE

LEAD LABEL DISTRIBUTION (open params k_tp=1.5, k_sl=0.75, H=16):
  WIN        : 167  (28.1%)
  LOSS       : 404  (68.0%)
  UNRESOLVED : 18   (3.0%)
  AMBIGUOUS  : 5    (0.8%)

ALL (before de-overlap): WIN 190 / LOSS 469 / UNRESOLVED 22 / AMBIGUOUS 5.

D. Current label contract (under review)

P3_S16_LABEL_CONTRACT v1 (immutable):
  UNIT     : ONE Candidate Setup (identity + lifecycle, F3-frozen).
  ENTRY    : CLOSE of the CANDIDATE_SETUP creation bar (M15).
  PRICE    : creation-bar close (mid reference; spread/slippage out of scope).
  ATR      : rolling 14-bar M15 ATR ending at the entry bar (reference at
             entry, causally available).
  TP       : entry + direction * k_tp * ATR        (k_tp = 1.5 candidate)
  SL       : entry - direction * k_sl * ATR        (k_sl = 0.75 candidate)
  HORIZON  : H = 16 M15 bars (robustness H = 8; lifetime-based, not tuned).
  CLASSES  : WIN (TP before SL) / LOSS (SL before TP) /
             UNRESOLVED (neither within H or insufficient data or gap —
             true censoring, never forced to LOSS) /
             AMBIGUOUS (same-bar TP+SL — no OHLC-ordering assumption).
  DE-OVERLAP : setup-level lead-per-episode (follow-ons reported, excluded
             from the primary independent set).

E. Entry semantics review

Question : does entry = CLOSE of the creation bar represent "the moment the
           setup becomes actionable"?

Findings:
  - The chain COMPLETES at creation_bar (CANDIDATE_SETUP); direction fixed;
    the M15 entry condition is already satisfied by construction at that bar.
  - The first causally-available executable point after completion is the
    creation-bar close (P3.2 §6 A: |A-B| ~ 0.008 ATR vs next-bar open — not
    material). This is a CLOSED-bar, no-look-ahead choice.
  - M3 is OPTIONAL and occurs AFTER creation; it does not define entry and
    cannot precede entry without breaking its optional/no-veto semantics
    (canonical §F/OD-4). No semantic contradiction: M3_CONFIRMED upgrades the
    same setup AFTER entry; entry is unchanged.

VERDICT : ENTRY SEMANTICS = SEMANTICALLY APPROPRIATE.

F. TP/SL review

Question : does TP = +k_tp*ATR, SL = -k_sl*ATR measure setup VALIDATION
           (did the expected outcome occur before the invalidation boundary)
           rather than mere price excursion?

Findings:
  - TP/SL are anchored at ATR(entry) in the setup direction — the level whose
    first hit decides WIN/LOSS — i.e., an outcome-resolver with a 2:1 semantic
    ratio candidate (1.5/0.75), not a drift measure (L1 is severed, P3.2 B).
  - The constants are OPEN parameters recorded by contract §D, explicitly
    NOT AUC/PF/profit/win-rate selected.
  - The LOSS-heavy (68.0%) distribution under these open parameters is a
    contract/data observation, not a defect and not an optimization input
    (§18 of the brief prohibits changing TP/SL because the WIN rate looks low).

VERDICT : TP/SL SEMANTICS = SEMANTICALLY APPROPRIATE (constants remain OPEN).

G. Horizon review

Question : does H=16 mean "setup remains valid for 16 bars" or merely "the
           label observes price for 16 bars"? Are these conflated?

Findings:
  - P3.2/P3.2.2 lifetime evidence: outcomes mostly occur within 1-8 M15 bars;
    ~90% <= 8; >98% <= 16. H=16 is the LABEL OBSERVATION WINDOW, chosen on
    lifetime evidence, NOT a runtime validity claim.
  - The runtime Candidate Setup validity (W_setup placeholder 40) is a
    SEPARATE, still-OPEN parameter and is NOT the label horizon. The label
    contract does not claim the setup "remains valid for 16 bars" — it
    observes the price path for 16 bars after entry to resolve TP/SL.
  - Censoring at H=16 is low (3.0% of leads UNRESOLVED), consistent with
    P3.2.2 (§G).

VERDICT : HORIZON = SEMANTICALLY APPROPRIATE (label window; distinct from
          runtime validity; not conflated). H stays OPEN at 16 (robustness 8).

H. WIN/LOSS review

Question : is binary TP-before-SL sufficient as the PRIMARY label?

Findings:
  - P3.2 scorecard: L3 (TP-before-SL) is the ONLY family meeting the
    meta-labeling requirements (causal, SMC-aligned, event/setup-specific,
    low ambiguity 1-3%, low censoring at H16+, binary, economically
    interpretable).
  - A setup can reach meaningful favorable excursion without TP, remain
    structurally valid, become invalidated/consumed, or time out — all of
    these are captured as LOSS (SL first), UNRESOLVED (censored), or are
    secondary diagnostics; they do NOT need extra primary classes at v1.
  - L2 (MFE/MAE) and L4 (time-to-outcome) remain DESCRIPTIVE complements,
    not primary classification targets (§16).

VERDICT : WIN/LOSS = SEMANTICALLY APPROPRIATE AS THE PRIMARY LABEL.

I. UNRESOLVED review

Question : are the UNRESOLVED sub-cases equivalent, and should the primary
           target preserve one class or a granular reason code?

Findings:
  - Diagnostic on the real population: ALL 22 UNRESOLVED (all-population)
    carry reason "timeout" — zero "insufficient_future_data" in the
    authorized scope (the 686 in-scope setups all have 16 future bars
    available within the feed). The implementation already distinguishes
    internally (timeout vs insufficient_future_data vs gap) even though the
    primary field is a single UNRESOLVED class.
  - These sub-cases are NOT numerically merged into a single semantic at v1;
    the reason is preserved in the resolver and can be surfaced as a
    secondary code.

VERDICT : UNRESOLVED = SEMANTICALLY APPROPRIATE as a single primary class,
          with an internal reason (recommended: expose as a secondary field
          in v2 — additive, not a defect correction).

J. AMBIGUOUS review

Question : is same-bar TP+SL = AMBIGUOUS correct, and should tick-level
           chronology stay out of the primary contract?

Findings:
  - From OHLC, a same-bar TP AND SL cannot be causally ordered (which touched
    first is undecidable without tick chronology). Classifying AMBIGUOUS
    deterministically (never WIN/LOSS) is the honest contract (§F).
  - Tick-level/lower-timeframe reconstruction remains a SEPARATE, authorized
    future revision; Tickstory/Dukascopy is NOT introduced (§26).
  - Real population: 5 AMBIGUOUS leads (0.8%) — low, intrinsic class.

VERDICT : AMBIGUOUS = SEMANTICALLY APPROPRIATE as an intrinsic label class.

K. De-overlap review

Question : is lead-setup-per-episode exclusion conceptually appropriate?

Findings:
  - Follow-on setups share the previous setup's outcome window (creation
    within [prev.entry, prev.entry+H]) -> NOT independent samples. Keeping
    the first of each episode (lead) and reporting the rest is the P3.2.2
    setup-level adaptation; verified separation > H (TRUE).
  - 594 leads / 92 follow-ons / 0 duplicates; serial-dependence evidence from
    P3.2.2 (§J: ac1 0.5 -> ~0 after de-overlap on the old event units).
  - Same-zone reuse / repeated direction / overlapping lifecycles are
    recognized as possible future refinements (episode weighting) but are not
    a v1 defect: the rule guarantees independent training observations.

VERDICT : DE-OVERLAP = CORRECT (neither too aggressive nor too weak for v1;
          possible episode-level refinements recorded for future design).

L. Lifecycle vs label lifetime

Question : can a setup expire/invalidate/consume before TP/SL, and should
           that affect the label?

Findings (runtime truth — canonical §F, P3.2.2 §I):
  - A setup CAN be lifecycle-terminated (EXPIRED after W_setup, INVALIDATED
    by zone mitigation / contrary CHoCH / context break, CONSUMED by entry)
    INDEPENDENTLY of TP/SL.
  - P3.2.2 §I: on the setup/event lifetime, SL (price) is the DE-FACTO
    invalidator — opposite-structure invalidation is much slower
    (median ~22-24 bars) than the outcome (1-3 bars). So TP/SL-first remains
    the authoritative primary resolution.
  - FINDING (implementation gap, not a contract defect): the current dataset
    rows carry label_invalidated_early=False uniformly. The F3 registry keeps
    creation-time snapshots (state=CANDIDATE_SETUP, m3_bar=None), so the
    canonical terminal state (EXPIRED/INVALIDATED/CONSUMED), its cause and
    timing, and M3 confirmation are NOT yet wired into the population rows.
    This is a SECONDARY-diagnostic wiring gap — it does not change the
    primary label, but it means lifecycle information is currently NOT
    preserved in rows for future design.

VERDICT : PRIMARY LABEL UNAFFECTED (price-first-hit authoritative).
          SECONARY LIFECYCLE WIRING = REVIEW REQUIRED -> recommended v2
          enrichment (terminal cause + timing + M3 presence as secondary
          fields). This is additive and evidence-based, NOT a correction of
          the primary TP-before-SL semantics.

M. Label family recommendation

Preserve, in future rows (information preservation — §16/§19):
  PRIMARY  L3 : TP-before-SL (WIN/LOSS/UNRESOLVED/AMBIGUOUS) — keep as the
                classification target.
  SECONDARY (descriptive, NOT classification targets):
    - L4 time-to-TP / time-to-SL (survival-compatible),
    - L2 MFE/MAE descriptors,
    - invalidation cause + timing (EXPIRED / INVALIDATED / CONSUMED),
    - UNRESOLVED reason code (timeout / insufficient_future_data / gap).

Design intent: never destroy useful outcome information in the dataset even
when only L3 is used for training. Recommended v2 = single file v2 with the
secondary fields added; v1 remains immutable (§23).

N. Feature/label separation (leakage audit)

Audited against the contract and the implementation:
  - entry = creation-bar close -> features are causally available at entry;
  - labels scan ONLY bars AFTER entry within H (first-hit);
  - no feature references post-entry movement, future mitigation, future
    CHoCH, future zone state, or MFE/MAE;
  - the immutable identity (Store 1) never encodes the outcome; the label
    (Store 3) never enters the feature store (Store 2);
  - closed-bar/as-of lock verified by DS-T06/T14/T15 + VEC-T04.

VERDICT : FEATURE/LABEL SEPARATION = PASS (no leakage).

O. Label distribution observations (diagnostic only)

From the verified 686 in-scope population (leads = 594), descriptive only,
NO parameter or filter change derived from these:

  ALL  : WIN 190 | LOSS 469 | UNRESOLVED 22 | AMBIGUOUS 5
  LEAD : WIN 167 | LOSS 404 | UNRESOLVED 18 | AMBIGUOUS 5

  Direction (leads) : -1 (short): WIN 90 / LOSS 198 / U 7 / A 4 (n=299)
                      +1 (long) : WIN 77 / LOSS 206 / U 11 / A 1 (n=295)
  Zone type (leads) : OB: n=594 (ALL leads are OB — no FVG-based lead in the
                      in-scope population under the current chain inputs;
                      FVG remains a valid alternative per contract §C, and
                      the OB-only outcome is a population composition
                      observation, not a defect)
  Year (leads)      : 2017:4, 2018:50, 2019:64, 2020:70, 2021:82, 2022:75,
                      2023:68, 2024:67, 2025:83, 2026:31 — LOSS-heavy in
                      every year.
  H4/M30 gates      : equal to setup direction by construction (hard gates);
                      no independent gate-vs-direction split exists in this
                      population.
  Time-to-event (leads): median TP hit = 3 bars, median SL hit = 2 bars
                      (bars after entry) — SL resolves faster, consistent
                      with P3.2.2 §G (SL ~2:1 faster than TP).
  UNRESOLVED reason : all in-scope UNRESOLVED = timeout (no insufficient-
                      data case inside the authorized window).

These are diagnostics; NO conclusion about strategy profitability/model
validity shall be drawn from them (§6, §10, §18).

P. Final contract decision

DECISION : APPROVED AS V1

The primary P3-S.16 setup-outcome label contract is SEMANTICALLY
APPROPRIATE for the verified Candidate Setup population:
  entry (creation-bar close)        : APPROPRIATE
  TP/SL (ATR-anchored, 2:1 candidate): APPROPRIATE (constants OPEN)
  horizon (H=16 label window)       : APPROPRIATE (distinct from runtime W)
  WIN/LOSS primary                  : APPROPRIATE (meta-labeling-suitable)
  UNRESOLVED single class           : APPROPRIATE (reason preserved)
  AMBIGUOUS intrinsic class         : APPROPRIATE
  de-overlap lead-per-episode       : CORRECT
  feature/label separation          : PASS (no leakage)

Rationale for NOT revising:
  - The LOSS-heavy distribution (68%) is a CONTRACT/DATA observation under
    OPEN parameters; revising because the WIN rate looks low is explicitly
    prohibited (§18) and would be hidden optimization.
  - The only gap found (secondary lifecycle wiring: invalidation cause,
    terminal state, M3 presence, UNRESOLVED reason, L2/L4 descriptors not
    yet surfaced in rows) is ADDITIVE and does not invalidate the primary
    TP-before-SL semantics; it is RECOMMENDED as v2 enrichment, not required
    as a correction.

Recommended (non-blocking, separately-authorizable):
  P3-S18B = implement P3_S16_LABEL_CONTRACT_v2 (add secondary fields:
  invalidation cause/timing, terminal state, M3 presence, UNRESOLVED reason,
  time-to-event, MFE/MAE) while keeping v1 immutable and the primary L3
  target unchanged.

Q. Versioning

P3_S16_LABEL_CONTRACT v1      : REMAINS IMMUTABLE (this review does NOT edit it).
P3_S16_SETUP_DATASET_CONTRACT v1 : REMAINS IMMUTABLE.
If the recommended enrichment is authorized -> create
  docs/P3_S16_LABEL_CONTRACT_v2.md  (and/or dataset contract v2)
as NEW files in a separate phase (P3-S18B). No silent rewrite.

R. Production files unchanged

NO MQL5 CHANGES. Unchanged: MQL5/** production files, AF_Engine2_Setup.mqh,
AF_Engine2_Agents.mqh, AF_Defines.mqh, F1/F2/F3/F4 runtime semantics,
FEATURE_CONTRACT.md, SniperGold_ML.mqh, model weights, legacy v4.x
semantics, the frozen P3-S.16 v1 contract, and every historical spec suite.

S. ML status

NOT TOUCHED. No MLP / LSTM / Informer / regime / calibration / retraining /
model comparison / AUC / PF / profit / win-rate selection performed or
started by this review. Legacy MLP remains FROZEN LEGACY / REFERENCE.

T. Forge commits

1. research: review P3-S18A setup-outcome label contract (OPTION A)
   (script + label-distribution CSV + review JSON)   [P3_S18A_FINAL_SHA head]
2. docs: record P3-S18A label contract review        (this document)

U. Final Forge HEAD

P3_S18A_FINAL_SHA : <recorded after the docs commit and push (see provenance)>

V. Working tree

local HEAD == remote HEAD, branch main, working tree CLEAN (verified after
push). Regression suites re-run green during the session: P3-S16 20/20,
VEC 15/15, full-scope reference==vectorized zero mismatch, chain parity
694==694 — no historical suite modified or weakened.

W. P3-S.18 readiness

P3-S.18 (setup-level baseline ML) is NOT started by this session. With the
label contract APPROVED AS V1, P3-S.18 may be authorized SEPARATELY by the
owner (baseline hierarchy: linear/logistic -> simple tree -> small MLP; no
LSTM/Informer/regime first). If the owner prefers the v2 secondary-field
enrichment first, that is P3-S18B (separate authorization). Both require an
explicit owner decision; parity/review does NOT auto-select either.

Provenance / evidence

Script      : ml/p3/setup_dataset/spec_tests_s18a_label_review.py
              (reuses the byte-locked R.2 chain — identical inputs, gate
               cache, sweep port, vectorized kernels; writes NEW artifacts)
Outputs     : ml/p3/setup_dataset/output/p3_s18a_label_distribution.csv
              ml/p3/setup_dataset/output/p3_s18a_label_review.json
Reference   : docs/P3_S16_LABEL_CONTRACT.md, P3_S16_SETUP_DATASET_CONTRACT_v1.md,
              P3_2_LABEL_FORENSIC.md, P3_2_2_DEOVERLAP_SURVIVAL.md,
              SNIPERGOLD_CANONICAL_SETUP_CONTRACT_v1.md,
              P3_S17R2_VECTORIZE_CH0CH_OB_FVG.md
Regression  : P3-S16 20/20 (re-run), VEC 15/15 (re-run, FULL PARITY ACHIEVED),
              note: re-running the committed output JSONs rewrote only
              generated_utc/elapsed fields — those committed artifacts were
              restored byte-identical (no historical suite weakened).

End of P3-S18A label contract review. Decision: APPROVED AS V1 (primary semantics appropriate for the verified Candidate Setup population), with recommended additive v2 secondary-field enrichment pending separate owner authorization. No ML, no optimization, no production change.