{"approach": "Spread 3 only. Replaced the base's clipped-fill flow estimate with a per-run Bayesian estimate of retail rate and mean order size, read from the base's own fills on both sides. Each side-step on which our main order showed at least $0.50 and sat clear of the estimated probability (no rival quote jump) counts as exposure; any fill above 0.1 share is one arrival. A fill below displayed size gives the order's notional (shares x ask price for buys, shares x max(p, 0.05) for sells) and a lognormal likelihood with the known sigma 1.2 over a 9-node grid of the public mean-size band; a fill that used up our size is treated as a lower bound with a survival likelihood plus 0.5, which removes the upward bias from arbitrageur sweeps. Rate has a 9-node Poisson posterior on the public band. The posterior means replace the fixed rate and size in the quantile sizing of bids and asks (rho, mu), and rate x size / 2 / 0.6 scales the ammo targets and the tick-1 stock target (clipped 0.5 to 2 for stock). Mechanism: low-flow runs quote less into the arbitrageur, high-flow runs quote more; retail falls a little and arbitrage loss falls more. Error of log(estimated buy flow / true buy flow) over 977 tuning runs, rms (bias): step 200 0.237 (+0.045), step 500 0.183 (+0.012), step 1000 0.145 (0.000); the base's estimator on the same runs 0.335 (+0.167), 0.318 (+0.195), 0.299 (+0.201); the prior alone has sd 0.339. Oracle sizing with the true values gained 1.49 on the same half against 1.15 for the estimate. The unseen gain is larger than the tuning gain (about +1.0 over all 1954 tuning seeds, from +1.151 and +0.898 on the two halves); the two agree within their standard errors, and about +1 is the more cautious expectation. Tuning used a sorted-book patch of the simulator, checked identical on sample seeds; holdout, base_unseen, identity and timing used the unmodified simulator, each seed run as run_batch runs it. Timing: 200 unseen spread-3 seeds, one process, alternating order. base_mean_edge ran through the CLI with --workers 6 in chunks of seeds because of a 10-minute limit per command on this machine, weighted back to the 4000-run mean.", "blocked": null, "python_version": "3.12.3", "spread": 3, "base_mean_edge": 98.4694596619638, "runs": {"tuning": 1954, "unseen": 2035}, "base_unseen": {"mean_edge": 118.8166859338749, "retail_edge": 149.05823988395983, "arb_edge": -30.241553950072774}, "holdout": {"mean_edge": 121.26176198972144, "retail_edge": 147.77786916219893, "arb_edge": -26.516107172465894, "failures": 0}, "diff": {"mean": 2.4450760558465348, "standard_error": 0.6648425737393336, "retail": -1.280370721760903, "arb": 3.72544677760688}, "others_identical": {"runs": 900, "identical": true}, "seconds": {"base": 209.8979747754056, "yours": 207.18756804941222}, "code": "\"\"\"Crossing-cover base with isolated spread overrides; spread 3 sizes on this run's own estimated retail flow.\"\"\"\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)\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\n# Spread 3 only: grids over the simulator's public bands for retail rate and mean order size.\nLAM_NODES = [0.154 + (i + 0.5) * 0.022 for i in range(9)]\nLAM_LOGS = [math.log(v) for v in LAM_NODES]\nM_NODES = [2.64 + (i + 0.5) * 3.696 / 9.0 for i in range(9)]\nM_MUS = [math.log(v) - 0.72 for v in M_NODES]\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        self.flow_ll = [0.0] * 9   # log likelihood of each M_NODES value\n        self.flow_events = 0       # retail orders seen\n        self.flow_exposed = 0      # side-steps on which one would have been seen\n        self.flow_lam = 0.253      # posterior means, starting at the prior's\n        self.flow_m = 4.488\n        self.flow_ask = None       # (shares, price, rival quote) we showed last step\n        self.flow_bid = None\n        self.params = P.copy()\n\n    def _oid(self, tag):\n        self.n += 1\n        return tag + str(self.n)\n\n    def _flow_side(self, seen, filled):\n        # One side's last step: an order under our displayed size shows its whole notional, one\n        # that used it up only shows a lower bound. Such bounds also come from the arbitrageur,\n        # so they are weighted down by adding 0.5 to their likelihood.\n        self.flow_exposed += 1\n        if filled <= 0.1:\n            return False\n        self.flow_events += 1\n        cap, price = seen[0], seen[1]\n        ll = self.flow_ll\n        if filled < cap - 0.01:\n            ln = math.log(filled * price)\n            for j in range(9):\n                d = (ln - M_MUS[j]) / 1.2\n                ll[j] -= 0.5 * d * d\n        else:\n            ln = math.log(cap * price)\n            for j in range(9):\n                ll[j] += math.log(0.5 + 0.5 * math.erfc((ln - M_MUS[j]) / (1.2 * SQ2)))\n        return True\n\n    def _flow_update(self, state, cb, ca):\n        new = False\n        seen = self.flow_ask\n        if seen is not None and ca <= seen[2] + 1:\n            new = self._flow_side(seen, state.sell_filled_quantity)\n        seen = self.flow_bid\n        if seen is not None and cb >= seen[2] - 1:\n            new = self._flow_side(seen, state.buy_filled_quantity) or new\n        if new:\n            ev = self.flow_events\n            ex = 0.5 * self.flow_exposed\n            lg = [ev * a - ex * b for a, b in zip(LAM_LOGS, LAM_NODES)]\n            top = max(lg)\n            ws = [math.exp(v - top) for v in lg]\n            self.flow_lam = sum(w * v for w, v in zip(ws, LAM_NODES)) / sum(ws)\n            top = max(self.flow_ll)\n            ws = [math.exp(v - top) for v in self.flow_ll]\n            self.flow_m = sum(w * v for w, v in zip(ws, M_NODES)) / sum(ws)\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            if self.s == 1:\n                self.params.update({'dmin': 0.3, 'pfl': 1e-06})\n            if self.s == 3:\n                self.params.update({'flow_level': 0.6, 'flow_safety': 2.0})\n        P = self.params\n        if self.s == 3:\n            self._flow_update(state, cb, ca)\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        fscale = 1.0\n        if self.s == 3:\n            rho = self.flow_lam * 0.5\n            mu = math.log(self.flow_m) - 0.5 * P['sig_n'] ** 2\n            fscale = self.flow_lam * self.flow_m * 0.5 / P['flow_level']\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            return 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 = 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(fscale * P['ydem'] * min(H, P['W']) / x, capw)\n            full = min(fscale * 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            stock_rate = P['ydf1']\n            if self.s == 3:\n                stock_rate *= max(0.5, min(2.0, fscale))\n            q1 = max(0.0, stock_rate * min(H, P['Wf']) / (self.s / 100.0) - Y)\n\n        # Bridge expected retail demand until another tick crossing is available.\n        if 0.02 < phat < 0.1:\n            ct = max(2, min(99, int(math.floor(ptick))))\n            wealth = state.cash + Y * phat\n            goal = min(1 * qa, 0.3 * max(wealth, 0.0) / phat)\n            if Y < goal and ct < ask_t:\n                amt, qam = ct, min(3000.0, goal - 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 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                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        if self.s == 3:\n            margin = max(0.005, P['flow_safety'] * self.st / 100.0)\n            q = ka + sum(o.quantity for o in out if o.side is Side.SELL and o.quantity > PROBE)\n            self.flow_ask = (q, ask_t / 100.0, ca) if q * ask_t >= 50.0 and ask_t / 100.0 > phat + margin else None\n            q = 0.0\n            tb = 0\n            if kb > 0:\n                q, tb = kb, bid_t\n            for o in out:\n                if o.side is Side.BUY and o.quantity > PROBE and o.price_ticks > cb:\n                    q += o.quantity\n                    tb = max(tb, o.price_ticks)\n            x = max(phat, 0.05)\n            self.flow_bid = (q, x, cb) if q * x >= 0.5 and tb / 100.0 < phat - margin else None\n        return actions + out\n", "code_sha256": "f6d3af1aff274accc7d2f24959562428ea5ed81a370b442d39c0cd9fba9a73c3", "tried": ["Oracle ceiling on tuning half (977 runs, cheating with the run's true rate and mean size): stock target only +0.101 (se 0.073); ask/bid sizing only +1.125 (se 0.339); sizing + stock + ammo target +1.490 (se 0.357). This bounds what flow can give under the base's sizing formula.", "Constant shift instead of a per-run estimate (lam 0.25, m 4.49 in every run): -0.201 (se 0.266), retail -1.865, arb +1.663, so the gain comes from per-run information, not from smaller quotes on average.", "Oracle with stronger dependence (exponent 1.5 on both rate and size): +0.591 (se 0.422), worse than exponent 1.", "Exponent 0.75 on estimated rate and size: -0.248 (se 0.165) against exponent 1, rejected.", "Multiplying estimated size by 1.11 / 1.05 so the prior matches the base's m=5: -0.097 (se 0.270) / -0.209 (se 0.179), rejected.", "kA 0.6 instead of 0.7 on top of the estimator: -0.010 (se 0.148), rejected: optimum is flat.", "Estimator without down-weighting used-up orders: size estimate biased +14.6% in log at step 1000 and rms log flow error 0.237, because arbitrageur sweeps look like large retail orders. Adding 0.05 / 0.15 / 0.5 to the censored likelihood cut flow rms at step 1000 to 0.181 / 0.157 / 0.148 and bias to +0.015 on 245 runs; kept 0.5.", "Estimator sizing only (rate and size into rho and mu): +0.907 (se 0.347), retail -0.887, arb +1.794 on the tuning half.", "Kept: estimator sizing + stock + ammo target: +1.151 (se 0.364) on the half used to find it, +0.898 (se 0.560) on the other half of the tuning seeds, then +2.445 (se 0.665) on unseen."], "next": "Flow is nearly used up under this sizing formula: the oracle ceiling is 1.49 on the tuning half and the estimate reaches about 1.15 there. The remaining gap is early in the run, so a seat could count retail arrivals from the probes as well as main orders, which raises exposure in the first 200 steps. Larger gains need a different size rule at 20-80 cents, where the base takes only 40% of retail buy dollars ($261 of $646) and retail and arbitrage trade about 1 to 1 at the margin."}