MTF and Repainting

This page is about timing. Every multi-timeframe indicator has to make decisions about how slot-timeframe data is requested, when published values settle, and what happens while a slot-timeframe bar is still forming....

Written By Axiom Admin

Last updated 22 days ago

MTF and Repainting

This page is about timing. Every multi-timeframe indicator has to make decisions about how slot-timeframe data is requested, when published values settle, and what happens while a slot-timeframe bar is still forming. Those decisions are usually buried and rarely named honestly. This page names them explicitly, walks through what each choice buys you, and gives you verification moves you can actually perform.

A reader who has been burned by an MTF indicator before usually already knows why this page exists. The bad version of multi-timeframe behavior is an indicator that looks pristine on historical bars because it quietly used future information during replay, and then behaves nothing like its backtest on live data. The defense against that is not a promise in the marketing copy; it is knowing what the timing model is doing at every moment, which is what this page is here to give you.

If you hit this page looking for a specific runtime-error message, the Troubleshooting page is organized by symptom and will be faster. This page is for the reader who wants to understand the timing model itself.

The three timing relationships

Three timeframe relationships exist inside this indicator, and each has its own rules and its own runtime guardrail.

  • Chart timeframe vs slot timeframe. The chart is what you have open. The slot is what the indicator is requesting. A slot can be equal to or higher than the chart; it cannot be lower.

  • Slot timeframe vs lower TF precision. Each slot walks a finer timeframe's intrabars inside each of its own bars. The lower TF must be strictly lower than the slot.

  • Window timeframe vs slot timeframe. Session-mode anchor or rolling lookback, compared against the slot's own bar. The window must be at least as long as a slot bar.

All three relationships are enforced by runtime.error calls that name the slot in the message. Violating one does not produce a silent wrong answer; it produces a visible error. That is a deliberate choice and worth understanding as a feature, not a failure mode.

Rule 1: slot timeframe must be β‰₯ chart timeframe

The slot timeframe cannot honestly deliver a resolution below the chart's own bar. If your chart is on 5m and you try to set a slot to 1m, there is no coherent answer to "what was the 1m slot's value on this 5m bar" β€” the 5m bar contains five 1m bars, and the slot request would have to pick one or somehow merge them in a way that has no defensible interpretation.

The script refuses to do that. When it detects slotSeconds < chartSeconds, it throws a runtime error along the lines of "CVD 01 timeframe cannot be lower than the chart timeframe." The message names the specific slot so you do not have to guess which of the three caused the problem.

What to do when this happens:

  • Either raise the slot's TimeFrame so it is at or above the chart timeframe.

  • Or lower the chart timeframe until the constraint holds.

  • Do not try to work around this by using a sub-bar-resolution source. There is no version of that that behaves honestly in a Pine Script MTF context.

Verification move. On a 5m chart, set CVD 01's TimeFrame to 1m in the Inputs dialog. Read the error message on the chart. Set it back to 5m or higher and confirm the error clears. Do this once so you know what the message looks like when it shows up during a real configuration session.

Rule 2: lower TF precision must be < slot timeframe

The estimator walks lower-timeframe OHLCV bars inside each slot bar. For that walk to have any meaning, the lower timeframe has to resolve to something finer than the slot bar. Equal is not allowed. Higher is not allowed.

  • If Lower TF equals Slot TF, the walk would produce exactly one intrabar per slot bar, and the whole estimation architecture collapses into single-bar OHLCV.

  • If Lower TF is higher than Slot TF, the walk is meaningless; you would be asking for a lower-resolution source to produce a higher-resolution intrabar view, which is nonsense.

The script checks lowerSeconds >= slotSeconds and throws a runtime error naming the slot if the check fails.

What to do when this happens:

  • Lower the Lower TF Precision below the slot's TimeFrame. For a 5m slot, valid options include 1m, 30s, and anything finer the data feed will support.

  • Or raise the slot's TimeFrame above the Lower TF you picked.

