How to Use Bar Magnifier in a Pine Script v6 Strategy

How to Use Bar Magnifier in a Pine Script v6 Strategy

By HorizonAI Team · 13 min read · Intermediate

How to Use Bar Magnifier in a Pine Script v6 Strategy

A limit order that appears to fill and hit its profit target inside one historical candle can make a Pine strategy look far better, or far worse, than the price path justified. The issue isn't your entry formula. It's the intrabar path TradingView's broker emulator has to infer when your chart bar contains no lower-timeframe detail.

Short answer: add use_bar_magnifier = true to your strategy() declaration, then rerun the Strategy Tester. Bar Magnifier asks TradingView to use lower-timeframe data inside each available chart bar, so historical limit, stop, and bracket-order fills are based on a more detailed path rather than the emulator's default OHLC assumption. It can change fills, exits, trade count, and therefore every reported backtest metric.

The fuller answer is that Bar Magnifier improves historical intrabar fill modeling, not your signal and not your market-data quality. It has a coverage limit, it doesn't make unavailable lower-timeframe history appear, and it solves a different problem from calc_on_every_tick, process_orders_on_close, commissions, and slippage. Turn it on when your strategy relies on limit entries, stops, profit targets, or competing exit orders that can all be touched within one chart bar.

Why the default broker-emulator path can distort a trade

A Pine strategy normally evaluates historical bars using their open, high, low, and close. That tells the broker emulator the price extremes, but not the sequence in which they occurred. If a 60-minute candle trades through both your buy limit and your profit target, a backtest must make an assumption about what happened first.

TradingView documents the default historical assumption as an inferred path based on the bar's open, high, low, and close, with no gaps inside the bar's range. That assumption is necessary, but it can be a poor fit for order-heavy intraday systems. See TradingView's broker-emulator documentation for the fill model behind those results.

Consider a 1-hour bar with these values:

ValuePrice
Open100.00
High103.20
Low98.80
Close102.40
Buy-limit order99.20
Stop-loss98.40
Profit target101.20

The chart bar proves that price reached 99.20 and 101.20. It doesn't prove whether it first dipped to your entry and then rallied to target, rallied first and only later dipped, or filled the entry near the end of the bar. That order is the difference between a completed winner, an open position, and no fill at all.

Bar Magnifier replaces some of that guesswork with actual lower-timeframe bars. On a 60-minute chart, TradingView may inspect a lower timeframe selected by its Bar Magnifier mapping, then apply your orders to that lower-timeframe sequence. The feature is described in TradingView's Bar Magnifier strategy documentation and its support article.

Use case: If a strategy only enters at the next bar's market price and exits several bars later, Bar Magnifier may barely affect it. If it places a pullback limit and attaches a stop and target, inspect it before trusting the result.

Add Bar Magnifier to a Pine Script v6 strategy

The setting belongs in strategy(). It isn't an input.bool() you can flip during a single run because Pine needs the strategy property when it compiles the script. To compare results, run the version below with true, record the Strategy Tester values, change it to false, and run the same symbol, timeframe, date range, and settings again.

//@version=6
strategy(
     "Bar Magnifier Limit-Entry Demo",
     overlay = true,
     initial_capital = 10000,
     pyramiding = 0,
     commission_type = strategy.commission.percent,
     commission_value = 0.05,
     slippage = 1,
     calc_on_order_fills = true,
     process_orders_on_close = false,
     use_bar_magnifier = true)

// Trend and pullback settings.
emaLength = input.int(50, "EMA length", minval = 1)
atrLength = input.int(14, "ATR length", minval = 1)
limitAtrOffset = input.float(0.35, "Limit offset in ATR", minval = 0.05, step = 0.05)
stopAtrMultiple = input.float(1.00, "Stop loss in ATR", minval = 0.25, step = 0.25)
targetAtrMultiple = input.float(1.50, "Profit target in ATR", minval = 0.25, step = 0.25)

ema50 = ta.ema(close, emaLength)
atr14 = ta.atr(atrLength)

// A bullish close back above the EMA places a pullback buy limit.
bullishReclaim = ta.crossover(close, ema50)
limitPrice = close - atr14 * limitAtrOffset

if bullishReclaim and strategy.position_size == 0
    strategy.entry("Long", strategy.long, limit = limitPrice)

