SniperGold_ML/docs/SMC_FVG_SPEC_v1.md

327 lines
15 KiB
Markdown

# 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)
```