TL;DR: A candle records only its open, high, low and close, not the order in which the high and low happened. When a trade's take-profit and stop-loss both fall inside one candle, the backtester has to decide which came first, and an optimistic rule quietly inflates win rates. The honest approach is to look inside the bar with finer data, and when that still cannot settle it, let the stop win.
Why is a stop and a target in one candle a problem?
Imagine a long position entered at 100 with a take-profit at 102 and a stop-loss at 99. The next 4-hour candle opens at 100.2, trades as high as 102.5 and as low as 98.7, and closes at 100.8.
Both of your exits were touched. If the price went up first, you made 2%. If it went down first, you lost 1%. The candle itself cannot tell you which, because OHLC data summarizes four prices and throws away the path between them.
This is not an edge case. Any time the distance between your exits is comparable to the typical high-to-low range of a bar, a meaningful share of trades will end in an ambiguous candle. The backtester's rule for those trades becomes part of your strategy's result, whether you chose it or not.
What rules do backtesters use?
There are five common approaches, each with a different bias.
| Rule | What it assumes | Bias |
|---|---|---|
| Take-profit first | Price reached the target before the stop | Optimistic; inflates win rate |
| Stop first | Price reached the stop before the target | Conservative; can understate slightly |
| Open-proximity heuristic | Whichever level is closer to the open was hit first | Reasonable guess, still a guess |
| Random or 50/50 | Each outcome equally likely | Adds noise; unbiased only if paths are truly symmetric |
| Intrabar replay | Uses finer bars inside the candle to find the real order | Most accurate, needs finer data |
The optimistic rule is common in quick spreadsheet or notebook backtests because it falls out naturally from checking the take-profit condition before the stop condition in code. Nobody chose it on purpose; it is simply the order the if statements were written in.
How much can the tie-break change a result?
Here is a hypothetical illustration. A strategy makes 300 trades with a 2% take-profit and a 1% stop-loss. Suppose 240 trades resolve cleanly, 110 at the target and 130 at the stop, and the remaining 60 end in a candle that touched both levels.
| Tie-break rule | Winners | Losers | Win rate | Sum of trade returns |
|---|---|---|---|---|
| Take-profit first | 170 | 130 | 56.7% | +210% |
| Stop first | 110 | 190 | 36.7% | +30% |
| Half and half | 140 | 160 | 46.7% | +120% |
The signal, entries and exits are identical in every row. Only the assumption about 60 ambiguous candles changed, and the summed return moved from +30% to +210% of notional, before fees. A strategy that looked excellent under the optimistic rule is barely positive under the conservative one, and it would likely be negative after costs.
The effect grows with three things:
- Tighter exits. A 0.5% stop on a 4-hour chart is touched by many candles.
- Longer timeframes. A daily candle contains far more price path than a 15-minute one.
- Volatile markets. Crypto perps routinely have hourly ranges that span both a tight target and a tight stop.
Why not just assume the stop always wins?
"Stop first" is a sound default because its error runs in the safe direction: it can make a real strategy look slightly worse, but it cannot make a bad one look good. That said, it throws away information. In many ambiguous candles the target really was reached first, and a finer look can recover that.
The better approach is to resolve what you can and be conservative only about what you cannot. That means stepping inside the candle with smaller bars:
- Take the ambiguous bar, say a 4-hour candle.
- Load the shorter bars that make it up, for example 48 five-minute bars.
- Walk through them in order and see which level was touched first.
- If a single short bar touches both levels, or the finer data is missing, fall back to the conservative rule.
Replay narrows the ambiguity from hours to minutes. It does not eliminate it, because a 5-minute bar is still a summary of its own price path, but it greatly reduces the number of trades that depend on a guess.
How does Trigr handle it?
Trigr uses the replay-then-conservative approach by default. When a take-profit and stop-loss are both touched inside one bar, the engine replays 5-minute bars inside it to find which level was hit first. If that still cannot decide it, the stop-loss wins. On a 5-minute strategy there is no finer bar to replay, so ties go to the stop directly.
Two related conventions follow the same philosophy:
- Gaps. A stop that the market gaps through fills at the worse opening price, as a real stop-market order would, rather than at the stop level.
- Missing data. The engine never fills gaps in data with invented values. If a required input is missing, the signal stays pending instead of firing on a guess.
This is one piece of a broader discipline covered in point-in-time backtesting. Entries also follow a causal rule: a signal computed on a bar's close fills at the next bar's open, not the same close. We cover that in next-bar-open fills and how fill assumptions change results. The backtesting docs summarize the intrabar and data rules in one place.
What this means for you
You do not need to audit the engine's code to trust how exits were resolved. Every result includes the full trade log, so you can open any trade, see where it exited and check it against the chart. If you see an unusually high win rate with tight exits, the likely explanation is no longer "the backtester guessed in my favor."
The cost is that some strategies look worse on Trigr than in a quick script. That is the point: a conservative tie-break removes one of the easiest ways for a backtest to flatter a strategy.
How should you set exits to avoid the problem?
Intrabar ambiguity is partly a design choice. You can reduce it before any backtest runs:
- Size exits to the bar range. Compare your take-profit and stop distances with the average high-to-low range of the timeframe, or with ATR. If both exits sit inside one typical bar, expect many ties.
- Match timeframe to exit distance. Tight scalping exits belong on short timeframes. A 0.5% target on a daily chart is mostly a question about the intrabar path, not about your signal.
- Prefer volatility-scaled exits. An ATR trailing stop adapts distance to current volatility, which keeps the exit meaningful across calm and wild markets. Trigr's RISK node offers an ATR trail, a time stop and exit on signal flip alongside fixed take-profit and stop-loss between 0.2% and 50%. See risk settings that matter for how to combine them.
- Stress the exits. Move the take-profit and stop by 25% in each direction and rerun. A strategy whose result depends heavily on exactly where the exits sit is showing one of the warning signs of overfitting.
Live trading has its own version of this problem. A real stop order on Hyperliquid triggers on the venue's mark price and then executes against the order book, so fills can differ from the exact stop level. A conservative backtest does not remove that gap, but it avoids adding an optimistic one on top. Backtests are not guarantees; perps are leveraged and can lose more than expected.
A quick checklist for any backtester
| Question | Good answer |
|---|---|
| What happens when TP and SL share a bar? | A stated rule, ideally replay with a conservative fallback |
| Where does a gapped stop fill? | At the worse opening price, not the stop level |
| Can you inspect each trade's exit? | Yes, in a full trade log |
| How close are your exits to the typical bar range? | Comfortably wider, or a shorter timeframe |
| Does the result survive moving exits by 25%? | Mostly, with gradual degradation |
If a tool cannot answer the first question, assume the optimistic rule and discount the win rate accordingly.
Next steps
Rerun a strategy that uses tight exits, then walk through its trade log, check where each trade exited, and compare the win rate with what you expected. You can also ask an AI assistant to run and inspect those backtests for you once you connect it over MCP.