SniperGold_ML/docs/P3_S21_1_FEATURE_CONTRIBUTION_AUDIT.md

23 KiB

P3-S21.1 FEATURE CONTRIBUTION AUDIT — FINAL REPORT

Date       : 2026-08-25
Session    : P3-S21.1 — Feature Contribution Audit (frozen Logistic, P3-S20 folds)
Status     : COMPLETE
Verdict    : D — MIXED CONTRIBUTION (ZONE-leading, CONTEXT secondary; both
             sign-stable across the three pre-registered folds; weak ranking
             edge with redundant-by-construction feature structure)
Question   : WHICH FROZEN FEATURES CONSISTENTLY CONTRIBUTE TO THE WEAK LOGISTIC
             SIGNAL OBSERVED IN P3-S20, AND IS THAT CONTRIBUTION CONSISTENT
             ENOUGH TO DESERVE FURTHER INVESTIGATION?
Scope      : DESCRIPTIVE COEFFICIENT AUDIT ONLY. NO calibration, NO new model,
             NO ablation, NO feature selection/removal, NO TP/SL/horizon/label
             change, NO Candidate Setup/MQL5/FEATURE_CONTRACT change, NO
             external data, NO hyperparameter tuning.
Human verif: REMAINS CANCELLED (historical only).

A. Latest SESSION_HANDOVER used

docs/SESSION_HANDOVER_2026-08-24_P3_S20_WALK_FORWARD.md
  (newest authoritative handover, committed at HEAD 7c9602c; read completely
   FIRST, before any diagnostic — session-handover-first rule).

Reconciles with Git (verified before any work):
  local HEAD == origin/main == 7c9602ca4964f42f4ae8b7ac1ea14ab5e49e9176
  branch main, working tree CLEAN,
  origin = https://forge.mql5.io/chiki2bum2/SniperGold_ML.git

Handover confirms:
  P3-S.20  = COMPLETE
  verdict  = A — STABLE WEAK SIGNAL (pre-registered rule output)
  P3-S.21  = NOT STARTED (owner decision required)
  next     = feature-mechanism + calibration diagnostics (this session is the
             feature-mechanism diagnostic: P3-S21.1, explicitly authorized).

Required documents (all read completely):
  docs/P3_S20_WALK_FORWARD_BASELINE.md       (A verdict, folds, quality gates)
  docs/P3_S19_DATASET_FEATURE_AUDIT.md       (audit PASSED; 686=594+92)
  docs/P3_S18_BASELINE_ML_REPORT.md          (INCONCLUSIVE / DATA TOO SMALL)
  docs/P3_S18A_LABEL_CONTRACT_REVIEW.md      (label contract APPROVED AS V1)
  docs/P3_S16_LABEL_CONTRACT.md              (v1, immutable)
  docs/P3_S16_SETUP_DATASET_CONTRACT_v1.md   (v1, immutable)

B. Checkpoint

Starting checkpoint (verified): 7c9602ca4964f42f4ae8b7ac1ea14ab5e49e9176
  local HEAD == origin/main, branch main, working tree CLEAN,
  origin = forge.mql5.io/chiki2bum2/SniperGold_ML.git
  no stashes; reflog top = P3-S20 docs commit.
Final Forge HEAD             : <P3_S21_1_FINAL_SHA recorded after push>

C. Frozen Logistic configuration

The audit refits the EXACT P3-S20 frozen configuration per fold and VERIFIES
byte-level reproduction before using any coefficient:

  Model      : LogisticRegression(C=1.0, L2 via default lbfgs solver,
               max_iter=5000, random_state=42, fit_intercept=True,
               class_weight=None) — identical to walk_forward.py.
  Preprocess : StandardScaler(z=(x-mean)/std) fitted on THAT fold's TRAINING
               rows only; applied unchanged to OOS.
  Folds      : expanding-window, chronological (P3-S20 pre-registered):
               F1 train[0:300] OOS[300:395]; F2 train[0:395] OOS[395:490];
               F3 train[0:490] OOS[490:571]; purge gaps 555/472/321 bars.
  Coefficients reported: std_coef = coefficient on the STANDARDIZED input
               (the quantity the frozen model actually used); raw_coef =
               std_coef / scaler.scale_ (back-transformed to original units).