// The bracket is calculated from the actual average fill price.
if strategy.position_size > 0
    stopPrice = strategy.position_avg_price - atr14 * stopAtrMultiple
    targetPrice = strategy.position_avg_price + atr14 * targetAtrMultiple
    strategy.exit("Long bracket", "Long", stop = stopPrice, limit = targetPrice)

plot(ema50, "EMA 50", color = color.teal, linewidth = 2)
plot(strategy.position_size == 0 ? limitPrice : na, "Pending limit", color = color.orange, style = plot.style_linebr)
plot(strategy.position_size > 0 ? strategy.position_avg_price : na, "Average fill", color = color.blue, style = plot.style_linebr)
bgcolor(strategy.position_size > 0 ? color.new(color.teal, 90) : na)

This is deliberately a fill-model test harness, not a claim that an EMA reclaim has edge. It creates the conditions that expose intrabar ambiguity: a pullback limit may be reached later in a bar, and a one-ATR stop or 1.5-ATR target may be touched before the next chart bar appears.

Run the on-versus-off comparison correctly

  1. Put the strategy on a liquid symbol and start with a 15-minute or 60-minute chart.
  2. In Strategy Tester, fix the date range and leave the inputs unchanged.
  3. Keep use_bar_magnifier = true, then note net profit, number of trades, percent profitable, maximum drawdown, and several individual trades around busy bars.
  4. Change only use_bar_magnifier = false in the declaration and add the script to the chart again.
  5. Compare the marker sequence, not just the headline net profit. Find bars where the two versions disagree about whether a limit filled, a stop fired, or the target was reached.

A result that changes is useful information. It identifies a strategy whose reported outcome depends on the path inside a bar. It doesn't prove that either simulation matches the exact fills your broker would have given.

For the broader workflow around dates, out-of-sample checks, and interpreting performance statistics, use this backtesting guide. Here, keep the scope narrower: are your orders being modeled at a resolution appropriate to how they work?

What Bar Magnifier changes, and what it cannot change

Bar Magnifier uses lower-timeframe data automatically. You don't select its inspection timeframe in code. TradingView determines it from the chart timeframe according to its documented mapping. That means a 1-hour strategy and a daily strategy don't receive the same intrabar resolution.

It can change four practical things:

  • Whether a resting limit order fills. A chart bar may span the limit price, but the lower bars can show when that happened relative to your order creation and other fills.
  • Which bracket exit wins. A bar that contains both stop and target prices is precisely where a lower-timeframe path matters.
  • Whether entry and exit occur in the same chart bar. With a detailed enough path and order recalculation after fills, an order can fill and then meet a bracket condition before the chart bar ends.
  • Trade sequencing and statistics. One changed fill can alter position state, subsequent signals, pyramiding availability, drawdown, and the full strategy report.

It cannot fix structural weaknesses. A strategy that overfits 20 parameters is still overfit. It cannot reproduce bid/ask spread behavior from a centralized order book, guarantee a queue position for a limit order, or retrieve lower-timeframe history TradingView doesn't have for the relevant chart bars.

The lower-timeframe coverage limit matters

TradingView limits the amount of lower-timeframe data Bar Magnifier can use. Recent portions of the chart may therefore use detailed intrabar data while older bars rely on the normal emulator behavior. TradingView notes this limitation in the Bar Magnifier documentation.

That creates a testing trap: a strategy may have two fill models inside one report. Before comparing a multi-year equity curve, scroll to the earliest trade markers and verify whether detailed intrabar coverage exists there. If your evaluation depends heavily on a long historical sample, split the test into date windows and label which window had magnified coverage.

Read a same-bar limit and exit without fooling yourself

The demo uses three prices: a limit below the signal-bar close, a stop one ATR below the actual fill, and a target 1.5 ATR above it. On a volatile 60-minute bar, all three levels can lie inside a single candle's range.

With Bar Magnifier off, the emulator applies its assumed route to that OHLC bar. With it on, lower bars decide whether the price reached the pullback limit early enough to make the later target possible, or whether it reached the target before the order existed as a filled position. The markers can move even though the large candle looks unchanged.

Use this inspection routine on every disagreement:

  1. Mark the chart-bar open, high, low, and close.
  2. Record when the strategy submitted the order. A limit created at a bar close can't fill earlier in that same historical calculation unless a subsequent calculation makes it active.
  3. Open the lower chart timeframe that approximates the Bar Magnifier resolution and inspect the order of price travel.
  4. Check the List of Trades entry and exit timestamps, prices, and order IDs.
  5. Ask whether a real trading plan could submit and manage that order at those times, rather than accepting a favorable marker because it sits inside the candle.

