
Of all the Pine Script v6 breaking changes, integer division is the most dangerous. Every other breaking change either produces a compilation error that forces you to fix it or is caught by the auto-converter1. Integer division does neither. Your script compiles without any error, runs without any warning, and produces different results that you might not notice until your backtest numbers look wrong or, worse, your live strategy behaves unexpectedly.
This guide explains exactly what changed, shows the common code patterns that are affected, demonstrates how different results propagate through a real strategy, and gives you a migration checklist to audit your own scripts.
In Pine Script v5, dividing two const int values performed integer division. The fractional remainder was silently discarded1. In v6, all integer division returns the full fractional result2.
v5 behavior (integer division for const int)
//@version=5
indicator("v5 Integer Division")
plot(1 / 2) // Returns 0
plot(5 / 2) // Returns 2
plot(7 / 3) // Returns 2
plot(10 / 4) // Returns 2
v6 behavior (fractional division always)
//@version=6
indicator("v6 Integer Division")
plot(1 / 2) // Returns 0.5
plot(5 / 2) // Returns 2.5
plot(7 / 3) // Returns 2.333...
plot(10 / 4) // Returns 2.5
There is an important nuance. In v5, this behavior only applied to const int values: literal integers and compile-time constants. If either operand had an input, simple, or series qualifier, v5 already returned the fractional result1. So the inconsistency only affected literal-to-literal division. V6 eliminates this inconsistency by always returning the fractional result, regardless of qualifier2.
Every other Pine Script v6 breaking change has a safety net. Removed parameters cause compilation errors1. Boolean changes either fail to compile or are handled by the auto-converter. The when parameter removal is caught immediately1.
Integer division has no safety net. The script compiles. It runs. It produces numbers. Those numbers are just different from what they were in v5. If you converted a v5 strategy to v6 and did not specifically check for integer division issues, you may have been running altered calculations without knowing it.
The danger is magnified because integer division often appears in core logic: position sizing, bar counting, array indexing, and timeframe calculations. A subtle change in any of these can cascade through an entire strategy.
Here are the code patterns most likely to produce different results in v6.
Any code that divides bar_index or a bar count by a constant integer to find a midpoint or fractional position is affected.
//@version=5
indicator("Bar Midpoint v5")
int lookback = 100
int midpoint = lookback / 2 // Returns 50 (correct)
int quarter = lookback / 4 // Returns 25 (correct)
// But:
int thirdPoint = lookback / 3 // Returns 33 (truncated from 33.33)
In v6, lookback / 3 returns 33.333... instead of 331. If this value is used as an offset for close[thirdPoint], Pine Script will truncate it to an integer at the point of use3, but if it feeds into further arithmetic first, the fractional component propagates.
This is where the financial impact is most direct. Strategies that calculate position size by dividing account equity or a fixed amount by a number of positions or a lot size are affected.
//@version=5
strategy("Position Sizing v5", overlay = true)
int maxPositions = 4
int capitalPerPosition = 10000 / maxPositions // Returns 2500
// But what if the math is not clean:
int totalLots = 10000 / 3 // Returns 3333 in v5, 3333.33 in v6
In a v5 strategy, 10000 / 3 returns 3333. In v6, it returns 3333.333.... If that value is then multiplied by a price or used in a quantity calculation, the extra 0.333 accumulates and changes the final order size. For strategies that run many trades, these small differences compound into measurably different equity curves.
Finding the midpoint of an array is a textbook use of integer division. In v5, array.size(arr) / 2 with a const array size returns an integer that works directly with array.get()3. In v6, if the size happens to be const, the division may return a float1.
//@version=6
indicator("Array Midpoint v6")
var array<float> prices = array.new<float>(10, 0.0)
// If array.size() returns a series int, this was already fractional in v5.
// But if you hardcode: int mid = 10 / 2, this was 5 in v5 and is now 5.0 in v6.
// The key risk is odd sizes:
int mid = int(array.size(prices) / 2) // Wrap in int() to be safe
Array access functions like array.get() expect integer indices3. If you pass a float, Pine Script truncates it, but the truncation may produce a different index than the integer division that v5 would have performed.
Scripts that calculate bar offsets based on dividing one timeframe by another are affected. For example, calculating how many 5-minute bars fit in one hour by dividing 60 by 5 is safe (clean division), but dividing 60 by 7 returns 8 in v5 and 8.571... in v6.
//@version=6
indicator("Timeframe Calc")
// Safe: 60 / 5 = 12 in both v5 and v6
int barsPerHour = int(60 / 5)
// Dangerous: 60 / 7 = 8 in v5, 8.571 in v6
int barsPerSession = int(60 / 7) // Wrap in int() to restore v5 behavior
Here is a simplified strategy that demonstrates how integer division changes affect actual trading results. The strategy splits equity into thirds and enters positions based on a simple moving average crossover.
v5 version
//@version=5
strategy("Division Demo v5", overlay = true, default_qty_type = strategy.fixed,
margin_long = 100, margin_short = 100)
int numSlots = 3
float slotSize = 10000 / numSlots // v5: 3333 (integer division)
if ta.crossover(ta.sma(close, 10), ta.sma(close, 30))
strategy.entry("Long", strategy.long, qty = slotSize / close)
if ta.crossunder(ta.sma(close, 10), ta.sma(close, 30))
strategy.close("Long")
v6 version (different results)
//@version=6
strategy("Division Demo v6", overlay = true, default_qty_type = strategy.fixed,
margin_long = 100, margin_short = 100)
int numSlots = 3
float slotSize = 10000 / numSlots // v6: 3333.333... (fractional)
if ta.crossover(ta.sma(close, 10), ta.sma(close, 30))
strategy.entry("Long", strategy.long, qty = slotSize / close)
if ta.crossunder(ta.sma(close, 10), ta.sma(close, 30))
strategy.close("Long")
The v5 version allocates $3,333 per slot. The v6 version allocates $3,333.33 per slot. That extra $0.33 per slot means slightly larger position sizes on every trade. Over hundreds of trades in a backtest, the equity curves diverge. Winning trades earn slightly more, losing trades lose slightly more, and the compounding effect means net profit, max drawdown, and Sharpe ratio all differ.
v6 version (corrected)
//@version=6
strategy("Division Demo v6 Fixed", overlay = true, default_qty_type = strategy.fixed,
margin_long = 100, margin_short = 100)
int numSlots = 3
float slotSize = int(10000 / numSlots) // Explicitly truncate: 3333
if ta.crossover(ta.sma(close, 10), ta.sma(close, 30))
strategy.entry("Long", strategy.long, qty = slotSize / close)
if ta.crossunder(ta.sma(close, 10), ta.sma(close, 30))
strategy.close("Long")
Wrapping the division in int() restores the v5 integer truncation behavior and produces identical backtest results.
The auto-converter does not flag integer division changes1. You need to audit your scripts manually. Here is a systematic approach:
/ operatorconst int variables, or integer function returns)There are three ways to restore integer behavior depending on the rounding you want:
int(a / b) truncates toward zero3. This matches v5 behavior for positive numbers. int(7 / 2) returns 3. int(-7 / 2) returns -3.math.floor(a / b) rounds down (toward negative infinity)3. math.floor(7 / 2) returns 3. math.floor(-7 / 2) returns -4.math.round(a / b) rounds to the nearest integer3. math.round(7 / 2) returns 4. Use this when you want standard rounding rather than truncation.For most trading applications where you are dividing positive integers and want the old v5 behavior, int() is the correct choice4. Use math.floor() when you specifically need floor rounding for negative values, such as calculating offsets in both directions.
Use this checklist when auditing any v5-to-v6 conversion for integer division issues:
/ operations in your scriptint() wherever you need v5 truncation behaviorOnce you have verified that your v6 strategy produces the correct calculations, you can automate it with TradersPost. TradersPost connects your TradingView strategy alerts to supported brokers, executing orders automatically based on your Pine Script signals5. It works with both v5 and v6 strategies, so you can migrate at your own pace without disrupting live automation.
The key is to verify your math before going live. Integer division is the one v6 change that will not announce itself. Take the time to audit every division in your strategy, wrap the ones that need truncation in int(), and confirm your backtest results match expectations. The effort is small compared to the risk of running a strategy with silently altered position sizing.
For the complete list of v6 changes, see our Pine Script v6 breaking changes guide. For a broader overview of what v6 offers, start with Pine Script v6: What's New and Why It Matters.
1 Pine Script v6 Migration Guide
2 Pine Script Release Notes
3 Pine Script v6 Language Reference
4 Pine Script User Manual
5 TradersPost