Your Live Signal Stream Has No N — Online FDR Control After the Deflated Sharpe Ratio
The Deflated Sharpe Ratio answers a finished-batch question: you counted your trials, you have all N results, now correct the winner. A live scanner never gives you that batch. Signals arrive one at a time, each is acted on before the next exists, and the stream has no N. Muhammad Minhas Qamar's Online False Discovery Rate Control: Putting an Error Budget on a Live Signal Stream (MQL5 24577, 16 Oct 2026) ports the online answer — LORD3, LORD++ and SAFFRON — into pure MQL5, builds the causal p-value source they need, and then spends most of its effort trying to break them. This page is that method as the sequel the DSR page was missing. It is not a gate you bolt on to make a losing rule profitable; the author's own gated EA loses money, and says so.
The opening arithmetic is the motivation, and it is the author's: a 28-symbol × 7-timeframe scanner tested at 5% per cell expects roughly ten false lights per sweep on pure noise — about five hundred confident signals a year if run weekly. An EA firing forty times a month at 5% manufactures two false alarms a month by construction, and the strongest-looking are the ones that get deployed.
1 / What the object actually is
Alpha-wealth. Start with a budget w0 below the target α. Every hypothesis examined spends its test level α_t; every discovery refunds a payout (α − w0 for the first, α thereafter). Discoveries finance further testing; a long run of nulls starves the procedure — which, the author insists, is correct behaviour, not a defect. The guarantee, provided the p-values are valid: among the signals you acted on, the expected fraction that were noise stays below α. That is FDR, not family-wise error: it tolerates a known share of mistakes among discoveries in exchange for still being able to find things. A false discovery is a statement about the hypothesis, not the trade — a true discovery can lose money and a false one can win.
The level comes from a gamma sequence (non-increasing, summing to at most one) — the only real tuning knob. Two shapes ship. ZETA (j^-1.6 / ζ(1.6), ζ(1.6) ≈ 2.2856) front-loads: γ₁ = 0.4375, 88% of its allowance in the first 20 terms. LORD (the Javanmard–Montanari default) holds reserve: γ₁ = 0.0500, and after 2,000 hypotheses it has paid out only 0.305 of its total — a large part of LORD++'s later gap to target is the sequence, the author notes, not the procedure. Every number in the article uses the LORD sequence.
- LORD3 — level = γ indexed at the gap since the last rejection × the wealth recorded at that rejection. Compact, and therefore brittle: it prices today off one number produced at one moment.
- LORD++ — level priced off the entire rejection history, each past discovery decayed by how long ago it happened.
- SAFFRON — LORD++ with one change: hypotheses with p below λ are candidates and are tested for free (the gamma index advances only on non-candidates), with the sum scaled by (1 − λ) and capped at λ. At λ = 0.5 roughly half of null p-values are candidates, so in the calibration bench the shift and the scaling nearly cancel — SAFFRON and LORD++ are indistinguishable there, and the author says so plainly.
Where the p-values come from is the part a port can get wrong. The stream is firings, not bars (a bar-by-bar stream would submit near-duplicate questions). Five heterogeneous close-only rules ship (MA cross, z-score reversion, breakout, momentum, volatility squeeze), each firing on a transition, not a state. For a firing at bar i, the p-value is computed from the rule's own past firings inside an evidence window that ends h bars before i, so every forward return in it is already observed; the outcome window i..i+h is strictly later. The null is a stationary (block) bootstrap over the same window, same firing count, same direction multiset, mean block 20 against horizon h = 10 throughout. Two silent failures live here:
- The resolution floor. A rank-based bootstrap p-value cannot be smaller than 1/(B+1). At B = 200 the floor is 0.005, while LORD++ hands out 0.0025 on the first hypothesis and reaches 1e-4 by the twentieth quiet one. The smallest producible p-value is larger than the threshold it must clear: zero rejections are arithmetically certain, and from outside that looks exactly like a well-behaved quiet gate. B = 2000 only moves the floor to 5.00e-04. The fix shipped is
BOOT_NORMAL: keep the block-bootstrap null, read the tail off a normal fitted to the draws (centre estimated, not assumed zero). No floor — at the cost of an explicit modelling assumption in the far tail where there are no draws to check. - Anti-conservative tails. Validity requires super-uniformity — P(p ≤ x) ≤ x — which is one-sided. The author's first attempt used a two-sided KS test and condemned the correct bootstrap alongside the broken comparator; the shipped check is D+ = sup(F_n(x) − x).
Calibration before the market (α 0.10, w0 0.05, λ 0.50, LORD gamma, seed 20260826, as reported). On null series: 6,148 null hypotheses from four 6,000-bar Gaussian random walks at B = 2000. Both bootstrap modes pass D+ (0.0101 and 0.0118 vs 5% critical 0.0156); the naive t-test fails (0.0828), returning 10.74% of p-values below 0.05 where 5% are promised. The uncomfortable column the author keeps: below 0.01, the rank bootstrap returns 1.63% and boot-normal 1.84% — neither is conservative that deep, and the online levels live deeper still. D+ passing means "no gross failure", not "valid at the levels the procedures use". Then, procedures alone (exact p-values, 2,000 hypotheses, 5% non-null at effect size 3 SD, target FDR 10%, 200 replications): uncorrected realises FDR 0.6691 at power 0.9567; Bonferroni 0.0013 at power 0.0841; LORD3 0.0786 / 0.4021; LORD++ 0.0266 / 0.3123; SAFFRON 0.0242 / 0.3125. All three real procedures sit under the 10% target; LORD3 is closest and most powerful — in the independent case.
2 / What it does not claim — and where it fails
- Block dependence breaks two of the three. The dependence bench (two models, one generator, 100 reps/cell, no confidence intervals tabled — the author flags cells near 0.10 as uncallable) reports, at block correlation ρ = 0.9: LORD3 FDR 0.2396 (≈2.4× its target), SAFFRON 0.1542, LORD++ 0.0760 — the only one under target in every cell. LORD3's extra independent-case power is exactly what it cannot afford when p-values correlate.
- Bursts, in this model, cost power, not validity. At within-burst correlation 0.95, repeats rarely reject at all; LORD3 loses nearly half its power at burst length 10 (FDR 0.0386) while staying under target. Weaker within-burst correlation was not tested.
- The throttle buys the guarantee back with questions. Submitting only the first hypothesis per group per gap (gap 25 in the block cells) drives LORD3 at ρ = 0.9 from 0.2396 to 0.0125 — but cuts a 2,000-hypothesis stream to 100, with power falling with it. Under bursts the trade can invert: dropping a repeat that would never reject saves budget, and at burst length 10 throttling lifts LORD3's power while cutting FDR.
- A discovery is not an edge. On 20,000 EURUSD H1 bars (3,428 tested hypotheses), the gated procedures accept about 3% of the stream and the accepted side's mean 10-bar forward return lands near zero (LORD++ −0.000002, SAFFRON +0.000003, author); the uncorrected arm's 382 accepts carry +0.000018, "comfortably inside the spread". Had every hypothesis been null, control at 0.10 would allow a rejection on at most one run in ten — not a hundred. The gap between a statistical discovery and a tradable edge is one no FDR procedure closes.
- The gated EA loses in both arms. EURUSD H1, Jan 2024–Jun 2026, SAFFRON at α 0.10 (chosen for legibility on the panel; the author recommends LORD++, and notes the two are within two accepts on this stream): GATE_OFF 938 trades, net −$1,773.90, max DD 19.08%; GATE_ON 89 trades, net −$132.86, max DD 2.95%. Expected payoff differs by about $0.40 per trade against a per-trade noise scale the author puts at "tens of dollars" on 89 trades, and the control arm skipped 1,232 of 2,195 signals because the book was busy — so this is an execution-realism check, not a clean signal comparison, and a random gate passing the same 5% would cut exposure just as much. That control was not run.
- Starvation is the practical failure mode. Share of hypotheses tested below the 1e-4 floor: Bonferroni 98.9% of the stream, LORD3 57.5%, LORD++ 33.3%, SAFFRON 32.6%. On a 4,000-bar window the identical LORD++ configuration made zero discoveries and sat starved for 94% of its tests. Judge a quiet gate by its starved share, not its silence. The author's "roughly one half" warning level is a practical rule used in the article, not derived from theory — quoted as such.
- Scope. The dependence envelope is two models from one generator; the calibration nulls are Gaussian with constant volatility, so the bench cannot expose error in the normal tail fit on fat-tailed returns; and marginal super-uniformity is necessary, not sufficient, for the conditional validity the proofs assume. SAFFRON's reported end-of-run "wealth" of 7.658 is the shared ledger's bookkeeping (refunds 10.65 vs charges 3.04), never compared against a probability — the author warns against reading it as one.
3 / How a reader could tear it down next
Not a signal. A next attempt on a stream you already run:
- Validate the p-value source first, one-sided, and then past D+. Super-uniformity on a known-null series, then the sub-0.01 tail specifically, because that is where online levels live. A marginal check does not establish conditional validity; treat a pass as a licence to continue, not as the guarantee.
- Check resolution against the smallest level before you check anything else. If your p-value floor sits above the level the procedure will assign after a quiet stretch, zero rejections are guaranteed by arithmetic. Change the estimator (a fitted tail, with its assumption stated), not just the replication count.
- Default to LORD++ when dependence is unknown — on this evidence it is the only one of the three that held in every block and burst cell. If you ship LORD3 or SAFFRON on a multi-symbol, multi-timeframe scanner (the block-dependence case), the burden of proof is yours.
- Throttle correlated groups. One submission per group per gap, gap pre-declared. Expect to buy the guarantee back with most of the questions under block dependence; under pure repetition it can be nearly free.
- Report the starved share with every quiet result. A gate that found nothing while spending a third (or 94%) of its stream below 1e-4 has told you about its budget, not about the market. Throttle the stream rather than lowering α until something passes.
- Keep the arms honest. If you A/B a gate, the control must be "every tested firing" with the same position constraints, plus the control this article did not run: a random gate passing the same fraction. Otherwise fewer trades will flatter any gate.
4 / Verdict
The DSR corrects a batch you have finished; online FDR control is the error budget for a stream that never finishes. The portable findings are narrower than the port: validate p-values one-sided and in the far tail, never let a resolution floor masquerade as conservatism, prefer LORD++ under unknown dependence, and read starved share before you read silence. None of that makes the underlying rules profitable — on the author's EURUSD stream there was nothing to find, and the gate correctly found approximately nothing, at 3% of the exposure. The small open edge is procedural: a live scanner that today reports "significant at 5%" per cell is running the uncorrected arm, whose measured false-discovery share in the bench was two-thirds. Replacing that one habit is a real improvement even before any rule behind the gate has an edge.
Source
- Muhammad Minhas Qamar, Online False Discovery Rate Control: Putting an Error Budget on a Live Signal Stream, MQL5, 16 Oct 2026. https://www.mql5.com/en/articles/24577
- Fetched in full 2026-10-17. Attached MQL5.zip (44.59 KB per the page) was not vendored, compiled, or run here. Companion on this site: Deflated Sharpe Ratio.
Numbers
From the article, not from a Quant for Free run: scanner arithmetic ≈10 false lights per 196-cell sweep at 5%, ≈500/year weekly (author's illustration); gamma γ₁ LORD 0.0500 vs ZETA 0.4375, LORD sum 0.305 after 2,000 terms, ζ(1.6) ≈ 2.2856; calibration 6,148 null hypotheses, D+ bootstrap 0.0101 / boot-normal 0.0118 / t-test 0.0828 (critical 0.0156), P(p<0.05) 0.0395 / 0.0389 / 0.1074, P(p<0.01) 0.0163 / 0.0184 / 0.0423, smallest p 5.00e-04 vs 3.23e-13; procedure bench (target 0.10) FDR/power: uncorrected 0.6691/0.9567, Bonferroni 0.0013/0.0841, LORD3 0.0786/0.4021, LORD++ 0.0266/0.3123, SAFFRON 0.0242/0.3125; block ρ=0.9 FDR LORD3 0.2396, SAFFRON 0.1542, LORD++ 0.0760, throttled LORD3 0.0125 (2,000 → 100 hypotheses at gap 25); EURUSD stream 3,428 hypotheses, accepts ≈3%, starved shares 98.9% / 57.5% / 33.3% / 32.6% (Bonferroni/LORD3/LORD++/SAFFRON), 4,000-bar LORD++ starved 94%; gated EA (SAFFRON, α 0.10) OFF 938 trades −$1,773.90 DD 19.08% vs ON 89 trades −$132.86 DD 2.95%, passed 116, book-busy skips 1,232 (OFF) vs 22 (ON). Config throughout: h=10, B=2000 (StreamBench) / 500 (EA), mean block 20, evidence window 1,500 bars, ≥25 past firings, α 0.10, w0 0.05, λ 0.50, seed 20260826. No site numbers; no summary.json (no clean-room run).
summary.json. Figures in the text are the source’s, labeled as such. See the full disclaimer.