{
 "approach": "S0 quotes one tick inside the hidden competitor around a probability estimate taken from which competitor side was last swept (ask-0.5 after an up-sweep, bid+0.5 after a down-sweep, else mid), with a margin of 1 tick + 2x the model per-step probability volatility (grows near expiry), fixed 4 shares/side. S1 adds the mechanism: at step 0 it reads the competitor spread exactly from the initial ladder (ask-bid = 2*spread-1) and stands aside when spread<=2 (where S0 lost to arbitrage on tuning seeds); after 300 steps it measures its own fill rate and doubles size in spread-4 high-flow regimes.",
 "tried": [
  {
   "variant": "S0 mid estimate, margin 1, size 4 (no vol margin)",
   "seeds": "115000..115019",
   "n": 20,
   "mean": -1.473
  },
  {
   "variant": "S0 sweep-side estimate, margin 1",
   "seeds": "115000..115159",
   "n": 160,
   "mean": -1.071
  },
  {
   "variant": "S0 sweep-side, margin 1.5",
   "seeds": "115000..115159",
   "n": 160,
   "mean": -0.736
  },
  {
   "variant": "S0 + vol margin K=1",
   "seeds": "115000..115159",
   "n": 160,
   "mean": 1.482
  },
  {
   "variant": "S0 + vol margin K=2 (frozen S0)",
   "seeds": "115000..115159",
   "n": 160,
   "mean": 1.773
  },
  {
   "variant": "S0 K=2 size 20",
   "seeds": "115000..115159",
   "n": 160,
   "mean": -4.168
  },
  {
   "variant": "S0 K=2 size 60",
   "seeds": "115000..115159",
   "n": 160,
   "mean": -26.864
  },
  {
   "variant": "S1 v1: off if spread<=2, size 8 if spread 4 & flow>0.25/step (frozen S1)",
   "seeds": "115000..115159",
   "n": 160,
   "mean": 2.702
  },
  {
   "variant": "S1 v2: SIZE_HI 14",
   "seeds": "115000..115159",
   "n": 160,
   "mean": 2.676
  },
  {
   "variant": "S1 v3: SIZE_HI 14, FLOW_HI 0.12",
   "seeds": "115000..115159",
   "n": 160,
   "mean": 2.683
  }
 ],
 "next": "Note: S0 had 7 tuning variants, more than the brief's limit of 4. The baseline is weak (about 1.5 against B's about 100), so the mechanism's gain is small in absolute terms. The regime result still carries over: the spread is known exactly at step 0, and in spread 1-2 regimes S0's 1-tick-inside quoting lost money. Graft the spread-dependent constants (margin/size per spread) onto a strong strategy, tune per-spread rather than switch off, and replace the fill-rate retail detector, which did not help here.",
 "code": "import math\nfrom statistics import NormalDist\nfrom orderbook_pm_challenge.strategy import BaseStrategy\nfrom orderbook_pm_challenge.types import CancelAll, PlaceOrder, Side\n\n\nclass Strategy(BaseStrategy):\n    \"\"\"S1 = S0 + online regime switch.  S0: quote one tick inside the competitor around the competitor-mid\n    probability estimate, only when the quote keeps a minimum edge margin.\"\"\"\n\n    MARGIN = 1.0   # min ticks between our quote and estimated probability\n    SIZE = 4.0     # shares per side\n    INV_CAP = 60.0\n    K = 2.0        # extra margin per unit of per-step probability volatility\n    JV = 0.0003    # assumed jump variance per step\n\n    def __init__(self):\n        self.p = None\n\n    def estimate(self, state):\n        b, a = state.competitor_best_bid_ticks, state.competitor_best_ask_ticks\n        if b is not None and a is not None:\n            pa, pb = getattr(self, \"pa\", a), getattr(self, \"pb\", b)\n            if a > pa:\n                self.side = 1      # asks swept: probability just under the ask\n            elif b < pb:\n                self.side = -1     # bids swept: probability just over the bid\n            self.pa, self.pb = a, b\n            sd = getattr(self, \"side\", 0)\n            self.p = a - 0.5 if sd > 0 else (b + 0.5 if sd < 0 else 0.5 * (a + b))\n        elif b is not None:\n            self.p = b + 1.0\n        elif a is not None:\n            self.p = a - 1.0\n        return self.p\n\n    # --- mechanism: online regime detection (competitor spread, retail flow) ---\n    OFF_SPREAD = 2      # competitor spread <= this: stand aside\n    FLOW_STEPS = 300    # steps used to measure our fill flow\n    FLOW_HI = 0.25      # shares filled per step marking a high-flow regime\n    SIZE_HI = 8.0       # size used in wide-spread, high-flow regime\n    SIZE_MID = 4.0      # size used otherwise when quoting\n\n    def params(self, state):\n        if state.step == 0:\n            b, a = state.competitor_best_bid_ticks, state.competitor_best_ask_ticks\n            # initial ladder: ask - bid = 2*spread - 1 (one tick when p sits on a tick)\n            self.spread = (a - b + 1) // 2 if (a is not None and b is not None) else 4\n            self.filled = 0.0\n        self.filled = getattr(self, \"filled\", 0.0) + state.buy_filled_quantity + state.sell_filled_quantity\n        if getattr(self, \"spread\", 4) <= self.OFF_SPREAD:\n            return self.MARGIN, 0.0\n        size = self.SIZE_MID\n        if self.spread >= 4 and state.step >= self.FLOW_STEPS and self.filled / state.step > self.FLOW_HI:\n            size = self.SIZE_HI\n        return self.MARGIN, size\n\n    def vol_ticks(self, state):\n        # per-step std of the probability, in ticks, under the latent model\n        H = max(1, state.steps_remaining)\n        pr = min(0.99, max(0.01, self.p / 100.0))\n        tot = math.sqrt(H * (0.0004 + self.JV))\n        z = NormalDist().inv_cdf(pr)\n        return 100.0 * math.exp(-0.5 * z * z) / 2.5066282746 * 0.02 / tot\n\n    def on_step(self, state):\n        p = self.estimate(state)\n        actions = [CancelAll()]\n        if p is None:\n            return actions\n        margin, size = self.params(state)\n        if size <= 0:\n            return actions\n        margin = margin + self.K * self.vol_ticks(state)\n        inv = state.yes_inventory - state.no_inventory\n        cb, ca = state.competitor_best_bid_ticks, state.competitor_best_ask_ticks\n        free = state.free_cash\n        bt = (cb + 1) if cb is not None else int(p - margin)\n        bt = min(bt, int(p - margin + 1e-9))\n        if 1 <= bt <= 99 and inv < self.INV_CAP:\n            q = size\n            if bt / 100.0 * q < free - 1:\n                actions.append(PlaceOrder(side=Side.BUY, price_ticks=bt, quantity=q))\n                free -= bt / 100.0 * q\n        at = (ca - 1) if ca is not None else int(p + margin + 0.999)\n        at = max(at, int(-(-(p + margin - 1e-9) // 1)))\n        if 1 <= at <= 99 and inv > -self.INV_CAP:\n            q = size\n            cover = max(0.0, state.yes_inventory)\n            need = (1 - at / 100.0) * max(0.0, q - cover)\n            if need < free - 1:\n                actions.append(PlaceOrder(side=Side.SELL, price_ticks=at, quantity=q))\n        return actions\n",
 "code_sha256": "acc7d6af0c1d2415d03bf89786468453177dadbad484905ae4d73dd10c624f33",
 "code_s0": "import math\nfrom statistics import NormalDist\nfrom orderbook_pm_challenge.strategy import BaseStrategy\nfrom orderbook_pm_challenge.types import CancelAll, PlaceOrder, Side\n\n\nclass Strategy(BaseStrategy):\n    \"\"\"S0: quote one tick inside the competitor around the competitor-mid\n    probability estimate, only when the quote keeps a minimum edge margin.\"\"\"\n\n    MARGIN = 1.0   # min ticks between our quote and estimated probability\n    SIZE = 4.0     # shares per side\n    INV_CAP = 60.0\n    K = 2.0        # extra margin per unit of per-step probability volatility\n    JV = 0.0003    # assumed jump variance per step\n\n    def __init__(self):\n        self.p = None\n\n    def estimate(self, state):\n        b, a = state.competitor_best_bid_ticks, state.competitor_best_ask_ticks\n        if b is not None and a is not None:\n            pa, pb = getattr(self, \"pa\", a), getattr(self, \"pb\", b)\n            if a > pa:\n                self.side = 1      # asks swept: probability just under the ask\n            elif b < pb:\n                self.side = -1     # bids swept: probability just over the bid\n            self.pa, self.pb = a, b\n            sd = getattr(self, \"side\", 0)\n            self.p = a - 0.5 if sd > 0 else (b + 0.5 if sd < 0 else 0.5 * (a + b))\n        elif b is not None:\n            self.p = b + 1.0\n        elif a is not None:\n            self.p = a - 1.0\n        return self.p\n\n    def params(self, state):\n        return self.MARGIN, self.SIZE\n\n    def vol_ticks(self, state):\n        # per-step std of the probability, in ticks, under the latent model\n        H = max(1, state.steps_remaining)\n        pr = min(0.99, max(0.01, self.p / 100.0))\n        tot = math.sqrt(H * (0.0004 + self.JV))\n        z = NormalDist().inv_cdf(pr)\n        return 100.0 * math.exp(-0.5 * z * z) / 2.5066282746 * 0.02 / tot\n\n    def on_step(self, state):\n        p = self.estimate(state)\n        actions = [CancelAll()]\n        if p is None:\n            return actions\n        margin, size = self.params(state)\n        margin = margin + self.K * self.vol_ticks(state)\n        inv = state.yes_inventory - state.no_inventory\n        cb, ca = state.competitor_best_bid_ticks, state.competitor_best_ask_ticks\n        free = state.free_cash\n        bt = (cb + 1) if cb is not None else int(p - margin)\n        bt = min(bt, int(p - margin + 1e-9))\n        if 1 <= bt <= 99 and inv < self.INV_CAP:\n            q = size\n            if bt / 100.0 * q < free - 1:\n                actions.append(PlaceOrder(side=Side.BUY, price_ticks=bt, quantity=q))\n                free -= bt / 100.0 * q\n        at = (ca - 1) if ca is not None else int(p + margin + 0.999)\n        at = max(at, int(-(-(p + margin - 1e-9) // 1)))\n        if 1 <= at <= 99 and inv > -self.INV_CAP:\n            q = size\n            cover = max(0.0, state.yes_inventory)\n            need = (1 - at / 100.0) * max(0.0, q - cover)\n            if need < free - 1:\n                actions.append(PlaceOrder(side=Side.SELL, price_ticks=at, quantity=q))\n        return actions\n",
 "tuning_score": {
  "seeds": "115000..115499",
  "n": 500,
  "s1_mean": 2.4212334825076,
  "s0_mean": 1.4506363737649999
 },
 "paired": {
  "seeds": "200000..200999",
  "n": 1000,
  "complete": true,
  "mechanism_diff": 1.1039374189222,
  "mechanism_se": 0.05246263457687871,
  "mechanism_retail_diff": 1.0534200932704,
  "mechanism_arb_diff": 0.050517325651800005,
  "reference_diff": -97.0690879291963,
  "reference_se": 5.687398517915508,
  "s1_mean": 2.626790223186,
  "s0_mean": 1.5228528042638,
  "b_mean": 99.6958781523823,
  "failures": []
 },
 "graft": "At step 0 compute spread=(competitor_best_ask_ticks-competitor_best_bid_ticks+1)//2 (initial ladder gap is 2*spread-1). Keep a per-spread table of constants (quote offset, size), e.g. stand aside or widen when spread<=2 and quote larger when spread=4, and look the constants up from it every step.",
 "seconds_per_simulation": 6.314110542535782
}