Verification move. On a 5m chart, with CVD 01 at TimeFrame 5m, set Lower TF Precision to 5m. Confirm the runtime error text. Set Lower TF back to 1m and confirm the line redraws without error.

Rule 3: window timeframe must be β‰₯ slot timeframe

The window is either the anchor at which the cumulative delta resets (Session mode) or the lookback over which the cumulative is summed (Rolling mode). Either way, the window has to be long enough to contain at least one slot bar.

  • A window shorter than the slot timeframe in Session mode would reset the cumulative inside individual slot bars, which does not correspond to anything meaningful.

  • A window shorter than the slot timeframe in Rolling mode would ask the lookback to hold less than one bar, which is degenerate.

The script checks windowSeconds < slotSeconds and throws a runtime error naming the slot.

What to do when this happens:

  • Lengthen the Window. The default D is almost always valid for any reasonable slot timeframe.

  • Or shorten the slot's TimeFrame.

Verification move. On a 5m chart with CVD 01 at TimeFrame 60m, set Window to 30m. Confirm the error. Restore the Window to D and the slot runs.

On Bar Close β€” the repaint switch

This is the single knob most likely to change your relationship with the pane, and the one most misunderstood on multi-timeframe indicators in general.

On Bar Close is a global switch on this trim. All three slots share it. Setting it changes how every slot publishes its output.

ON: settled, one-slot-bar-lagged read

When On Bar Close is ON, each slot publishes the prior slot-bar's value β€” that is, the [1] offset β€” rather than the live slot-bar's running value.

  • What you get. A CVD value and a signal value that, once published, will not be revised.

  • What it costs. Up to one slot-bar of lag. A 60m slot publishes values that correspond to the last completed 60m bar, not the in-progress one.

  • Why this is the default. ON is the honest default for readers who want a value they can act on knowing it will not move. For most reading and most alerting, ON is the right choice.

  • Does it mean the indicator "never repaints" in ON mode? On the settled values it publishes, no. The published values are derived from a prior, completed slot bar. That is stable. The next slot bar will produce a new published value at the next slot-bar close, and that new value will be settled at publication. Calling the ON-mode behavior "does not repaint" is a qualified true statement; calling the indicator as a whole "never repaints" is not, because the OFF mode can and will update until the slot bar closes.

OFF: live, evolving read

When On Bar Close is OFF, each slot publishes the live slot-bar's running value β€” cvdValue, not cvdValue[1].

  • What you get. A CVD value that reflects the slot bar in progress, updating as the bar forms.

  • What it costs. The value can change from what you saw a moment ago. Until the slot bar closes, the published value is not settled. This is repaint behavior.

  • Why you might want it. Faster. If you are making a decision that depends on seeing the pane's current best estimate during bar formation, OFF is the only way to see it.

  • Why you might not want it. If you are wiring the pane into any workflow that assumes published values are stable β€” automated alerts treated as signals, logging a value for later replay, any kind of counting or averaging β€” OFF's live-update behavior will make the receiving side lie. Use ON instead.

The tradeoff in one sentence

ON is slow and settled. OFF is fast and live. Neither is a trick.

Which mode belongs with which posture

Two frames for thinking about the choice:

  • If you are reading the pane to inform an existing plan, leave ON. The read will arrive a slot-bar late, which is fine. Nothing about a participation read that arrives twenty minutes after the hour closes is less useful than the same read arriving mid-hour.

  • If you are watching the pane while a bar is forming because you actually need to see the in-progress estimate, use OFF. But be honest about what that looks like in practice β€” the line will move, sometimes substantially, until the slot bar closes, and the value you see at any moment is not the value the pane will settle on. Decisions staked to that live value are staked to a number that can be revised.

