SniperGold_ML/docs/SMC_FVG_SPEC_v1.md

15 KiB

SMC FVG — PROJECT SEMANTIC SPECIFICATION v1

Status  : PROJECT SEMANTIC SPECIFICATION (not "universal SMC ground truth")
Session : P3-S.4 — Formal Specification + Code-Conformance Audit (Fair Value Gap)
Date    : 2026-08-22
Scope   : The Fair Value Gap (FVG / imbalance) primitive as consumed by
          Engine 2 agents (AF_FindFVG — Context agent C, Entry agent E),
          Engine 3 display (AF_CollectFVG), the legacy v4.3/v4.4/v4.5 indicators
          (DetectAndDrawFVG + MTF FVG), and the legacy entry chain
          (Sweep -> CHoCH -> OB/FVG within InpSeqWindow).
          FVG is NOT a Feature Contract feature (f0-f18) — see §13.
Secondary reference : AF_FindFVG (Engine 2), AF_CollectFVG (display),
          DetectAndDrawFVG (v4.4/v4.5) — implementation comparisons, NOT the
          canonical definition where they diverge.
Provenance : P2 8d330343 | contract C44CC6F2 (P2-era) / 7b908b12 (committed)
             model 06df8452 | Forge HEAD 85e3b48 (post P3-S.3 + docs)

This document ESTABLISHES what "FVG" (Fair Value Gap / imbalance) means in the SniperGold_ML / Algo Forge project, derived from: (a) design intent (DESIGN.md agents C/E, DESAIN_MTF_v45.md), (b) the legacy indicator implementation (v4.3/v4.4/v4.5 DetectAndDrawFVG + MTF FVG), (c) the current Algo Forge implementation (AF_FindFVG / AF_CollectFVG), (d) logical requirements (temporal causality, closed-bar, zone vs event). This document is NOT a claim of universal SMC truth; FVG definitions outside this project (e.g. variants requiring displacement or body rules) do not automatically apply here.


1. CONCEPTUAL DEFINITION (CORE)

FVG in this project is a zone of price imbalance (a gap) left between two candles by an intermediate "gap candle":

  1. Three consecutive fully-closed candles C1 (oldest), C2 (middle), C3 (newest);
  2. For a bullish FVG: Low(C3) > High(C1) — the newest candle's low is above the oldest candle's high; the untraded space between them is the gap zone [High(C1), Low(C3)];
  3. For a bearish FVG: High(C3) < Low(C1) — the newest candle's high is below the oldest candle's low; the gap zone is [High(C3), Low(C1)];
  4. The middle candle C2 is the displacement candle that created the gap; C2's extremes are not used in the zone bounds (all four implementations agree).

FVG is a ZONE primitive (a persistent price region), NOT an event. It does not require a trend precondition, a liquidity event, or displacement to be detected (see §5). FVG detection is purely geometric.


2. GAP BOUNDARIES (answer: wick vs body)

Zone boundaries     : WICK-BASED — the zone is bounded by the High/Low of C1 and
                      C3 (not their closes, not their bodies).
Bullish FVG zone    : bot = High(C1), top = Low(C3)      (gap upward)
Bearish FVG zone    : bot = High(C3), top = Low(C1)      (gap downward)
Body vs wick        : NOT required — no body rule; only the High/Low extremes of
                      C1 and C3 participate in the gap test.
Close-based         : NOT used for FVG detection (close is used only by the
                      display mitigation variant, see §9 A-2).

Reason: every implementation (AF_FindFVG, AF_CollectFVG, v4.3/v4.4/v4.5) compares Low vs High (wick extremes), never closes.


3. MINIMUM GAP / TOLERANCE (answer)

Zero gap   : Low(C3) == High(C1) (bullish) / High(C3) == Low(C1) (bearish)
             -> NOT an FVG (strict inequality; >= 1 tick excess required).
