{
 "approach": "Instrumented copy of the simulator at b244530 by wrapping (not changing) PredictionMarket.__init__, execute_arbitrage, execute_retail_buy/sell and _fill_order in-process. This logs every maker fill: its owner (B or the competitor), aggressor (retail or arb), price, quantity, the true probability after the step, and the sampled competitor spread. Ran B serially, one run_batch(n_simulations=1) per seed, default ChallengeConfig/ParameterVariance, 2000 steps. Instrumentation check: on seeds 240000-240019, B's total/retail/arb edge was bit-identical with and without the instrumentation (all 20 matched), and the logged B fills sum back to the simulator's retail_edge and arb_edge.",
 "tried": "Bucketed every fill by true-probability decile, by competitor spread (1-4), and by spread x {p<0.2, 0.2-0.8, p>0.8}. Classified each retail order by who filled it: B only, competitor only, split, or nobody (no fill above the 0.01-share quantum).",
 "next": [
  "Spread-1 markets, 0.2<p<0.8: B takes 0.2% of retail notional, and the competitor earns 9.11 retail edge per simulation (averaged over all 1000; about 36 per spread-1 simulation). Test joining the competitor's best tick, or a tick that ties it, when the spread is 1 and p is mid-range, accepting queue position behind the competitor. At stake: at most ~9 per simulation, less any added arbitrage loss.",
  "Spread-2 markets, mid-range p: B's share is 21.5% and the competitor earns 8.13 per simulation, with B's arb loss already at -2.46 there. Across all spreads in 0.2<p<0.8 the competitor takes about 32 retail edge per simulation (spread 1: 9.1, 2: 8.1, 3: 7.5, 4: 5.7). Quote one tick tighter in mid-range p when the estimated probability is confident, for example right after a stable stretch with no jump. At stake: up to ~8-16 per simulation, gross of arbitrage."
 ],
 "code": "# harness.py\n# Instrumented harness: wraps (never alters) simulator methods to log every fill's owner/price/qty\nimport sys, json, time\nsys.path.insert(0, sys.argv[1])\nfrom orderbook_pm_challenge import market as M\nfrom orderbook_pm_challenge.config import ChallengeConfig, ParameterVariance\nfrom orderbook_pm_challenge.runner import run_batch\nfrom orderbook_pm_challenge.loader import load_strategy_factory\nstrat, s0, n, out = sys.argv[2], int(sys.argv[3]), int(sys.argv[4]), sys.argv[5]\ninstr = len(sys.argv) < 7\nCTX = {}\nif instr:\n    PM = M.PredictionMarket\n    oi, oarb, obuy, osell, ofill = PM.__init__, PM.execute_arbitrage, PM.execute_retail_buy, PM.execute_retail_sell, PM._fill_order\n    def i(self, config):\n        CTX['spread'] = config.competitor.spread_ticks; return oi(self, config)\n    def arb(self, *, probability, step):\n        CTX['p'] = probability; CTX['agg'] = 'arb'\n        return oarb(self, probability=probability, step=step)\n    def startorder():\n        CTX['agg'] = 'retail'; CTX['ord'] = {'B': 0.0, 'C': 0.0}\n    def endorder():\n        o = CTX['ord']; b = int(min(CTX['p'], 0.9999) * 10)\n        k = 'B_only' if o['C'] == 0 and o['B'] > 0 else 'C_only' if o['B'] == 0 and o['C'] > 0 else 'split' if o['B'] > 0 else 'none'\n        CTX['cls'][k] = CTX['cls'].get(k, 0) + 1\n        CTX['agg'] = None\n    def rb(self, *, notional, step):\n        startorder(); r = obuy(self, notional=notional, step=step); endorder(); return r\n    def rs(self, *, quantity, step):\n        startorder(); r = osell(self, quantity=quantity, step=step); endorder(); return r\n    def fo(self, order, quantity, *, aggressor, step):\n        q = M.quantize_down(quantity, self._config.share_quantum)\n        if q > 0:\n            p = CTX['p']; price = order.price_ticks / 100.0\n            # edge to the resting side (the maker)\n            e = q * (p - price) if order.side is M.Side.BUY else q * (price - p)\n            who = 'B' if order.owner == M.PARTICIPANT else 'C'\n            b = str(int(min(p, 0.9999) * 10))\n            d = CTX['ev'].setdefault(b, {})\n            key = ('r' if aggressor == 'retail' else 'a') + who\n            for kk, v in ((key + '_n', q * price), (key + '_e', e)):\n                d[kk] = d.get(kk, 0.0) + v\n            if aggressor == 'retail': CTX['ord'][who] += q * price\n        return ofill(self, order, quantity, aggressor=aggressor, step=step)\n    PM.__init__, PM.execute_arbitrage, PM.execute_retail_buy, PM.execute_retail_sell, PM._fill_order = i, arb, rb, rs, fo\nfac = load_strategy_factory(strat)\nrows = []\nt = time.time()\nfor s in range(s0, s0 + n):\n    CTX.update(ev={}, cls={})\n    r = run_batch(fac, base_config=ChallengeConfig(), variance=ParameterVariance(), n_simulations=1, seed_start=s, workers=1).simulation_results[0]\n    rec = dict(seed=s, total=r.total_edge, retail=r.retail_edge, arb=r.arb_edge, failed=r.failed)\n    if instr: rec.update(spread=CTX['spread'], ev=CTX['ev'], cls=CTX['cls'])\n    rows.append(rec)\njson.dump(dict(rows=rows, sec=(time.time() - t) / n), open(out, 'w'))\n\n# analyze.py\nimport json, math, statistics as st\nR = sum((json.load(open(f'p{k}.json'))['rows'] for k in range(4)), [])\nn = len(R)\ndef se(x): return st.stdev(x) / math.sqrt(len(x))\ndef r4(x): return round(x, 4)\ninc = dict(mean=r4(st.mean(r['total'] for r in R)), retail_mean=r4(st.mean(r['retail'] for r in R)),\n           arb_mean=r4(st.mean(r['arb'] for r in R)), se=r4(se([r['total'] for r in R])))\ndef row(name, sel, nsims=n):\n    # sel(r) -> list of ev dicts for sim r (empty if sim not in class); per-sim means over all n sims\n    per = []\n    for r in R:\n        t = {}\n        for d in sel(r):\n            for k, v in d.items(): t[k] = t.get(k, 0) + v\n        per.append(t)\n    g = lambda k: [t.get(k, 0.0) for t in per]\n    rBn, rCn = sum(g('rB_n')), sum(g('rC_n'))\n    tot = [a + b for a, b in zip(g('rB_e'), g('aB_e'))]\n    cnt = sum(1 for r in R if sel(r))\n    return dict(name=name, count=cnt, mean=r4(st.mean(tot)), retail=r4(st.mean(g('rB_e'))), arb=r4(st.mean(g('aB_e'))), se=r4(se(tot)),\n                retail_se=r4(se(g('rB_e'))),\n                B_share_retail_notional=r4(rBn / (rBn + rCn)) if rBn + rCn else None,\n                retail_notional_per_sim=r4((rBn + rCn) / n),\n                competitor_retail_edge=r4(st.mean(g('rC_e'))), competitor_retail_edge_se=r4(se(g('rC_e'))),\n                competitor_arb_edge=r4(st.mean(g('aC_e'))))\nF = [row('all', lambda r: list(r['ev'].values()))]\nfor b in range(10):\n    F.append(row(f'p_{b/10:.1f}-{(b+1)/10:.1f}', lambda r, b=b: [r['ev'][str(b)]] if str(b) in r['ev'] else []))\nfor s in range(1, 5):\n    F.append(row(f'spread_{s}', lambda r, s=s: list(r['ev'].values()) if r['spread'] == s else []))\nfor s in range(1, 5):\n    for lo, hi, nm in ((0, 2, 'tails<0.2'), (2, 8, 'mid0.2-0.8'), (8, 10, 'tails>0.8')):\n        F.append(row(f'spread_{s}_{nm}', lambda r, s=s, lo=lo, hi=hi: [v for k, v in r['ev'].items() if lo <= int(k) < hi] if r['spread'] == s else []))\ncls = {}\nfor r in R:\n    for k, v in r['cls'].items(): cls[k] = cls.get(k, 0) + v\ntc = sum(cls.values())\nF.append(dict(name='retail_orders_by_filler', count=tc, per_sim={k: r4(v / n) for k, v in cls.items()}, share={k: r4(v / tc) for k, v in cls.items()}))\njson.dump(dict(n=n, inc=inc, F=F, fail=sum(r['failed'] for r in R)), open('an.json', 'w'), indent=1)\nprint(json.dumps(inc), n)\nfor f in F: print({k: f.get(k) for k in ('name', 'count', 'mean', 'retail', 'arb', 'se', 'B_share_retail_notional', 'retail_notional_per_sim', 'competitor_retail_edge', 'competitor_arb_edge', 'per_sim')})\n",
 "code_sha256": "8c8c6dde8fcdd095742294c5728d45e02cfc20ef5e437fb87c35975dded524fb",
 "incumbent_code_sha256": "baef955ec10728839f7c3357016ec9eb0550e7ec689bbd5171b1cdd5c9e37273",
 "tuning": null,
 "seeds": "240000..240999",
 "n": 1000,
 "complete": true,
 "incumbent": {
  "mean": 99.0554,
  "retail_mean": 125.0629,
  "arb_mean": -26.0075,
  "se": 5.416
 },
 "findings_note": "Every edge figure is a per-simulation mean over all 1000 simulations, i.e. that class's contribution to B's overall mean; a simulation outside the class counts as 0. For spread rows, 'count' is the number of simulations with that spread. For p rows, 'count' is the number of simulations with any fill in that bucket. Bucket p is the true probability after the step's process move, which is the probability the simulator scores fills at. 'mean'/'retail'/'arb' are B's edge; competitor_* is the competitor's maker edge from retail and arb takers. B_share_retail_notional = B's retail fill notional / all retail fill notional. Observed but not explained here: p<0.1 gives B 92.6 retail per simulation against 3.4 for p>0.9. This is plausibly because retail buy notional at a low price buys many shares, so it is structural to the simulator and not a gap in B, but this was not tested.",
 "findings": [
  {
   "name": "all",
   "count": 1000,
   "mean": 99.0554,
   "retail": 125.0629,
   "arb": -26.0075,
   "se": 5.416,
   "retail_se": 5.6296,
   "B_share_retail_notional": 0.3728,
   "retail_notional_per_sim": 2063.2163,
   "competitor_retail_edge": 70.2479,
   "competitor_retail_edge_se": 2.0522,
   "competitor_arb_edge": -825.4649
  },
  {
   "name": "p_0.0-0.1",
   "count": 570,
   "mean": 79.2694,
   "retail": 92.6026,
   "arb": -13.3332,
   "se": 4.8808,
   "retail_se": 5.3793,
   "B_share_retail_notional": 0.6322,
   "retail_notional_per_sim": 244.7584,
   "competitor_retail_edge": 25.2576,
   "competitor_retail_edge_se": 1.5047,
   "competitor_arb_edge": -125.6774
  },
  {
   "name": "p_0.1-0.2",
   "count": 608,
   "mean": 5.3704,
   "retail": 8.188,
   "arb": -2.8176,
   "se": 0.6061,
   "retail_se": 0.5335,
   "B_share_retail_notional": 0.3227,
   "retail_notional_per_sim": 175.4108,
   "competitor_retail_edge": 11.0819,
   "competitor_retail_edge_se": 0.5924,
   "competitor_arb_edge": -116.4412
  },
  {
   "name": "p_0.2-0.3",
   "count": 694,
   "mean": 3.8354,
   "retail": 5.2658,
   "arb": -1.4305,
   "se": 0.2961,
   "retail_se": 0.3075,
   "B_share_retail_notional": 0.289,
   "retail_notional_per_sim": 194.8572,
   "competitor_retail_edge": 8.1747,
   "competitor_retail_edge_se": 0.4038,
   "competitor_arb_edge": -107.9715
  },
  {
   "name": "p_0.3-0.4",
   "count": 762,
   "mean": 3.1214,
   "retail": 4.3086,
   "arb": -1.1872,
   "se": 0.2286,
   "retail_se": 0.2337,
   "B_share_retail_notional": 0.284,
   "retail_notional_per_sim": 216.8223,
   "competitor_retail_edge": 6.7017,
   "competitor_retail_edge_se": 0.2843,
   "competitor_arb_edge": -100.3321
  },
  {
   "name": "p_0.4-0.5",
   "count": 795,
   "mean": 2.4044,
   "retail": 3.4388,
   "arb": -1.0344,
   "se": 0.1681,
   "retail_se": 0.1757,
   "B_share_retail_notional": 0.2762,
   "retail_notional_per_sim": 223.6676,
   "competitor_retail_edge": 5.6251,
   "competitor_retail_edge_se": 0.2207,
   "competitor_arb_edge": -86.0434
  },
  {
   "name": "p_0.5-0.6",
   "count": 788,
   "mean": 0.7915,
   "retail": 2.6962,
   "arb": -1.9047,
   "se": 0.8624,
   "retail_se": 0.1517,
   "B_share_retail_notional": 0.2807,
   "retail_notional_per_sim": 210.3091,
   "competitor_retail_edge": 4.2128,
   "competitor_retail_edge_se": 0.1756,
   "competitor_arb_edge": -85.7732
  },
  {
   "name": "p_0.6-0.7",
   "count": 737,
   "mean": 1.3176,
   "retail": 2.0113,
   "arb": -0.6937,
   "se": 0.1411,
   "retail_se": 0.1165,
   "B_share_retail_notional": 0.2806,
   "retail_notional_per_sim": 186.0767,
   "competitor_retail_edge": 3.2435,
   "competitor_retail_edge_se": 0.1654,
   "competitor_arb_edge": -57.9953
  },
  {
   "name": "p_0.7-0.8",
   "count": 665,
   "mean": -0.0205,
   "retail": 1.7696,
   "arb": -1.7901,
   "se": 1.2777,
   "retail_se": 0.1064,
   "B_share_retail_notional": 0.3039,
   "retail_notional_per_sim": 178.109,
   "competitor_retail_edge": 2.4717,
   "competitor_retail_edge_se": 0.1405,
   "competitor_arb_edge": -55.4832
  },
  {
   "name": "p_0.8-0.9",
   "count": 574,
   "mean": 0.9826,
   "retail": 1.3816,
   "arb": -0.399,
   "se": 0.0856,
   "retail_se": 0.0955,
   "B_share_retail_notional": 0.3366,
   "retail_notional_per_sim": 156.8866,
   "competitor_retail_edge": 1.7013,
   "competitor_retail_edge_se": 0.0971,
   "competitor_arb_edge": -32.7938
  },
  {
   "name": "p_0.9-1.0",
   "count": 538,
   "mean": 1.9833,
   "retail": 3.4003,
   "arb": -1.417,
   "se": 0.7673,
   "retail_se": 0.2062,
   "B_share_retail_notional": 0.5794,
   "retail_notional_per_sim": 276.3187,
   "competitor_retail_edge": 1.7774,
   "competitor_retail_edge_se": 0.1045,
   "competitor_arb_edge": -56.9538
  },
  {
   "name": "spread_1",
   "count": 251,
   "mean": 11.2831,
   "retail": 17.4577,
   "arb": -6.1746,
   "se": 1.8325,
   "retail_se": 2.3387,
   "B_share_retail_notional": 0.1016,
   "retail_notional_per_sim": 523.6145,
   "competitor_retail_edge": 24.8378,
   "competitor_retail_edge_se": 1.9446,
   "competitor_arb_edge": -253.7396
  },
  {
   "name": "spread_2",
   "count": 232,
   "mean": 14.8175,
   "retail": 20.598,
   "arb": -5.7805,
   "se": 2.365,
   "retail_se": 2.4106,
   "B_share_retail_notional": 0.3259,
   "retail_notional_per_sim": 490.131,
   "competitor_retail_edge": 16.464,
   "competitor_retail_edge_se": 1.2665,
   "competitor_arb_edge": -214.9347
  },
  {
   "name": "spread_3",
   "count": 273,
   "mean": 32.486,
   "retail": 39.2554,
   "arb": -6.7694,
   "se": 3.3401,
   "retail_se": 3.67,
   "B_share_retail_notional": 0.4853,
   "retail_notional_per_sim": 548.9263,
   "competitor_retail_edge": 16.157,
   "competitor_retail_edge_se": 1.2132,
   "competitor_arb_edge": -183.3517
  },
  {
   "name": "spread_4",
   "count": 244,
   "mean": 40.4689,
   "retail": 47.7518,
   "arb": -7.2829,
   "se": 4.0005,
   "retail_se": 4.2479,
   "B_share_retail_notional": 0.5792,
   "retail_notional_per_sim": 500.5444,
   "competitor_retail_edge": 12.7891,
   "competitor_retail_edge_se": 0.99,
   "competitor_arb_edge": -173.439
  },
  {
   "name": "spread_1_tails<0.2",
   "count": 160,
   "mean": 11.3347,
   "retail": 17.2721,
   "arb": -5.9374,
   "se": 1.8314,
   "retail_se": 2.3391,
   "B_share_retail_notional": 0.2728,
   "retail_notional_per_sim": 112.7542,
   "competitor_retail_edge": 14.5699,
   "competitor_retail_edge_se": 1.5602,
   "competitor_arb_edge": -71.5979
  },
  {
   "name": "spread_1_mid0.2-0.8",
   "count": 251,
   "mean": -0.1598,
   "retail": 0.0158,
   "arb": -0.1757,
   "se": 0.0874,
   "retail_se": 0.0019,
   "B_share_retail_notional": 0.0021,
   "retail_notional_per_sim": 302.8249,
   "competitor_retail_edge": 9.1117,
   "competitor_retail_edge_se": 0.6716,
   "competitor_arb_edge": -161.7556
  },
  {
   "name": "spread_1_tails>0.8",
   "count": 149,
   "mean": 0.1083,
   "retail": 0.1698,
   "arb": -0.0615,
   "se": 0.0169,
   "retail_se": 0.0222,
   "B_share_retail_notional": 0.2019,
   "retail_notional_per_sim": 108.0355,
   "competitor_retail_edge": 1.1562,
   "competitor_retail_edge_se": 0.1237,
   "competitor_arb_edge": -20.386
  },
  {
   "name": "spread_2_tails<0.2",
   "count": 143,
   "mean": 13.9263,
   "retail": 17.0763,
   "arb": -3.1501,
   "se": 1.9802,
   "retail_se": 2.3413,
   "B_share_retail_notional": 0.4552,
   "retail_notional_per_sim": 90.3382,
   "competitor_retail_edge": 7.4713,
   "competitor_retail_edge_se": 0.8224,
   "competitor_arb_edge": -60.5949
  },
  {
   "name": "spread_2_mid0.2-0.8",
   "count": 232,
   "mean": 0.1354,
   "retail": 2.5912,
   "arb": -2.4558,
   "se": 1.2722,
   "retail_se": 0.179,
   "B_share_retail_notional": 0.2154,
   "retail_notional_per_sim": 288.7729,
   "competitor_retail_edge": 8.1272,
   "competitor_retail_edge_se": 0.6252,
   "competitor_arb_edge": -127.6136
  },
  {
   "name": "spread_2_tails>0.8",
   "count": 143,
   "mean": 0.7557,
   "retail": 0.9304,
   "arb": -0.1747,
   "se": 0.0874,
   "retail_se": 0.1025,
   "B_share_retail_notional": 0.5081,
   "retail_notional_per_sim": 111.0198,
   "competitor_retail_edge": 0.8654,
   "competitor_retail_edge_se": 0.0917,
   "competitor_arb_edge": -26.7262
  },
  {
   "name": "spread_3_tails<0.2",
   "count": 165,
   "mean": 26.8206,
   "retail": 30.6102,
   "arb": -3.7896,
   "se": 3.1603,
   "retail_se": 3.4916,
   "B_share_retail_notional": 0.6059,
   "retail_notional_per_sim": 110.8258,
   "competitor_retail_edge": 7.9145,
   "competitor_retail_edge_se": 0.8619,
   "competitor_arb_edge": -53.6661
  },
  {
   "name": "spread_3_mid0.2-0.8",
   "count": 273,
   "mean": 4.8206,
   "retail": 7.0403,
   "arb": -2.2197,
   "se": 0.3605,
   "retail_se": 0.4482,
   "B_share_retail_notional": 0.4035,
   "retail_notional_per_sim": 328.5864,
   "competitor_retail_edge": 7.4981,
   "competitor_retail_edge_se": 0.543,
   "competitor_arb_edge": -106.6129
  },
  {
   "name": "spread_3_tails>0.8",
   "count": 160,
   "mean": 0.8448,
   "retail": 1.605,
   "arb": -0.7602,
   "se": 0.5161,
   "retail_se": 0.1575,
   "B_share_retail_notional": 0.6088,
   "retail_notional_per_sim": 109.5142,
   "competitor_retail_edge": 0.7444,
   "competitor_retail_edge_se": 0.0786,
   "competitor_arb_edge": -23.0727
  },
  {
   "name": "spread_4_tails<0.2",
   "count": 155,
   "mean": 32.5583,
   "retail": 35.832,
   "arb": -3.2737,
   "se": 3.678,
   "retail_se": 3.942,
   "B_share_retail_notional": 0.6805,
   "retail_notional_per_sim": 106.251,
   "competitor_retail_edge": 6.3838,
   "competitor_retail_edge_se": 0.7036,
   "competitor_arb_edge": -56.2597
  },
  {
   "name": "spread_4_mid0.2-0.8",
   "count": 244,
   "mean": 6.6534,
   "retail": 9.843,
   "arb": -3.1895,
   "se": 1.0055,
   "retail_se": 0.6623,
   "B_share_retail_notional": 0.5164,
   "retail_notional_per_sim": 289.6576,
   "competitor_retail_edge": 5.6927,
   "competitor_retail_edge_se": 0.4324,
   "competitor_arb_edge": -97.6166
  },
  {
   "name": "spread_4_tails>0.8",
   "count": 144,
   "mean": 1.2571,
   "retail": 2.0768,
   "arb": -0.8197,
   "se": 0.5848,
   "retail_se": 0.2193,
   "B_share_retail_notional": 0.65,
   "retail_notional_per_sim": 104.6358,
   "competitor_retail_edge": 0.7127,
   "competitor_retail_edge_se": 0.0821,
   "competitor_arb_edge": -19.5627
  },
  {
   "name": "retail_orders_by_filler",
   "count": 511176,
   "per_sim": {
    "B_only": 201.521,
    "split": 129.939,
    "C_only": 145.611,
    "none": 34.105
   },
   "share": {
    "B_only": 0.3942,
    "split": 0.2542,
    "C_only": 0.2849,
    "none": 0.0667
   }
  }
 ],
 "paired": null,
 "failures": 0,
 "seconds_per_simulation": 0.786
}