SniperGold_ML/docs/SMC_DISPLACEMENT_SPEC_v1.md

14 KiB

SMC DISPLACEMENT — PROJECT SEMANTIC SPECIFICATION v1

Status  : PROJECT SEMANTIC SPECIFICATION (not "universal SMC ground truth")
Session : P3-S.6 — Formal Specification + Code-Conformance Audit (Displacement)
Date    : 2026-08-22
Scope   : The Displacement primitive as consumed by Engine 2 Entry agent E
          (AF_DetectDisplacement), and its relationship to the "strong move"
          gate used by Order Block (AF_E3_MOVE_BODY), FVG, and CHoCH/MSS.
          Displacement is NOT a Feature Contract feature (f0-f18) — see §15.
Secondary reference : AF_FindOrderBlock / AF_CollectOBs ("strong move"),
          AF_DetectChoch, FVG detectors — for cross-concept consistency only.
Provenance : P2 8d330343 | contract C44CC6F2 (P2-era) / 7b908b12 (committed)
             model 06df8452 | Forge HEAD 07883f6 (P3-S.5)

This document ESTABLISHES what "Displacement" means in the SniperGold_ML / Algo Forge project, derived from: (a) design intent (DESIGN.md E agent), (b) the current implementation (AF_DetectDisplacement), (c) the relationship with the Order Block "strong move" gate (P3-S.5), (d) logical requirements (closed-bar, candle attribute vs event, no look-ahead). This document is NOT a claim of universal SMC truth; displacement definitions outside this project (e.g. ATR-multiple range, body-to-range ratio, liquidity displacement) do not automatically apply here.


1. WHAT IS DISPLACEMENT (CORE)

Displacement in this project is a candle attribute of the newest closed bar: the candle's body is at least 1.6 x the average body over the last 20 closed bars.

avg_body(t)   = mean |Close - Open| over the newest min(20, t+1) closed bars
                (AF_AvgBody, AF_E2_LOOKBACK_AVG = 20).
Displacement  : |Close(t) - Open(t)| >= 1.6 x avg_body(t)   on the NEWEST CLOSED bar.
Direction     : +1 if Close(t) > Open(t)  (bullish displacement)
                -1 if Close(t) < Open(t)  (bearish displacement)
                0 otherwise               (no displacement at t)

Displacement is purely a candle-level property — no BOS, no CHoCH, no liquidity sweep, no FVG, no Order Block, no structure context is required (see §8/§13). It is a per-bar, non-persistent attribute: each closed bar is evaluated independently; a displacement on bar t does NOT carry forward to bar t+1 (verified DP-T18).

Classification of the project's displacement definition:

CANONICAL (current, Engine 2 AF_DetectDisplacement) : body >= 1.6 x avg body,
           direction by Close vs Open, no structure, newest closed bar only.
LEGACY    : NONE — no displacement concept exists in v4.3/v4.4/v4.5
           (verified: 0 references).
DERIVED   : the Order Block "strong move" gate (body >= 1.5 x avg body) is the
           SAME concept family with a different constant (see §9 / BUG-P3S6-001).
AMBIGUOUS : canonical project timeframe (per-TF vs M15) — see §12.

2. CANDLE MEASUREMENT (answer)

Body        : |Close - Open|   (open-to-close magnitude).
Full range  : NOT used — (High - Low) plays NO role in displacement.
Wicks       : NOT used — upper/lower wicks are ignored.
Close-to-close : NOT used.
Body-to-range ratio : NOT used.
ATR         : NOT used — the baseline is AVERAGE BODY, not ATR.
True range  : NOT used.

The exact mathematical relationship (canonical):

|Close(t) - Open(t)| >= 1.6 x (1/min(20, t+1)) x SUM_{i=t-min(20,t+1)+1..t} |Close(i) - Open(i)|

This is the ONLY displacement rule in the project. It is NOT equivalent to (High-Low) >= K x ATR nor to a body-to-range ratio — those are NOT used.


3. LOOKBACK / BASELINE (answer)

Baseline      : average body, arithmetic mean of |Close - Open|.
Lookback      : AF_E2_LOOKBACK_AVG = 20 bars.
Window        : the newest min(20, t+1) closed bars (bars t-19..t when full).
Current candle: INCLUDED — the displacement candidate bar IS part of the
                baseline window (AF_AvgBody includes index 0).
Warmup        : none explicit; with fewer than 20 bars the window shrinks
                (min(20, count)); the rule still applies (DP-T08).
Future        : NONE — only closed bars <= t are used; no look-ahead (DP-T19).

4. DIRECTION (answer)

Bullish displacement (+1) : Close(t) > Open(t)   (net upward body).
Bearish displacement (-1) : Close(t) < Open(t)   (net downward body).
Neutral (0)               : |body| < 1.6 x avg_body (or body == 0).
Doji (Close == Open)      : body = 0 -> 0 (never displacement).

Direction = the BODY direction (Close vs Open) of the displacement candle.
The rule is symmetric: bullish mirrors bearish exactly (property test DP-T11).