1 tick gap : geometrically VALID FVG (spec: no minimum gap).
Threshold  : the PROJECT has NO single canonical minimum-gap threshold.
             Three different consumer-side filters exist (see §12 A-1):
               - Engine 2 AF_FindFVG      : NO filter (any positive gap)
               - Engine 3 AF_CollectFVG   : >= 0.02 x ATR (AF_E3_FVG_MIN_ATR)
               - v4.3/v4.4/v4.5 (auto ON) : >= 0.25 x ATR (InpFVGAutoThreshold)
               - v4.3/v4.4/v4.5 (auto OFF): NO filter
Near-zero gap : treated as a normal small gap; no special handling anywhere.

SPEC DECISION: the FVG definition itself has NO minimum gap (strictly positive
gap = valid). Minimum-size thresholds are consumer/display configuration and are
NOT part of the FVG definition. The absence of a canonical project threshold is
recorded as SPECIFICATION AMBIGUOUS (A-1). No threshold is optimized in this
session.

4. DIRECTION (answer)

Bullish FVG (+1) : Low(C3) > High(C1)  — an upward imbalance; the zone is
                   expected to act as support/continuation for an up move.
Bearish FVG (-1) : High(C3) < Low(C1)  — a downward imbalance; the zone is
                   expected to act as resistance/continuation for a down move.
Neutral (0)      : no FVG in the query window.

Direction = the GAP direction (up = bullish, down = bearish). The directional
implication (support/resistance, continuation) is a CONSUMER interpretation
(DESIGN.md agents C/E, legacy entry chain); the detection itself carries no
trend precondition: a bullish FVG can form inside a downtrend and vice versa
(no prior-trend gate, unlike CHoCH S-7).

5. DISPLACEMENT REQUIREMENT (answer)

DISPLACEMENT = NOT REQUIRED BY CURRENT SPEC

No implementation requires a displacement/impulse/range/ATR condition on C2 (or
on the move) for FVG detection. A geometric gap alone is sufficient.

Displacement exists in the project ONLY as a separate independent primitive
(AF_DetectDisplacement, Engine 2 Entry agent) used as an additional confirmation
input — it is NOT a precondition of FVG detection. The displacement rule is NOT
added here because it is not in the project source.

6. FORMATION TIMING (answer)

Observable : an FVG becomes observable when C3 CLOSES — i.e. after three
             fully-closed candles (bars b-2, b-1, b with b = C3).
Decision   : at decision time t (the newest closed bar), an FVG with C3 = b is
             valid iff b <= t (C3 already closed). An FVG whose C3 is the still
             forming bar does NOT exist at t.
Timestamp  : canonical = open time of C3 (bar b), the bar at which the zone
             becomes observable. NOTE: the legacy v4.4/v4.5 timestamp at C2
             (middle candle) and the Engine-3 display timestamp at C3 differ —
             recorded as ambiguity A-5 (display-only, no ML impact).
Newest eligibility : the newest closed bar IS eligible as C3 (v4.3/v4.4/v4.5,
             display). Engine 2 AF_FindFVG skips index 0 (1-bar lag) — see
             conformance E-6 / BUG-P3S4-002.

7. CLOSED-BAR CONTRACT (answer)

Decision timestamp : closed bar t (the last closed bar; Engine-1 closed-bar lock,
                     v4.4 tc = total-1 excluding the forming bar).
Available candles  : bars <= t only (C1, C2, C3 all closed).
Future visibility  : NONE — mutating bars > t must NOT change the FVG decision at
                     t (property test FVG-T15).
Determinism        : full recompute per closed bar on closed data -> deterministic,
                     non-repainting (all implementations).

8. FVG LIFECYCLE (answer)

FVG = ZONE (persistent), NOT an event, NOT an event stream.

- DETECTION  : every qualifying 3-candle formation (each closed bar b >= 2 as C3)
               produces ONE zone. One formation = one zone.
- PERSISTENCE: a zone remains present (unmitigated) until MITIGATED (§9). There is
               NO age expiry and NO invalidation (§10).
