TradokiTradoki/blog
Subscribe
← back to indexblog / pine script / pine-script-v6-breaking-changes
Pine Script

Pine Script V6 Breaking Changes That Don't Show as Errors

TradingView's own migration guide confirms it: integer division and a flipped margin default change a script's numbers with zero compile errors.

A
ArthurFounder, Tradoki
publishedSep 07, 2026
read7 min
Pine Script V6 Breaking Changes That Don't Show as Errors

You click "Update script" on an old Pine Script strategy because the little v6 banner has been nagging you for weeks, the editor compiles it with zero errors, and you move on with your day. Then you rerun the exact backtest you've stared at

You click "Update script" on an old Pine Script strategy because the little v6 banner has been nagging you for weeks, the editor compiles it with zero errors, and you move on with your day. Then you rerun the exact backtest you've stared at fifty times and the equity curve is a different shape. No red text. No warning. Nothing you did wrong in any way the compiler can see. TradingView's own migration guide confirms several of the "quiet" changes in Pine Script v6 alter what your strategy actually does, not just how it's typed, and a compiler has no reason to flag a script that runs correctly under a different set of rules than the one you tested against. A clean v6 compile tells you your syntax is valid. It tells you nothing about whether your numbers still match.

Your v5 script is safe until you touch it

Here's the part that gets skipped in most "what's new in v6" roundups: nothing changes automatically. TradingView's own announcement post for the release states it directly: "the upgrades included in Pine v6 do not affect personal or published scripts written in earlier Pine versions." A script sitting untouched on version 5 keeps running exactly as it always has, forever, whether you ever look at it again or not.

The risk shows up the moment you convert. That's either you clicking "Update script" in the Pine Editor and accepting the auto-converter's output, or you (or, increasingly, an AI tool writing Pine on your behalf) starting a new script fresh in v6. Either path can carry behavior differences that a green compile has no way of surfacing, because the new behavior is still perfectly valid Pine. It's just not the same program.

Division stopped truncating, and that number travels

In Pine Script v5, dividing two whole numbers threw away the remainder automatically. Five divided by two came back as two, full stop, the same way a vending machine won't give you half a candy bar. TradingView's own Pine Script operators documentation spells out the v6 change plainly: "when using the division operator with 'int' operands, if the two 'int' values are not evenly divisible, the result of the division is always a number with a fractional value," meaning 5/2 now returns 2.5.

That's not a cosmetic difference. Any calculation that used integer division and assumed a clean whole number, a contract count derived from account risk, a loop counter, a bucket index, an "is this an exact multiple" comparison, now carries a decimal it never used to have. The fix is straightforward once you know to look for it: wrap the division in int(), or round it explicitly with math.round(), math.floor(), or math.ceil(). What isn't straightforward is finding every place you need to apply it, since position-sizing math built on this exact kind of arithmetic is precisely the code most likely to lean on a whole-number assumption nobody wrote down.

5/2 = 2.5how Pine Script v6 evaluates integer division that v5 truncated to 2, per TradingView's own operators documentation
100%the default margin_long / margin_short percentage in v6 strategies, up from 0% in v5, per TradingView's own migration guide
9,000the trade count where v6 strategies start trimming their oldest trades instead of throwing the v5 error, per the same migration guide

"and" and "or" quit early now, and that can skip a stateful call

Pine v6 also changed how the and and or operators evaluate. They now stop as soon as the outcome is already decided, a behavior called lazy evaluation: if the first side of an and is false, the second side never runs at all. Most languages do this and most of the time it's just a speed win. In Pine, it's a trap for a specific, common pattern.

Some Pine functions, ta.rsi() and ta.crossover() among them, keep a running memory across bars. If you were calling one of those functions on the second side of a compound condition, the old behavior evaluated both sides every single time, so the function's internal history stayed continuous no matter what the first condition did. Under lazy evaluation, that second call can get skipped on some bars and not others, and a function that depends on an unbroken bar-by-bar history just had that history quietly interrupted. The safer pattern, and one worth adopting regardless of version, is pulling any stateful function call out to its own line at the top of the script, assigning it to a variable, and referencing that variable inside your conditions instead of calling the function inline. The same discipline matters anywhere a script leans on a feature with hard technical limits it doesn't advertise: know exactly what a piece of code depends on before you trust what it outputs.

The default margin flipped from "don't check" to "don't open it"

