{
  "key": "f5-mid-gap",
  "mechanism": "rival-mid EMA gap, cancel exposed side for the current callback",
  "approach": "Blind RC subclass; infer spread once from first quotes. Update rival-mid EMA with alpha=1-2**(-1/H); if abs(mid-EMA)>=G, suppress new asks and cancel resting asks on upward gaps, bids on downward gaps. Otherwise return RC actions unchanged. Select one of four H/G pairs using only 200 tuning seeds; evaluate frozen winner once on 500 holdout seeds.",
  "tried": [
    {
      "name": "H5_G2",
      "code_sha256": "1ffe4b04291001efc902a65ae137655c5d8d93b9eb79b459fb25de28bdf3cfa1",
      "tuning": {
        "n": 200,
        "mean_diff": -0.646794664872,
        "se": 0.4411401952550237
      }
    },
    {
      "name": "H5_G3",
      "code_sha256": "f80953959ccb1f0e4498ba2aad38079b12735e5d056b48f39ce74fd3210b6cba",
      "tuning": {
        "n": 200,
        "mean_diff": -0.2959768791000002,
        "se": 0.11353310186447027
      }
    },
    {
      "name": "H20_G2",
      "code_sha256": "57dced07f654db801b68d52b438ad9892c55a5badfb62599dbd02bf5c2105570",
      "tuning": {
        "n": 200,
        "mean_diff": -11.3949375876615,
        "se": 2.042996952069124
      }
    },
    {
      "name": "H20_G3",
      "code_sha256": "50e04054e5e670defb892267bc4fc3a3d4429f38084bc8e296611022ff257d8c",
      "tuning": {
        "n": 200,
        "mean_diff": -5.888273515177,
        "se": 1.3462126084406854
      }
    }
  ],
  "next": "Screen only; retain RC. Do not promote this overlay or retune on this holdout. Reserved finalist seeds 900000..903999 were not used.",
  "selected_variant": "H5_G3",
  "spreads_acted": [
    1,
    2,
    3,
    4
  ],
  "off_equals_rc": true,
  "code": "from orderbook_pm_challenge.types import CancelAll, CancelOrder, PlaceOrder, Side\n\n\nclass Strategy(_RC):\n    \"\"\"Suppress the exposed side for callbacks with a rival-mid EMA gap.\"\"\"\n\n    HALF_LIFE = 5\n    GAP_TICKS = 3\n    ENABLED = True\n\n    def on_step(self, state):\n        actions = super().on_step(state)\n        if not self.ENABLED:\n            return actions\n        bid = state.competitor_best_bid_ticks\n        ask = state.competitor_best_ask_ticks\n        if state.step == 0:\n            self._f5_spread = (\n                max(1, (ask - bid + 1) // 2)\n                if bid is not None and ask is not None else None\n            )\n            self._f5_ema = None\n        if getattr(self, \"_f5_spread\", None) not in (1, 2, 3, 4):\n            return actions\n        if bid is None or ask is None:\n            return actions\n        mid = (bid + ask) / 2.0\n        previous = self._f5_ema\n        if previous is None:\n            self._f5_ema = mid\n            return actions\n        # Update the EMA before measuring this callback's gap.\n        alpha = 1.0 - 2.0 ** (-1.0 / self.HALF_LIFE)\n        self._f5_ema = previous + alpha * (mid - previous)\n        gap = mid - self._f5_ema\n        if abs(gap) < self.GAP_TICKS:\n            return actions\n        exposed = Side.SELL if gap > 0.0 else Side.BUY\n        # Keep RC's cancellation order, suppress new exposed-side quotes,\n        # then cancel any exposed resting orders RC has left outstanding.\n        edited = [\n            action for action in actions\n            if not (isinstance(action, PlaceOrder) and action.side == exposed)\n        ]\n        cancels_all = any(isinstance(action, CancelAll) for action in edited)\n        canceled = {\n            action.order_id for action in edited if isinstance(action, CancelOrder)\n        }\n        if not cancels_all:\n            edited.extend(\n                CancelOrder(order.order_id) for order in state.own_orders\n                if order.side == exposed and order.order_id not in canceled\n            )\n        return edited\n",
  "code_sha256": "f80953959ccb1f0e4498ba2aad38079b12735e5d056b48f39ce74fd3210b6cba",
  "assembled_sha256": "14a54f5cbfa52520c18f9ac8f68b2dc8f0cf55e4c1102238482013c78812e285",
  "comparator_sha256": "3c07bdcd221ac25729c3ebc92b21ac9e2014510ecb85816c4391ed81e933291f",
  "tuning": {
    "seeds": [
      330000,
      330199
    ],
    "n": 200,
    "complete": true,
    "missing_seeds": [],
    "overall": {
      "n": 200,
      "sum_d": -59.195375820000045,
      "sum_d2": 530.5331183072889,
      "mean_diff": -0.2959768791000002,
      "se": 0.11353310186447027,
      "comparator_mean": 97.4672210850045,
      "candidate_mean": 97.1712442059045,
      "retail_diff": -0.26077694690449854,
      "arb_diff": -0.035199932197000405
    },
    "by_spread": {
      "1": {
        "n": 54,
        "sum_d": 7.16512459709993,
        "sum_d2": 130.57674216600577,
        "mean_diff": 0.1326874925388876,
        "se": 0.2128194312669044,
        "comparator_mean": 46.18284342076481,
        "candidate_mean": 46.315530913303704,
        "retail_diff": -0.33294078828518364,
        "arb_diff": 0.46562828079999974
      },
      "2": {
        "n": 57,
        "sum_d": -10.972994742500056,
        "sum_d2": 71.08682773129823,
        "mean_diff": -0.19250867969298344,
        "se": 0.14699840480561416,
        "comparator_mean": 87.23571902150526,
        "candidate_mean": 87.04321034181227,
        "retail_diff": -0.050252158396490734,
        "arb_diff": -0.14225652127017627
      },
      "3": {
        "n": 49,
        "sum_d": -35.31309125599986,
        "sum_d2": 219.9317386974531,
        "mean_diff": -0.7206753317550991,
        "se": 0.2875554256994041,
        "comparator_mean": 112.87398754092447,
        "candidate_mean": 112.1533122091694,
        "retail_diff": -0.2925671966530614,
        "arb_diff": -0.4281081350836738
      },
      "4": {
        "n": 40,
        "sum_d": -20.07441441860006,
        "sum_d2": 108.9378097125318,
        "mean_diff": -0.5018603604650015,
        "se": 0.25174169817530323,
        "comparator_mean": 162.4077324637125,
        "candidate_mean": 161.9058721032475,
        "retail_diff": -0.42441052872249535,
        "arb_diff": -0.07744983177750009
      }
    }
  },
  "paired": {
    "seeds": [
      440000,
      440499
    ],
    "n": 500,
    "complete": true,
    "missing_seeds": [],
    "overall": {
      "n": 500,
      "sum_d": -75.9552909310999,
      "sum_d2": 3468.0763551890755,
      "mean_diff": -0.1519105818621998,
      "se": 0.11770241921886238,
      "comparator_mean": 101.4369256297634,
      "candidate_mean": 101.2850150479012,
      "retail_diff": -0.07210721438239977,
      "arb_diff": -0.07980336747719999
    },
    "by_spread": {
      "1": {
        "n": 142,
        "sum_d": 26.295648100299974,
        "sum_d2": 208.33454907210697,
        "mean_diff": 0.1851806204246477,
        "se": 0.10080712746368203,
        "comparator_mean": 28.71468187990704,
        "candidate_mean": 28.899862500331686,
        "retail_diff": 0.08832390435140822,
        "arb_diff": 0.09685671605985917
      },
      "2": {
        "n": 110,
        "sum_d": -37.12015923389997,
        "sum_d2": 400.2085181106664,
        "mean_diff": -0.33745599303545426,
        "se": 0.17981597903085642,
        "comparator_mean": 88.78927784058273,
        "candidate_mean": 88.45182184754727,
        "retail_diff": -0.3102348298481817,
        "arb_diff": -0.027221163183636047
      },
      "3": {
        "n": 119,
        "sum_d": -77.49720379240004,
        "sum_d2": 532.6036171086035,
        "mean_diff": -0.6512370066588239,
        "se": 0.18529753922670006,
        "comparator_mean": 143.37780997585378,
        "candidate_mean": 142.72657296919496,
        "retail_diff": -0.32319169427815203,
        "arb_diff": -0.32804531238487394
      },
      "4": {
        "n": 129,
        "sum_d": 12.366423994900153,
        "sum_d2": 2326.9296708976985,
        "mean_diff": 0.0958637518984508,
        "se": 0.37530221826210947,
        "comparator_mean": 153.5829305298,
        "candidate_mean": 153.67879428169846,
        "retail_diff": 0.18596931235116457,
        "arb_diff": -0.09010556042713198
      }
    }
  },
  "failures": [],
  "check_values": {
    "310000": 17.5126554022,
    "310001": 20.6298693268,
    "310002": 2.3903113616,
    "310003": 248.006347259
  },
  "python_version": "3.12.16",
  "seconds_per_simulation": 0.18462907875996798,
  "protocol": {
    "simulator_commit": "b244530ee2a6247b5f930830eeca9dd950da0e7e",
    "simulator_unmodified": true,
    "configuration": "sample_config(ChallengeConfig(), ParameterVariance(), seed=seed); SimulationEngine(cfg, factory, seed=seed).run(); 2000 steps; single process; no sandbox",
    "chunk_size_max_seeds": 50,
    "tuning_target_spreads": [
      1,
      2,
      3,
      4
    ],
    "selection": "maximum paired tuning mean over all target spreads 1..4",
    "frozen_before_holdout": true,
    "record_validation": "Exactly one record per seed and strategy; 1000 tuning records and 1000 holdout records; no missing, duplicate, failed or unexpected records.",
    "se_formula": "sqrt((sum_d2 - sum_d*sum_d/n)/(n-1)/n)",
    "retail_diff_and_arb_diff": "Paired means (candidate minus RC), not sums.",
    "mid_gap_convention": "Initialize EMA from first available rival mid at step 0. On subsequent valid two-sided quotes update EMA, then test gap. Missing quotes leave EMA unchanged and return RC actions unchanged. No persistent cooldown: reevaluate every callback.",
    "off_target_behavior": "First-quote inferred spread outside 1..4 or unavailable: return RC actions unchanged; d exactly 0 by identical actions.",
    "assembly_recipe": "Rename the last textual class declaration Strategy to _RC (leaving embedded predecessor class declarations unchanged) in exact RC UTF-8 text, append the exact overlay source with no additional separator.",
    "checks": {
      "disabled_variant": "H5_G3",
      "off_seeds": [
        320000,
        320001,
        320002
      ],
      "off_callbacks": 6000,
      "assembled_equals_imported": true,
      "assembled_equality_seeds": [
        320000,
        320001,
        320002
      ],
      "unit_tests": "Passed initialization, no-trigger identity, upward/downward cancellation, CancelAll handling, cancel deduplication, off-target identity, missing quotes, disabled identity, next-callback recovery. Python compilation passed."
    },
    "timing_scope": "Mean wall seconds for measured RC and candidate simulations in tuning, holdout and four RC check runs; excludes equality/unit checks."
  }
}