- ONE-ZONE   : a zone that stays untraded for 20 bars is ONE FVG, not 20 events.
               No implementation emits repeated "FVG events" for a persistent zone
               (the f7/f9/f18 duplication pattern does NOT apply to FVG).
- REPLACEMENT: a newer formation produces a NEW zone; older zones are NOT removed
               by the newer one (except by display count limits).

9. FVG MITIGATION (answer)

Canonical (project, from legacy v4.3/v4.4/v4.5 — wick full-fill):
  A bullish zone is MITIGATED when a subsequent bar (j > b) prints
  Low(j) <= bot (= High(C1)) — price traded THROUGH the entire zone.
  A bearish zone is MITIGATED when a subsequent bar prints
  High(j) >= top (= Low(C1)).

  = FULL FILL semantics: mitigation requires price to reach the FAR boundary of
    the zone (the entire gap traded through), by WICK.

PARTIAL FILL  : price entering the zone (touching the NEAR boundary / filling part
                of the gap) is NOT mitigation in the legacy semantics.
Display variant (AF_CollectFVG) : mitigated when a subsequent CLOSE < bot (bull)
                / > top (bear) — full fill by CLOSE (stricter than wick).
Engine 2 (AF_FindFVG) : NO mitigation check at all — see BUG-P3S4-001.

STATES        : UNMITIGATED / MITIGATED. PARTIALLY MITIGATED and INVALIDATED are
                NOT modeled by the project.

10. FVG INVALIDATION (answer)

INVALIDATION = NOT MODELED BY CURRENT SPEC

No implementation invalidates an FVG on: full fill (that is MITIGATION, §9),
closed-through, opposite displacement, structure break, or time expiry.
A zone is valid until mitigated; after mitigation it is simply no longer usable
(display/legacy filter it out; Engine 2 ignores the state entirely — BUG-P3S4-001).

11. MULTIPLE / OVERLAPPING FVGs (answer)

- New FVG before an old one is mitigated : both zones coexist (separate zones).
- Overlapping formations (a 4-5 bar move creates several candidate C3 bars) :
  EACH qualifying bar b produces its OWN zone; zones are NOT merged, NOT replaced,
  NOT deduplicated.
- Same-bar double condition (bull & bear both true on one C3) : geometrically
  impossible (Low(b) > High(b-2) and High(b) < Low(b-2) cannot both hold);
  the code evaluates bull first (AF_FindFVG) / bull else-if (AF_CollectFVG) —
  unreachable, recorded as A-4 (analogous to the P3-S.2/P3-S.3 same-bar notes).
- Consumers: Engine 2 uses only the NEWEST zone; legacy entry uses ALL unmitigated
  zones within tap (FindEntryFVG); display draws the newest N unmitigated.

12. TIMEFRAME SEMANTICS (answer)

Engine 2   : FVG is computed INDEPENDENTLY per agent-slot TF (H4 = Narrative,
             M30 = Context, M15 = Entry, M3 = Price Action); each slot has its own
             AF_FindFVG query.
Display    : chart TF (M15 in the canonical deployment).
Legacy     : chart TF + OPTIONAL HTF projection (InpFVGTF) for display; v4.5
             computes per-TF MTF FVG (D1/H4/H1) via cache for display only.
HTF as context  : supported by v4.5 (MTF FVG) and Engine 2 (per-slot agents);
             NOT defined as a canonical rule ("HTF FVG must act as M15 context").
M3 entry trigger : NOT defined anywhere.
Equivalence : HTF and LTF FVG use the SAME geometric definition (TF-agnostic
             geometry), but the project does not define which TF's FVG is the
             canonical entry reference.

Status: feature-level FVG (Engine 2 M15 slot) is EXPLICIT; the canonical project
FVG (whether HTF FVG must affect LTF decisions) = SPECIFICATION AMBIGUOUS
(same class as CHoCH G-4 and sweep G-3).

13. TRAINING / RUNTIME PARITY (answer)

FVG IS NOT A FEATURE CONTRACT FEATURE.