A middle posture that sometimes gets reached for β€” "I'll use OFF so I can act sooner, but I'll wait for the bar to close before trusting the value" β€” is a hazard. That is ON behavior wearing an OFF costume. If you want settled values, use ON. If you want live values, know that "trusting" them is a choice you are making about a number that has not yet finished.

Verification move. On a 5m chart, set On Bar Close to OFF. Watch the pane during the next 5m bar's formation. You should see the slot lines move as the bar develops. Set On Bar Close back to ON and watch the lines stabilize on the prior bar's values and hold until the next slot-bar close. The contrast is the tradeoff.

Lookahead posture

Under the hood, each slot's request.security call uses lookahead = barmerge.lookahead_on. That phrase has a bad reputation because it is often combined with zero-offset reads to create hidden forward leakage in other indicators. This script pairs it with an explicit [1] offset on the published values when On Bar Close is ON.

  • With On Bar Close ON + lookahead_on + [1] offset: the indicator asks the slot-timeframe source to serve whatever intrabar information is available while still offsetting the published value by one slot bar. The net result is that the value you see on a given chart bar corresponds to a slot bar that had already completed, so there is no forward leakage in the published output.

  • With On Bar Close OFF + lookahead_on + no offset: the indicator serves the live slot-bar value. Lookahead combined with the live read means the displayed value reflects the current state of the still-forming slot bar. This is not leakage from the future; it is the honest live state. It can change until the slot bar closes.

A reader who has been burned by a lookahead-on-plus-no-offset indicator in the past β€” where historical bars were replayed as if the indicator had future knowledge β€” should be reassured by the ON-mode offset here. A reader who wants OFF mode should be clear-eyed that the live read can move.

Why lookahead_on rather than lookahead_off

The alternative would be to request slot-timeframe data with lookahead = barmerge.lookahead_off, which asks TradingView to serve only values whose slot bars had completed by the historical chart bar. That posture has its own tradeoff: historical bars get more conservative values, but the indicator has to wait a full slot bar before any slot-timeframe information is available, which on a chart deep in history means the first several slot-worth of chart bars show no slot data at all. The ON-mode-plus-[1]-offset posture used here gives you a settled value on every chart bar once the first slot bar has closed, without leaking future knowledge. That pairing is the honest version of the tradeoff; a tool that paired lookahead_on with a zero offset, or that claimed to "not repaint" while actually running OFF-mode live values, would be the dishonest version.

The silent intrabar fallback

Covered briefly on Limitations and Trust Boundaries; this is the longer walkthrough from the timing side.

Each slot uses request.security_lower_tf to get lower-timeframe OHLCV arrays inside each slot bar. Those arrays populate the intrabar walk the estimator depends on.

Two situations cause the arrays to come back empty or too short to use:

  • Chart history beyond TradingView's intrabar window. TradingView provides intrabar history only for a finite number of recent bars. Scroll past that window and request.security_lower_tf starts returning empty or partial arrays.

  • Data feeds without intrabar coverage. Some symbols on some feeds do not carry intrabar data at the requested precision. The request returns nothing usable.

When the arrays are empty, the estimator falls back to _calcFallbackBarDelta, which reads the slot bar's own OHLCV and computes delta from that single bar. The participation model still runs; it just has one bar of evidence instead of many.

  • The fallback is not announced visually. No warning, no color, no marker.

  • You notice it by character. The line looks cruder β€” fewer inflections, blockier movement, less resolved response to wick-heavy bars.

  • The pane still works. The estimate is just coarser.

Verification moves for the fallback

  • Scroll the chart backward in history. Past the intrabar window, the slot line will look noticeably less resolved. Scroll forward into recent bars and watch the resolution improve as the intrabar data becomes available again.

  • Compare a liquid symbol and a sparse symbol on the same configuration. The sparse symbol will more often run in fallback mode, and the character of the line will reflect that.

  • Push Lower TF Precision down. Finer precision demands more intrabar data. On a symbol where intrabars are thin, finer precision will trip fallback more often and earlier in history. Moving Lower TF up (but still below slot TF) can reduce fallback frequency at the cost of a slightly coarser high-precision mode when intrabars are present.

