{"approach":"Blind baseline estimates probability from the static competitor quote boundaries, quotes around that estimate, and scales quantity by modeled retail edge versus one-step adverse-selection loss. S1 alone allocates a common cash budget between bids and uncovered asks in proportion to positive expected edge per collateral dollar. Rules and implementation: https://raw.githubusercontent.com/danrobinson/prediction-market-challenge/b244530ee2a6247b5f930830eeca9dd950da0e7e/docs/orderbook_prediction_market_challenge.md","tried":[{"variant":"v1","margin_ticks":1.5,"budget_cash":100.0,"cap_shares":100.0,"sigma_factor":0.8,"seeds":"115000..115499","n":500,"s0_mean":-0.3596708341342,"s1_mean":-0.3624440277916,"mechanism_diff":-0.002773193657400001,"mechanism_se":0.0021015225140486116,"failures":[]},{"variant":"v2","margin_ticks":0.5,"budget_cash":40.0,"cap_shares":100.0,"sigma_factor":0.3,"seeds":"115000..115499","n":500,"s0_mean":-2.3075283287724,"s1_mean":-3.6237117929268,"mechanism_diff":-1.3161834641544,"mechanism_se":0.12832042210862799,"failures":[]},{"variant":"v3","margin_ticks":1.0,"budget_cash":60.0,"cap_shares":160.0,"sigma_factor":0.3,"seeds":"115000..115499","n":500,"s0_mean":-36.7610438012654,"s1_mean":-43.419042193706,"mechanism_diff":-6.6579983924406,"mechanism_se":1.058682119437721,"failures":[]},{"variant":"v4","margin_ticks":1.5,"budget_cash":100.0,"cap_shares":160.0,"sigma_factor":0.3,"seeds":"115000..115499","n":500,"s0_mean":-39.6631183805546,"s1_mean":-45.6748336671542,"mechanism_diff":-6.011715286599601,"mechanism_se":0.9954150433206629,"failures":[]}],"next":"Do not graft this allocator yet. The best tuning setting mostly suppresses quotes; on holdout only 5/1000 seeds differ and its paired gain is negative. The more active tuning settings also lose, mainly through additional arbitrage. A future mechanism should first improve conditional probability estimation, then retest collateral allocation on fresh seeds.","code":"import math\nfrom orderbook_pm_challenge.types import CancelAll, PlaceOrder, Side\n\n# These constants are set before measurement.\nMARGIN = 1.5\nBUDGET = 100.0\nCAP = 100.0\nALLOCATE = True\n\nclass Strategy:\n    def __init__(self):\n        self.p = None\n        self.prev_bid = None\n        self.prev_ask = None\n\n    def on_step(self, state):\n        bid0, ask0 = state.competitor_best_bid_ticks, state.competitor_best_ask_ticks\n        if self.p is None:\n            self.p = (bid0 + ask0) / 200 if bid0 is not None and ask0 is not None else 0.5\n        else:\n            p = self.p\n            if bid0 is not None:\n                p = max(p, (bid0 + 0.5) / 100)\n            if ask0 is not None:\n                p = min(p, (ask0 - 0.5) / 100)\n            if ask0 is not None and self.prev_ask is not None and ask0 > self.prev_ask:\n                p = max(p, (ask0 - 1.5) / 100)\n            if bid0 is not None and self.prev_bid is not None and bid0 < self.prev_bid:\n                p = min(p, (bid0 + 1.5) / 100)\n            self.p = max(0.01, min(0.99, p))\n        self.prev_bid, self.prev_ask = bid0, ask0\n        p = self.p\n        bid = max(1, min(99, math.floor(100 * p - MARGIN)))\n        ask = max(1, min(99, math.ceil(100 * p + MARGIN)))\n        # An order behind the competitor's top quote is unlikely to see retail flow.\n        if bid0 is not None and bid <= bid0:\n            bid = None\n        if ask0 is not None and ask >= ask0:\n            ask = None\n        # The expected next-step probability move grows as expiry approaches.\n        sigma_p = min(0.12, 0.8 / math.sqrt(max(8, state.steps_remaining)))\n        flow = 0.13\n        def edge(tick, side):\n            distance = (p - tick / 100) if side is Side.BUY else (tick / 100 - p)\n            z = distance / sigma_p\n            tail = 0.5 * math.erfc(z / math.sqrt(2))\n            arb = sigma_p * math.exp(-z*z/2) / math.sqrt(2*math.pi) - distance * tail\n            return max(0.0, flow * distance * (1-tail) - arb)\n        eb = edge(bid, Side.BUY) if bid is not None else 0.0\n        ea = edge(ask, Side.SELL) if ask is not None else 0.0\n        # Flow-sized orders: a few typical arrivals, reduced where adverse risk dominates.\n        qb = CAP * min(1.0, eb / max(0.001, flow * max(0.001, p - bid/100))) if eb else 0.0\n        qa = CAP * min(1.0, ea / max(0.001, flow * max(0.001, ask/100 - p))) if ea else 0.0\n        covered = min(max(0.0, state.yes_inventory), qa)\n        cb = bid / 100 if bid is not None else 1.0\n        ca = 1 - ask / 100 if ask is not None else 1.0\n        budget = min(BUDGET, max(0.0, state.free_cash - 0.01))\n        if ALLOCATE:\n            # Marginal expected edge per locked dollar; split the budget in proportion.\n            rb = eb / cb if qb else 0.0\n            ra = ea / ca if qa > covered else 0.0\n            weight = rb + ra\n            bb = budget * rb / weight if weight else 0.0\n            ba = budget - bb if weight else 0.0\n        else:\n            bb = budget / 2\n            ba = budget / 2\n        qb = min(qb, bb / cb)\n        qa = min(qa, covered + ba / ca)\n        qb = math.floor(qb * 100 - 1e-8) / 100\n        qa = math.floor(qa * 100 - 1e-8) / 100\n        actions = [CancelAll()]\n        if qb >= 0.01 and bid is not None:\n            actions.append(PlaceOrder(Side.BUY, bid, qb))\n        if qa >= 0.01 and ask is not None:\n            actions.append(PlaceOrder(Side.SELL, ask, qa))\n        return actions\n\ndef strategy_factory():\n    return Strategy()\n","code_sha256":"b752830e27feff1b6ae135f94775b11241b4c7715202d4b70e71b80a0eb94cbf","code_s0":"import math\nfrom orderbook_pm_challenge.types import CancelAll, PlaceOrder, Side\n\n# These constants are set before measurement.\nMARGIN = 1.5\nBUDGET = 100.0\nCAP = 100.0\nALLOCATE = False\n\nclass Strategy:\n    def __init__(self):\n        self.p = None\n        self.prev_bid = None\n        self.prev_ask = None\n\n    def on_step(self, state):\n        bid0, ask0 = state.competitor_best_bid_ticks, state.competitor_best_ask_ticks\n        if self.p is None:\n            self.p = (bid0 + ask0) / 200 if bid0 is not None and ask0 is not None else 0.5\n        else:\n            p = self.p\n            if bid0 is not None:\n                p = max(p, (bid0 + 0.5) / 100)\n            if ask0 is not None:\n                p = min(p, (ask0 - 0.5) / 100)\n            if ask0 is not None and self.prev_ask is not None and ask0 > self.prev_ask:\n                p = max(p, (ask0 - 1.5) / 100)\n            if bid0 is not None and self.prev_bid is not None and bid0 < self.prev_bid:\n                p = min(p, (bid0 + 1.5) / 100)\n            self.p = max(0.01, min(0.99, p))\n        self.prev_bid, self.prev_ask = bid0, ask0\n        p = self.p\n        bid = max(1, min(99, math.floor(100 * p - MARGIN)))\n        ask = max(1, min(99, math.ceil(100 * p + MARGIN)))\n        # An order behind the competitor's top quote is unlikely to see retail flow.\n        if bid0 is not None and bid <= bid0:\n            bid = None\n        if ask0 is not None and ask >= ask0:\n            ask = None\n        # The expected next-step probability move grows as expiry approaches.\n        sigma_p = min(0.12, 0.8 / math.sqrt(max(8, state.steps_remaining)))\n        flow = 0.13\n        def edge(tick, side):\n            distance = (p - tick / 100) if side is Side.BUY else (tick / 100 - p)\n            z = distance / sigma_p\n            tail = 0.5 * math.erfc(z / math.sqrt(2))\n            arb = sigma_p * math.exp(-z*z/2) / math.sqrt(2*math.pi) - distance * tail\n            return max(0.0, flow * distance * (1-tail) - arb)\n        eb = edge(bid, Side.BUY) if bid is not None else 0.0\n        ea = edge(ask, Side.SELL) if ask is not None else 0.0\n        # Flow-sized orders: a few typical arrivals, reduced where adverse risk dominates.\n        qb = CAP * min(1.0, eb / max(0.001, flow * max(0.001, p - bid/100))) if eb else 0.0\n        qa = CAP * min(1.0, ea / max(0.001, flow * max(0.001, ask/100 - p))) if ea else 0.0\n        covered = min(max(0.0, state.yes_inventory), qa)\n        cb = bid / 100 if bid is not None else 1.0\n        ca = 1 - ask / 100 if ask is not None else 1.0\n        budget = min(BUDGET, max(0.0, state.free_cash - 0.01))\n        if ALLOCATE:\n            # Marginal expected edge per locked dollar; split the budget in proportion.\n            rb = eb / cb if qb else 0.0\n            ra = ea / ca if qa > covered else 0.0\n            weight = rb + ra\n            bb = budget * rb / weight if weight else 0.0\n            ba = budget - bb if weight else 0.0\n        else:\n            bb = budget / 2\n            ba = budget / 2\n        qb = min(qb, bb / cb)\n        qa = min(qa, covered + ba / ca)\n        qb = math.floor(qb * 100 - 1e-8) / 100\n        qa = math.floor(qa * 100 - 1e-8) / 100\n        actions = [CancelAll()]\n        if qb >= 0.01 and bid is not None:\n            actions.append(PlaceOrder(Side.BUY, bid, qb))\n        if qa >= 0.01 and ask is not None:\n            actions.append(PlaceOrder(Side.SELL, ask, qa))\n        return actions\n\ndef strategy_factory():\n    return Strategy()\n","tuning_score":{"seeds":"115000..115499","n":500,"s1_mean":-0.3624440277916,"s0_mean":-0.3596708341342},"paired":{"seeds":"200000..200999","n":1000,"complete":true,"mechanism_diff":-0.0012405603923000017,"mechanism_se":0.0006636302224588415,"mechanism_retail_diff":-0.0003440473981999996,"mechanism_arb_diff":-0.0008965129940999983,"reference_diff":-100.0638487834241,"reference_se":5.742667411207072,"s1_mean":-0.3679706310418,"s0_mean":-0.36673007064950003,"b_mean":99.6958781523823,"failures":[]},"graft":"After choosing bid and ask prices, estimate each side’s positive next-step edge per share. Divide by its locked cash per share (bid price or 1 minus ask price), then split the cash budget in proportion to those rates; cover asks with existing YES first. This blind test found no gain, so validate before use.","seconds_per_simulation":0.1276615798473358}
