Skip to content

[C] Orion Delivery — Phase 7.2 Binary CLOB Switch (Apr 18)

To: Vesper (she/her) CC: Katja (Captain) From: Orion Date: 2026-04-18


Source Variable — Confirmed

anchor_error_bps is StrategyEngine.last_anchor_divergence_bps, computed at neo_engine/strategy_engine.py:203:

self.last_anchor_divergence_bps = ((quote_anchor_price - mid_price) / mid_price) * 10000.0

This is the post-cap divergence — under capped_amm at cap=10, a 15 bps raw AMM-vs-CLOB divergence pins last_anchor_divergence_bps at ±10, not ±15. Per the brief that's the correct quantity to threshold against.

clob_mid is snapshot.mid_price, which this repo already defines as (best_bid + best_ask) / 2 in MarketDataAdapter — no recomputation needed; I used mid_price directly.


Exact Lines Changed

File: neo_engine/strategy_engine.py

Insertion after line 206 (immediately after self.last_cap_applied = cap_applied):

# Phase 7.2: binary CLOB/anchor switch for quote placement.
# When the anchor is in unreliable territory (|anchor_error_bps| > 3),
# use CLOB mid as the reference_mid for quote placement; otherwise
# use the selected anchor. Atlas-locked threshold is 3 bps (control
# threshold — distinct from the 5 bps evaluation reliability floor).
# Binary only — no blending, no weighted average.
if (
    self.last_anchor_divergence_bps is not None
    and abs(self.last_anchor_divergence_bps) > 3.0
):
    reference_mid = mid_price
    reference_source = "clob_mid_phase7_switch"
else:
    reference_mid = quote_anchor_price
    reference_source = quote_anchor_source

Replacement at buy/sell quote placement (was lines 255–256):

- buy_price  = quote_anchor_price * (1.0 - (final_bid_offset_bps / 10000.0))
- sell_price = quote_anchor_price * (1.0 + (final_ask_offset_bps / 10000.0))
+ buy_price  = reference_mid * (1.0 - (final_bid_offset_bps / 10000.0))
+ sell_price = reference_mid * (1.0 + (final_ask_offset_bps / 10000.0))

Replacement in the bid-ladder loop (was line 355):

- level_price = quote_anchor_price * (1.0 - ((final_bid_offset_bps + level_offset) / 10000.0))
+ level_price = reference_mid * (1.0 - ((final_bid_offset_bps + level_offset) / 10000.0))

Log additions (inserted in the Quote calculated log.debug extras dict):

  "quote_anchor_source": quote_anchor_source,
  "quote_anchor_price": quote_anchor_price,
+ "reference_mid": reference_mid,
+ "reference_source": reference_source,

quote_anchor_price and quote_anchor_source are preserved in the log so historical diagnostic tooling still reads the pre-switch anchor. reference_source takes one of two values: clob_mid_phase7_switch when the switch flipped, or whatever quote_anchor_source was when it didn't.

That is the entire behavioral change. Spread offsets, size, skew/drift, momentum, all bid-protection logic, risk engine, fill paths, and schema are untouched.


What Does NOT Move

  • quote_anchor_price itself is unchanged — only its use in quote placement is replaced. Downstream uses (self._anchor_history.append(...), bid_protection_delta_bps, anchor_divergence_bps for Phase 3E) still reference quote_anchor_price. That preserves existing Phase 3D/3E behavior as-is.
  • last_anchor_divergence_bps is computed and persisted before the switch — the session summary |err|>5bps stat measures anchor drift, not post-switch drift. Those two signals now live side-by-side.

Test Coverage

File: tests/test_phase_7_2_clob_switch.py — 5 tests, all passing:

# Test Covers
1 test_divergence_below_threshold_uses_anchor amm 2 bps above mid → anchor path
2 test_divergence_exactly_3_uses_anchor exactly 3 bps → anchor path (strict >)
3 test_positive_divergence_above_threshold_uses_clob amm +5 bps → CLOB path
4 test_negative_divergence_above_threshold_uses_clob amm −5 bps → CLOB path (symmetric)
5 test_at_anchor_cap_uses_clob raw +15 bps pinned at cap=10 → CLOB path

Each test drives a live StrategyEngine.calculate_quote() with crafted MarketSnapshot(mid, amm) values and asserts on the buy/sell intent prices end-to-end.

Regression check: phase3d, phase4a, task5, and main_loop tests have the same pass/fail count before and after. The pre-existing failures are FLAG-016 territory; my change doesn't touch them. No new regressions.


Git Commands for Katja

Block 1 — create branch off main:

git checkout main
git pull origin main
git checkout -b feat/phase-7.2-clob-switch

Block 2 — apply patch:

git am --3way "orion-patches-2026-04-18-phase7.2\0001-feat-phase-7.2-binary-CLOB-anchor-switch-at-3-bps-th.patch"

Block 3 — verify:

git log --oneline main..HEAD
python -m pytest tests/test_phase_7_2_clob_switch.py -v
Expected: one commit; 5 passed.

Block 4 — push:

git push origin feat/phase-7.2-clob-switch

Then merge via GitHub UI.


Expected Effect

Given S37's 69.4% |err|>5bps rate, the engine will price against CLOB for the majority of ticks. The session after merge is the controlled comparison against S37 baseline (29 fills, VW +3.40 bps). The reference_source log field gives direct post-session observability on how often the switch flipped.

— Orion