This is the one most likely to actually reshape a converted strategy's results, and it's buried in a single sentence of the migration guide. In v5, if a strategy() declaration left margin_long and margin_short unset, the default was 0%, and per TradingView's own migration documentation, that meant the strategy "does not check its available funds before creating or managing orders." Your backtest could open a trade regardless of whether the account could actually afford it.

In v6, that same unset default becomes 100%. The strategy "does not open entries that require more money than is available, and short orders are margin called if too much money is lost." Nothing about your entry logic changed. The account's willingness to let a trade through did. A strategy that used to fill every signal in the backtest can, after conversion, start skipping the ones it can't afford, and skipped trades mean a different trade count, a different win rate, and a different-looking equity curve, all without a single line of your strategy logic being wrong. It's one more way a backtest can disagree with the trade you'd actually get, just arriving from the opposite direction this time: v5 was too permissive by default, and v6's default is stricter than most people realize they just inherited.

A script that compiles clean in v6 didn't just survive the upgrade. It's running different math than the version you actually backtested.

The Tradoki desk note

Your exits stopped picking a favorite

One more change worth knowing if you use strategy.exit() with both a fixed price and a percentage-based trail in the same call. Per TradingView's migration guide, "the strategy.exit() command no longer ignores relative parameters defining take-profit and stop-loss prices or trailing stop activation levels when the call also includes arguments for the related absolute parameters." In v5, giving both meant the absolute, fixed-price parameter always won. In v6, both get evaluated, and whichever one triggers first is the one that fires.

If you built an exit assuming the fixed price was the real rule and the percentage parameter was just a leftover from an earlier version of the strategy, v6 just turned that leftover into a live, competing exit condition.

What actually needs your eyes, not just a green compile

TradingView built an auto-converter for a reason, and it does handle real work. The removed when parameter on strategy.entry() and friends gets rewritten into an if block for you automatically. Most of the boolean-casting changes, where an int or float used to slide silently into a bool context, get patched too. TradingView's own support article on converting scripts is honest about the limit of that automation, stating plainly that "in some cases, the code cannot be converted fully and requires manual changes."

The division change, the lazy and/or evaluation, the flipped margin default, and the strategy.exit() parameter handling all sit in that second bucket. None of them will stop your script from compiling. All of them can change what it does. The only real test isn't reading the migration guide once and trusting your memory of it. It's running the original and the converted version on the same data and actually comparing what came out the other end.

● FAQ

Does upgrading to Pine Script v6 change how my existing v5 script trades?
Not on its own. TradingView's own announcement of v6 states directly that the upgrades in v6 do not affect personal or published scripts written in earlier Pine versions, so an untouched v5 script keeps running exactly as it always has. The changes only apply once you convert that script to v6, whether through the Pine Editor's auto-converter or by rewriting it yourself.
Why does 5/2 no longer equal 2 in Pine Script?
Because v6 changed how integer division works. Per TradingView's own Pine Script documentation, dividing two int values that aren't evenly divisible now returns the fractional result, 5/2 = 2.5, instead of the old truncated result, 5/2 = 2. Wrap the division in int(), math.round(), math.floor(), or math.ceil() if you need the old truncating behavior back.
Will the Pine Editor's auto-converter catch these behavior changes for me?
Only some of them. TradingView's own support article on converting scripts states plainly that in some cases the code cannot be converted fully and requires manual changes. The when parameter removal and most boolean-casting issues convert automatically, but the division change, the lazy and/or evaluation, and the new default margin all require you to read the migration guide and test the result yourself.
Why did my converted strategy's backtest results change even though nothing errored?
The most likely culprit is the default margin change. In v5, a strategy with no margin_long or margin_short set defaults to 0%, meaning the backtest never checks available funds before opening a trade. In v6, that same unset default becomes 100%, meaning the strategy won't open a position it can't fully afford, and it can margin-call a short that loses too much. That alone can shrink your trade count and reshape your equity curve on a converted script.
How should I verify a converted v6 script still does what I expect?
Run the same date range and settings on the original v5 version and the converted v6 version side by side, then compare trade count, win rate, and the shape of the equity curve rather than just checking that it compiled. A clean compile only means the syntax is valid Pine v6, not that the strategy behaves the way it did before.
— share
— keep reading

Three more from the log.

Why 'Once Per Bar Close' Alerts Still Fire Late
003 · Pine Script

Why 'Once Per Bar Close' Alerts Still Fire Late

TradingView's own support docs explain the confirmation logic behind alert delay, and why the webhook relay is rarely where the real bottleneck hides.

Sep 05, 2026 · 7 min