Session resets and window rollovers

The Session mode reset event fires on two conditions: barstate.isfirst (the first bar of the chart series) and timeframe.change(windowTimeframe) (the window anchor just rolled over).

  • First-bar reset. On the first bar of the chart, every Session-mode slot resets. This is initialization, not a real rollover event. The dashed marker does draw on bar one.

  • Anchor rollover. When the window timeframe ticks over β€” D rolling over at the start of a new session, W rolling over at the start of a new week, etc. β€” the slot resets and the dashed marker drops.

  • Rolling mode has no reset. timeframe.change is not used in Rolling mode; the accumulation is timestamp-bounded, not anchor-bounded. No dashed marker is drawn.

Verification move

Set one slot to Session mode with D window, and another to Rolling with D window. Let the chart run across a daily boundary. Confirm the Session slot draws a dashed marker at the boundary and the Rolling slot does not. Both slots are correct; they are reporting different accumulation structures.

Post-reset calibration

The first several bars after a session reset are calibration bars. The window has just been emptied; the cumulative starts near its own initial value, and the normalization range is being observed fresh. During this stretch, the slot line often travels through extremes because the observed high and low are close together and any delta pushes the normalized value quickly.

This is not a bug and it is not a special state. It is the consequence of resetting an accumulator. The All CVD Slots Bullish / Bearish alignment alert can fire spuriously in this stretch because the newly-reset slots can all transiently lean the same way. The Workflows alert-triage pattern builds a post-reset pause into the decision process for exactly this reason.

Timing relationships summarized

Relationship

Constraint

Violation behavior

Typical fix

Slot TF vs Chart TF

Slot TF β‰₯ Chart TF

Runtime error naming the slot

Raise Slot TF or lower Chart TF

Lower TF vs Slot TF

Lower TF < Slot TF

Runtime error naming the slot

Lower the Lower TF or raise Slot TF

Window TF vs Slot TF

Window TF β‰₯ Slot TF

Runtime error naming the slot

Lengthen Window or shorten Slot TF

Intrabar available?

Best effort

Silent fallback to single-bar

No runtime action; read the line's character as the signal that fallback is active

On Bar Close ON

Published = [1]

No repaint on published values

Accept one slot-bar of lag

On Bar Close OFF

Published = live

Published values can update until slot bar closes

Accept the live repaint behavior

Alert barstate.isconfirmed

Fires at chart bar close

Alerts do not fire mid-bar

No action; this is the intended behavior

A single combined verification session

If you want to feel all of the above in one pass, run through this sequence on a chart you have history on.

  1. Set chart to 5m. Default indicator config.

  2. Try to set CVD 01 TimeFrame to 1m. Read the runtime error. Set it back to 5m.

  3. Try to set CVD 01 Lower TF Precision to 5m. Read the runtime error. Set it back to 1m.

  4. Try to set CVD 01 Window to 30m with TimeFrame 60m. Read the runtime error. Set it back to D.

  5. Toggle On Bar Close OFF. Watch the pane update during the next bar. Toggle ON.

  6. Scroll back in history to the edge of the intrabar window. Watch the slot lines become cruder past that edge.

  7. Wait for a session boundary. Confirm the dashed marker drops in Session mode on the right bar.

  8. Set CVD 02 to Rolling mode with D window. Confirm it does not draw a dashed marker at the next boundary.

You now have the timing model in your hands. From here, any timing question you have while reading the pane can be answered by remembering what you just saw.

  • Troubleshooting for the specific runtime-error messages and their one-step fixes.

  • Settings for the full description of each control that participates in the timing model.

  • Limitations and Trust Boundaries for the estimator-wide boundaries, including the silent fallback framing.

  • Alerts for barstate.isconfirmed and why alerts fire only on chart-bar closes.