{
 "key": "f-order-count-cap",
 "mech": "order count cap: keep at most the best-priced K resting orders per side, cancelling deeper ones (K=2 and K=3 screened)",
 "approach": "Overlay on N: after N's on_step, rebuild the resting book from own_orders plus N's cancels/places, rank each side by price (ties keep older), cancel existing orders beyond rank K and drop N's new placements beyond K. A conservative collateral guard skips placements the account cannot fund after a drop. K=3 frozen on tuning.",
 "tried": "Tuning 320000..320199: K=2 all spreads (-40.63, se 4.19), K=3 all spreads (-10.32, se 1.50), K=2 spreads 3-4 only (-34.01, se 4.23). Every variant loses edge at every spread: the cap removes retail fills and N relies on deep orders. A first overlay without the collateral guard failed 1 of 200 sims (seed 320151, insufficient collateral); the guard fixed it and all tuning runs were redone.",
 "next": "Cap hurts; do not promote. If anything, test K>=4 or capping only orders beyond a price distance from the fair-value estimate, but the K=3 loss suggests N's depth is worth more than its arbitrage exposure.",
 "spreads_acted": [
  1,
  2,
  3,
  4
 ],
 "off_equals_n": {
  "seeds": "310000..310009",
  "equal": true,
  "note": "CAP=None overlay actions identical to N every step (2000 steps, repr compared) and equal total_edge"
 },
 "code": "class Strategy(_N):\n    \"\"\"Order-count cap: keep at most CAP best-priced resting orders per side.\"\"\"\n    CAP = 3\n    SPREADS = (1, 2, 3, 4)\n\n    def on_step(self, state):\n        actions = list(super().on_step(state))\n        cap = self.CAP\n        if cap is None or getattr(self, \"s\", None) not in self.SPREADS:\n            return actions\n        live = [[o.order_id, o.side, o.price_ticks, None, o.remaining_quantity] for o in state.own_orders]\n        for a in actions:\n            if isinstance(a, CancelAll):\n                live = []\n            elif isinstance(a, CancelOrder):\n                live = [x for x in live if x[0] != a.order_id]\n            elif isinstance(a, PlaceOrder):\n                live.append([None, a.side, a.price_ticks, a, a.quantity])\n        drop_ids = set()\n        drop_new = set()\n        for side in (Side.BUY, Side.SELL):\n            lst = [x for x in live if x[1] == side]\n            lst.sort(key=lambda x: -x[2] if side == Side.BUY else x[2])\n            for x in lst[cap:]:\n                if x[0] is None:\n                    drop_new.add(id(x[3]))\n                else:\n                    drop_ids.add(x[0])\n        if not drop_ids and not drop_new:\n            return actions\n        cancels = [CancelOrder(i) for i in sorted(drop_ids)]\n        out = cancels + [a for a in actions if id(a) not in drop_new]\n        # conservative collateral guard: skip a placement the account cannot fund\n        free = state.free_cash\n        yes = state.yes_inventory\n        resting = {o.order_id: o for o in state.own_orders}\n        asks = sum(o.remaining_quantity for o in state.own_orders if o.side == Side.SELL)\n        final = []\n        for a in out:\n            if isinstance(a, CancelAll):\n                free = state.cash\n                asks = 0.0\n                resting = {}\n            elif isinstance(a, CancelOrder):\n                o = resting.pop(a.order_id, None)\n                if o is not None:\n                    if o.side == Side.BUY:\n                        free += o.price_ticks / 100.0 * o.remaining_quantity\n                    else:\n                        asks -= o.remaining_quantity\n            elif isinstance(a, PlaceOrder):\n                if a.side == Side.BUY:\n                    need = a.price_ticks / 100.0 * a.quantity\n                else:\n                    avail = max(0.0, yes - asks)\n                    need = (1.0 - a.price_ticks / 100.0) * max(0.0, a.quantity - avail)\n                    asks_add = a.quantity\n                if need > free + 1e-6:\n                    continue\n                free -= need\n                if a.side == Side.SELL:\n                    asks += asks_add\n            final.append(a)\n        return final\n",
 "code_sha256": "3a013516071b1dd153574048a64925fc7bf0630936e01c5a8cca36c53f1b186c",
 "assembled_sha256": "407026518f77f9b68f9cb959cda3ea26b13b4fb1145bc6575913ce8c2902e245",
 "tuning": {
  "seeds": "320000..320199",
  "selected": "k3",
  "variants": {
   "k2": {
    "desc": "cap 2 per side, spreads 1-4",
    "mean_diff": -40.633085183775,
    "se": 4.192214792815564,
    "n": 200,
    "candidate_mean": 57.8376331307905,
    "incumbent_mean": 98.47071831456549
   },
   "k3": {
    "desc": "cap 3 per side, spreads 1-4",
    "mean_diff": -10.31507285485,
    "se": 1.4976024376707837,
    "n": 200,
    "candidate_mean": 88.1556454597155,
    "incumbent_mean": 98.47071831456549
   },
   "k2s34": {
    "desc": "cap 2 per side, spreads 3-4 only",
    "mean_diff": -34.0082316142735,
    "se": 4.232662617740361,
    "n": 200,
    "candidate_mean": 64.462486700292,
    "incumbent_mean": 98.47071831456549
   }
  }
 },
 "paired": {
  "seeds": "430000..430499",
  "n": 500,
  "complete": true,
  "missing_seeds": [],
  "overall": {
   "n": 500,
   "sum_d": -5359.1246263210005,
   "sum_d2": 519219.504106475,
   "mean_diff": -10.718249252642002,
   "se": 1.3604476903500318,
   "incumbent_mean": 95.54201511346659,
   "candidate_mean": 84.8237658608246,
   "retail_diff": -10.4096759077388,
   "arb_diff": -0.30857334489800003
  },
  "by_spread": {
   "1": {
    "n": 131,
    "sum_d": -98.44607642220004,
    "sum_d2": 14954.686593408876,
    "mean_diff": -0.7514967665816796,
    "se": 0.9347692662100039,
    "incumbent_mean": 38.277936657049615,
    "candidate_mean": 37.526439890467934,
    "retail_diff": -1.0693465390442747,
    "arb_diff": 0.31784977249313034
   },
   "2": {
    "n": 120,
    "sum_d": -1316.5579468472001,
    "sum_d2": 245823.95714595116,
    "mean_diff": -10.971316223726667,
    "se": 4.025301488301815,
    "incumbent_mean": 77.8558643979175,
    "candidate_mean": 66.88454817419083,
    "retail_diff": -8.018236705425833,
    "arb_diff": -2.9530795182775003
   },
   "3": {
    "n": 133,
    "sum_d": -1795.4348896592,
    "sum_d2": 97715.24162699885,
    "mean_diff": -13.499510448565413,
    "se": 2.045809246628051,
    "incumbent_mean": 146.55140363646615,
    "candidate_mean": 133.05189318790076,
    "retail_diff": -14.220862833642855,
    "arb_diff": 0.7213523850436088
   },
   "4": {
    "n": 116,
    "sum_d": -2148.6857133924,
    "sum_d2": 160725.61874011607,
    "mean_diff": -18.52315270165862,
    "se": 3.0107900057960246,
    "incumbent_mean": 120.02204692465259,
    "candidate_mean": 101.49889422299397,
    "retail_diff": -19.06198617007759,
    "arb_diff": 0.5388334684215519
   }
  }
 },
 "failures": [],
 "check_values": [
  17.116002,
  20.017111,
  2.390311,
  241.484752
 ],
 "python_version": "3.12.3",
 "seconds_per_simulation": 3.38
}