This is closely related to avoiding synthetic-chart fills. If you test on non-standard candles, read how to avoid the Heikin Ashi backtest trap before interpreting a Bar Magnifier result. More intrabar detail doesn't turn synthetic OHLC into executable market prices.

Bar Magnifier vs. calc_on_every_tick vs. process_orders_on_close

These settings get lumped together because each affects strategy timing. They answer different questions, so switching on all of them without a reason makes a test harder to explain.

SettingPrimary jobHistorical-bar effectWhen to use it
use_bar_magnifier = trueModels fills using lower-timeframe barsCan improve the intrabar sequence for available historyLimit, stop, and bracket orders that may interact within one chart bar
calc_on_every_tick = trueRecalculates on live price updatesHistorical bars still don't contain every tickA live strategy must react during a forming realtime bar
calc_on_order_fills = trueRecalculates after an order fillsLets the script respond to a simulated fillYou need a bracket or follow-up order to be placed after an entry fills
process_orders_on_close = trueAllows order processing on the bar closeCan allow close-based fills under the emulator's rulesYour written rule explicitly acts at the bar close

calc_on_every_tick is often misunderstood. TradingView's execution-model documentation explains that tick-by-tick recalculation applies to realtime updates. Reloading a chart turns those elapsed realtime bars into historical bars, so a backtest doesn't preserve every tick decision your live script saw.

For the demo, calc_on_order_fills = true is useful because the exit bracket uses strategy.position_avg_price. After the limit fills, the strategy gets another chance to calculate and submit the bracket based on that actual simulated average price. Without it, the protective order may wait for the next normal calculation, which changes the test you think you're running.

Leave process_orders_on_close = false initially. The strategy creates a pullback order after a confirmed reclaim, and the point is to test the subsequent price path. Turning it on changes the timing assumption, not the precision of that path. Test it separately only if your rules truly submit or execute orders on a close.

Add friction, but don't confuse it with intrabar precision

The code includes a 0.05% commission and one tick of slippage. Those are intentionally modest placeholders, not universal costs. They apply friction to every simulated trade; Bar Magnifier changes how and when orders can fill.

A backtest can be wrong in both ways at once. A target may be credited through an unrealistic intrabar path, and the result may also ignore trading costs. Fix the fill path first when same-bar order collisions are driving the trade count, then test commissions and slippage appropriate to the instrument. The implementation details are covered in Pine Script v6 commission and slippage settings.

For liquid futures or major FX pairs, one tick may be a reasonable sensitivity starting point. For thin stocks, small-cap crypto, or wide-spread sessions, test several values. Don't hide a fragile strategy behind one favorable cost assumption.

A credibility checklist before you trust the report

Use this checklist before you compare variants or optimize an input:

  • Match the chart timeframe to the trading decision. A 4-hour signal with a 0.2-ATR stop asks the engine to resolve a lot of intrabar behavior.
  • Enable Bar Magnifier when resting orders can collide inside bars. Market-only systems can still benefit, but the largest impact is usually stops, limits, and bracket exits.
  • Identify the coverage boundary. Don't treat early non-magnified history and recent magnified history as one equally precise sample.
  • Keep calc_on_order_fills only when your order lifecycle needs it. It can be correct, but it changes when the script can submit follow-up orders.
  • Test close processing as a separate hypothesis. process_orders_on_close isn't a realism checkbox.
  • Set commission and slippage deliberately. Use the actual contract tick size and a cost range you can defend.
  • Inspect twenty trades by hand. Choose wins, losses, volatile sessions, and same-bar exits rather than only the prettiest examples.
  • Retest on another liquid symbol and a later date window. If only one instrument survives, the execution assumptions may be part of the apparent edge.

Common Bar Magnifier mistakes

❌ Mistake: Treating a better net-profit figure as proof that Bar Magnifier improved the strategy. A changed result means the fill model changed. It may expose favorable default assumptions just as often as it removes them.

✅ Do this: Compare individual trades first. On a 60-minute chart, isolate the bars where a 0.35-ATR limit and 1.0/1.5-ATR bracket changed outcome, then decide whether the lower-timeframe sequence resembles your intended execution.

❌ Mistake: Using calc_on_every_tick = true to repair historical intrabar fills. It affects realtime bar updates, not the complete tick path of every historical candle after reload.

