# SMC FVG — PROJECT SEMANTIC SPECIFICATION v1 ```text 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) ```text 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) ```text 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) ```text 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) ```text 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) ```text 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) ```text 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) ```text 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) ```text 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) ```text 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) ```text - 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) ```text 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) ```text 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) ```text 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 ```text 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) ```