- FEATURE_CONTRACT.md (f0-f18): 0 FVG references (verified by scan).
- EA runtime (AlgoForge_Backtest_Baseline.mq5): 0 FVG references.
- Python training pipeline (ml/**/*.py): 0 FVG references.
- FVG exists ONLY in: Engine 2 agents (C/E fuzzy inputs), Engine 3 display,
  and the legacy v4.3/v4.4/v4.5 indicators (display + legacy entry gate).

Consequence: there is NO runtime-vs-training parity target for FVG. The ML model
was trained WITHOUT FVG. Any future use of FVG as an ML feature requires a new
Feature Contract entry (out of scope for this session). The "parity" audit item
is therefore N/A by absence — documented, not a mismatch.

14. SPEC DECISION SUMMARY (tabular)

# Aspect Decision
S-1 Definition 3-candle: bullish Low(C3) > High(C1), zone [High(C1), Low(C3)]; bearish High(C3) < Low(C1), zone [High(C3), Low(C1)]; C2 extremes unused
S-2 Gap boundaries WICK-BASED (High/Low of C1 & C3); no body rule; close not used for detection
S-3 Minimum gap None in the definition (>= 1 tick); zero gap = NOT FVG; consumer filters 0.02 ATR / 0.25 ATR / none = AMBIGUOUS (A-1)
S-4 Direction +1 bullish (up gap), -1 bearish (down gap), 0 none; no trend precondition
S-5 Displacement NOT REQUIRED (geometric gap sufficient); displacement is a separate primitive
S-6 Formation observable at C3 close; C3 = b <= t; newest closed bar eligible; canonical timestamp = C3 open
S-7 Closed-bar all inputs <= t; no future visibility; non-repainting
S-8 Lifecycle ZONE (persistent); one zone per formation; no event stream; no age expiry
S-9 Mitigation full fill by wick (Low <= bot bull / High >= top bear); partial fill NOT mitigation; display uses close (A-2)
S-10 Invalidation NOT MODELED
S-11 Overlap separate zones per formation; no merge/replace/dedup
S-12 Timeframe Engine 2 per-TF independent; canonical project FVG = SPECIFICATION AMBIGUOUS (A-3)
S-13 Parity FVG NOT an ML feature (contract f0-f18 has none); runtime/training parity N/A by absence

15. RECORDED AMBIGUITIES (SPECIFICATION AMBIGUOUS)

A-1  Minimum gap filters diverge: Engine 2 none / display 0.02 ATR /
     legacy auto 0.25 ATR. No canonical project threshold. NOT optimized here.
A-2  Mitigation trigger: legacy = full fill by WICK (low<=bot / high>=top);
     display = full fill by CLOSE; Engine 2 = no mitigation at all (BUG-P3S4-001).
     Partial-fill semantics are not modeled anywhere.
A-3  Canonical FVG timeframe: Engine-2 M15 slot is explicit; HTF FVG as M15
     context and M3 FVG as entry trigger are NOT defined (same as CHoCH G-4 /
     sweep G-3).
A-4  Same-bar bull/bear double condition: geometrically impossible; bull-first
     evaluation order in AF_FindFVG; unreachable (analogous to P3-S.2 E-11).
A-5  Zone timestamp convention: legacy v4.4/v4.5 = middle candle (C2); Engine-3
     display = C3; Engine 2 = none. Display-only; no ML impact.
A-6  Consumer zone scope: Engine 2 = NEWEST zone only (AF_FindFVG returns the
     first match); legacy entry = ALL unmitigated zones within tap
     (FindEntryFVG). Different zone-selection semantics.

16. PROVENANCE & CHECKPOINT

Forge HEAD (audit)      : 85e3b48 (b6100f9 = P3-S.3 research checkpoint intact;
                          three documentation-only commits ahead: eb8a818, 0ac6ed1,
                          85e3b48 — no research/code content changed)
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_S4_FVG_CONFORMANCE.md §A
Human verification      : CANCELLED (human annotation is not a validation gate)