5. STRUCTURAL REQUIREMENT (answer)

NO structural requirement.

A "large bullish candle" IS "bullish displacement" in this project if
|body| >= 1.6 x avg_body — regardless of BOS/CHoCH/MSS/sweep/FVG/OB context.
The project does NOT define displacement as a structural-break + momentum
combination, nor as a liquidity-taking move.

Cross-check (DP-T12, DP-T13):
  - large candle in a flat sequence WITHOUT any structure break = displacement;
  - a structural break (close beyond a level) WITHOUT a sufficient body
    (< 1.6 x avg) = NOT displacement.

6. FVG RELATIONSHIP (answer)

FVG dependency: NOT REQUIRED (independent).

FVG detection (P3-S.4 S-5) does NOT require displacement, and displacement does
NOT require an FVG. A displacement candle MAY create an FVG (a strong body move
often gaps the price away, DP-T14), but displacement is detected even when no
FVG forms (DP-T15). The relationship is CORRELATED in practice, INDEPENDENT in
definition.

7. ORDER BLOCK RELATIONSHIP (answer)

The Order Block (P3-S.5 S-1) requires a "strong move" candle M with
|body(M)| >= 1.5 x avg_body — the SAME concept family as displacement
(|body| >= 1.6 x avg_body) with a LOWER constant.

Answer to "is the OB strong move the same concept as Displacement?":

  B. A simplified proxy for Displacement (same concept family, lower threshold).

Evidence:
  1. Identical measurement (body vs avg body via AF_AvgBody);
  2. Identical structure-free semantics (pure candle property);
  3. The OB "strong move" threshold (AF_E3_MOVE_BODY = 1.5) vs displacement
     (hardcoded 1.6) differ only in the constant;
  4. DESIGN.md describes the C-agent OB as "opposite bar before a strong move"
     and the E-agent confirmation as "displacement" — two names for the same
     family;
  5. Since 1.6 > 1.5: every displacement candle is a "strong move" candle for
     OB, but a candle with body in [1.5, 1.6) x avg is "strong" for OB and NOT
     displacement.

-> Cross-concept inconsistency (BUG-P3S6-001): the project uses TWO constants
   (1.5 and 1.6) for ONE concept family without documenting the split.

8. CHOCH / MSS RELATIONSHIP (answer)

CHoCH/MSS (P3-S.3 S-6) does NOT require displacement: CHoCH is a close-confirmed
structure event (close across the last internal pivot + prior trend + swing
gate). Displacement is NOT retrofitted into the CHoCH definition.

Displacement does NOT require CHoCH either. A CHoCH bar with a small body is NOT
displacement (DP-T17); a displacement bar may or may not coincide with a CHoCH.
The two primitives are independent.

9. EVENT VS STATE / LIFECYCLE (answer)

Displacement = CANDLE ATTRIBUTE (per-bar evaluation). NOT an event, NOT a state.

- Each closed bar t is evaluated independently: displacement(t) = +1/-1/0.
- There is NO persistence: a displacement on bar t does NOT carry to bar t+1
  (DP-T18: one displacement candle -> displacement = 0 on the next bar).
- There is NO onset/active/expired/consumed lifecycle, NO validity window,
  NO multi-bar state, NO repeated events.
- This design is INHERENTLY free of the f7/f9/f18 stale-consumer bug class:
  the consumer (E agent) reads the per-bar value; a stale result is impossible
  by construction (no state to go stale).

10. THRESHOLD / BOUNDARY SEMANTICS (answer)

Rule : |body| >= 1.6 x avg_body  (>=, inclusive at exact equality).

Boundary behavior (given the baseline window):
  body == 1.6 x avg   : DISPLACEMENT (inclusive)        (DP-T05)
  body == 1.6 x avg - 1 tick : NOT displacement          (DP-T06)
  body == 1.6 x avg + 1 tick : displacement              (DP-T07)

NOTE: avg_body includes the candidate candle, so the exact threshold value is
data-dependent (the threshold is NOT a fixed constant in price terms). The
boundary tests solve the self-consistent equality.
No threshold optimization is performed in this session (1.6 is the project
constant from AF_DetectDisplacement).

11. SYMMETRY (answer)

The rule is symmetric: bullish = |body| >= 1.6 x avg AND Close > Open;
bearish = |body| >= 1.6 x avg AND Close < Open. Mirroring a bullish
displacement bar (prices mirrored around a pivot) yields a bearish displacement
with the same magnitude (property test DP-T11). No intentional asymmetry exists.

12. TIMEFRAME SEMANTICS (answer)

Engine 2   : displacement is computed INDEPENDENTLY per agent-slot TF
             (H4/M30/M15/M3) — AF_DetectDisplacement is called on each slot.
Consumers  : the E (Entry) agent uses the M15 slot's displacement as an entry
             confirmation input; each slot has its own per-bar displacement.
Display    : displacement is NOT rendered (no display code for it).
Legacy     : no displacement concept (v4.3/v4.4/v4.5 have none).

