{
 "key": "f-phat-band-size",
 "mech": "f-phat-band-size",
 "approach": "Overlay on N: after N's on_step, every PlaceOrder quantity is multiplied by B_MID when the rival midpoint (best bid+ask)/2 is within 20..80 cents, else by B_EDGE (one-sided book counts as edge). Upscaled orders are capped by a conservative free-cash budget so collateral never fails; cancels of overlay-dropped orders are filtered. Cancels/prices untouched. Tuned 3 pairs on 320000..320199; froze B_MID=1.3, B_EDGE=1.0. Holdout 430000..430499: -0.345 (se 0.140), slightly negative: mostly extra arbitrage loss (-0.75) only partly offset by retail (+0.40).",
 "tried": [
  "A b_mid=1.0 b_edge=0.6: tuning -68.00 (se 8.59), arb loss up sharply",
  "B b_mid=0.7 b_edge=1.0: tuning -20.72 (se 1.89)",
  "C b_mid=1.3 b_edge=1.0: tuning -0.23 (se 0.18), frozen; holdout -0.345 (se 0.140)"
 ],
 "next": "Drop this mechanism: N's sizes look near-optimal by band; shrinking either band costs heavily (arbitrage loss grows), and upscaling the 20-80 band adds more arb loss than retail edge. Band-sized quoting does not help; if anything, test b_mid in 1.0-1.1 restricted to s=1 (only spread with non-negative point estimate, +0.01).",
 "spreads_acted": [
  1,
  2,
  3,
  4
 ],
 "off_equals_n": {
  "equal": true,
  "seeds": "310000..310009",
  "steps_compared": 20000,
  "detail": "with B_MID=B_EDGE=1 the overlay returns N's action list unchanged; repr of actions identical every step and total edge identical on all 10 seeds"
 },
 "code": "# Overlay f-phat-band-size: scale N's order sizes by probability band of the rival midpoint.\nfrom orderbook_pm_challenge.types import PlaceOrder, CancelAll, CancelOrder, Side\n\n\nclass Strategy(_N):\n    B_MID = 1.0   # size multiplier when rival mid is within [LO, HI] cents\n    B_EDGE = 1.0  # size multiplier outside the band\n    LO = 20.0\n    HI = 80.0\n    SPREADS = (1, 2, 3, 4)\n\n    def on_step(self, state):\n        acts = list(super().on_step(state))\n        if self.B_MID == 1.0 and self.B_EDGE == 1.0:\n            return acts\n        if getattr(self, \"s\", None) not in self.SPREADS:\n            return acts\n        bid = state.competitor_best_bid_ticks\n        ask = state.competitor_best_ask_ticks\n        if bid is not None and ask is not None:\n            mid = 0.5 * (bid + ask)\n        elif bid is not None:\n            mid = 99.0\n        elif ask is not None:\n            mid = 1.0\n        else:\n            return acts\n        b = self.B_MID if self.LO <= mid <= self.HI else self.B_EDGE\n        if b == 1.0:\n            return acts\n        # collateral budget: free cash plus what this step's cancels release\n        free = state.free_cash\n        own = {o.order_id: o for o in state.own_orders}\n        res = {}\n        avail_yes = max(0.0, state.yes_inventory)\n        for o in state.own_orders:\n            if o.side == Side.SELL:\n                avail_yes -= min(avail_yes, o.remaining_quantity)\n        out = []\n        placed = set()\n        for a in acts:\n            if isinstance(a, CancelAll):\n                free = state.cash\n                avail_yes = max(0.0, state.yes_inventory)\n                out.append(a)\n            elif isinstance(a, CancelOrder):\n                o = own.get(a.order_id)\n                if o is None and a.order_id not in placed:\n                    continue  # its placement was dropped by this overlay\n                if o is not None and o.side == Side.BUY:\n                    free += (o.price_ticks / 100.0) * o.remaining_quantity\n                out.append(a)\n            elif isinstance(a, PlaceOrder):\n                q = int(a.quantity * b * 100) / 100.0\n                p = a.price_ticks / 100.0\n                if a.side == Side.BUY:\n                    cost_per = p\n                    cov = 0.0\n                else:\n                    cov = min(q, avail_yes)\n                    cost_per = 1.0 - p\n                need = cost_per * (q - cov)\n                if need > free - 1e-6:\n                    q = cov + max(0.0, (free - 1e-6) / cost_per)\n                    q = int(q * 100) / 100.0\n                if q < 0.01:\n                    continue\n                if a.side == Side.SELL:\n                    cov = min(q, avail_yes)\n                    avail_yes -= cov\n                    free -= cost_per * (q - cov)\n                else:\n                    free -= cost_per * q\n                if a.client_order_id:\n                    placed.add(a.client_order_id)\n                out.append(PlaceOrder(a.side, a.price_ticks, q, a.client_order_id))\n            else:\n                out.append(a)\n        return out\n",
 "code_sha256": "6011971e639d6f81baa48c08e3ee910641500b09b7bdbb3d744328bf612d91ac",
 "assembled_sha256": "608c1176ae3bf9cab74bdd39e59bc53b17f42b4737f86b13804e1e21d47e28a7",
 "n_sha256": "bf0d179f3e47d28819f6fa7e0d25548c2ced43374c216d36460b00a26a26ffae",
 "tuning": {
  "seeds": "320000..320199",
  "selected": "C",
  "selected_params": {
   "B_MID": 1.3,
   "B_EDGE": 1.0,
   "LO": 20,
   "HI": 80
  },
  "variants": {
   "A": {
    "B_MID": 1.0,
    "B_EDGE": 0.6,
    "overall": {
     "n": 200,
     "sum_d": -13600.274397,
     "sum_d2": 3859525.270177,
     "mean_diff": -68.0014,
     "se": 8.587,
     "incumbent_mean": 98.4707,
     "candidate_mean": 30.4693,
     "retail_diff": -15.4851,
     "arb_diff": -52.5163
    },
    "by_spread": {
     "1": {
      "n": 50,
      "sum_d": -1957.033089,
      "sum_d2": 572765.336866,
      "mean_diff": -39.1407,
      "se": 14.2308,
      "incumbent_mean": 25.7113,
      "candidate_mean": -13.4294,
      "retail_diff": -19.0012,
      "arb_diff": -20.1395
     },
     "2": {
      "n": 50,
      "sum_d": -1480.29003,
      "sum_d2": 173281.205725,
      "mean_diff": -29.6058,
      "se": 7.2691,
      "incumbent_mean": 61.2199,
      "candidate_mean": 31.6141,
      "retail_diff": -12.5096,
      "arb_diff": -17.0962
     },
     "3": {
      "n": 48,
      "sum_d": -2847.62073,
      "sum_d2": 532267.253276,
      "mean_diff": -59.3254,
      "se": 12.6906,
      "incumbent_mean": 130.8342,
      "candidate_mean": 71.5088,
      "retail_diff": -17.4554,
      "arb_diff": -41.87
     },
     "4": {
      "n": 52,
      "sum_d": -7315.330549,
      "sum_d2": 2581211.474309,
      "mean_diff": -140.6794,
      "se": 24.192,
      "incumbent_mean": 174.3758,
      "candidate_mean": 33.6964,
      "retail_diff": -13.1465,
      "arb_diff": -127.5329
     }
    },
    "failures": 0
   },
   "B": {
    "B_MID": 0.7,
    "B_EDGE": 1.0,
    "overall": {
     "n": 200,
     "sum_d": -4144.063982,
     "sum_d2": 227983.325968,
     "mean_diff": -20.7203,
     "se": 1.8897,
     "incumbent_mean": 98.4707,
     "candidate_mean": 77.7504,
     "retail_diff": -8.0304,
     "arb_diff": -12.6899
    },
    "by_spread": {
     "1": {
      "n": 50,
      "sum_d": -5.51657,
      "sum_d2": 221.991434,
      "mean_diff": -0.1103,
      "se": 0.3006,
      "incumbent_mean": 25.7113,
      "candidate_mean": 25.6009,
      "retail_diff": -0.5573,
      "arb_diff": 0.4469
     },
     "2": {
      "n": 50,
      "sum_d": -474.02055,
      "sum_d2": 5655.729241,
      "mean_diff": -9.4804,
      "se": 0.6886,
      "incumbent_mean": 61.2199,
      "candidate_mean": 51.7395,
      "retail_diff": -8.8941,
      "arb_diff": -0.5863
     },
     "3": {
      "n": 48,
      "sum_d": -1342.807323,
      "sum_d2": 50326.496316,
      "mean_diff": -27.9752,
      "se": 2.3784,
      "incumbent_mean": 130.8342,
      "candidate_mean": 102.8591,
      "retail_diff": -14.0725,
      "arb_diff": -13.9026
     },
     "4": {
      "n": 52,
      "sum_d": -2321.71954,
      "sum_d2": 171779.108977,
      "mean_diff": -44.6485,
      "se": 5.0681,
      "incumbent_mean": 174.3758,
      "candidate_mean": 129.7273,
      "retail_diff": -8.8082,
      "arb_diff": -35.8402
     }
    },
    "failures": 0
   },
   "C": {
    "B_MID": 1.3,
    "B_EDGE": 1.0,
    "overall": {
     "n": 200,
     "sum_d": -45.642539,
     "sum_d2": 1277.032502,
     "mean_diff": -0.2282,
     "se": 0.1784,
     "incumbent_mean": 98.4707,
     "candidate_mean": 98.2425,
     "retail_diff": 0.4625,
     "arb_diff": -0.6907
    },
    "by_spread": {
     "1": {
      "n": 50,
      "sum_d": 1.383642,
      "sum_d2": 18.490177,
      "mean_diff": 0.0277,
      "se": 0.0868,
      "incumbent_mean": 25.7113,
      "candidate_mean": 25.7389,
      "retail_diff": -0.2486,
      "arb_diff": 0.2763
     },
     "2": {
      "n": 50,
      "sum_d": -3.457793,
      "sum_d2": 166.198312,
      "mean_diff": -0.0692,
      "se": 0.2603,
      "incumbent_mean": 61.2199,
      "candidate_mean": 61.1508,
      "retail_diff": 0.8481,
      "arb_diff": -0.9172
     },
     "3": {
      "n": 48,
      "sum_d": -38.180276,
      "sum_d2": 553.817594,
      "mean_diff": -0.7954,
      "se": 0.4817,
      "incumbent_mean": 130.8342,
      "candidate_mean": 130.0388,
      "retail_diff": 0.7676,
      "arb_diff": -1.563
     },
     "4": {
      "n": 52,
      "sum_d": -5.388112,
      "sum_d2": 538.526419,
      "mean_diff": -0.1036,
      "se": 0.4504,
      "incumbent_mean": 174.3758,
      "candidate_mean": 174.2722,
      "retail_diff": 0.4938,
      "arb_diff": -0.5974
     }
    },
    "failures": 0
   }
  }
 },
 "paired": {
  "seeds": "430000..430499",
  "n": 500,
  "complete": true,
  "missing_seeds": [],
  "overall": {
   "n": 500,
   "sum_d": -172.570106,
   "sum_d2": 4915.140385,
   "mean_diff": -0.3451,
   "se": 0.1395,
   "incumbent_mean": 95.542,
   "candidate_mean": 95.1969,
   "retail_diff": 0.4001,
   "arb_diff": -0.7453
  },
  "by_spread": {
   "1": {
    "n": 131,
    "sum_d": 1.654472,
    "sum_d2": 247.281752,
    "mean_diff": 0.0126,
    "se": 0.1205,
    "incumbent_mean": 38.2779,
    "candidate_mean": 38.2906,
    "retail_diff": -0.1976,
    "arb_diff": 0.2102
   },
   "2": {
    "n": 120,
    "sum_d": -69.894481,
    "sum_d2": 355.9367,
    "mean_diff": -0.5825,
    "se": 0.1486,
    "incumbent_mean": 77.8559,
    "candidate_mean": 77.2734,
    "retail_diff": 0.7938,
    "arb_diff": -1.3763
   },
   "3": {
    "n": 133,
    "sum_d": -57.499016,
    "sum_d2": 3402.419442,
    "mean_diff": -0.4323,
    "se": 0.4386,
    "incumbent_mean": 146.5514,
    "candidate_mean": 146.1191,
    "retail_diff": 0.6236,
    "arb_diff": -1.056
   },
   "4": {
    "n": 116,
    "sum_d": -46.831081,
    "sum_d2": 909.502491,
    "mean_diff": -0.4037,
    "se": 0.2584,
    "incumbent_mean": 120.022,
    "candidate_mean": 119.6183,
    "retail_diff": 0.4117,
    "arb_diff": -0.8154
   }
  }
 },
 "failures": 0,
 "check_values": {
  "310000": 17.116002,
  "310001": 20.017111,
  "310002": 2.390311,
  "310003": 241.484752
 },
 "check_values_match": true,
 "python_version": "3.12.3",
 "seconds_per_simulation": 0.68,
 "notes": "Screen only, never a promotion. Default ChallengeConfig/ParameterVariance, 2000 steps, unmodified simulator at b244530, in-process SimulationEngine runs, no --workers/--sandbox; each (seed,strategy) run once. seconds_per_simulation measured unloaded on the check seeds; several harness processes shared one CPU during tuning/holdout."
}