{
  "key": "f-fill-prob-pricing",
  "mech": "fill-probability pricing",
  "approach": "Blind subclass of hash-verified N. On spreads 3-4 with a valid two-sided rival midpoint, reconstruct exposed own price levels and allocate next-step aggregate fills in price priority. Estimate side/distance Bernoulli fill rates with decayed counts, Beta priors and decreasing isotonic pooling. Move each order outward to the feasible tick maximizing midpoint edge times fill probability, preserving size and staying outside the rival's best. Missing midpoint: defer to N. Disabled: return N's actions directly.",
  "tried": [
    {
      "check": "blind provenance",
      "incumbent_code_sha256": "bf0d179f3e47d28819f6fa7e0d25548c2ced43374c216d36460b00a26a26ffae",
      "incumbent_url": "https://api.imd.fun/artifacts/db22aff7167a4798251ed3d20432509f30e511e4958799aba5b17b41bb39b4b6",
      "simulator_commit": "b244530ee2a6247b5f930830eeca9dd950da0e7e",
      "detail": "N loaded and SHA-256 checked by script without viewing its source. Eighteen downloaded simulator/doc/project files matched pinned Git blob hashes; no simulator modifications or added dependencies."
    },
    {
      "check": "implementation",
      "passed_synthetic_tests": 9,
      "detail": "Tested disabled and spread gating, missing quotes, exact objective maximization, boundary prices, FIFO aggregate-fill attribution, decay, pooling duplicate price levels, isotonic rates, and retained-order collateral."
    },
    {
      "check": "seed discipline",
      "detail": "Serial SimulationEngine(config, factory, seed=seed).run(), sample_config(ChallengeConfig(), ParameterVariance(), seed=seed), 2000 steps. Three predeclared variants on all 200 tuning seeds; one frozen variant plus N on all 500 holdout seeds. Each logged (seed,strategy) unique; no finalist seeds used.",
      "timing_scope": "Wall seconds averaged over 800 tuning and 1000 holdout executions, excluding the 20 correctness-check executions."
    },
    {
      "check": "quote constraint on holdout",
      "checked_new_or_repriced_orders": 1334283,
      "violations": 0,
      "midpoint_steps": 422269,
      "missing_or_invalid_midpoint_steps": 75731,
      "moved_orders": 1325678,
      "price_level_observations": 764874,
      "detail": "On acted spreads and steps with both rival quotes and bid < ask, every placed/repriced order was checked against the same-side rival best; fallback steps return N unchanged."
    }
  ],
  "next": "Reject this overlay and retain N; this is a screen, not a promotion. Any follow-up should address fill quality: the observable fill totals do not identify retail versus arbitrage, and a midpoint-edge times hit-rate objective can reward toxic fills.",
  "spreads_acted": [
    3,
    4
  ],
  "off_equals_n": {
    "passed": true,
    "seeds": {
      "start": 310000,
      "end": 310009,
      "inclusive": true
    },
    "steps_compared": 20000,
    "mismatches": 0,
    "edge_equal_on_all_seeds": true,
    "method": "Separate N and disabled frozen-overlay simulations; SHA-256 of the ordered action types and all action fields compared at every step.",
    "code_sha256": "3f2378590590b1c0315557f9b16c4bc699714d68ff3310a8ca73f30fcbe90500"
  },
  "code": "# Append to the hash-verified incumbent after renaming its Strategy to _N.\nimport math as _fp_math\nfrom orderbook_pm_challenge.types import (\n    CancelAll as _FPAll, CancelOrder as _FPCancel,\n    PlaceOrder as _FPPlace, Side as _FPSide,\n)\n\n\nclass Strategy(_N):\n    \"\"\"Empirical fill probability times midpoint edge, outside rival quotes.\"\"\"\n\n    _fp_enabled = True\n    _fp_spreads = (3, 4)\n    _fp_prior_mass = 64.0\n    _fp_half_life = 1024.0\n\n    def _fp_init(self):\n        self._fp_counts = [[0.0] * 199 for _ in range(2)]\n        self._fp_hits = [[0.0] * 199 for _ in range(2)]\n        self._fp_last = [[0] * 199 for _ in range(2)]\n        self._fp_prior = [0.03 * _fp_math.exp(-0.65 * k / 2)\n                          for k in range(199)]\n        self._fp_previous = ([], [])\n        self._fp_moves = 0\n        self._fp_observations = 0\n\n    def _fp_learn(self, state):\n        # Fills consume participant price levels in price-time order, even\n        # though competitor liquidity may stand between those levels.\n        for side, filled in enumerate((state.buy_filled_quantity,\n                                       state.sell_filled_quantity)):\n            for distance, quantity in self._fp_previous[side]:\n                if 1 <= distance <= 198:\n                    factor = 2.0 ** (-(state.step - self._fp_last[side][distance])\n                                     / self._fp_half_life)\n                    self._fp_counts[side][distance] = (\n                        factor * self._fp_counts[side][distance] + 1.0)\n                    self._fp_hits[side][distance] = (\n                        factor * self._fp_hits[side][distance]\n                        + float(filled > 1e-9))\n                    self._fp_last[side][distance] = state.step\n                    self._fp_observations += 1\n                filled = max(0.0, filled - quantity)\n\n    def _fp_probabilities(self, side, step):\n        # Beta shrinkage and decreasing isotonic regression keep sparse,\n        # distant observations from creating an increasing fill curve.\n        blocks = []\n        for k in range(1, 199):\n            factor = 2.0 ** (-(step - self._fp_last[side][k])\n                             / self._fp_half_life)\n            successes = self._fp_hits[side][k] * factor\n            exposures = self._fp_counts[side][k] * factor\n            numerator = successes + self._fp_prior_mass * self._fp_prior[k]\n            weight = exposures + self._fp_prior_mass\n            blocks.append([k, k, numerator, weight])\n            while len(blocks) > 1:\n                left, right = blocks[-2], blocks[-1]\n                if left[2] * right[3] >= right[2] * left[3]:\n                    break\n                blocks.pop()\n                blocks.pop()\n                blocks.append([left[0], right[1], left[2] + right[2],\n                               left[3] + right[3]])\n        probabilities = [0.0] * 199\n        for lo, hi, numerator, weight in blocks:\n            probability = numerator / weight\n            for k in range(lo, hi + 1):\n                probabilities[k] = probability\n        return probabilities\n\n    @staticmethod\n    def _fp_side(side):\n        return 0 if side == _FPSide.BUY else 1\n\n    @staticmethod\n    def _fp_quantity(quantity):\n        return round(_fp_math.floor((float(quantity) + 1e-9) / 0.01) * 0.01, 10)\n\n    def on_step(self, state):\n        actions = super().on_step(state)\n        if not self._fp_enabled or self.s not in self._fp_spreads:\n            return actions\n        if not hasattr(self, '_fp_counts'):\n            self._fp_init()\n        self._fp_learn(state)\n        self._fp_previous = ([], [])\n        bid = state.competitor_best_bid_ticks\n        ask = state.competitor_best_ask_ticks\n        if bid is None or ask is None or bid >= ask:\n            # No two-sided midpoint: defer to N and collect no exposure.\n            return actions\n        midpoint2 = bid + ask\n        probabilities = [self._fp_probabilities(side, state.step)\n                         for side in range(2)]\n\n        def target(side, old_tick):\n            # Outward-only moves cannot increase collateral at N's size.\n            ticks = (range(min(old_tick, bid), 0, -1) if side == 0\n                     else range(max(old_tick, ask), 100))\n            best_tick = None\n            best_value = -1.0\n            for tick in ticks:\n                distance = midpoint2 - 2 * tick if side == 0 else 2 * tick - midpoint2\n                value = distance * probabilities[side][distance]\n                if value > best_value + 1e-15:\n                    best_tick, best_value = tick, value\n            return best_tick\n\n        # Track the book after N's actions. Entries carry IDs only where\n        # cancellations can refer to them; newly generated IDs are unnecessary.\n        book = {order.order_id: (self._fp_side(order.side), order.price_ticks,\n                                order.remaining_quantity, order.side, True)\n                for order in state.own_orders}\n        output = []\n        for index, action in enumerate(actions):\n            if isinstance(action, _FPAll):\n                book.clear()\n                output.append(action)\n            elif isinstance(action, _FPCancel):\n                book.pop(action.order_id, None)\n                output.append(action)\n            elif isinstance(action, _FPPlace):\n                side = self._fp_side(action.side)\n                tick = target(side, action.price_ticks)\n                if tick != action.price_ticks:\n                    self._fp_moves += 1\n                    action = _FPPlace(action.side, tick, action.quantity,\n                                      action.client_order_id)\n                output.append(action)\n                key = action.client_order_id if action.client_order_id else ('new', index)\n                book[key] = (side, tick, self._fp_quantity(action.quantity),\n                             action.side, False)\n            else:\n                output.append(action)\n\n        for order_id, (side, old_tick, quantity, side_enum, retained) in list(book.items()):\n            if not retained:\n                continue\n            tick = target(side, old_tick)\n            if tick != old_tick:\n                output.extend((_FPCancel(order_id),\n                               _FPPlace(side_enum, tick, quantity, order_id)))\n                book[order_id] = (side, tick, quantity, side_enum, False)\n                self._fp_moves += 1\n\n        levels = ({}, {})\n        for side, tick, quantity, _, _ in book.values():\n            levels[side][tick] = levels[side].get(tick, 0.0) + quantity\n        for side in range(2):\n            for tick in sorted(levels[side], reverse=(side == 0)):\n                distance = midpoint2 - 2 * tick if side == 0 else 2 * tick - midpoint2\n                self._fp_previous[side].append((distance, levels[side][tick]))\n        return output\n",
  "code_sha256": "3f2378590590b1c0315557f9b16c4bc699714d68ff3310a8ca73f30fcbe90500",
  "assembled_sha256": "5864c054e2ae51ed5692e433a04b4aa6ad715c68d500c6b2cad5d28b49d14245",
  "tuning": {
    "seeds": {
      "start": 320000,
      "end": 320199,
      "inclusive": true
    },
    "selected": "fp_slow",
    "incumbent_code_sha256": "bf0d179f3e47d28819f6fa7e0d25548c2ced43374c216d36460b00a26a26ffae",
    "selection_rule": "Highest paired mean total-edge difference on all 200 tuning seeds; tie by label.",
    "frozen_utc": "2026-11-06T22:15:27.075099+00:00",
    "selected_score": 48.4493410609675,
    "variants": [
      {
        "id": "fp_slow",
        "prior_mass": 64.0,
        "half_life_steps": 1024.0,
        "spreads_acted": [
          3,
          4
        ],
        "code_sha256": "3f2378590590b1c0315557f9b16c4bc699714d68ff3310a8ca73f30fcbe90500",
        "bytes": 6895,
        "n": 200,
        "tuning_score": 48.4493410609675,
        "overall": {
          "n": 200,
          "sum_d": -10004.2754507196,
          "sum_d2": 1933726.1550734956,
          "mean_diff": -50.021377253598004,
          "se": 6.001043708645096,
          "incumbent_mean": 98.47071831456549,
          "candidate_mean": 48.4493410609675,
          "retail_diff": -45.0570314920255,
          "arb_diff": -4.964345761626
        },
        "by_spread": {
          "1": {
            "n": 50,
            "sum_d": 0.0,
            "sum_d2": 0.0,
            "mean_diff": 0.0,
            "se": 0.0,
            "incumbent_mean": 25.711261479664,
            "candidate_mean": 25.711261479664,
            "retail_diff": 0.0,
            "arb_diff": 0.0
          },
          "2": {
            "n": 50,
            "sum_d": 0.0,
            "sum_d2": 0.0,
            "mean_diff": 0.0,
            "se": 0.0,
            "incumbent_mean": 61.219908510538,
            "candidate_mean": 61.219908510538,
            "retail_diff": 0.0,
            "arb_diff": 0.0
          },
          "3": {
            "n": 48,
            "sum_d": -4062.4299631474,
            "sum_d2": 588317.1471574815,
            "mean_diff": -84.63395756557084,
            "se": 10.410408518193424,
            "incumbent_mean": 130.8342429047854,
            "candidate_mean": 46.20028533921459,
            "retail_diff": -69.44429066802708,
            "arb_diff": -15.189666897733334
          },
          "4": {
            "n": 52,
            "sum_d": -5941.8454875722,
            "sum_d2": 1345409.007916014,
            "mean_diff": -114.26625937638846,
            "se": 15.852551053663227,
            "incumbent_mean": 174.37579815333268,
            "candidate_mean": 60.10953877694423,
            "retail_diff": -109.19385281422691,
            "arb_diff": -5.072406562192308
          }
        }
      },
      {
        "id": "fp_medium",
        "prior_mass": 16.0,
        "half_life_steps": 512.0,
        "spreads_acted": [
          3,
          4
        ],
        "code_sha256": "75f7453822fc636126c1cb65a38d137a6ec466e350fd56a0048e93835d3323c2",
        "bytes": 6894,
        "n": 200,
        "tuning_score": 48.3636627856395,
        "overall": {
          "n": 200,
          "sum_d": -10021.4111057852,
          "sum_d2": 1959009.3467926367,
          "mean_diff": -50.107055528926004,
          "se": 6.0501794982236,
          "incumbent_mean": 98.47071831456549,
          "candidate_mean": 48.3636627856395,
          "retail_diff": -45.036362349017,
          "arb_diff": -5.070693179961
        },
        "by_spread": {
          "1": {
            "n": 50,
            "sum_d": 0.0,
            "sum_d2": 0.0,
            "mean_diff": 0.0,
            "se": 0.0,
            "incumbent_mean": 25.711261479664,
            "candidate_mean": 25.711261479664,
            "retail_diff": 0.0,
            "arb_diff": 0.0
          },
          "2": {
            "n": 50,
            "sum_d": 0.0,
            "sum_d2": 0.0,
            "mean_diff": 0.0,
            "se": 0.0,
            "incumbent_mean": 61.219908510538,
            "candidate_mean": 61.219908510538,
            "retail_diff": 0.0,
            "arb_diff": 0.0
          },
          "3": {
            "n": 48,
            "sum_d": -4000.772846193,
            "sum_d2": 587909.7198922576,
            "mean_diff": -83.3494342956875,
            "se": 10.620124380217769,
            "incumbent_mean": 130.8342429047854,
            "candidate_mean": 47.48480860909792,
            "retail_diff": -69.29097046876458,
            "arb_diff": -14.058463827091666
          },
          "4": {
            "n": 52,
            "sum_d": -6020.6382595922005,
            "sum_d2": 1371099.626900379,
            "mean_diff": -115.7815049921577,
            "se": 15.942263240725488,
            "incumbent_mean": 174.37579815333268,
            "candidate_mean": 58.594293161174996,
            "retail_diff": -109.25588244812886,
            "arb_diff": -6.5256225440730775
          }
        }
      },
      {
        "id": "fp_fast",
        "prior_mass": 4.0,
        "half_life_steps": 256.0,
        "spreads_acted": [
          3,
          4
        ],
        "code_sha256": "a0c00c44deadd2d13d1fa846a4a744ac087ba310aad7925eea66715f336a3932",
        "bytes": 6893,
        "n": 200,
        "tuning_score": 47.913793968556,
        "overall": {
          "n": 200,
          "sum_d": -10111.3848692019,
          "sum_d2": 1932664.3453438205,
          "mean_diff": -50.5569243460095,
          "se": 5.976217155896112,
          "incumbent_mean": 98.47071831456549,
          "candidate_mean": 47.913793968556,
          "retail_diff": -45.3001257634905,
          "arb_diff": -5.2567985825755
        },
        "by_spread": {
          "1": {
            "n": 50,
            "sum_d": 0.0,
            "sum_d2": 0.0,
            "mean_diff": 0.0,
            "se": 0.0,
            "incumbent_mean": 25.711261479664,
            "candidate_mean": 25.711261479664,
            "retail_diff": 0.0,
            "arb_diff": 0.0
          },
          "2": {
            "n": 50,
            "sum_d": 0.0,
            "sum_d2": 0.0,
            "mean_diff": 0.0,
            "se": 0.0,
            "incumbent_mean": 61.219908510538,
            "candidate_mean": 61.219908510538,
            "retail_diff": 0.0,
            "arb_diff": 0.0
          },
          "3": {
            "n": 48,
            "sum_d": -4069.1914064414,
            "sum_d2": 587080.063891431,
            "mean_diff": -84.77482096752917,
            "se": 10.359561719892369,
            "incumbent_mean": 130.8342429047854,
            "candidate_mean": 46.059421937256246,
            "retail_diff": -69.39402194891875,
            "arb_diff": -15.380799018802085
          },
          "4": {
            "n": 52,
            "sum_d": -6042.1934627605,
            "sum_d2": 1345584.2814523897,
            "mean_diff": -116.19602813000961,
            "se": 15.577197918105506,
            "incumbent_mean": 174.37579815333268,
            "candidate_mean": 58.17977002332308,
            "retail_diff": -110.17523267596154,
            "arb_diff": -6.0207954540884625
          }
        }
      }
    ]
  },
  "paired": {
    "seeds": {
      "start": 430000,
      "end": 430499,
      "inclusive": true
    },
    "n": 500,
    "complete": true,
    "missing_seeds": [],
    "overall": {
      "n": 500,
      "sum_d": -22540.2061456882,
      "sum_d2": 4182110.2920151865,
      "mean_diff": -45.0804122913764,
      "se": 3.562208961966889,
      "incumbent_mean": 95.54201511346659,
      "candidate_mean": 50.4616028220902,
      "retail_diff": -42.3941188218194,
      "arb_diff": -2.6862934695700003
    },
    "by_spread": {
      "1": {
        "n": 131,
        "sum_d": 0.0,
        "sum_d2": 0.0,
        "mean_diff": 0.0,
        "se": 0.0,
        "incumbent_mean": 38.277936657049615,
        "candidate_mean": 38.277936657049615,
        "retail_diff": 0.0,
        "arb_diff": 0.0
      },
      "2": {
        "n": 120,
        "sum_d": 0.0,
        "sum_d2": 0.0,
        "mean_diff": 0.0,
        "se": 0.0,
        "incumbent_mean": 77.8558643979175,
        "candidate_mean": 77.8558643979175,
        "retail_diff": 0.0,
        "arb_diff": 0.0
      },
      "3": {
        "n": 133,
        "sum_d": -12013.5685116703,
        "sum_d2": 2246573.351719773,
        "mean_diff": -90.32758279451355,
        "se": 8.133570885812732,
        "incumbent_mean": 146.55140363646615,
        "candidate_mean": 56.22382084195263,
        "retail_diff": -82.04723649350977,
        "arb_diff": -8.280346301048121
      },
      "4": {
        "n": 116,
        "sum_d": -10526.6376340179,
        "sum_d2": 1935536.9402954134,
        "mean_diff": -90.74687615532672,
        "se": 8.572284838974317,
        "incumbent_mean": 120.02204692465259,
        "candidate_mean": 29.27517076932586,
        "retail_diff": -88.6618703213181,
        "arb_diff": -2.0850058340137934
      }
    }
  },
  "failures": [],
  "check_values": {
    "310000": 17.1160017503,
    "310001": 20.0171113118,
    "310002": 2.3903113616,
    "310003": 241.4847522404
  },
  "python_version": "3.13.5",
  "seconds_per_simulation": 0.752413036856257
}