REPRODUCTION (hard gate, section 7):
  OOS WIN-probabilities recomputed from a fresh frozen refit match the
  committed ml/p3/baseline/output/p3_s20_oos_predictions.csv EXACTLY:
    max_abs_prob_diff = 0.00e+00  (271/271 rows, fold/setup_id/outcome match)
    pooled OOS ROC-AUC recomputed = 0.5791603786527645 == committed.
  -> exact reproduction established; the coefficients below ARE the P3-S20
     fitted decision function's coefficients. STOP condition not triggered.

D. Feature inventory

Frozen 12-feature schema (feature_sha16 = 0414e401522ea4e2, UNCHANGED).
Statistics below are over the 571 binary WIN/LOSS lead rows (the P3-S20
population); missing rate is 0.0 for all features. Full table:
ml/p3/baseline/output/p3_s21_1_feature_inventory.csv

  feature                  family          mean      median   std      unique  const
  direction                CONTEXT        -0.0088   -1.0      1.000     2     no
  h4_gate                  CONTEXT        -0.0088   -1.0      1.000     2     no
  m30_gate                 CONTEXT        -0.0088   -1.0      1.000     2     no
  sweep_age_bars           LIQ/STRUCT     20.37     19.0     11.316    41     no
  choch_age_bars           LIQ/STRUCT      4.36      0.0      7.295    34     no
  choch_latency_bars       LIQ/STRUCT     16.01     14.0     10.140    41     no
  zone_type_code           ZONE            1.0       1.0      0.0       1     YES
  zone_age_bars            ZONE            8.99      3.0     30.238    44     no
  zone_width_atr           ZONE            1.194     1.047    0.684   571     no
  price_in_zone_offset     ZONE            0.4066    0.493    2.308   570     no
  dist_to_zone_center_atr  ZONE           -0.0934   -0.0068   2.308   571     no
  atr_at_entry             SCALE           3.119     2.12     2.971   568     no

Semantic families (predefined, per section 9, from feature definitions):
  CONTEXT            = direction, h4_gate, m30_gate
  LIQUIDITY_STRUCTURE= sweep_age_bars, choch_age_bars, choch_latency_bars
  ZONE               = zone_type_code, zone_age_bars, zone_width_atr,
                       price_in_zone_offset, dist_to_zone_center_atr
  SCALE              = atr_at_entry
  ENTRY_MOMENTUM     = EMPTY (no M15 displacement/entry-condition column in
                       the frozen 12)
  MICRO              = EMPTY (no M3 confirmation column in the frozen 12)

E. Feature coefficients

Standardized coefficients (on the standardized input the frozen model used),
per fold. Full table: ml/p3/baseline/output/p3_s21_1_fold_coefficients.csv
and ml/p3/baseline/output/p3_s21_1_feature_coefficients.csv.

  feature                std F1      std F2      std F3      mean|std|  pattern
  direction             -0.0945     -0.0688     -0.0824      0.0819     all -
  h4_gate               -0.0945     -0.0688     -0.0824      0.0819     all -
  m30_gate              -0.0945     -0.0688     -0.0824      0.0819     all -
  sweep_age_bars        -0.0089     +0.0303     +0.0323      0.0238     mixed
  choch_age_bars        -0.0313     -0.0686     -0.0503      0.0501     all -
  choch_latency_bars    +0.0108     +0.0806     +0.0710      0.0541     all +
  zone_type_code         0.0         0.0         0.0         0.0        zero
  zone_age_bars         -0.0217     -0.0077     +0.0160      0.0151     mixed
  zone_width_atr        -0.0786     -0.0939     -0.0642      0.0789     all -
  price_in_zone_offset  +0.1186     +0.1251     +0.1705      0.1380     all +
  dist_to_zone_center_atr +0.1186   +0.1251     +0.1705      0.1380     all +
  atr_at_entry          +0.0509     +0.0490     +0.1398      0.0799     all +

