SniperGold_ML/docs/SMC_DISPLACEMENT_SPEC_v1.md

344 lines
14 KiB
Markdown

# SMC DISPLACEMENT — PROJECT SEMANTIC SPECIFICATION v1
```text
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.
```text
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:
```text
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)
```text
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):
```text
|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)
```text
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)
```text
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)
```text
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)
```text
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)
```text
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)
```text
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)
```text
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)
```text
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)
```text
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)
```text
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)
```text
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)
```text
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 | |Close - Open| vs average body (AF_AvgBody); range/wicks/ATR/ratio NOT used |
| 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)
```text
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
```text
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
```