We use analytics to improve the website, which helps us reach more people. Essential cookies are always on. Cookie Policy
Last updated: September 19, 2026
A backtest number is only worth as much as the assumptions behind it, and those assumptions are usually invisible. Two platforms can run the same rules over the same days and report returns that differ by a factor of several, purely through cost modelling and fill assumptions.
So this page states the assumptions. Where GapperLab makes a choice that flatters results, it is named. Where the model is known to be optimistic, it is named too, in section 7.
The timeframe is part of the strategy, not a platform constant. Each strategy declares the bar size its rules are evaluated on, and the simulation runs on intraday bars at that resolution. A strategy written on 15-minute bars is backtested on 15-minute bars, and comparing its results against a 1-minute strategy is comparing two different models, not two different edges.
Universe construction and previous-day reference levels are derived from daily aggregates over the same price history the intraday bars come from, so a rule that refers to "yesterday's high" and a rule that refers to an intraday level are reading a consistent record rather than two histories that can disagree.
One consequence worth stating plainly: the simulation inherits whatever is wrong in the underlying price history, including bad prints and corporate-action adjustments applied after the fact. Coverage is also thinner for very illiquid names than for liquid ones, which matters in this niche specifically, because illiquid names are where the most extreme moves happen.
The word "gapper" is used loosely across the industry, so here is the definition this platform uses, which is broader than the common one.
A ticker-day enters the gapper segment when it moved at least 10% in any one of three separate windows:
Three clauses, not two. A stock that opened flat and then ran 30% in after-hours is in the segment. This matters when you reason about how many opportunities a strategy should have seen: applying the narrow "it opened with a gap" definition to this universe gives the wrong answer.
Related, because the name misleads: the gap-streak filter counts consecutive days a stock ran, not consecutive days it gapped, and it is capped at 11. A minimum of zero on that filter is a no-op, not a way to say "no streak".
R is the unit of risk. One R is what a single trade was designed to lose if the stop had been hit exactly as planned. A result of +2R means the trade made twice what it risked.
The denominator is what the stop was meant to cost. Expressing results in R rather than in percent is what makes trades of different sizes comparable, and it is why the platform reports expectancy, Sharpe and drawdown in R terms.
R is net, not gross. The numerator is realised profit and loss after commission and after short-locate fees, so every downstream metric that hangs off R already reflects those costs. A pre-cost R exists as an internal intermediate, because feeding a cost-adjusted number back into position sizing would charge commission twice, but it is never displayed and never returned anywhere.
Three costs are modelled, and they are applied at different stages, which is worth understanding because it changes what a reported figure includes.
All three flow into pnl_usd, and therefore into R, and therefore into every aggregate metric.
Entry price. By default a trade enters at the close of the bar that produced the signal, adjusted by the configured limit offset, with slippage applied against the position. If instead you configure a specific entry price, the simulation requires the following bar to actually trade through that price before filling: if it does not, no trade is taken. That is the conservative treatment, and it is why a price-triggered configuration produces fewer trades than a market-entry one over the same signals.
Position sizing is based on a fixed dollar risk per trade in every mode except the percent-of-account mode. The number of shares follows from that risk budget and the distance to the stop, so a wider stop buys fewer shares for the same risk.
Stops and targets are evaluated bar by bar at the strategy's own timeframe, including partial exits at multiple targets, in which case the reported R for the trade is the size-weighted blend of the legs and the remainder.
This is the section that matters most, and the one most backtest tools omit. Every item below makes reported results better than reality, not worse.
The practical reading: treat a backtested edge as an upper bound on the live edge, and treat a strategy whose edge only survives at low cost assumptions as not having an edge.
Some standard metrics are actively misleading in this asset class, and the platform takes documented positions on them.
The rules you backtest and the rules that watch the live session are held to each other automatically: both which trades trigger and what each metric evaluates to are compared, and a disagreement is treated as a defect. This matters more than it sounds. A platform where the tested behaviour and the live behaviour drift apart produces confidence that was never earned, which is worse than producing nothing.
The limitation is worth stating: what that guarantees is that the rules are evaluated the same way in both places. Whether the live market data reaching those rules is complete and timely on any given morning is a separate question, and no rule comparison can answer it.
If something on this page is wrong, incomplete, or does not match what the platform actually does, that is a defect and it is worth reporting to info@gapperlab.com. This page is versioned with the product and carries the date it was last revised.
More about the product and who operates it is on the about page.