Top-3 by mean |std coef|:
  1. price_in_zone_offset / dist_to_zone_center_atr  (0.1380 each)
  2. direction / h4_gate / m30_gate                  (0.0819 each)
  3. zone_width_atr                                  (0.0789)

Wording: these are contributions to the FITTED LINEAR DECISION FUNCTION of
the frozen logistic, NOT causal importance, NOT independent predictive power,
NOT robustness, NOT production usefulness.

F. Fold-level coefficient stability

  feature              F1 rank  F2 rank  F3 rank  sign pattern     class
  direction/h4/m30        3       5       4      all negative     STABLE
  sweep_age_bars         11      10      10      mixed            INCONCLUSIVE
  choch_age_bars          8       8       9      all negative     STABLE
  choch_latency_bars     10       4       7      all positive     VARIABLE
  zone_type_code         12      12      12      zero             INCONCLUSIVE
  zone_age_bars           9      11      11      mixed            INCONCLUSIVE
  zone_width_atr          6       3       8      all negative     STABLE
  price_in_zone_offset    1       1       1      all positive     STABLE
  dist_to_zone_center_atr 2       2       2      all positive     STABLE
  atr_at_entry            7       9       3      all positive     VARIABLE

  Sign consistency : direction/h4/m30, choch_age, zone_width,
                     price_in_zone_offset, dist_to_zone_center_atr are
                     SAME-SIGN in all 3 folds.
  Magnitude spread : atr_at_entry jumps in F3 (0.050 -> 0.140) and
                     choch_latency grows from F1 (0.011) to F2/F3
                     (0.08/0.07) -> classified VARIABLE (same sign, spread
                     > 2.5x).
  Fold disagreement: sweep_age (F1 - / F2,F3 +) and zone_age (F1,F2 - /
                     F3 +) FLIP sign -> INCONCLUSIVE (no consistent sign).
  No feature is selected as "important" because it is strongest in one fold;
  ranks 1-2 (zone offset pair) and the direction triple are the only
  features in the top-4 in >= 2 folds with a stable sign.

G. Group-level contribution

Aggregation: combined = mean over folds of sum(|std coef|) of the group's
members (deterministic, documented). Sign stability = dominant member's sign
stable across folds. Full table:
ml/p3/baseline/output/p3_s21_1_group_contributions.csv

  group                n  combined_mean  F1     F2     F3   sign_stable  dominant
  CONTEXT              3    0.2457      0.283  0.206  0.247  True        direction
  LIQUIDITY_STRUCTURE  3    0.1280      0.051  0.179  0.154  True        choch_latency
  ZONE                 5    0.3701      0.337  0.352  0.421  True        price_in_zone_offset
  SCALE                1    0.0799      0.051  0.049  0.140  True        atr_at_entry
  ENTRY_MOMENTUM       0    0.0         -      -      -      -           -
  MICRO                0    0.0         -      -      -      -           -

  ZONE carries the largest combined contribution (0.370), CONTEXT second
  (0.246). CAUTION: CONTEXT mass is inflated ~3x by the identical
  direction/h4/m30 columns and ZONE mass is inflated ~2x by the affine
  price_in_zone_offset / dist_to_zone_center_atr pair (see section I) — the
  unique-dimension ordering is: (1) ZONE entry-position/offset, (2) CONTEXT
  direction/gate, (3) ZONE width, (4) ATR scale, (5) CHoCH timing.
  Aggregation is used for DESCRIPTION only; nothing is removed.

H. Feature distribution by fold

Per-fold TRAINING-row distributions: ml/p3/baseline/output/p3_s21_1_fold_feature_stats.csv
(mean/median/std/min/max/q05/q25/q50/q75/q95; missing=0 everywhere).

