{ "meta": { "spec_doc": "docs/SMC_DISPLACEMENT_SPEC_v1.md", "spec_version": "v1", "phase": "P3-S.6", "principle": "Expected results derived from PROJECT SEMANTIC SPECIFICATION (S-1..S-14), NOT from current implementation. Code port results are reported for conformance observation, not as truth.", "constants": { "AVG_N": 20, "K": 1.6, "OB_MOVE_BODY_MULT": 1.5, "SYMBOL": "XAUUSD", "DECISION_TF": "M15" }, "bar_format": "[open, high, low, close] per bar, chronological (index 0 = oldest). Displacement is evaluated on the NEWEST CLOSED bar (decision_bar) only (S-1/S-9).", "displacement_format": "dir of the newest closed bar: +1 bullish (body >= 1.6 x avg AND Close>Open), -1 bearish, 0 otherwise (S-1/S-4/S-10).", "code_dir_expected": "Engine-2 AF_DetectDisplacement observed result (identical formula — the implementation IS the audited primitive). Reported as conformance observation.", "note": "All 20 required cases (DP-T01..T20). Expected outputs are the SPEC truth; code outputs are observations." }, "cases": [ { "id": "DP-T01", "title": "Valid bullish displacement", "rule": "SPEC S-1/S-4 — body >= 1.6 x avg AND Close > Open -> +1", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.0, 100.6, 99.9, 100.3]]]}, "decision_bar": 24, "expected": {"dir": 1, "code_dir_expected": 1} }, { "id": "DP-T02", "title": "Valid bearish displacement", "rule": "SPEC S-4 — body >= 1.6 x avg AND Close < Open -> -1", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.3, 100.5, 99.7, 100.0]]]}, "decision_bar": 24, "expected": {"dir": -1, "code_dir_expected": -1} }, { "id": "DP-T03", "title": "Large range but small body -> NOT displacement", "rule": "SPEC S-2 — (High-Low) plays NO role; body 0.1 < 1.6 x avg -> 0", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.0, 101.0, 99.0, 100.1]]]}, "decision_bar": 24, "expected": {"dir": 0, "code_dir_expected": 0} }, { "id": "DP-T04", "title": "Large body but small full range -> displacement", "rule": "SPEC S-2 — body-based rule; range irrelevant; body 0.3 >= 1.6 x avg -> +1", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.0, 100.31, 99.99, 100.3]]]}, "decision_bar": 24, "expected": {"dir": 1, "code_dir_expected": 1} }, { "id": "DP-T05", "title": "Exactly at threshold (inclusive)", "rule": "SPEC S-10 — body == 1.6 x avg (within float precision) IS displacement (>=)", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.0, 100.6, 99.9, 100.1652174]]]}, "decision_bar": 24, "expected": {"dir": 1, "code_dir_expected": 1, "note": "body 0.1652174 = 1.6 x avg (avg=(1.9+body)/20=0.10326087, thr=0.16521739); inclusive boundary confirmed."} }, { "id": "DP-T06", "title": "One tick below threshold -> NOT displacement", "rule": "SPEC S-10 — body < 1.6 x avg -> 0 (strict <)", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.0, 100.6, 99.9, 100.1642174]]]}, "decision_bar": 24, "expected": {"dir": 0, "code_dir_expected": 0} }, { "id": "DP-T07", "title": "One tick above threshold -> displacement", "rule": "SPEC S-10 — body > 1.6 x avg -> +1", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.0, 100.6, 99.9, 100.1662174]]]}, "decision_bar": 24, "expected": {"dir": 1, "code_dir_expected": 1} }, { "id": "DP-T08", "title": "Insufficient historical baseline (window shrinks)", "rule": "SPEC S-3 — with < 20 bars the window = min(20, count); the rule still applies", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 6, "patches": [[5, [100.0, 100.6, 99.9, 100.3]]]}, "decision_bar": 5, "expected": {"dir": 1, "code_dir_expected": 1, "note": "avg over 6 bars = (5x0.1+0.3)/6 = 0.1333, thr = 0.2133 < body 0.3 -> +1."} }, { "id": "DP-T09", "title": "Current candle still forming is NOT evaluated", "rule": "SPEC S-1/S-10 — displacement uses the NEWEST CLOSED bar; the forming bar (beyond t) is excluded", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.0, 100.6, 99.9, 100.3]]]}, "decision_bar": 23, "expected": {"dir": 0, "code_dir_expected": 0, "note": "bar 24 (would-be displacement) is forming beyond t=23; bar 23 is neutral -> 0."} }, { "id": "DP-T10", "title": "Valid only after candle close", "rule": "SPEC S-10 — at t=24 the bar closed -> displacement observable (+1); pair with DP-T09", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.0, 100.6, 99.9, 100.3]]]}, "decision_bar": 24, "expected": {"dir": 1, "code_dir_expected": 1} }, { "id": "DP-T11", "title": "Bullish/bearish symmetry", "rule": "SPEC S-11 — mirror of DP-T01; runner asserts mirror property on every case", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.3, 100.5, 99.7, 100.0]]]}, "decision_bar": 24, "expected": {"dir": -1, "code_dir_expected": -1} }, { "id": "DP-T12", "title": "Large candle WITHOUT structural break -> displacement", "rule": "SPEC S-5 — NO structural requirement; a large body in a flat sequence IS displacement", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.0, 100.6, 99.9, 100.3]]]}, "decision_bar": 24, "expected": {"dir": 1, "code_dir_expected": 1, "note": "no BOS/CHoCH/sweep/FVG/OB in the data -> displacement stands alone."} }, { "id": "DP-T13", "title": "Structural break WITHOUT sufficient displacement", "rule": "SPEC S-5 — a close beyond a level with a small body (< 1.6 x avg) is NOT displacement", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.4, 100.6, 100.3, 100.5]]]}, "decision_bar": 24, "expected": {"dir": 0, "code_dir_expected": 0, "note": "close 100.5 above the prior range (structural break) but body 0.1 < thr -> 0."} }, { "id": "DP-T14", "title": "Displacement followed by FVG (correlated, NOT required)", "rule": "SPEC S-6 — FVG dependency NOT REQUIRED; displacement detected even when an FVG also forms", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.0, 100.6, 100.4, 100.3]]]}, "decision_bar": 24, "expected": {"dir": 1, "code_dir_expected": 1, "note": "bar 24 body 0.3 -> +1; Low(24)=100.4 > High(22)=100.3 -> an FVG also forms; FVG NOT required by displacement."} }, { "id": "DP-T15", "title": "Large candle but NO FVG -> displacement still detected", "rule": "SPEC S-6 — displacement is independent of FVG; no FVG -> displacement remains", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.0, 100.6, 100.25, 100.3]]]}, "decision_bar": 24, "expected": {"dir": 1, "code_dir_expected": 1, "note": "Low(24)=100.25 <= High(22)=100.3 -> no FVG; displacement still +1."} }, { "id": "DP-T16", "title": "Displacement and Order Block relationship", "rule": "SPEC S-7 — displacement body 0.6 also satisfies the OB strong-move gate (1.5 x avg); same concept family", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[23, [100.2, 100.5, 99.8, 100.1]], [24, [100.3, 101.0, 100.2, 100.9]]]}, "decision_bar": 24, "expected": {"dir": 1, "code_dir_expected": 1, "note": "bar 24 body 0.6 >= 1.6 x avg (0.2) -> displacement +1; also >= 1.5 x avg -> OB strong-move gate satisfied on the same candle (BUG-P3S6-001: 1.5 vs 1.6)."} }, { "id": "DP-T17", "title": "Displacement and CHoCH relationship", "rule": "SPEC S-8 — CHoCH is close-confirmed structure, displacement is body-only; a small-body CHoCH-like bar is NOT displacement", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.4, 100.6, 100.3, 100.5]]]}, "decision_bar": 24, "expected": {"dir": 0, "code_dir_expected": 0, "note": "CHoCH does NOT require displacement (P3-S.3 S-6); displacement = 0 on this bar."} }, { "id": "DP-T18", "title": "Repeated bars after one displacement -> no duplicate events", "rule": "SPEC S-9 — displacement is a per-bar candle attribute; the NEXT bar is re-evaluated independently (no carry-forward)", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 26, "patches": [[24, [100.0, 100.6, 99.9, 100.3]]]}, "decision_bar": 25, "expected": {"dir": 0, "code_dir_expected": 0, "note": "bar 24 was displacement (+1 at t=24, see DP-T01); at t=25 the newest bar (neutral body 0.1) gives 0 -> no persistence, no repeated events."} }, { "id": "DP-T19", "title": "Future-bar mutation must not change the historical result", "rule": "SPEC S-3 — property test: mutating bars beyond t leaves the displacement at t unchanged", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.0, 100.6, 99.9, 100.3]]]}, "decision_bar": 24, "mutations": [[30, [200.0, 210.0, 199.0, 205.0]]], "expected": {"dir": 1, "code_dir_expected": 1} }, { "id": "DP-T20", "title": "Timeframe boundary (TF-agnostic geometry)", "rule": "SPEC S-12 — the displacement rule is TF-agnostic; canonical project displacement TF = AMBIGUOUS (A-1)", "bar_spec": {"neutral": [100.0, 100.3, 99.9, 100.1], "count": 25, "patches": [[24, [100.0, 100.6, 99.9, 100.3]]]}, "decision_bar": 24, "tf_agnostic": true, "expected": {"dir": 1, "code_dir_expected": 1} } ] }