Status: the displacement rule is TF-agnostic (same closed bar -> same result on
any TF); the canonical project displacement (whether H4/M30 displacement must
influence M15 entry) = SPECIFICATION AMBIGUOUS (same class as CHoCH G-4,
sweep G-3, FVG A-3, OB A-4). M3 displacement as an entry confirmation is
computed per-slot but its canonical role is not defined.

13. CONSUMER SEMANTICS (answer)

Chain : AF_DetectDisplacement (per-bar body check, newest closed bar)
        -> E (Entry) agent confirmation input:
           mDispBull = (disp>0)?1:0 ; mDispBear = (disp<0)?1:0
           weight wDisp = 0.20 (x1.3 when |disp|>0) — "strong displacement ->
           confirmation weight up" (DESIGN.md)
           reason strings "+displacement naik" / "-displacement turun"
        -> ZONE + CONFIRMATION = setup rule (MathMin(mZone, conf))
        -> Engine 2 aggregator (weighted fuzzy), Engine 3 display (aggregated).

Consumer correctness: displacement is consumed as a per-bar value; there is NO
state to carry forward, so a persistent large candle cannot become repeated
"displacement events" (DP-T18). NO stale-consumer bug exists for displacement
(detector correct AND consumer correct — differs from the f7/CHoCH/FVG/OB
findings where mitigation/expiry was missing; displacement has no zone/state to
go stale).

ML features: NONE — displacement is not in f0-f18.

14. RUNTIME / TRAINING PARITY (answer)

Displacement is NOT a Feature Contract feature.

- FEATURE_CONTRACT.md (f0-f18): 0 displacement references.
- EA runtime (AlgoForge_Backtest_Baseline.mq5): 0 displacement references
  (the EA does not compute it).
- Python training (ml/**/*.py): 0 displacement references.
- Legacy indicators (v4.3/v4.4/v4.5): 0 displacement references.

Consequence: PARITY = N/A BY ABSENCE. Displacement exists ONLY in Engine 2
(agents), consumed as an entry confirmation input. Any future use as an ML
feature requires a new Feature Contract entry (out of scope).

15. SPEC DECISION SUMMARY (tabular)

# Aspect Decision
S-1 Definition body >= 1.6 x avg body on the NEWEST CLOSED bar; direction by Close vs Open; pure candle attribute
S-2 Measurement
S-3 Baseline arithmetic mean over newest min(20, t+1) bars; candidate INCLUDED; no look-ahead
S-4 Direction +1 Close>Open, -1 Close<Open, 0 otherwise; symmetric
S-5 Structural req. NONE — BOS/CHoCH/MSS/sweep/FVG/OB not required
S-6 FVG relationship NOT REQUIRED (independent; correlated in practice)
S-7 OB relationship OB "strong move" (1.5 x avg) = SAME concept family, lower constant (proxy); cross-concept inconsistency BUG-P3S6-001
S-8 CHoCH relationship NOT REQUIRED by CHoCH; independent primitives
S-9 Event vs State CANDLE ATTRIBUTE (per-bar); no persistence, no events, no stale state
S-10 Threshold >= 1.6 x avg (inclusive); boundary tests T05/T06/T07
S-11 Symmetry symmetric (bullish mirrors bearish)
S-12 Timeframe per-TF independent; canonical = SPECIFICATION AMBIGUOUS
S-13 Consumers E agent confirmation (w 0.20, x1.3); per-bar; no stale consumer
S-14 Parity PARITY = N/A BY ABSENCE

16. RECORDED AMBIGUITIES (SPECIFICATION AMBIGUOUS)

A-1  Canonical displacement timeframe (MTF vs M15): per-slot computation is
     explicit; the cross-TF influence rule is not defined (same class as
     CHoCH G-4 / sweep G-3 / FVG A-3 / OB A-4).
A-2  "Strong move" vs "Displacement" terminology: DESIGN.md uses both loosely;
     the implementation has two constants (OB 1.5, displacement 1.6) for one
     concept family (BUG-P3S6-001). Whether 1.5 and 1.6 should be unified is
     NOT adjudicated (no optimization/repair this session).

17. PROVENANCE & CHECKPOINT

Forge HEAD (audit)      : 07883f6abf116b656e2cb8adfb41ec47e1fce498 (P3-S.5)
P3-S.5 spec (immutable) : docs/SMC_ORDER_BLOCK_SPEC_v1.md
P3-S.4 spec (immutable) : docs/SMC_FVG_SPEC_v1.md
P3-S.3 spec (immutable) : docs/SMC_CHOCH_MSS_SPEC_v1.md
P3-S.2 spec (immutable) : docs/SMC_LIQUIDITY_SWEEP_SPEC_v1.md
FEATURE_CONTRACT        : C44CC6F2... (P2-era) / 7b908b12... (committed)
Reconciled sources      : see docs/P3_S6_DISPLACEMENT_CONFORMANCE.md §A
Human verification      : CANCELLED