{"approach":"S0 estimates the initial probability from the midpoint of the public competitor ladder, then shrinks its probit toward 0.5 with the remaining horizon; it posts 4-share passive quotes five ticks either side. S1 adds 0.01-share buy and sell probes at the legal tick that most evenly splits a symmetric probability-uncertainty interval around that estimate, maximizing binary fill/no-fill entropy.","tried":[{"strategy":"S0","variant":{"offset":1,"size":4.0},"tuning_mean":-13.6084505119648,"retail_mean":0.3242927162584,"arb_mean":-13.9327432282256,"n":500,"seeds":[115000,115499]},{"strategy":"S0","variant":{"offset":2,"size":4.0},"tuning_mean":-13.0433283986634,"retail_mean":0.3756800334172,"arb_mean":-13.419008432082,"n":500,"seeds":[115000,115499]},{"strategy":"S0","variant":{"offset":3,"size":4.0},"tuning_mean":-12.6721092686654,"retail_mean":0.262627387034,"arb_mean":-12.9347366556996,"n":500,"seeds":[115000,115499]},{"strategy":"S0","variant":{"offset":5,"size":4.0},"tuning_mean":-12.550385471355,"retail_mean":0.111470681743,"arb_mean":-12.6618561530978,"n":500,"seeds":[115000,115499]},{"strategy":"S1","variant":{"offset":5,"size":4.0,"probe":0.01,"width":0.025},"tuning_mean":-12.6426012029188,"retail_mean":0.1126022434036,"arb_mean":-12.7552034463194,"n":500,"seeds":[115000,115499]},{"strategy":"S1","variant":{"offset":5,"size":4.0,"probe":0.05,"width":0.025},"tuning_mean":-12.8199795977276,"retail_mean":0.115401465829,"arb_mean":-12.9353810635574,"n":500,"seeds":[115000,115499]},{"strategy":"S1","variant":{"offset":5,"size":4.0,"probe":0.1,"width":0.025},"tuning_mean":-12.8522053607408,"retail_mean":0.119958633481,"arb_mean":-12.972163994217,"n":500,"seeds":[115000,115499]},{"strategy":"S1","variant":{"offset":5,"size":4.0,"probe":0.25,"width":0.025},"tuning_mean":-13.1279320890926,"retail_mean":0.1320088523368,"arb_mean":-13.2599409414258,"n":500,"seeds":[115000,115499]}],"next":"The max-entropy probes do not improve paired edge: their additional arbitrage loss outweighs the small retail gain, and the current implementation does not feed probe outcomes into a calibrated posterior update. Explore a fill-source-aware Bayesian update before increasing probe size.","code":"from __future__ import annotations\n\nimport math\n\nfrom orderbook_pm_challenge.strategy import BaseStrategy\nfrom orderbook_pm_challenge.types import CancelAll, PlaceOrder, Side\n\n\ndef normal_cdf(x: float) -> float:\n    return 0.5 * (1.0 + math.erf(x / math.sqrt(2.0)))\n\n\ndef normal_quantile(p: float) -> float:\n    lo, hi = -8.0, 8.0\n    for _ in range(48):\n        mid = (lo + hi) / 2.0\n        if normal_cdf(mid) < p:\n            lo = mid\n        else:\n            hi = mid\n    return (lo + hi) / 2.0\n\n\nclass S0(BaseStrategy):\n    \"\"\"Passive two-sided quotes around a time-adjusted initial-value estimate.\"\"\"\n\n    def __init__(self, offset: int = 3, size: float = 4.0):\n        self.offset = offset\n        self.size = size\n        self.initial = None\n\n    def estimate(self, state):\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            observed = (bid + ask) / 200.0\n            if self.initial is None:\n                self.initial = min(.99, max(.01, observed))\n        if self.initial is None:\n            self.initial = .5\n        # The latent score's expected value stays fixed while remaining-horizon\n        # diffusion shrinks, so the probability forecast returns toward 1/2.\n        z0 = normal_quantile(self.initial)\n        h = max(0, state.steps_remaining)\n        return min(.99, max(.01, normal_cdf(z0 * math.sqrt(h / 2000.0))))\n\n    def on_step(self, state):\n        p = self.estimate(state)\n        center = int(round(p * 100))\n        actions = [CancelAll()]\n        bid_tick = max(1, min(99, center - self.offset))\n        ask_tick = max(1, min(99, center + self.offset))\n        if state.yes_inventory < 120 and state.free_cash > bid_tick * self.size / 100:\n            actions.append(PlaceOrder(Side.BUY, bid_tick, self.size))\n        if state.no_inventory < 120 and state.free_cash > (100 - ask_tick) * self.size / 100:\n            actions.append(PlaceOrder(Side.SELL, ask_tick, self.size))\n        return actions\n\n\nclass S1(S0):\n    \"\"\"S0 plus small threshold probes at the maximum-entropy probability cut.\"\"\"\n\n    def __init__(self, offset: int = 3, size: float = 4.0, probe: float = .10, width: float = .025):\n        super().__init__(offset, size)\n        self.probe = probe\n        self.width = width\n\n    def on_step(self, state):\n        actions = super().on_step(state)\n        p = self.estimate(state)\n        # The uncertainty band reflects the initial quote's unknown spread and\n        # tick rounding. A threshold at its median maximizes binary entropy.\n        lo = max(.01, p - self.width)\n        hi = min(.99, p + self.width)\n        # Among legal ticks, choose the cut whose posterior event probability\n        # is closest to 1/2 (one-step fill/no-fill information value).\n        threshold = min(range(1, 100), key=lambda tick: abs((hi - max(lo, tick / 100)) / max(1e-9, hi - lo) - .5))\n        if state.yes_inventory < 120 and state.free_cash > threshold * self.probe / 100:\n            actions.append(PlaceOrder(Side.BUY, threshold, self.probe))\n        if state.no_inventory < 120 and state.free_cash > (100 - threshold) * self.probe / 100:\n            actions.append(PlaceOrder(Side.SELL, threshold, self.probe))\n        return actions\n\nStrategy = S1\n","code_sha256":"118a9889cdca417aff9845fbe1938bc6f0eab887908e6fad0af2d80ced26c90c","code_s0":"from __future__ import annotations\n\nimport math\n\nfrom orderbook_pm_challenge.strategy import BaseStrategy\nfrom orderbook_pm_challenge.types import CancelAll, PlaceOrder, Side\n\n\ndef normal_cdf(x: float) -> float:\n    return 0.5 * (1.0 + math.erf(x / math.sqrt(2.0)))\n\n\ndef normal_quantile(p: float) -> float:\n    lo, hi = -8.0, 8.0\n    for _ in range(48):\n        mid = (lo + hi) / 2.0\n        if normal_cdf(mid) < p:\n            lo = mid\n        else:\n            hi = mid\n    return (lo + hi) / 2.0\n\n\nclass S0(BaseStrategy):\n    \"\"\"Passive two-sided quotes around a time-adjusted initial-value estimate.\"\"\"\n\n    def __init__(self, offset: int = 3, size: float = 4.0):\n        self.offset = offset\n        self.size = size\n        self.initial = None\n\n    def estimate(self, state):\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            observed = (bid + ask) / 200.0\n            if self.initial is None:\n                self.initial = min(.99, max(.01, observed))\n        if self.initial is None:\n            self.initial = .5\n        # The latent score's expected value stays fixed while remaining-horizon\n        # diffusion shrinks, so the probability forecast returns toward 1/2.\n        z0 = normal_quantile(self.initial)\n        h = max(0, state.steps_remaining)\n        return min(.99, max(.01, normal_cdf(z0 * math.sqrt(h / 2000.0))))\n\n    def on_step(self, state):\n        p = self.estimate(state)\n        center = int(round(p * 100))\n        actions = [CancelAll()]\n        bid_tick = max(1, min(99, center - self.offset))\n        ask_tick = max(1, min(99, center + self.offset))\n        if state.yes_inventory < 120 and state.free_cash > bid_tick * self.size / 100:\n            actions.append(PlaceOrder(Side.BUY, bid_tick, self.size))\n        if state.no_inventory < 120 and state.free_cash > (100 - ask_tick) * self.size / 100:\n            actions.append(PlaceOrder(Side.SELL, ask_tick, self.size))\n        return actions\n","tuning_score":{"seeds":[115000,115499],"n":500,"s1_mean":-12.6426012029188,"s0_mean":-12.550385471355},"paired":{"seeds":[200000,200999],"n":1000,"complete":true,"mechanism_diff":-0.07858056646149998,"mechanism_se":0.0054625971273622115,"mechanism_retail_diff":0.000890145338,"mechanism_arb_diff":-0.07947071179659995,"reference_diff":-111.2198878380359,"reference_se":5.689324710489984,"s1_mean":-11.5240096856536,"s0_mean":-11.4454291191921,"b_mean":99.6958781523823,"failures":[]},"graft":"Keep the incumbent forecast and its uncertainty distribution. For each legal tick, calculate the entropy of the binary fill/no-fill outcome under that distribution; place capped passive probes at the tick with maximum expected entropy reduction while retaining the incumbent quotes.","seconds_per_simulation":0.4564134658575058}