Key comparisons (train rows):
  price_in_zone_offset : F1 mean 0.422 | F2 0.415 | F3 0.372; medians
                         0.465/0.436/0.448 — NO material shift; F2's stronger
                         result is NOT explained by a different offset
                         distribution (mean/std nearly identical).
  zone_width_atr       : F1 1.184 | F2 1.191 | F3 1.195 (stable, small).
  atr_at_entry         : F1 2.026 | F2 2.011 | F3 2.381, max jumps to 19.97
                         in F3 (vs 8.72 before) — the F3 ATR-coefficient jump
                         (+0.140) coincides with a wider/right-skewed ATR
                         regime in the F3 training window.
  direction/h4/m30     : mean -0.02/-0.033/-0.029 (short-favoring throughout).
  choch_age_bars       : medians 0 in all folds; mean ~4.2-4.3 (stable).

Conclusion: F2's OOS improvement is NOT attributable to a distinct feature
distribution in the offset/gate/width features; it appears period-specific
(temporal heterogeneity), consistent with P3-S20's own fold analysis. No
feature adaptation, no per-fold renormalization was performed (the frozen
train-only scaler was respected).

I. H4/M30/direction collinearity

VERIFIED (matches P3-S19 result, exactly):
  h4_gate == m30_gate == direction on every one of the 571 binary rows.
  unique combinations: only (-1,-1,-1) and (+1,+1,+1).
  direction/h4/m30 have identical standardized columns -> identical
  coefficients by construction.

NEW STRUCTURAL FINDING (affine identities in the verified population):
  dist_to_zone_center_atr == price_in_zone_offset - 0.5 on every row
    (the zone-center offset is the in-zone offset shifted by half a zone
     width; the two features carry the SAME information after centering).
  choch_latency_bars == sweep_age_bars - choch_age_bars on every row
    (CHoCH latency is defined as sweep age minus CHoCH age — a functional
     identity, not a new independent dimension).
  zone_type_code is CONSTANT (all in-scope setups share one zone type).

Interpretation: these are EXACT structural/affine identities from the
verified canonical chain (F3 hard gates must be direction-compatible;
zone-center offset = in-zone offset - 0.5 width; latency = age difference).
They explain the identical coefficients; they do NOT make any feature leaky
or invalid, and NO feature is removed. The effective independent dimension
count of the 12 columns is ~8 (12 minus 2 exact duplicates minus 1 constant
minus 1 functional combination), NOT a defect.

J. Zone geometry / ATR mechanism

Exact definitions (from prepare_dataset.py, all causally available at entry
= creation-bar close):
  zone_width_atr          : (zone_top - zone_bot) / ATR(entry); 0 if degenerate.
                            units = ATR-ratio (width in ATR multiples).
  price_in_zone_offset    : (entry_price - zone_bot) / zone_width in [0,1];
                            entry position within the zone.
  dist_to_zone_center_atr : (entry_price - zone_midpoint) / zone_width (signed);
                            NOTE the divisor is ZONE WIDTH, not ATR, despite
                            the column name — documented exactly here.
  atr_at_entry            : rolling 14-bar M15 ATR ending at the entry bar.

Availability at entry: ALL zone/ATR values are computed from closed bars and
the zone bounds as-of the creation bar — the entry bar itself is closed, so
every value is known before any future bar. ATR(entry) also scales the TP/SL
label; this is CONTEXTUAL SCALE dependence, NOT leakage: the value is known
at entry and does not reveal the outcome (P3-S19 section J/K; S18A N).
The model's persistent positive weight on entry position within the zone
(+0.119/+0.125/+0.170 across folds) and persistent negative weight on zone
width (-0.079/-0.094/-0.064) are consistent with a zone-geometry mechanism;
this audit does not claim causality.

K. Mechanistic interpretation

