{
 "approach": "S0: quote one tick inside the competitor's static ladder (never closer than EDGE ticks to the estimate), estimate = competitor midpoint, fixed size, linear inventory skew. S1 = S0 with the estimate replaced by a scalar Kalman filter (ticks) whose process model is a two-component mixture (diffusion KQ per step, plus a jump with prob KJ and variance KJV) collapsed to one gaussian each update; readings are the competitor midpoint (variance spread^2/12+0.25) and own fills from the previous step (bid fill -> price below bid-1, ask fill -> above ask+1, variance KFILL); the posterior mean is clamped into [competitor bid, competitor ask].",
 "tried": [
  {
   "variant": "S0 EDGE=1 SIZE=6 (frozen)",
   "tuning_mean": -2.172
  },
  {
   "variant": "S0 EDGE=2",
   "tuning_mean": -3.815
  },
  {
   "variant": "S0 EDGE=1.5 SIZE=10",
   "tuning_mean": -3.871
  },
  {
   "variant": "S0 EDGE=3",
   "tuning_mean": -3.032
  },
  {
   "variant": "S1 KQ=0.05 KJ=0.003 KFILL=4",
   "tuning_mean": -6.863
  },
  {
   "variant": "S1 KQ=0.2 KFILL=2",
   "tuning_mean": -3.51
  },
  {
   "variant": "S1 KQ=0.02 KJ=0.01",
   "tuning_mean": -7.542
  },
  {
   "variant": "S1 KQ=0.1 KJ=0.01 KFILL=1 (frozen)",
   "tuning_mean": -2.896
  },
  {
   "variant": "note",
   "detail": "Tuning used seeds 115000..115199 only (200 of the allowed 500): this machine gave no parallel speedup (~0.4 s/sim serial). An earlier holdout run of S1 with unfrozen default params by mistake (KQ=0.05,KJ=0.003,KFILL=4) gave mean -7.798 on 200000..200999; it is discarded, not the measurement."
  }
 ],
 "next": "Mechanism hurts: the filter lags the competitor midpoint, which after each arbitrage sweep already brackets the true price, and fill readings cannot tell arb from retail fills. The variants trend toward following the midpoint faster (higher KQ, lower KFILL) i.e. toward S0. Worth testing only as a fill-side signal (distinguish arb fills by whether the competitor level also cleared) rather than as a smoother.",
 "code": "import math\nfrom orderbook_pm_challenge.strategy import BaseStrategy\nfrom orderbook_pm_challenge.types import CancelAll, PlaceOrder, Side, StepState\n\nEDGE = 1.0     # min ticks between estimate and our quote\nSIZE = 6.0     # base quote size (shares)\nSKEW = 0.02    # ticks of estimate shift per share of net inventory\nMAXINV = 150.0\n\n\nclass Strategy(BaseStrategy):\n    \"\"\"S0: quote one tick inside the competitor ladder around its midpoint.\"\"\"\n\n    def __init__(self):\n        self.last_bid = None\n        self.last_ask = None\n\n    def estimate(self, state, cb, ca):\n        return 0.5 * (cb + ca)\n\n    def on_step(self, state: StepState):\n        cb = state.competitor_best_bid_ticks\n        ca = state.competitor_best_ask_ticks\n        if cb is None and ca is None:\n            cb, ca = 49, 51\n        elif cb is None:\n            cb = max(0, ca - 2)\n        elif ca is None:\n            ca = min(100, cb + 2)\n        est = self.estimate(state, cb, ca)\n        net = state.yes_inventory - state.no_inventory\n        c = est - SKEW * net\n        bid = min(cb + 1, int(math.floor(c - EDGE)))\n        ask = max(ca - 1, int(math.ceil(c + EDGE)))\n        actions = [CancelAll()]\n        self.last_bid = self.last_ask = None\n        if 1 <= bid <= 99 and bid < ca and net < MAXINV:\n            q = SIZE\n            if state.free_cash > bid / 100.0 * q + 1:\n                actions.append(PlaceOrder(side=Side.BUY, price_ticks=bid, quantity=q))\n                self.last_bid = bid\n        if 1 <= ask <= 99 and ask > cb and net > -MAXINV:\n            q = SIZE\n            need = max(0.0, q - max(0.0, state.yes_inventory)) * (1 - ask / 100.0)\n            if state.free_cash > need + 1:\n                actions.append(PlaceOrder(side=Side.SELL, price_ticks=ask, quantity=q))\n                self.last_ask = ask\n        return actions\n\n# ---- S1 mechanism: Kalman filter on the latent price with jump-aware process model ----\nKQ = 0.1     # diffusion process variance per step (ticks^2)\nKJ = 0.01    # prior jump probability per step\nKJV = 400.0    # jump variance (ticks^2)\nKFILL = 1.0   # measurement variance of an own fill reading (ticks^2)\n\n\nclass Kalman:\n    def __init__(self):\n        self.x = None\n        self.P = 25.0\n\n    def update(self, z, R):\n        # two-hypothesis (no jump / jump) gaussian mixture collapsed to one gaussian\n        Pn, Pj = self.P + KQ, self.P + KQ + KJV\n        v = z - self.x\n        ln = math.exp(-0.5 * v * v / (Pn + R)) / math.sqrt(Pn + R) * (1 - KJ)\n        lj = math.exp(-0.5 * v * v / (Pj + R)) / math.sqrt(Pj + R) * KJ\n        w = lj / (ln + lj + 1e-300)\n        out = []\n        for P0, wt in ((Pn, 1 - w), (Pj, w)):\n            K = P0 / (P0 + R)\n            out.append((self.x + K * v, (1 - K) * P0, wt))\n        mx = sum(m * wt for m, _, wt in out)\n        self.P = sum(wt * (P + (m - mx) ** 2) for m, P, wt in out)\n        self.x = mx\n\n\n_base_on_step = Strategy.on_step\n\n\ndef _estimate(self, state, cb, ca):\n    k = getattr(self, \"kf\", None)\n    if k is None:\n        k = self.kf = Kalman()\n    mid = 0.5 * (cb + ca)\n    if k.x is None:\n        k.x = mid\n    # own fills from the previous step are readings of the latent price beyond our quote\n    if state.buy_filled_quantity > 0 and self.last_bid is not None:\n        k.update(self.last_bid - 1.0, KFILL)\n    if state.sell_filled_quantity > 0 and self.last_ask is not None:\n        k.update(self.last_ask + 1.0, KFILL)\n    sp = max(1.0, ca - cb)\n    k.update(mid, sp * sp / 12.0 + 0.25)\n    # competitor ladder survives arbitrage only on the right side of the price\n    return min(max(k.x, cb), ca)\n\n\nStrategy.estimate = _estimate\n",
 "code_sha256": "f7387407fb7930034507044d91630b841cdf75f443893ee14090a21a7e924833",
 "code_s0": "import math\nfrom orderbook_pm_challenge.strategy import BaseStrategy\nfrom orderbook_pm_challenge.types import CancelAll, PlaceOrder, Side, StepState\n\nEDGE = 1.0     # min ticks between estimate and our quote\nSIZE = 6.0     # base quote size (shares)\nSKEW = 0.02    # ticks of estimate shift per share of net inventory\nMAXINV = 150.0\n\n\nclass Strategy(BaseStrategy):\n    \"\"\"S0: quote one tick inside the competitor ladder around its midpoint.\"\"\"\n\n    def __init__(self):\n        self.last_bid = None\n        self.last_ask = None\n\n    def estimate(self, state, cb, ca):\n        return 0.5 * (cb + ca)\n\n    def on_step(self, state: StepState):\n        cb = state.competitor_best_bid_ticks\n        ca = state.competitor_best_ask_ticks\n        if cb is None and ca is None:\n            cb, ca = 49, 51\n        elif cb is None:\n            cb = max(0, ca - 2)\n        elif ca is None:\n            ca = min(100, cb + 2)\n        est = self.estimate(state, cb, ca)\n        net = state.yes_inventory - state.no_inventory\n        c = est - SKEW * net\n        bid = min(cb + 1, int(math.floor(c - EDGE)))\n        ask = max(ca - 1, int(math.ceil(c + EDGE)))\n        actions = [CancelAll()]\n        self.last_bid = self.last_ask = None\n        if 1 <= bid <= 99 and bid < ca and net < MAXINV:\n            q = SIZE\n            if state.free_cash > bid / 100.0 * q + 1:\n                actions.append(PlaceOrder(side=Side.BUY, price_ticks=bid, quantity=q))\n                self.last_bid = bid\n        if 1 <= ask <= 99 and ask > cb and net > -MAXINV:\n            q = SIZE\n            need = max(0.0, q - max(0.0, state.yes_inventory)) * (1 - ask / 100.0)\n            if state.free_cash > need + 1:\n                actions.append(PlaceOrder(side=Side.SELL, price_ticks=ask, quantity=q))\n                self.last_ask = ask\n        return actions\n",
 "tuning_score": {
  "seeds": "115000..115199",
  "n": 200,
  "s1_mean": -2.896,
  "s0_mean": -2.172
 },
 "paired": {
  "seeds": "200000..200999",
  "n": 1000,
  "complete": true,
  "mechanism_diff": -1.010803627898,
  "mechanism_se": 0.07644068338607703,
  "mechanism_retail_diff": -0.3629052186138,
  "mechanism_arb_diff": -0.6478984092818999,
  "reference_diff": -103.411138712604,
  "reference_se": 5.446887919168018,
  "s1_mean": -3.7152605602217,
  "s0_mean": -2.7044569323237,
  "b_mean": 99.69587815238229,
  "failures": []
 },
 "graft": "Replace the price estimate with a scalar Kalman filter in ticks: each step predict P+=KQ, update on competitor mid (R=spread^2/12) and on last-step own fills (bid-1 / ask+1, R=1) with a no-jump/jump (prob 0.01, var 400) gaussian mixture collapsed by moments; clamp the mean into [comp bid, comp ask]. Measured -1.0 vs the mid alone, so graft only to test.",
 "seconds_per_simulation": 3.241
}