377 lines
17 KiB
Markdown
377 lines
17 KiB
Markdown
# SMC ORDER BLOCK — PROJECT SEMANTIC SPECIFICATION v1
|
|
|
|
```text
|
|
Status : PROJECT SEMANTIC SPECIFICATION (not "universal SMC ground truth")
|
|
Session : P3-S.5 — Formal Specification + Code-Conformance Audit (Order Block)
|
|
Date : 2026-08-22
|
|
Scope : The Order Block (OB) primitive as consumed by Engine 2 agents
|
|
(AF_FindOrderBlock — Context agent C, Entry agent E), Engine 3 display
|
|
(AF_CollectOBs), and the legacy v4.3/v4.4/v4.5 indicators
|
|
(ProcessStructure RecordOB + v4.5 MTF RecordOB_mtf + entry gate
|
|
InpEntryOnFVGorOB / FindEntryOB / Sweep->CHoCH->OB chain).
|
|
OB is NOT a Feature Contract feature (f0-f18) — see §15.
|
|
Secondary reference : AF_CollectOBs (display), v4.3/v4.4/v4.5 RecordOB /
|
|
RecordOB_mtf — implementation comparisons; the legacy structure-break
|
|
definition is a SECOND historical definition (see §7 / A-2).
|
|
Provenance : P2 8d330343 | contract C44CC6F2 (P2-era) / 7b908b12 (committed)
|
|
model 06df8452 | Forge HEAD 176880f (P3-S.4)
|
|
```
|
|
|
|
> This document ESTABLISHES what "Order Block" (OB) means in the SniperGold_ML /
|
|
> Algo Forge project, derived from: (a) design intent (DESIGN.md agents C/E,
|
|
> display), (b) the current Algo Forge implementation (AF_FindOrderBlock /
|
|
> AF_CollectOBs), (c) the legacy indicator implementation (v4.3/v4.4/v4.5),
|
|
> (d) logical requirements (temporal causality, closed-bar, zone vs event).
|
|
> This document is NOT a claim of universal SMC truth; OB definitions outside
|
|
> this project (e.g. "last opposite candle before BOS") do not automatically
|
|
> apply here — the legacy structure-break definition IS part of the project's
|
|
> history and is recorded as a second definition (A-2), but the canonical
|
|
> current definition follows DESIGN.md and the Algo Forge implementation.
|
|
|
|
---
|
|
|
|
## 1. CONCEPTUAL DEFINITION (CORE)
|
|
|
|
**Order Block** in this project is a *zone* formed by an **opposite-color candle
|
|
immediately before a strong move**:
|
|
|
|
1. A closed candle **B** (the OB candle) whose color is OPPOSITE to the
|
|
immediately following closed candle **M** (the move candle);
|
|
2. The move candle **M** has a **strong body**: `|Close(M) - Open(M)| >= 1.5 x
|
|
average body` (average body = mean |Close-Open| over the last 20 closed bars,
|
|
AF_E2_LOOKBACK_AVG);
|
|
3. **Bullish OB**: B is bearish (Close < Open) and M is bullish (Close > Open);
|
|
**Bearish OB**: B is bullish and M is bearish;
|
|
4. The OB **zone** = the FULL range of candle B: `[Low(B), High(B)]`.
|
|
|
|
OB is a **ZONE primitive** (a persistent price region), NOT an event. The OB
|
|
detector requires **no structural break, no BOS/CHoCH, no displacement, and no
|
|
liquidity interaction** (canonical current definition — see §7 for the legacy
|
|
second definition). OB detection is a pure opposite-color + strong-move rule.
|
|
|
|
---
|
|
|
|
## 2. CANDLE SELECTION (answer)
|
|
|
|
```text
|
|
OB candle B : the candle IMMEDIATELY BEFORE the strong move candle M
|
|
(M = B+1 in chronological terms).
|
|
Color of B : determined by Close vs Open ONLY (Close < Open = bearish,
|
|
Close > Open = bullish). A doji (Close == Open) is neither
|
|
-> B does not qualify.
|
|
Full vs partial : the OB uses the FULL candle range [Low(B), High(B)].
|
|
Body / wick : no body-vs-wick selection; the entire candle is the zone.
|
|
MOVE candle M : |Close(M) - Open(M)| >= 1.5 x avg body (AF_E3_MOVE_BODY).
|
|
```
|
|
|
|
Reason: DESIGN.md states "OB (opposite bar before a strong move)"; the current
|
|
implementation (AF_FindOrderBlock / AF_CollectOBs) matches this exactly.
|
|
|
|
---
|
|
|
|
## 3. ZONE BOUNDARIES (answer)
|
|
|
|
```text
|
|
High boundary : High(B) (top of the OB candle)
|
|
Low boundary : Low(B) (bottom of the OB candle)
|
|
Body boundary : not used (full range)
|
|
Padding : NONE in the definition. Consumer taps are consumer-side:
|
|
Engine 2 trap tolerance +-0.3 x ATR (zone membership);
|
|
legacy entry tap +-1 x ATR (entry gate).
|
|
Minimum size : none in the definition (any positive range). Consumer-side
|
|
minimum-size filters exist and DIVERGE (A-1):
|
|
- Engine 2 AF_FindOrderBlock : NO filter
|
|
- Engine 3 AF_CollectOBs : >= 0.15 x ATR (AF_E3_OB_MIN_ATR)
|
|
- v4.3/v4.4/v4.5 RecordOB : >= 0.15 x ATR (g_atr)
|
|
A candle with range < 0.15 x ATR is still an OB per the
|
|
definition but is filtered by display/legacy consumers.
|
|
One-tick edge : the zone boundaries are exactly High(B)/Low(B); a close
|
|
exactly ON a boundary is NOT a mitigation event (strict
|
|
inequality, see §9); 1 tick beyond the boundary IS.
|
|
```
|
|
|
|
---
|
|
|
|
## 4. BULLISH / BEARISH SEMANTICS (answer)
|
|
|
|
```text
|
|
Bullish OB (+1) : B bearish (Close(B) < Open(B)), M bullish (Close(M) > Open(M)),
|
|
|body(M)| >= 1.5 x avg. Zone = [Low(B), High(B)].
|
|
Expected role: support / continuation zone in an UP move.
|
|
Bearish OB (-1) : B bullish (Close(B) > Open(B)), M bearish, |body(M)| >= 1.5 x
|
|
avg. Zone = [Low(B), High(B)].
|
|
Expected role: resistance / continuation zone in a DOWN move.
|
|
Neutral (0) : no qualifying pair in the window.
|
|
|
|
Direction = the direction of the MOVE candle (up move -> bullish OB). The OB
|
|
candle color is the OPPOSITE of the direction. This is the project rule; it is
|
|
not merely a variable sign (the definition comes from the pair (B, M) relation).
|
|
Symmetry is explicit (S-4 property test OB-T15).
|
|
```
|
|
|
|
---
|
|
|
|
## 5. STRUCTURAL PRECONDITION (answer)
|
|
|
|
```text
|
|
CANONICAL (current) : NO structural precondition. The detector requires ONLY:
|
|
1) opposite color of B vs M, and
|
|
2) strong body of M (>= 1.5 x avg).
|
|
BOS / CHoCH / MSS / displacement / liquidity sweep / FVG:
|
|
NOT required for OB detection.
|
|
|
|
LEGACY second definition (v4.3/v4.4/v4.5) : OB is recorded ONLY at a STRUCTURE
|
|
BREAK (close > last swing/internal pivot high for bullish, < low for bearish —
|
|
BOS or CHoCH). The OB candle is the last (or highest-volume) opposite-color
|
|
candle between the last opposite pivot and the break bar. This is a DIFFERENT
|
|
formation rule (A-2), documented, not canonical.
|
|
|
|
SPEC DECISION : a detector that calls ANY opposite-color candle before a strong
|
|
body an OB WITHOUT structural context is CONFORMING to the canonical current
|
|
definition (DESIGN.md + AF_FindOrderBlock). The legacy structure-break rule is
|
|
a separate historical definition.
|
|
```
|
|
|
|
---
|
|
|
|
## 6. FORMATION TIMING / CLOSED-BAR RULE (answer)
|
|
|
|
```text
|
|
Observable : an OB at candle B is observable when the MOVE candle M = B+1
|
|
CLOSES (the strong-body confirmation is a closed bar). The OB
|
|
requires the pair (B, B+1) both closed.
|
|
Decision : at decision time t (newest closed bar), valid OB candles B satisfy
|
|
B+1 <= t. The NEWEST observable pair is (B = t-1, M = t) — the move
|
|
candle may be the newest closed bar (NO 1-bar lag; contrast FVG S-6).
|
|
Timestamp : the OB zone timestamp = open time of candle B (all implementations:
|
|
AF_CollectOBs t=Time(obBar); v4.4 time[found]; v4.5 r[found].time).
|
|
Future : NONE — mutating bars > t must not change the OB decision at t
|
|
(property test OB-T19).
|
|
Repaint : closed-bar lock; deterministic full recompute per bar.
|
|
Boundary : the analysis region excludes the OLDEST cache bar as an OB candle
|
|
(Engine-1 index scan starts at 1) — a cache-region artifact, not a
|
|
semantic rule; irrelevant in the 700-bar runtime cache.
|
|
```
|
|
|
|
---
|
|
|
|
## 7. ORDER BLOCK LIFECYCLE (answer)
|
|
|
|
```text
|
|
OB = ZONE (persistent) + FORMATION EVENT (the qualifying pair).
|
|
|
|
- FORMATION EVENT : the bar pair (B, M) — ONE event when the pair first
|
|
satisfies the rule (M closes).
|
|
- ACTIVE ZONE : the zone [Low(B), High(B)] persists as ACTIVE (unmitigated)
|
|
for any number of bars. A zone untraded for 100 bars is ONE
|
|
OB, not 100 events.
|
|
- MITIGATED ZONE : terminated by mitigation (§9). Display/legacy remove it from
|
|
the usable set; Engine 2 IGNORES the mitigation state
|
|
(BUG-P3S5-001).
|
|
- INVALIDATED / EXPIRED / CONSUMED : NOT modeled (§10).
|
|
|
|
Do NOT treat a persistent active zone as repeated OB formations — this is the
|
|
f7/f9/f18 duplication class, and OB detectors do NOT emit events (they maintain
|
|
zone lists / a newest-zone query), so no duplication exists (verified OB-T09).
|
|
```
|
|
|
|
---
|
|
|
|
## 8. MITIGATION (answer)
|
|
|
|
```text
|
|
Canonical (display + legacy agree): MITIGATED when a subsequent bar j > B prints
|
|
Close(j) < Low(B) (bullish OB) — close THROUGH the zone bottom.
|
|
Close(j) > High(B) (bearish OB) — close THROUGH the zone top.
|
|
|
|
= CLOSE-THROUGH FULL FILL (price closed beyond the far boundary of the zone).
|
|
|
|
Partial fill : price entering the zone (touching a boundary, filling part of
|
|
the gap) is NOT mitigation. PARTIALLY MITIGATED is NOT modeled.
|
|
Wick-only : a wick penetrating the zone without a close beyond the far
|
|
boundary is NOT mitigation (close-based rule).
|
|
Engine 2 : AF_FindOrderBlock has NO mitigation check at all (BUG-P3S5-001).
|
|
States : UNMITIGATED / MITIGATED only.
|
|
```
|
|
|
|
---
|
|
|
|
## 9. INVALIDATION (answer)
|
|
|
|
```text
|
|
INVALIDATION = NOT MODELED BY CURRENT SPEC
|
|
|
|
An OB is NOT invalidated by: full mitigation (that is MITIGATION, §8),
|
|
structure break, opposite displacement, opposite CHoCH, or time expiration.
|
|
A mitigated zone is simply no longer usable (display/legacy filter it out;
|
|
Engine 2 ignores the state entirely — BUG-P3S5-001).
|
|
```
|
|
|
|
---
|
|
|
|
## 10. MULTIPLE / OVERLAPPING ORDER BLOCKS (answer)
|
|
|
|
```text
|
|
- Multiple OBs in sequence : each qualifying pair (B, M) produces its OWN zone;
|
|
zones are NOT merged (except the display dedupe below).
|
|
- Nested / overlapping : overlapping pairs produce separate zones.
|
|
- Same-direction consecutive OBs : separate zones, both kept.
|
|
- Opposite-direction OB before an old zone is mitigated : both zones coexist.
|
|
- New OB while old active : old zone stays (A-3; display keeps newest N).
|
|
- Display dedupe : AF_CollectOBs skips a zone whose top/bot are within
|
|
0.5 x ATR of an already-collected zone ("simple dedupe"). Engine 2 (newest
|
|
only) and legacy (keep all) do NOT dedupe. Keep-all vs dedupe = AMBIGUOUS
|
|
(A-3).
|
|
- Prioritization : Engine 2 returns the NEWEST OB; display draws the newest N
|
|
unmitigated; legacy draws the newest N unmitigated per type. No strength/
|
|
volume prioritization in the current implementation (legacy InpVolumeOB /
|
|
InpOBStyle=OB_HIGHEST_VOLUME is the historical volume mode, A-6).
|
|
```
|
|
|
|
---
|
|
|
|
## 11. BREAKER / MITIGATED OB DISTINCTION (answer)
|
|
|
|
```text
|
|
BREAKER BLOCK = NOT IMPLEMENTED
|
|
|
|
No Breaker Block / breaker / flipped-OB code exists anywhere in the project
|
|
(verified: grep "breaker|Breaker" = 0 project-code matches; only two P3 documents
|
|
mention "breaker" as a FUTURE concept, outside this session's mandate).
|
|
|
|
The project models:
|
|
original OB -> zone -> MITIGATED (no longer usable).
|
|
It does NOT model:
|
|
mitigated OB -> Breaker (flipped role) as a distinct concept.
|
|
|
|
If a reader wants a Breaker Block, the project does NOT define or implement it.
|
|
Do not add one in this session.
|
|
```
|
|
|
|
---
|
|
|
|
## 12. TIMEFRAME SEMANTICS (answer)
|
|
|
|
```text
|
|
Engine 2 : OB is computed INDEPENDENTLY per agent-slot TF (H4 = Narrative,
|
|
M30 = Context, M15 = Entry, M3 = Price Action); each slot has its
|
|
own AF_FindOrderBlock query.
|
|
Display : chart TF (M15 in the canonical deployment).
|
|
Legacy : chart TF (swing + internal OBs) + v4.5 per-TF MTF OB (D1/H4/H1)
|
|
via cache for display.
|
|
HTF as context : supported by v4.5 (MTF OB) and Engine 2 (per-slot agents);
|
|
NOT defined as a canonical rule ("HTF OB must act as M15 context").
|
|
M3 execution zone : NOT defined anywhere.
|
|
Cross-timeframe inheritance : not defined.
|
|
|
|
Status: the OB geometry/rule is TF-agnostic (same closed sequence -> same zone on
|
|
any TF); the canonical project OB (which TF's OB is the entry reference) =
|
|
SPECIFICATION AMBIGUOUS (same class as CHoCH G-4, sweep G-3, FVG A-3).
|
|
```
|
|
|
|
---
|
|
|
|
## 13. CONSUMER SEMANTICS (answer)
|
|
|
|
```text
|
|
Chain : OB detector (AF_FindOrderBlock / AF_CollectOBs / RecordOB)
|
|
-> zone state (top/bot/bull/mit)
|
|
-> consumer:
|
|
- Engine 2 C agent (context) : newest OB zone, price-in-zone fuzzy
|
|
membership (weight 0.30), tolerance +-0.3 x ATR.
|
|
- Engine 2 E agent (entry) : newest OB zone (same query), ZONE +
|
|
CONFIRMATION = setup rule.
|
|
- Legacy v4.4/v4.5 entry : FindEntryOB (unmitigated OB of the side
|
|
whose mid is within +-0.2 x ATR of price) + tap test +-1 x ATR;
|
|
+15 confluence; "Sweep->CHoCH->Bullish/Bearish OB (discount/premium)";
|
|
pending "wait pullback to bullish OB" at zone top.
|
|
- Engine 3 display : visual boxes (newest N unmitigated).
|
|
- ML features : NONE (OB not in f0-f18).
|
|
|
|
Zone-vs-event in consumers : OB is consumed as a ZONE (persistent membership).
|
|
The C/E agents recompute the newest OB each bar — a persistent OB yields a
|
|
persistent membership, which is ZONE semantics, NOT repeated events (the
|
|
f7/f9/f18 stale-consumer class does NOT apply to OB by construction, OB-T09).
|
|
The cross-layer gap is MITIGATION (Engine-2 detector ignores mit) and AGE (the
|
|
newest OB can be hundreds of bars old, no freshness bound) — BUG-P3S5-001.
|
|
```
|
|
|
|
---
|
|
|
|
## 14. RUNTIME / TRAINING PARITY (answer)
|
|
|
|
```text
|
|
OB IS NOT A FEATURE CONTRACT FEATURE.
|
|
|
|
- FEATURE_CONTRACT.md (f0-f18): no OB feature (the only "OB" text hit is "prOB"
|
|
inside "SGMLProb", a false positive).
|
|
- EA runtime (AlgoForge_Backtest_Baseline.mq5): no OB computation (the "OB"
|
|
hits are OrderSend + a comment "tanpa draw/OB/alert" stating OB is skipped).
|
|
- Python training pipeline (ml/**/*.py): 0 OB references.
|
|
|
|
Consequence: PARITY = N/A BY ABSENCE. The ML model was trained WITHOUT OB.
|
|
Any future use of OB as an ML feature requires a new Feature Contract entry
|
|
(out of scope). No runtime/training mismatch exists to document beyond the
|
|
absence itself.
|
|
```
|
|
|
|
---
|
|
|
|
## 15. SPEC DECISION SUMMARY (tabular)
|
|
|
|
| # | Aspect | Decision |
|
|
|---|--------|----------|
|
|
| S-1 | Formation | opposite-color candle B immediately before strong-move candle M (body >= 1.5 x avg); canonical current definition |
|
|
| S-2 | Candle selection | B = full opposite candle (Close vs Open); doji excluded; FULL RANGE [Low(B), High(B)] |
|
|
| S-3 | Zone boundaries | top = High(B), bot = Low(B); no padding; min size none in definition (0.15 ATR consumer filters, A-1) |
|
|
| S-4 | Direction | +1 bullish (bearish B + bullish M), -1 bearish, 0 none; direction = move direction |
|
|
| S-5 | Structural precondition | NONE (canonical); legacy = BOS/CHoCH structure break (A-2 second definition) |
|
|
| S-6 | Formation timing | observable at M close (B+1 <= t); newest pair (t-1, t); NO 1-bar lag; timestamp = B open |
|
|
| S-7 | Closed-bar | all inputs <= t; no future visibility; deterministic |
|
|
| S-8 | Lifecycle | ZONE + FORMATION EVENT; one zone per pair; no event stream; no age expiry |
|
|
| S-9 | Mitigation | close-through full fill: Close < Low(B) bull / Close > High(B) bear; partial/wick NOT mitigation |
|
|
| S-10 | Invalidation | NOT MODELED |
|
|
| S-11 | Overlap | separate zones per pair; display dedupe 0.5 ATR (A-3); Engine-2 newest-only; legacy keep-all |
|
|
| S-12 | Breaker | NOT IMPLEMENTED (no code) |
|
|
| S-13 | Timeframe | Engine 2 per-TF independent; canonical = SPECIFICATION AMBIGUOUS (A-4) |
|
|
| S-14 | Consumers | C/E zone membership (newest OB); legacy entry gate (all unmitigated within tap); display; NO ML feature |
|
|
| S-15 | Parity | OB NOT an ML feature; PARITY = N/A BY ABSENCE |
|
|
|
|
---
|
|
|
|
## 16. RECORDED AMBIGUITIES (SPECIFICATION AMBIGUOUS)
|
|
|
|
```text
|
|
A-1 Minimum zone size: Engine 2 none / display 0.15 ATR / legacy 0.15 ATR.
|
|
No canonical project threshold. NOT optimized here.
|
|
A-2 TWO OB DEFINITIONS IN ONE PROJECT:
|
|
canonical current = opposite candle before strong move (DESIGN.md,
|
|
AF_FindOrderBlock / AF_CollectOBs);
|
|
legacy = opposite candle before STRUCTURE BREAK (v4.3/v4.4/v4.5 RecordOB,
|
|
BOS/CHoCH on swing or internal structure, volume mode).
|
|
The two rules can select different candles. The current definition is
|
|
authoritative for the Algo Forge project; the legacy is historical.
|
|
A-3 Overlap handling: display dedupes zones within 0.5 x ATR; Engine 2 and
|
|
legacy keep all. Keep-all vs dedupe intent NOT adjudicated.
|
|
A-4 Canonical OB timeframe (MTF vs M15): Engine-2 M15 slot explicit; HTF OB as
|
|
M15 context / M3 execution not defined.
|
|
A-5 Consumer zone scope: Engine 2 newest-ANY (no mitigation filter) vs legacy
|
|
all-unmitigated within tap vs display newest-N-unmitigated (BUG-P3S5-001).
|
|
A-6 Volume-weighted OB selection exists only in the legacy path (InpVolumeOB /
|
|
InpOBStyle=OB_HIGHEST_VOLUME); the current implementation selects the last
|
|
opposite candle only. Highest-volume vs last-candle intent NOT canonical.
|
|
```
|
|
|
|
---
|
|
|
|
## 17. PROVENANCE & CHECKPOINT
|
|
|
|
```text
|
|
Forge HEAD (audit) : 176880f8f3f17afb7e922a48ed953daa22c1515f (P3-S.4)
|
|
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_S5_ORDER_BLOCK_CONFORMANCE.md §A
|
|
Human verification : CANCELLED
|
|
```
|