✅ Do this: Use Bar Magnifier for available historical lower-timeframe sequencing, then forward-test the live timing behavior separately. Keep the two questions distinct.

❌ Mistake: Enabling process_orders_on_close and assuming it makes all fills more realistic. It makes a specific close-processing assumption and can create fills that your original rule didn't permit.

✅ Do this: Write the order timing in plain English. For example: “After a 15-minute bar closes above the 50 EMA, leave a buy limit 0.35 ATR below that close until filled or cancelled.” Then configure the strategy to match that statement.

❌ Mistake: Ignoring an order because it looks possible inside the candle. A high and low don't establish sequence.

✅ Do this: Require lower-timeframe confirmation for every same-bar entry-and-exit claim. If the magnified lower bars don't cover that period, flag the trade as assumption-sensitive.

Pro tips for strategies that depend on intrabar fills

Name the execution model in the strategy title. “15m pullback, Bar Magnifier on” is more useful than “EMA strategy v4.” Six weeks later, you won't confuse a result from default OHLC assumptions with a magnified run.

Use price distances that fit the chart resolution. A 0.25-ATR stop on a daily chart can be reasonable for a swing system, but it demands much more intraday detail than a 3-ATR stop. If your stop is small relative to normal chart-bar range, test on a lower chart timeframe too.

Log changed trades in a separate list. Copy ten trade timestamps where on/off versions disagree. Those trades reveal the sensitivity of the method faster than optimizing EMA length from 50 to 51.

Treat a lower trade count as a diagnostic, not failure. If Bar Magnifier removes trades that only existed under an assumed path, that's a cleaner definition of what the rule could have done historically.

Generating this fill-aware strategy without writing the code yourself

You can describe the exact order lifecycle in HorizonAI and ask it to generate a Pine Script v6 strategy. It generates Pine Script, can compile-check it, and you can keep editing the script in chat. HorizonAI writes the code; you run it yourself in TradingView's Pine Editor and Strategy Tester.

“Create a Pine Script v6 strategy for a 15-minute chart. Use a 50 EMA and ATR 14. When close crosses above the EMA, place one long limit order 0.35 ATR below the close. After it fills, set a stop 1.0 ATR below the average fill and a target 1.5 ATR above it. Set pyramiding to zero, 0.05% commission, one tick slippage, calc_on_order_fills true, process_orders_on_close false, and use_bar_magnifier true. Plot the EMA, pending limit, average fill, stop, and target. Add comments explaining every order-timing assumption.”

If you already have a strategy, ask:

“Audit this Pine Script v6 strategy for same-bar limit/stop/target fill assumptions. Add Bar Magnifier and calc_on_order_fills only where appropriate, then explain what changed and which results I should compare.”

Try it free →

FAQs

Does Bar Magnifier make Pine Script backtests accurate?

It can make historical order-fill sequencing more detailed where lower-timeframe coverage is available. It doesn't model every real-world execution factor, such as spread changes, liquidity, or queue position.

Does Bar Magnifier work with market orders?

Yes, but it tends to matter most for resting limit orders, stop orders, and brackets that can be touched within one chart bar. A strategy that only enters at the next bar open may show little change.

Can I turn Bar Magnifier on from an input in Pine Script?

No. Set use_bar_magnifier directly in the strategy() declaration and re-add or rerun the script after changing it. Compare one complete run with it on against an otherwise identical run with it off.

Is calc_on_every_tick the same as Bar Magnifier?

No. Bar Magnifier uses lower-timeframe data to improve historical fill modeling where available. calc_on_every_tick recalculates on realtime price updates and doesn't recreate all historical ticks after a chart reload.

Why did my number of trades fall after enabling Bar Magnifier?

Some apparent fills or same-bar exits may only have occurred under the default inferred OHLC path. Fewer trades can mean the lower-timeframe sequence ruled out those assumed order interactions.

Final thoughts

Bar Magnifier is most valuable when your result depends on which price was touched first inside a chart bar. Add it before you optimize a pullback, breakout, or tight-bracket strategy, then inspect changed trades at the lower timeframe instead of trusting a single summary metric.

One practical rule: if a single bar can contain your entry, stop, and target, label that trade execution-sensitive until Bar Magnifier coverage and the lower-timeframe path support the sequence.

Related articles

Questions about Bar Magnifier and Pine Script backtesting? Join our Discord to discuss with other traders!