{"key":"t-b","approach":"New-incumbent code-free reference calibration, block t-b: measure immutable wave-3 combine-cash C against current incumbent B; no tuning or strategy changes.","tried":[{"code_sha256":"baef955ec10728839f7c3357016ec9eb0550e7ec689bbd5171b1cdd5c9e37273","against_code_sha256":"bf0d179f3e47d28819f6fa7e0d25548c2ced43374c216d36460b00a26a26ffae","seed_start":310500,"seed_end":310999,"n":500,"mean_diff":-1.4464272378175995,"se":1.2285534217821523,"complete":true}],"next":"Pool this fixed reference block with the other assigned calibration blocks. B remains the incumbent; this item makes no promotion decision and ran no finalist seeds.","code":"\"\"\"Stale-quote defence with tick probes, a sub-tick belief and cheap YES stock.\n\nEvery step the arbitrageur removes any order on the wrong side of p, so tiny\ntwo-sided probes around the estimate locate p to a tick; a grid filter narrows\nthat further.  Quotes sit one tick inside the competitor and are sized by the\nmarginal rule: one more share is worth quoting while the chance a retail order\nreaches it, times its edge, exceeds the expected arbitrage loss.  Near p=0 a\nretail buy pays almost its whole notional as edge, so YES is held to cover low\nasks.  That YES is bought when it is cheap: a large bid rests at tick 1 while p\nis above it, so the arbitrageur fills it on the crossing for about 0.1 tick a\nshare instead of nearly a full tick once p is near zero, and smaller bids sit on\nwhichever tick p is within 0.15 of.  Below tick 1 the estimate of p decays with\nthe time spent there, since no probe can see it.\n\"\"\"\nimport math\nfrom orderbook_pm_challenge.strategy import BaseStrategy\nfrom orderbook_pm_challenge.types import CancelOrder, PlaceOrder, Side\n\nP = dict(lam_r=0.25, m=5.0, sig_n=1.2, lam_j=0.0019, sig_j=0.35, sig=0.02,\n         qmax=3000.0, rmin=2, kA=0.7, kL=0.15, pL=0.05,\n         ammo=1.0, ydem=0.4, W=200.0, fy=0.6, ammo_q=60.0, ammo_pmax=0.05, ammo_maxpay=0.02,\n         fb=0.9, fu=0.7, xu=0.1, sticky=1.0, min_ahead=2.0, keep_hi=1.5, keep_lo=0.7, Hu=300.0, bins=8.0, filt=1.0, uni=0.01, jumpinfo=1.0, dmin=0.0, kLb=0.08, kLf=0.08, pinf=1.0, pre=0.0, H1=100.0,\n         ydf=0.6, Wf=2000.0, g_hi=0.15, g_lo=0.15, qf=400.0, pmaxf=0.05, pre_gap=1.0,\n         ydf1=0.6, g1=5.0, f1=0.6, a1=100.0, nb1=0.0, gs=1.0, p1t=1.0, m1=1.0, zd=1.0, pfl=0.0005)\nP.update({'W': 50, 'ammo_pmax': 0.02, 'fy': 0.7, 'fu': 0.25, 'Hu': 500})\nC = {'W': 50, 'ammo_pmax': 0.02, 'fy': 0.7, 'reserve': 200, 'scar': 0.0025, 'fu': 0.25, 'Hu': 500}\nSQ2 = math.sqrt(2.0)\nSQ2PI = math.sqrt(2.0 * math.pi)\ndef cdf(x): return 0.5 * (1.0 + math.erf(x / SQ2))\ndef pdf(x): return math.exp(-0.5 * x * x) / SQ2PI\ndef inv(p):\n    p = min(max(p, 1e-9), 1 - 1e-9)\n    t = math.sqrt(-2.0 * math.log(min(p, 1 - p)))\n    x = t - (2.515517 + 0.802853 * t + 0.010328 * t * t) / (1 + 1.432788 * t + 0.189269 * t * t + 0.001308 * t ** 3)\n    x = -x if p < 0.5 else x\n    for _ in range(2):\n        d = pdf(x)\n        if d < 1e-12:\n            break\n        x -= (cdf(x) - p) / d\n    return x\ndef lpm(k):\n    return pdf(k) + k * cdf(k)\ndef fl(q):\n    return math.floor(q * 100 + 1e-9) / 100\n\nNODES = [(-2.2, .06), (-1.3, .17), (-0.6, .27), (0.6, .27), (1.3, .17), (2.2, .06)]\nPROBE = 0.01\n\n\nclass Strategy(BaseStrategy):\n    def __init__(self):\n        self.n = 0\n        self.ahead = set()     # main orders placed strictly ahead of any competitor order at their tick\n        self.res = {}          # order id -> uncovered quantity at placement\n        self.bc = None         # belief: sub-tick grid centres (ticks)\n        self.bw = None         # belief: weights\n        self.st = 0.5          # last one-step sd in ticks\n        self.pcb = self.pca = None\n        self.pb = set()\n        self.pa = set()\n        self.tb = 0\n        self.s = None          # competitor spread parameter\n\n    def _oid(self, tag):\n        self.n += 1\n        return tag + str(self.n)\n\n    def on_step(self, state):\n        H = max(1, state.steps_remaining)\n        cb = state.competitor_best_bid_ticks or 0\n        ca = state.competitor_best_ask_ticks or 100\n        if self.s is None:\n            self.s = max(1, (ca - cb + 1) // 2)\n        lo, hi = cb, ca\n        for o in state.own_orders:\n            if o.side is Side.BUY:\n                lo = max(lo, o.price_ticks)\n            else:\n                hi = min(hi, o.price_ticks)\n        if P['pinf'] > 0:\n            sb = {o.price_ticks for o in state.own_orders if o.side is Side.BUY and o.remaining_quantity <= PROBE + 1e-9}\n            sa = {o.price_ticks for o in state.own_orders if o.side is Side.SELL and o.remaining_quantity <= PROBE + 1e-9}\n            ea = self.pa - sa\n            eb = self.pb - sb\n            if sa and ea:\n                lo = max(lo, min(max(ea), hi))\n            if eb and (sb or min(eb) <= P['p1t']):\n                hi = min(hi, max(min(eb), lo))\n        if P['jumpinfo'] > 0 and self.pcb is not None:\n            if ca > self.pca + 1:\n                lo = max(lo, ca - 1)\n            if cb < self.pcb - 1:\n                hi = min(hi, cb + 1)\n        self.pcb, self.pca = cb, ca\n        if lo > hi:\n            lo, hi = hi, lo\n        # sub-tick belief over p_(t-1): predict with one-step noise, truncate to [lo, hi]\n        wid = max(hi - lo, 1e-6)\n        nb = max(2, min(48, int(round(wid * P['bins']))))\n        cs = [lo + (i + 0.5) * wid / nb for i in range(nb)]\n        if self.bc is None or P['filt'] <= 0:\n            ws = [1.0 / nb] * nb\n        else:\n            sg = max(self.st, 0.6 * wid / nb)\n            k = -0.5 / (sg * sg)\n            ws = []\n            uni = P['uni'] * sg\n            for c in cs:\n                t = uni\n                for ci, wi in zip(self.bc, self.bw):\n                    d = c - ci\n                    d2 = d * d * k\n                    if d2 > -12.5:\n                        t += wi * math.exp(d2)\n                ws.append(t)\n            tot = sum(ws)\n            ws = [w / tot for w in ws]\n        self.bc, self.bw = cs, ws\n        mean_t = sum(c * w for c, w in zip(cs, ws))\n        var_t = max(sum(c * c * w for c, w in zip(cs, ws)) - mean_t * mean_t, 0.0)\n        phat = min(max(mean_t / 100.0, 0.002), 0.998)\n        var = P['sig'] ** 2 + P['lam_j'] * P['sig_j'] ** 2\n        sd = math.sqrt(H * var)\n        self.tb = self.tb + 1 if hi <= 1 else 0\n        if self.tb > 0 and P['zd'] > 0:\n            # below the last tick there is no probe: the score keeps walking away from it\n            phat = min(phat, max(P['pfl'], cdf(inv(0.01) - P['zd'] * 0.02 * math.sqrt(self.tb) / sd)))\n        z = inv(phat)\n        Z = z * sd\n        sp = pdf(z) / sd * P['sig']\n        self.st = sp * 100.0\n        s = math.sqrt(sp * sp + var_t / 1e4 + 1e-8)\n        sd1 = math.sqrt(max(1.0, H - 1.0) * var)\n        jp = [(cdf((Z + n * P['sig_j']) / sd1), w) for n, w in NODES]\n        lj = P['lam_j']\n\n        def AB(x):\n            k = (x - phat) / s\n            a = s * lpm(k)\n            b = a - (x - phat)\n            ja = sum(w * max(0.0, x - p) for p, w in jp)\n            jb = sum(w * max(0.0, p - x) for p, w in jp)\n            return (1 - lj) * a + lj * ja, (1 - lj) * b + lj * jb\n\n        if H == 1:\n            def AB(x):\n                return (1 - phat) * x, phat * (1 - x)\n        rho = P['lam_r'] * 0.5\n        mu = math.log(P['m']) - 0.5 * P['sig_n'] ** 2\n        kA = P['kL'] if phat < P['pL'] else P['kA']\n\n        def qsize(loss, gain, px):\n            loss *= kA\n            if gain <= 0:\n                return 0.0\n            tail = loss / (rho * gain)\n            if tail >= 1.0:\n                return 0.0\n            return min(P['qmax'], math.exp(mu + P['sig_n'] * inv(1 - max(tail, 1e-6))) / px)\n\n        ptk = phat * 100\n        def qbid(t):\n            if not 1 <= t <= 99:\n                return 0.0\n            a, b = AB(t / 100.0)\n            if phat * 100 - t < P['dmin']:\n                return 0.0\n            if P['nb1'] > 0 and self.s == 1 and t == 1 and ptk < 1.0:\n                return 0.0\n            if phat < P['pL']:\n                ytg = P['ydem'] * min(H, P['W']) / max(ca - 1, ptk + 1) * 100.0\n                a *= (P['kLb'] if state.yes_inventory < ytg else P['kLf']) / P['kL']\n            return qsize(a, b, max(phat, 0.05))\n\n        def qask(t):\n            if not 1 <= t <= 99:\n                return 0.0\n            a, b = AB(t / 100.0)\n            if t - phat * 100 < P['dmin']:\n                return 0.0\n            if phat < C.get('scar_p', .1):\n                a = max(0.0, a - C.get('scar', 0.0) * (1 - min(1.0, state.yes_inventory / C.get('stock', 3000.0))))\n            return min(C.get('askcap', P['qmax']), qsize(b, a, t / 100.0))\n\n        bids = [o for o in state.own_orders if o.side is Side.BUY and o.remaining_quantity > PROBE + 1e-9]\n        asks = [o for o in state.own_orders if o.side is Side.SELL and o.remaining_quantity > PROBE + 1e-9]\n        sticky = P['sticky'] > 0\n        def top(orders, comp, step):\n            if sticky and sum(o.remaining_quantity for o in orders if o.price_ticks == comp and o.order_id in self.ahead) >= P['min_ahead']:\n                return comp\n            return comp + step\n        bid_t = top(bids, cb, 1)\n        ask_t = top(asks, ca, -1)\n        qb = min(C.get('bidcap', 3000.0), qbid(bid_t))\n        qa = qask(ask_t)\n\n        Y = state.yes_inventory\n        if ask_t == 1 and H > P['H1'] and P['pre'] > 0:\n            qa = qa if Y >= P['a1'] > 0 else 0.0          # let the competitor's 2-tick ask erode instead of fronting it for nothing\n        # ammunition: hold YES so that low asks are covered\n        ptick = phat * 100\n        amt = 0\n        qam = 0.0\n        if P['ammo'] > 0 and ask_t >= 2 and phat < max(P['ammo_pmax'], P['pmaxf']):\n            wealth = state.cash + Y * phat\n            x = max(ask_t, ptick + 1) / 100.0\n            capw = P['fy'] * wealth / max(phat, 0.005)\n            target = min(P['ydem'] * min(H, P['W']) / x, capw)\n            full = min(P['ydf'] * min(H, P['Wf']) / x, capw) if phat < P['pmaxf'] else 0.0\n            t = max(1, min(99, int(math.ceil(ptick + 1e-9))))\n            g = t - ptick\n            if Y < full and g <= P['g_hi'] and bid_t <= t < ask_t:\n                amt, qam = t, min(P['qf'], full - Y)     # a tick p has just crossed: nearly free\n            elif Y < target and phat < P['ammo_pmax'] and bid_t <= t < ask_t and t / 100.0 - phat < P['ammo_maxpay']:\n                amt, qam = t, min(P['ammo_q'], target - Y)\n            elif Y < full and t >= 2 and 1.0 - g <= P['g_lo']:\n                amt, qam = t - 1, min(P['qf'], full - Y)  # rest just under p: filled only on the crossing, or by retail\n\n        if P['pre'] > 0 and ca == 2 and phat < 0.01 and H > P['H1'] and Y < P['pre'] and not qam and 1.0 - ptick < P['pre_gap']:\n            amt, qam = 1, min(P['ammo_q'], P['pre'] - Y)\n        q1 = 0.0\n        if P['ydf1'] > 0 and P['m1'] < ptick < P['g1'] + 1.0 and amt != 1:\n            q1 = max(0.0, P['ydf1'] * min(H, P['Wf']) / (self.s / 100.0) - Y)\n        # order management\n        actions = []\n        free = state.free_cash - 2.0\n        keep_ask = 0.0\n        new_b = []\n        new_a = []\n        def cancel(o):\n            nonlocal free\n            actions.append(CancelOrder(o.order_id))\n            x = o.price_ticks / 100.0\n            if o.side is Side.BUY:\n                free += x * o.remaining_quantity\n            else:\n                free += (1 - x) * min(self.res.get(o.order_id, 0.0), o.remaining_quantity)\n            self.ahead.discard(o.order_id)\n            self.res.pop(o.order_id, None)\n        for o in state.own_orders:\n            if o.remaining_quantity <= PROBE + 1e-9:\n                cancel(o)\n        kept_ids = set()\n        def manage(orders, t, q, comp):\n            kept = 0.0\n            for o in orders:\n                if not (C.get('recover', 0) and o.side is Side.SELL and t < comp and self.res.get(o.order_id, 0.0) > 1 and state.yes_inventory > C.get('recover_yes', 1) and state.free_cash < C.get('recover_cash', 200)) and o.price_ticks == t and q > 0 and kept + o.remaining_quantity <= max(q * P['keep_hi'], 1.0):\n                    kept += o.remaining_quantity\n                    kept_ids.add(o.order_id)\n                else:\n                    cancel(o)\n            return kept\n        kb = manage(bids, bid_t, qb, cb)\n        ka = manage(asks, ask_t, qa, ca)\n        add_b = (qb - kb) if (kb < qb * P['keep_lo'] and bid_t != cb) else 0.0\n        add_a = (qa - ka) if (ka < qa * P['keep_lo'] and ask_t != ca) else 0.0\n\n        budget = P['fb'] * max(free, 0.0)\n        cost = add_b * bid_t / 100.0 + qam * amt / 100.0\n        if cost > budget:\n            f = budget / cost\n            add_b *= f\n            qam *= f\n            cost = budget\n        out = []\n        q1 = min(q1, P['f1'] * max(budget - cost, 0.0) * 100.0)\n        if q1 >= 0.01:\n            out.append(PlaceOrder(side=Side.BUY, price_ticks=1, quantity=fl(q1)))\n            free -= fl(q1) / 100.0 + 1e-6\n        if amt and qam >= 0.01:\n            q = fl(qam)\n            out.append(PlaceOrder(side=Side.BUY, price_ticks=amt, quantity=q))\n            free -= q * amt / 100.0 + 1e-6\n        if bid_t >= 1 and add_b >= 0.01:\n            q = fl(add_b)\n            oid = self._oid('b')\n            out.append(PlaceOrder(side=Side.BUY, price_ticks=bid_t, quantity=q, client_order_id=oid))\n            free -= q * bid_t / 100.0 + 1e-6\n            if bid_t > cb:\n                self.ahead.add(oid)\n        if ask_t <= 99 and add_a >= 0.01:\n            x = ask_t / 100.0\n            covk = sum(o.remaining_quantity - min(self.res.get(o.order_id, 0.0), o.remaining_quantity)\n                       for o in asks if o.order_id in kept_ids)\n            cov = max(0.0, Y - covk - 0.1)\n            unc = max(0.0, add_a - cov)\n            if unc > 0:\n                ub = max(0.0, free - (1 - P['fu']) * max(state.cash, 0.0)) if x >= P['xu'] else 0.0\n                if H < P['Hu'] and phat < 0.05:\n                    ub = max(0.0, free * (1 - H / P['Hu']))\n                ub = min(ub, max(0.0, free - C.get('reserve', 0.0) * min(1.0, H / C.get('release', 50.0))))\n                unc = min(unc, ub / (1 - x))\n            q = fl(min(add_a, cov + unc))\n            if q >= 0.01:\n                oid = self._oid('a')\n                out.append(PlaceOrder(side=Side.SELL, price_ticks=ask_t, quantity=q, client_order_id=oid))\n                r = max(0.0, q - cov)\n                self.res[oid] = r\n                free -= r * (1 - x) + 1e-6\n                if ask_t < ca:\n                    self.ahead.add(oid)\n\n        # probes: tiny orders that the arbitrageur removes when p crosses them\n        f = int(math.floor(ptick + 1e-9))\n        r = max(int(P['rmin']), int(math.ceil(2.0 * s * 100)))\n        self.pb = set()\n        self.pa = set()\n        if free > 1.0:\n            for t in range(f, f + r + 1):\n                if cb < t < ca and 1 <= t <= 99:\n                    out.append(PlaceOrder(side=Side.BUY, price_ticks=t, quantity=PROBE))\n                    self.pb.add(t)\n            for t in range(f + 1 - r, f + 2):\n                if cb < t < ca and 1 <= t <= 99:\n                    out.append(PlaceOrder(side=Side.SELL, price_ticks=t, quantity=PROBE))\n                    self.pa.add(t)\n        return actions + out\n","code_sha256":"baef955ec10728839f7c3357016ec9eb0550e7ec689bbd5171b1cdd5c9e37273","incumbent_code_sha256":"bf0d179f3e47d28819f6fa7e0d25548c2ced43374c216d36460b00a26a26ffae","tuning":null,"paired":{"seeds":{"start":310500,"end":310999,"inclusive":true,"requested_count":500},"role":"fixed measurement holdout; no tuning","complete":true,"n":500,"sum_d":-723.2136189087997,"sum_d2":377627.2816652228,"mean_diff":-1.4464272378175995,"se":1.2285534217821523,"C_mean_edges":{"total_edge":96.8094928153738,"retail_edge":123.6577727783004,"arb_edge":-26.8482799628906},"B_mean_edges":{"total_edge":98.25592005319139,"retail_edge":125.35116413313479,"arb_edge":-27.0952440798986},"retail_diff":-1.6933913548344,"arb_diff":0.24696411700800008,"by_spread":{"1":{"n":132,"sum_d":-96.29739127089987,"sum_d2":248535.375956242,"mean_diff":-0.7295256914462112,"se":3.7906187429327565,"C_mean_edges":{"total_edge":42.72185736566515,"retail_edge":69.77895613598561,"arb_edge":-27.057098770279545},"B_mean_edges":{"total_edge":43.451383057111364,"retail_edge":70.84730683689621,"arb_edge":-27.39592377974015},"retail_diff":-1.068350700910606,"arb_diff":0.33882500946060573},"2":{"n":133,"sum_d":-10.336678192699903,"sum_d2":74386.4428577165,"mean_diff":-0.07771938490751806,"se":2.0584094376873807,"C_mean_edges":{"total_edge":81.87190021455413,"retail_edge":109.43291100442632,"arb_edge":-27.56101078987143},"B_mean_edges":{"total_edge":81.94961959946166,"retail_edge":112.59168834321203,"arb_edge":-30.642068743748872},"retail_diff":-3.1587773387857125,"arb_diff":3.081057953877444},"3":{"n":114,"sum_d":-278.332535011,"sum_d2":22852.89143810857,"mean_diff":-2.441513465008772,"se":1.3119699839526917,"C_mean_edges":{"total_edge":125.70656400476754,"retail_edge":148.28022579721753,"arb_edge":-22.573661792403506},"B_mean_edges":{"total_edge":128.1480774697763,"retail_edge":150.90874266292894,"arb_edge":-22.760665193082456},"retail_diff":-2.628516865711405,"arb_diff":0.18700340067894766},"4":{"n":121,"sum_d":-338.24701443419997,"sum_d2":31852.57141315573,"mean_diff":-2.7954298713570247,"se":1.458966425472119,"C_mean_edges":{"total_edge":145.0078529780157,"retail_edge":174.8722419399058,"arb_edge":-29.864388961830578},"B_mean_edges":{"total_edge":147.80328284937272,"retail_edge":174.75575496591736,"arb_edge":-26.95247211647603},"retail_diff":0.11648697398843008,"arb_diff":-2.9119168453545456}}},"failures":[],"failed_seeds":[],"missing_seeds":[],"exceptions":[],"failed_flags":{"C":{"false":500,"true":0,"no_return":0},"B":{"false":500,"true":0,"no_return":0}},"seconds_per_simulation":0.6300653642846737,"timing":{"simulation_wall_seconds":630.3042530319653,"limit_seconds":2700,"stopped_at_limit":false,"attempted_simulations":1000,"first_10_pairs":[{"seed":310500,"C_seconds":0.5018516979180276,"B_seconds":0.5702726480085403,"pair_seconds":1.0724422722123563},{"seed":310501,"C_seconds":0.6924084899947047,"B_seconds":0.7032172041945159,"pair_seconds":1.395916567184031},{"seed":310502,"C_seconds":0.5201057828962803,"B_seconds":0.5369255288969725,"pair_seconds":1.0573028810322285},{"seed":310503,"C_seconds":0.729125615209341,"B_seconds":0.7293347150553018,"pair_seconds":1.458791672019288},{"seed":310504,"C_seconds":0.7365090171806514,"B_seconds":0.7819279979448766,"pair_seconds":1.5187124400399625},{"seed":310505,"C_seconds":0.49734373297542334,"B_seconds":0.5693175680935383,"pair_seconds":1.066972522996366},{"seed":310506,"C_seconds":0.499053553910926,"B_seconds":0.5437581210862845,"pair_seconds":1.0430692660156637},{"seed":310507,"C_seconds":0.6200995370745659,"B_seconds":0.7520626720506698,"pair_seconds":1.3724376729223877},{"seed":310508,"C_seconds":0.7426972899120301,"B_seconds":0.7433392838574946,"pair_seconds":1.4863555929623544},{"seed":310509,"C_seconds":0.7642088069114834,"B_seconds":0.8003126119729131,"pair_seconds":1.5647907031234354}],"first_10_pair_seconds":13.036791590508074,"first_10_seconds_per_simulation":0.6518395795254037,"timing_pairs_retained_once":true,"definition":"seconds_per_simulation is the mean measured duration of each fresh load, factory construction, engine run and result validation; pair timing also includes config sampling and journal writes."},"simulator_commit":"b244530ee2a6247b5f930830eeca9dd950da0e7e","fixture":{"codec":"base64(zlib(UTF-8 JSON))","row_count":500,"seed_start":310500,"seed_end":310999,"schema":["seed","s","total_edge","retail_edge","arb_edge"],"uncompressed_sha256":"85f33d44f17e44d46b9dbc56faabdd9137639827777833709ac6cfdde4b334de","code_sha256":"bf0d179f3e47d28819f6fa7e0d25548c2ced43374c216d36460b00a26a26ffae","payload":"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"},"validation":{"simulation_processes":1,"simulation_concurrency":1,"steps_per_simulation":2000,"verified_simulator_git_blobs_before":25,"verified_simulator_git_blobs_after":25,"strategy_hashes_checked_before_and_after_every_simulation":true,"same_config_object_per_pair":true,"fresh_module_factory_and_instance_per_simulation":true,"strategy_imports":["math","orderbook_pm_challenge.strategy","orderbook_pm_challenge.types"],"strategy_inputs":"Unmodified StepState only; no seed, sampled config, latent probability or result data supplied to either strategy.","all_returned_seeds_flags_and_finite_edges_checked":true,"first_observed_spread_checked_against_sampled_and_returned_regime":true,"unique_seed_strategy_pairs":1000,"finalist_seeds_run":0,"fixture_decoded_rows_checked":500,"fixture_float_roundtrip":"bit-exact Python float.hex comparison","paired_se_crosschecked_from_sufficient_statistics":true,"measurement_journal_sha256":"22283ed09e04c8eb2fcc6c26f257093ee470864020bab799821a734f9f2abae3"},"reproduction":{"python_version":"3.13.5","candidate_url":"https://api.imd.fun/artifacts/ecbc9087b4f238fc1b5b0d52f55af073f676c038bfb6756172b1e51480ac1741","incumbent_url":"https://api.imd.fun/artifacts/db22aff7167a4798251ed3d20432509f30e511e4958799aba5b17b41bb39b4b6","simulator_archive_url":"https://codeload.github.com/danrobinson/prediction-market-challenge/tar.gz/b244530ee2a6247b5f930830eeca9dd950da0e7e","configuration_source":"https://raw.githubusercontent.com/danrobinson/prediction-market-challenge/b244530ee2a6247b5f930830eeca9dd950da0e7e/orderbook_pm_challenge/config.py","sampling_source":"https://raw.githubusercontent.com/danrobinson/prediction-market-challenge/b244530ee2a6247b5f930830eeca9dd950da0e7e/orderbook_pm_challenge/runner.py","engine_source":"https://raw.githubusercontent.com/danrobinson/prediction-market-challenge/b244530ee2a6247b5f930830eeca9dd950da0e7e/orderbook_pm_challenge/engine.py","factory_source":"https://raw.githubusercontent.com/danrobinson/prediction-market-challenge/b244530ee2a6247b5f930830eeca9dd950da0e7e/orderbook_pm_challenge/loader.py","spread_source":"https://raw.githubusercontent.com/danrobinson/prediction-market-challenge/b244530ee2a6247b5f930830eeca9dd950da0e7e/orderbook_pm_challenge/market.py","observation_source":"https://raw.githubusercontent.com/danrobinson/prediction-market-challenge/b244530ee2a6247b5f930830eeca9dd950da0e7e/orderbook_pm_challenge/types.py","base_config":{"process":{"n_steps":2000,"initial_score":0.0,"diffusion_sigma":0.02,"jump_intensity":0.001,"jump_mean":0.0,"jump_sigma":0.75,"terminal_threshold":0.0,"poisson_tail_mass":1e-12},"retail":{"arrival_rate":0.8,"mean_notional":12.0,"size_sigma":1.2,"buy_probability":0.5,"sell_quantity_price_floor":0.05},"competitor":{"quote_notional":60.0,"spread_ticks":2},"min_price_tick":1,"max_price_tick":99,"share_quantum":0.01,"default_simulations":200,"starting_cash":1000.0},"parameter_variance":{"initial_score_min":-0.75,"initial_score_max":0.75,"jump_intensity_min":0.0008,"jump_intensity_max":0.003,"jump_sigma_min":0.2,"jump_sigma_max":0.6,"jump_mean_min":-0.04,"jump_mean_max":0.04,"retail_arrival_rate_min":0.154,"retail_arrival_rate_max":0.352,"retail_mean_notional_min":2.64,"retail_mean_notional_max":6.336,"competitor_quote_notional_min":24.0,"competitor_quote_notional_max":72.0,"competitor_spread_ticks_min":1,"competitor_spread_ticks_max":4},"method":"Extract JSON.code as exact UTF-8 bytes and verify the stated hashes. Use the unmodified pinned simulator on the Python import path, without installing dependencies. In one Python process, for seed in range(310500,311000), sample cfg=sample_config(ChallengeConfig(),ParameterVariance(),seed=seed) once. In order C then B, call load_strategy_factory(path) freshly, then SimulationEngine(cfg,wrapped_factory,seed=seed).run(); wrapped_factory constructs one new strategy and forwards only the original StepState, recording the first callback's bid/ask and counting callbacks. Retain each run once, including the first 10 timing pairs. Do not call run_batch, multiprocessing, --workers or --sandbox. Check both returned seeds, failed/error flags, 2000 ordered callbacks, finite edges, source hashes and equal regimes/configs. Apply a 2700-second deadline to the simulation loop; incomplete/failed pairs are explicitly reported and cannot qualify.","spread_label":"s=(first_ask-first_bid+1)//2; require both quotes present, s in {1,2,3,4}, and equality to cfg.competitor.spread_ticks and result.regime.competitor_spread_ticks for both runs.","statistics":"For actually completed valid pairs, d=C.total_edge-B.total_edge. sum_d=math.fsum(d); sum_d2=math.fsum(d*d); mean_diff=sum_d/n; se=statistics.stdev(d)/sqrt(n), with sample SD (n-1). C_mean_edges and B_mean_edges are arithmetic means of total/retail/arb edges. retail_diff and arb_diff are signed C-minus-B paired means. Recompute for each s=1,2,3,4, including zero effects. No tuning dataset exists. Failed or unfinished simulations are recorded explicitly, not treated as full-length scores; missing_seeds lists requested seeds without a valid completed pair.","fixture":"Sort successful B runs by seed; serialize rows [seed,s,total_edge,retail_edge,arb_edge] using json.dumps(rows,ensure_ascii=False,allow_nan=False,separators=(',',':')).encode('utf-8'); SHA256 these bytes, zlib.compress(level=9), then base64.b64encode. Decode and verify every row, seed, type, float, hash and count. Fixture contains no B source or policy output."}}
