The backtest says your AI trading agent works. The preflight tells you whether to believe it.
The agent runs, the backtest chart goes up, and the only question that matters is whether any of it survives real money. Paste your trades and TripleBarrier computes the evidence — Sharpe with a confidence interval, deflated for the variants you tried, the cost at which your edge dies — then interrogates it for overfitting, look-ahead bias, and untested regimes before the agent gets anywhere near a live account.
The same bot, asked four questions
A regime-switching Bitcoin bot we built and tested on our own bench: two years of hourly data, 0.07% per side in costs, 2.5x leverage. Nothing about the model changed between these rows. Only the honesty of the test did.
The version people screenshot is the first row. The version your money experiences is the third.
| In-sample, no costs | +28.7% |
| Walk-forward, no costs | +36.9% |
| Walk-forward, with costs | −83.8% |
| Buy-and-hold, same period | +30.0% |
Table 1. Total return of one strategy under four test conditions, from a real run in our lab. Educational demo; hypothetical performance; not financial advice.
Live instruments
The method, and the selection-bias problem
Both instruments compute live in your browser from the same seeded, deterministic code this site uses everywhere — no hand-drawn numbers.
Triple-barrier labeling
The labeling method this site is named after: profit-take, stop-loss, and time barriers around every entry; the first barrier hit decides the label.
- Label
- −1 · stop-loss
- Exit
- t=41
- Trade return
- −3.6%
- PT / SL
- 111.4 / 104.2
Fig. 1 — labelEntry() on a seeded synthetic path (seed 73, N=120 bars, σ-scaled barriers, horizon 20). Sliders recompute the label live.
Expected maximum Sharpe, N trials
Your AI tried many configurations before showing you the winner. This is what the best of N looks like when none of them has an edge — and the deflated-Sharpe bar for calling it skill.
- N trials
- 100
- E[max SR], zero edge
- 2.53
- DSR 95% needs
- 4.21
- Skill margin
- +1.68
Fig. 2 — E[max SR] across N zero-edge strategies (Bailey & López de Prado, 2014) and the observed Sharpe needed for DSR ≥ 95%, T=252 daily bars.
Terms the report uses
- Backtest
- A strategy replayed over historical prices. Evidence only when the test couldn't peek at the answers.
- Overfitting
- The model memorized the past instead of learning a pattern — it aces the backtest and fails live.
- Sharpe ratio
- Mean return per unit of volatility; the standard one-number score for a strategy.
- Walk-forward analysis
- Fit on a rolling window, test on the next slice — development the way live trading actually happens.
- Deflated Sharpe ratio
- A Sharpe corrected for how many strategies were tried before this one. Selection luck is priced in.
The deliverable
A finished report, start to finish
This is exactly what you get. We generated a synthetic trade log — a bot that looks fundable at a glance — pasted it in, and let the pipeline compute the battery and write the verdict. The charts below are rendered from that computed battery; the submission, the numbers, and the report are unedited.
Submitted backtest
Instrument: single synthetic asset; 240 trades, 2024-01-03 to 2024-12-03 Data: seeded synthetic trade log (seed 53) from the included generator — not market data Total return over the log: +57.6% Annualized Sharpe: 1.90 Max drawdown: −15.3% Win rate: 56% Avg win/avg loss payoff: 1.04 Trades: 240 Variants tried before this one: 60 Tuned parameters: 6 Costs assumed: none. Execution: the signal and the fill use the same bar close.
Computed battery
240 obs · trade-level · 261 periods/yrFig. A — cumulative equity with drawdown shading, from 240 observations.
Fig. B — bootstrap of the annualized Sharpe (2,000 seeded resamples). Amber = observed; band = 95% CI; dashed = the Sharpe you stated.
Fig. C — rolling 40-period annualized Sharpe. Swings across zero mean the edge lived in only part of the window.
Fig. D — net Sharpe as per-side cost rises. The edge dies at 10.2 bps per side.
Return autocorrelation
±0.13 = sig.| lag | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| acf | 0.15* | 0.02 | −0.07 | 0.07 | −0.03 |
Significant positive lag-1: a smoothing or look-ahead tell worth explaining.
Payoff & edge attribution
- win rate
- 56%
- payoff
- 1.04
- breakeven wr
- 49%
- trades
- 240
- trades / parameter
- 40.0 (adequate)
- α/yr
- 57.6%
- β
- 0.34
- R²
- 0.05
Treated as a trade list (a side/size column was present), so per-trade diagnostics apply. A benchmark column was found; alpha / beta / R² will be regressed against it (no external market data is ever fetched). Annualization uses 260.6 periods/year, inferred from the dates in the paste. Figures are deterministic (seed 2654435769).
Backtest Audit Report
Verdict
DO NOT FUND ON THIS EVIDENCE.
The result is built on a confirmed same-bar look-ahead — the position at bar i earns the return computed from bar i — so the 1.90 Sharpe rests on a move the strategy could not have captured live. Even setting that aside, the deflated Sharpe after 60 variants gives the edge a 30.4% chance of being real (fails the 95% bar), and the observed 1.90 sits below the 2.44 Sharpe that random search on noise would be expected to throw off. This is a clean, honest demonstration of a strategy whose reported numbers the evidence does not support — which, since it is openly labeled synthetic, is exactly what it appears designed to show.
Computed diagnostics
The observed annualized Sharpe is 1.90, but its bootstrap 95% confidence interval is [−0.12, 3.96], which contains zero — the edge is statistically indistinguishable from luck at that confidence. The single-shot Probabilistic Sharpe reads 96.5% (passes 95%), but that figure ignores the 60 variants tried; once selection is priced in, the deflated Sharpe collapses to 30.4% and fails. The selection benchmark E[max Sharpe] is 2.44, so with 60 tries on noise you would expect a best-of-batch Sharpe near 2.44 by luck alone — the observed 1.90 is below that line. The max drawdown of 15.3% is not suspicious: it sits inside the Monte Carlo band [9.8%, 29.0%] with a mean of 16.8%, so the equity curve is realistically rough, not doctored. The lag-1 return autocorrelation of 0.15 is significant (threshold ±0.13) while every later lag is noise — the statistical fingerprint of a same-bar peek, concentrated exactly where look-ahead would put it. The 40-period rolling Sharpe swings from −2.21 to 8.69, so the full-sample 1.90 is an average over wildly different stretches, not a stable property. The longest underwater span is 68 periods. Costs finish the story: net mean return hits zero at 10.2 bps per side, and against a payoff of 1.04 and a breakeven win rate of 49.1% versus observed 56.3%, the margin is thin and cost-fragile.
What holds up
- The summary statistics are internally consistent. Every stated headline matches the computed value: Sharpe 1.90/1.90, drawdown −15.3%/15.3%, win rate 56%/56.3%, payoff 1.04/1.04, trades 240/240. The arithmetic is clean.
- The drawdown is honest. Observed 15.3% sits inside the Monte Carlo expected band with mean 16.8%. No evidence of a too-smooth or doctored equity line.
- The look-ahead is disclosed, not hidden. The prose states "signal and fill use the same bar close," and the code comment says "same-bar look-ahead lives here" outright. The submission tells you where the body is buried.
- The data is labeled synthetic and makes no tradability claim. Seed 53, generator output, stated plainly. It does not pretend to be market data.
- Data-per-parameter is adequate. 240 trades / 6 tuned parameters = 40 per parameter. The problem is not thin data per knob.
- No embedded instructions to the analyst were found in the submission.
What does not hold up
- Same-bar look-ahead manufactures the Sharpe. The position at bar
iearns the return *into* closei, which the signal was computed from. This is not a tradable rule; it is a peek. Confirmed by the code comment and by the significant lag-1 autocorrelation of 0.15 (later lags are noise). This is the failure most likely to flip the sign of the result — remove it and the reported edge may not exist at all. *Fix:* decide the signal on closei, fill oni+1, and re-run every metric.
- Selection is not priced into the headline. 60 variants were tried; the prose reports raw Sharpe 1.90 with no confidence figure. The deflated Sharpe is 30.4% (fails 95%), and 1.90 sits below the 2.44 luck benchmark. The reported number overstates what the evidence supports. *Fix:* report the deflated Sharpe alongside the raw one, and describe the search space and selection rule so the 60 tries can be audited.
- The edge is cost-fragile. Net mean return hits zero at 10.2 bps per side. A bot that re-decides position every bar generates many round trips, and roughly 20 bps of round-trip friction erases everything. Zero cost is assumed. *Fix:* add a commission-plus-slippage model and report the round-trip count so the 10.2 bps breakeven can be converted into a realized net figure.
- One synthetic path proves no regime robustness. Seed 53 is a single generator draw with no crises, gaps, or liquidity events. The rolling Sharpe range of −2.21 to 8.69 shows the edge is unstable even within that one path. *Fix:* real market data, out-of-sample, across multiple regimes — none of which exists here.
- No out-of-sample or walk-forward split. Every number is in-sample on the same data the parameters were chosen on. *Fix:* a purged, embargoed walk-forward split.
The three numbers that matter most
- Deflated Sharpe probability the edge is real: 30.4% (computed; fails the 95% bar, below the 2.44 luck benchmark).
- Lag-1 autocorrelation: 0.15 (computed; significant at ±0.13 — the look-ahead fingerprint that supports the 1.90 Sharpe).
- Cost breakeven: 10.2 bps per side (computed; the entire edge lives inside a 0-to-10.2 bps window).
What to test next
- Fix the execution timing first. Signal on close
i, fill oni+1. Re-run all metrics. Everything downstream is meaningless until the look-ahead is gone. - Re-run on real market data for the same instrument class the generator is meant to stand in for. The synthetic path cannot speak to tradability.
- Add a cost and slippage model and report net metrics, with the round-trip count made explicit.
- Document the 60-variant search — the space, the selection rule — and report the deflated Sharpe as the headline, not the raw one.
- Split out-of-sample with purging and embargo, and report in-sample versus out-of-sample metrics side by side.
Code fixes
The code was provided and cross-checked (lookback=20, entry_z=1.5, ±1 position confirmed). The defects:
- Same-bar look-ahead. *Defect:* the signal is computed from close
iand applied toprices[i]/prices[i-1] - 1, the return ending at closei— the code comment admits it. *Fix:* apply the signal decided at closeito the return fromitoi+1(prices[i+1]/prices[i] - 1), i.e. lag the position by one bar. *Why it changes the result:* it removes the return the strategy could not have captured; the 1.90 Sharpe and the 0.15 lag-1 autocorrelation should both fall. - Zero cost. *Defect:* no commission or slippage anywhere. *Fix:* subtract a per-side cost on every position change and expose it as a parameter. *Why:* the edge is zero at 10.2 bps per side, so any realistic cost materially changes net return.
- No round-trip accounting. *Defect:* the code re-decides every bar but does not count or charge position changes. *Fix:* count each change of position as a round trip and apply cost to it. *Why:* it converts the abstract 10.2 bps breakeven into a realized figure.
- In-sample everything. *Defect:* no train/test separation. *Fix:* add a purged, embargoed walk-forward split and report metrics per fold. *Why:* it stops parameter choice from leaking into the reported result.
Feature and label engineering
- Lag the z-score input. Compute the rolling mean and z-score using data up to and including close
i, and act only oni+1. The current construction reads the bar it trades. Removing that peek is the whole point of the next test. - Check the rolling mean for leakage. Confirm the 20-bar window is strictly backward-looking (no centered window, no inclusion of the current unrealized bar in a way that anticipates the fill).
- Move toward stationary inputs. The z-score is already a normalization, but verify the rolling standard deviation is estimated on a trailing window only, so the scaling itself is not forward-looking.
- Label trades honestly. Positions currently re-decide every bar with no exit rule, which blurs "trade" and "bar." Use volatility-scaled, event-based labels (e.g. triple-barrier: profit-take, stop, and time limit sized to local volatility) so each trade has a defined horizon and outcome rather than an implicit hold-until-flip.
- Split hygiene. Purge observations whose label windows overlap the train/test boundary, and embargo a gap after each test fold. Without this, adjacent overlapping returns leak across the split.
Every item above is about making the measurement trustworthy, not about raising returns.
Fix-it prompt
You wrote a backtest for a z-score mean-reversion bot on a synthetic series
(seed 53). An evidence audit found specific defects. Fix them for measurement
honesty only. Do NOT propose new trade ideas, do NOT tune parameters to raise
returns, and do NOT make any claim about future performance. Report metrics,
not promises.
Fix these defects:
1. SAME-BAR LOOK-AHEAD. The position at bar i currently earns the return
prices[i]/prices[i-1]-1, computed from close i — the same bar the signal
reads. Your own comment says "same-bar look-ahead lives here." Change it so
the signal decided at close i is applied to the return from i to i+1
(prices[i+1]/prices[i]-1). This is the change most likely to move the result:
the audit found a significant lag-1 autocorrelation of 0.15 that is the
fingerprint of this peek.
2. ZERO COST. Add a per-side transaction cost plus slippage on every position
change, exposed as a parameter. The audit found net mean return hits zero at
10.2 bps per side, so this is decisive. Count and report the number of round
trips.
3. SELECTION NOT PRICED IN. 60 variants were tried. Report the deflated Sharpe
(the audit computed 30.4% probability the edge is real, below the E[max]=2.44
luck benchmark) as the headline, alongside the raw Sharpe. Document the search
space and the rule used to pick this variant.
4. NO OUT-OF-SAMPLE SPLIT. Add a purged, embargoed walk-forward split. Purge
observations whose label windows cross the train/test boundary; embargo a gap
after each test fold.
Apply this feature and label engineering:
- Ensure the rolling mean and standard deviation use strictly trailing windows.
- Relabel trades with volatility-scaled, event-based labels (triple-barrier:
profit-take, stop, time limit sized to local volatility) instead of
hold-until-flip, so each trade has a defined horizon.
Then re-run the backtest and report, side by side, BEFORE and AFTER the fixes:
annualized Sharpe, bootstrap 95% CI, deflated Sharpe, max drawdown, longest
underwater span, win rate, payoff, lag-1 autocorrelation, round-trip count, and
net return at 0, 5, and 10 bps per-side cost. State plainly if the edge does not
survive the execution-timing fix.Scope of this report
This is an educational analysis of the evidence in the submission, based only on what was provided and the deterministic diagnostics computed from the buyer's own data. Hypothetical and synthetic performance has inherent limitations, including hindsight bias and the absence of real fills, costs, and market regimes. Nothing here is financial advice, a valuation of any strategy, or a prediction of future results; it judges the quality of the evidence and nothing else.
Generated by the production pipeline on 2026-07-06 from the synthetic submission shown above. The trade log, its benchmark column, and every number are synthetic and say so inside the submission itself; the figures are deterministic; no customer data appears here.
Start free
The Honest Backtest Checklist
Twelve questions about how your backtest was actually run — out-of-sample discipline, costs, look-ahead, parameter count, regime coverage — scored deterministically into a letter grade, with the reason behind every failed answer. No account, and the grading runs in your browser. Leave an email on the result if you want to keep it.
Run the free checklist$65, one time · one full analysis
The Backtest Audit
A chat can read your code. It cannot bootstrap your Sharpe. Paste your trades and the audit computes a deterministic battery — Sharpe with a confidence interval, deflated for the variants you tried, your drawdown against what your return and volatility predict, and the cost at which your edge dies. Then a multi-phase analysis interprets those numbers, reviews your code, and writes a verdict report you keep — with a fix-it prompt you can paste back into the AI that built the agent.
- →Sharpe with a bootstrap confidence interval, and a deflated Sharpe that prices in selection luck
- →Drawdown vs. what your return/vol predicts, rolling Sharpe, and a cost-sensitivity curve — as charts
- →Verdict on the evidence, code fixes for look-ahead and leakage, and a paste-back fix-it prompt
- →Report saved to your account — yours to keep
Straight answers
How do I know if my backtest is overfitted?
Symptoms: results collapse out-of-sample, small parameter changes swing the outcome, more tuned parameters than independent trades, and a test window that doubled as the development window. The audit checks all of these against your actual submission — plus costs, look-ahead bugs in your code, and what market regimes the test never saw.
What exactly do I get for $65?
Paste your trades and the audit computes a deterministic battery: your Sharpe with a bootstrap confidence interval, a deflated Sharpe that accounts for how many variants you tried, drawdown measured against what your return and volatility predict, rolling Sharpe, return autocorrelation, and a cost-sensitivity curve that finds the trading cost at which your edge dies — all as charts. Then a multi-phase analysis interprets those numbers, reviews your code, and writes a verdict report you keep. A chat can read your code; it cannot bootstrap your Sharpe. That is the $65. Without pasted trades the audit still runs, but it can only read — the cover says so.
Will it tell me what to trade?
No. The report judges the evidence you submitted: what holds, what doesn't, and what to test next. A good verdict means "the methodology supports the numbers," never "this will make money." Anyone who sells you the second thing for $65 is lying about something.
What happens to my strategy?
Your submission is analyzed by our server-side AI pipeline, under API terms that prohibit training on your data. We store only the final report on your account so you can come back to it. We don't trade, and we're not interested in your edge — only in whether you've proven it exists.