Why Renko backtests lie in NinjaTrader
A standard Renko brick's open and close are grid values, not trades, so whatever your backtest computes from them, it computes from prices that were never printed.
A standard Renko brick is drawn on a fixed price grid, and NinjaTrader's built-in bricks invent their open and close — both are grid levels, not prices a trade occurred at. Any test that fills at bar open or bar close is filling at those two numbers, so a strategy tested on built-in Renko is tested on prices that never printed. The arithmetic is fine. The inputs are grid values.
What a standard Renko brick actually records
Renko ignores time. A brick completes when price has moved a fixed distance, and the next brick starts from the grid level the last one closed at. That is the bar type working as designed, and it is why the chart looks so clean.
All four numbers a brick carries come out of that design rather than out of the tape. The built-in bricks invent their open and close, and with no wicks there is nothing else to read: the high and the low are the body, which is those same two grid values again.
So a brick that reads as a one-point move from 5000.00 to 5001.00 could have come from a run to 5001.75 and back, or from eight ticks of chop that finally tipped over. Both produce the same brick. The difference between them is not in the record.
What that does to a backtest
Three things follow from that, and none of them looks like a defect while the test is running.
Fills sit on grid levels. An order filled at a brick's open or close is filled at a level the grid picked. Since the built-in bricks invent both of those numbers, a strategy tested that way is tested on prices that never printed — which is a different set of prices from the ones a resting order would have met.
Anything reading High and Low reads the body. An ATR, a channel, a swing detector, a stop placed a fixed distance beyond the previous bar's extreme: all of them take High and Low from the bar. On bricks without wicks those two values are the brick's own edges, so the range they report is the brick size rather than the distance price covered inside it.
A gap-crossing brick can be indistinguishable from a traded one. When price crosses several grid levels at once, across a data gap or in one fast print, the levels in between still have to be filled with bricks. Unless a brick is marked as one of those, nothing reading the series afterwards can separate it from a brick that trades built.
None of the three is an error in the test. They are properties of the bars the test was handed.
What real wicks and a real open change
A bars type built the other way keeps the grid where the grid belongs and changes where the other numbers come from.
The close stays quantized. A brick's close is the grid level it confirmed at, and that quantized close is the Renko part of the bar type — it is a grid level and it stays one.
The tick that confirms a brick belongs to the next brick. Its price opens that brick and its volume is the first volume counted into it, so the open is a price something traded at. While a brick develops, its high and low track the real extremes the trades reached; only the confirming boundary is clipped into whichever of the two the brick completes on. Bricks that exist only because price traversed grid levels with no prints in between are emitted as explicit gap-fill bricks at zero volume, so a brick built by trades and a brick built to cross a gap are not the same object in the series. Closed bricks are appended once and never revisited, so nothing behind the developing brick moves after the fact.
At a session boundary the last brick is left as an unconfirmed partial rather than forced onto the grid, and the grid re-seeds from that price on the next session's first tick.
What that changes for a test is narrow, and worth keeping narrow: the open is a traded price, the high and low are the range the brick covered, the close is still a grid level, and the gap-fill bricks are labeled as gap fills. Whether a strategy holds up is a separate question, and the bars type has no opinion on it.
Where this shows up in my own tools
TakeFlight Renko + Projection is what I built because I wanted Renko I could trust in a backtest: a NinjaTrader 8 bars type that keeps the true open, high and low alongside the grid-quantized close, marks its gap-fill bricks at zero volume, and never revisits a closed brick. It ships with the projection overlay I wrote alongside it, which draws where the next brick completes on both sides while the current one is still forming.
Built custom. I do this for hire — fixed quote, most jobs under a week. Get a quote →