Persistent contributors and candidate mechanisms (language: "consistent
with" / "associated with", NOT "causes"):

  price_in_zone_offset / dist_to_zone_center_atr  (+ stable, ranks 1-2 all
    folds): entry position relative to the zone. Candidate mechanism: setups
    entering deeper into the zone (larger in-zone offset, i.e., nearer the
    far edge of the zone in the setup direction) are associated with higher
    WIN log-odds. This is the single most persistent contributor.

  direction / h4_gate / m30_gate  (- stable, one dimension): short-favoring
    context. Candidate mechanism: in this historical XAUUSD population,
    short-context setups are weakly associated with higher WIN log-odds
    (consistent with P3-S18A's descriptive short/long counts). Because the
    gates are equal to direction by construction, this is one context
    dimension, not three.

  zone_width_atr  (- stable): wider zones (relative to ATR) are associated
    with LOWER WIN log-odds. Candidate mechanism: a wider zone implies entry
    farther from a tight invalidation anchor (0.75 ATR SL) relative to the
    1.5 ATR TP — geometrically consistent with a width-vs-outcome distance
    relationship. Descriptive only.

  atr_at_entry  (+ but VARIABLE, F3 jump): higher ATR regime associated with
    higher WIN log-odds in F3; not stable enough for a confident mechanism.

  choch_age_bars (- stable) / choch_latency_bars (+ variable): fresher CHoCH
    (smaller age) weakly associated with higher WIN log-odds; latency's sign
    is stable but its magnitude varies across folds.

  INCONCLUSIVE: sweep_age_bars, zone_age_bars (sign flips), zone_type_code
  (constant, zero coefficient).

No causal claim is made; these are candidate mechanisms of the frozen fitted
decision function only.

L. Reproducibility

The audit was executed multiple times with identical results:
  - all 5 CSVs BYTE-IDENTICAL across runs (verified by fc /b):
      p3_s21_1_feature_inventory.csv
      p3_s21_1_feature_coefficients.csv
      p3_s21_1_fold_coefficients.csv
      p3_s21_1_group_contributions.csv
      p3_s21_1_fold_feature_stats.csv
  - p3_s21_1_summary.json identical except generated_utc (git_commit same
    HEAD) — verified programmatically: only 'generated_utc' differed.
  - deterministic tests S21.1-T01..T07 ALL PASS (7/7):
      T01 feature schema identical to P3-S20
      T02 label contract unchanged
      T03 P3-S20 fold boundaries unchanged
      T04 frozen Logistic configuration reproduced
      T05 coefficient calculation deterministic
      T06 group assignment deterministic
      T07 repeated execution identical
  - frozen parity-absence guards (P3-S.4/P3-S.5) scan CLEAN across ml/**/*.py
    (0 hits) after adding the new scripts.

Recorded provenance (summary JSON):
  dataset/population : 686 setups = 594 leads + 92 follow-ons; binary 571
                       (167 WIN / 404 LOSS)
  feature_sha16      : 0414e401522ea4e2 (unchanged)
  label_sha16        : b52a80677d5e9b99 (unchanged)
  schema_sha16       : 470193a9d372c348 (unchanged)
  model config       : LogisticRegression(C=1.0, L2, max_iter=5000), seed 42
  folds              : ((0,300,300,395),(0,395,395,490),(0,490,490,571))
  purge gaps         : 555 / 472 / 321 bars
  Git commit         : recorded at run time

M. Final feature classification

Deterministic classification (thresholds documented in the script; NOT tuned
to results):
  STABLE       : direction, h4_gate, m30_gate (one dimension, all -),
                 choch_age_bars (all -), zone_width_atr (all -),
                 price_in_zone_offset, dist_to_zone_center_atr
                 (one affine dimension, all +).
  VARIABLE     : choch_latency_bars (all +, magnitude spread),
                 atr_at_entry (all +, F3 spike).
  INCONCLUSIVE : sweep_age_bars, zone_age_bars (sign flips),
                 zone_type_code (constant, zero coefficient).

FOCUS features (top-4 by |std coef| in >= 2 folds, stable sign, mean|std| >=
0.05): direction/h4/m30 (CONTEXT) and price_in_zone_offset /
dist_to_zone_center_atr (ZONE). After collapsing exact duplicates these are
TWO distinct dimensions: (1) ZONE entry position, (2) CONTEXT direction/gate.

FINAL CLASSIFICATION : D — MIXED CONTRIBUTION
  - based on coefficient sign consistency (stable in both leading
    dimensions), magnitude consistency, fold stability (ranks 1-2 all folds),
    semantic plausibility (zone-geometry + direction context), and feature
    distribution stability (no fold-specific distribution driver for F2);
  - NOT based on highest AUC, a single fold, or a single large coefficient.

Deserves further investigation? YES, cautiously: the ZONE entry-position
dimension and the CONTEXT direction dimension are the only candidates with
rank-consistent, sign-stable, fold-stable contribution to the weak signal.
The evidence remains a weak ranking edge (P3-S20: pooled OOS ROC 0.579), so
further investigation should be descriptive/mechanistic or an explicitly
authorized restrained-nonlinear study — NOT feature removal, NOT deployment.

N. Production files unchanged

NO MQL5 change. Unchanged: MQL5/** production files, F1/F2/F3/F4 runtime
semantics, Candidate Setup, FEATURE_CONTRACT.md, SniperGold_ML.mqh, model
weights, legacy MLP. Research-only artifacts under ml/p3/baseline/ only.

O. Label contract unchanged

P3_S16_LABEL_CONTRACT v1 : UNCHANGED (WIN=TP-before-SL, LOSS=SL-before-TP,
UNRESOLVED/AMBIGUOUS preserved; TP=+1.5 ATR, SL=-0.75 ATR, H=16). No label
v2 in this session. No label issue requiring documentation was found.

P. ML escalation status

NOT escalated. No calibration (that is P3-S21.2), no tree/boost/MLP/LSTM/
Informer/regime/ensemble, no feature ablation, no permutation importance, no
feature selection, no threshold/HP tuning, no retraining with subsets. Only
the EXISTING frozen logistic's coefficients were described.

Q. Forge commits

1. test: define P3-S21.1 feature contribution audit coverage (S21.1-T01..T07)
2. research: audit frozen Logistic feature contributions (P3-S21.1)
3. docs: record P3-S21.1 feature contribution results (this report)
P3_S21_1_FINAL_SHA = <recorded after push>

R. Final Forge HEAD

See Provenance (verified local == remote == P3_S21_1_FINAL_SHA after push).

S. Working tree

CLEAN after push (verified).

T. P3-S21.2 readiness

P3-S21.2 (CALIBRATION DIAGNOSTICS) is NOT started automatically. This
session's finding (D — MIXED CONTRIBUTION, ZONE-leading + CONTEXT secondary,
weak but rank/sign stable) is recorded for the owner decision. P3-S21.2
remains a SEPARATELY AUTHORIZED phase (probability calibration diagnostics,
NOT threshold tuning). Any feature removal / ablation / nonlinear model /
external data / production change also requires a separate authorization.

Provenance / evidence

Scripts (research-only, new in P3-S21.1):
  ml/p3/baseline/p3_s21_1_feature_audit.py     (frozen refit + verification +
                                                inventory + coefficients +
                                                groups + stats + redundancy)
  ml/p3/baseline/test_p3_s21_1_feature_audit.py (S21.1-T01..T07; 7/7 PASS)
Outputs (ml/p3/baseline/output/):
  p3_s21_1_feature_inventory.csv
  p3_s21_1_feature_coefficients.csv
  p3_s21_1_fold_coefficients.csv
  p3_s21_1_group_contributions.csv
  p3_s21_1_fold_feature_stats.csv
  p3_s21_1_summary.json
  p3_s21_1_tests.json
Reused (UNCHANGED):
  ml/p3/baseline/prepare_dataset.py   (12-feature schema, label v1)
  ml/p3/baseline/walk_forward.py      (frozen folds + config, imported only)
  ml/p3/baseline/output/p3_s20_oos_predictions.csv (reproduction oracle)
  ml/p3/baseline/output/p3_s20_summary.json        (pooled ROC oracle)
Regression : S21.1-T01..T07 7/7 PASS; guard scan clean; no historical
             artifact modified or weakened.

End of P3-S21.1 feature contribution audit. Verdict: D — MIXED CONTRIBUTION (ZONE-leading: entry-position + width; CONTEXT secondary: direction/gate; both sign-stable across the three pre-registered folds; weak ranking edge, honest caveats). Exact reproduction of the P3-S20 frozen logistic was verified before any coefficient was reported.