v6 Integer Division Changes

Fact checked by
Mike Christensen, CFOA
March 11, 2026
How Pine Script v6 integer division changes can silently alter your strategy calculations, and how to fix them.

Bottom Line

  • In v5 dividing two const integers like 1/2 returned 0 using integer division but v6 returns 0.5
  • This change can silently alter strategy calculations without causing any compilation errors
  • Common affected patterns include bar counting position sizing lot calculations and array index arithmetic
  • Wrap divisions in int() to restore v5 integer division behavior where needed

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.

What Changed

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.

Why This Is the Most Dangerous v6 Change

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.

Common Patterns Affected

Here are the code patterns most likely to produce different results in v6.

Bar Counting and Midpoint Calculations

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.

Position Sizing and Lot Calculations

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.

Array Index Arithmetic

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.

Timeframe and Period Calculations

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

Real Strategy Example: Different Backtest Results

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.

How to Detect Affected Code

The auto-converter does not flag integer division changes1. You need to audit your scripts manually. Here is a systematic approach:

  • Search your script for every / operator
  • For each division, check whether both operands are integer expressions (literals, const int variables, or integer function returns)
  • If both are integers, determine whether your logic depends on the result being truncated
  • Pay special attention to divisions where the result feeds into array indexing, loop boundaries, position sizing, or quantity calculations
  • Compare backtest results between v5 and v6 versions of the same strategy to catch any silent differences

The Fix: int() and math.floor()

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.

Migration Checklist

Use this checklist when auditing any v5-to-v6 conversion for integer division issues:

  • Search for all / operations in your script
  • Identify divisions where both operands are integers
  • For each, determine if the truncated or fractional result is correct for your logic
  • Wrap in int() wherever you need v5 truncation behavior
  • Check position sizing calculations for any division that splits equity or calculates lots
  • Check array index calculations that use division to find midpoints or offsets
  • Check loop boundaries that use division to calculate iteration counts
  • Check timeframe arithmetic that divides minutes, hours, or bar counts
  • Run your strategy on both v5 and v6 and compare backtest metrics: net profit, max drawdown, trade count, and win rate
  • If metrics differ, trace the difference back to specific division operations

Automate with Confidence

Once 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.

References

1 Pine Script v6 Migration Guide
2 Pine Script Release Notes
3 Pine Script v6 Language Reference
4 Pine Script User Manual
5 TradersPost

Ready to automate your trading? Try a free 7-day account:
Try it for free ->