Pine Script v6 Data Types Explained: bool, float, and int — When and How to Use Each
Understanding the three fundamental scalar data types in Pine Script v6 — bool, float, and int — is essential for writing correct, predictable indicators and strategies. Each type has distinct memory representation, arithmetic rules, and v6-specific constraints that differ meaningfully from prior versions.
1. Overview of the Three Types
Pine Script v6 is a statically-typed language with type inference. Every variable has a resolved type at compile time. The three primitive numeric/logical types are:
| Type | Value Domain | Can Hold na? |
Typical Use Case |
|---|---|---|---|
| bool | true or false only |
❌ No (v6 breaking change) | Conditions, flags, signal gates |
| int | 64-bit signed integer or na |
✅ Yes | Bar counts, indices, loop counters |
| float | 64-bit IEEE 754 double or na |
✅ Yes | Prices, ratios, indicator values |
2. The bool Type — v6 Breaking Changes
In Pine Script v6, bool is strictly binary. It can only hold true or false. This is a critical breaking change from v5, where bool could hold na as a third state.
2-A. What Was Removed in v6
bool b = na— illegal in v6.boolcannot holdna.na(myBool)— compile error.na()does not acceptboolarguments.nz(myBool, false)— compile error.nz()does not acceptboolarguments.- Implicit numeric → bool cast:
if myIntis illegal. You must writeif myInt != 0orif bool(myInt).
2-B. History Reference on Bar 0
When you reference a bool variable's history on bar 0 (e.g., myBool[1] on the first bar), v5 returned na. In v6, it returns false. This can silently change logic if you migrated code from v5.
2-C. Three-State Logic Pattern
If you need a variable that can be true, false, or missing (uninitialized), use int or float as a proxy:
//@version=6
indicator("Three-State Demo", overlay = false)
// Use int as a 3-state proxy: 1 = true, 0 = false, na = missing
var int state = na // starts as na (missing), not false
if bar_index == 10
state := 1 // set to "true" on bar 10
if bar_index == 20
state := 0 // set to "false" on bar 20
// Check state safely
bool isTrue = state == 1
bool isFalse = state == 0
bool isMissing = na(state)
plot(state, title = "State", color = color.blue)
3. The int Type
The int type represents a 64-bit signed integer. It is used for discrete, countable quantities: bar indices, loop counters, array sizes, and period lengths.
3-A. Integer Division — Critical Rule
The / operator in Pine Script always returns float, regardless of operand types. There is no C-style integer truncation.
To perform integer division (truncating toward zero), use explicit casting:
//@version=6
indicator("Integer Division Demo", overlay = false)
float divResult = 7 / 2 // → 3.5 (float, always)
int truncated = int(7 / 2) // → 3 (truncate toward zero)
int floored = math.floor(7 / 2) // → 3 (floor toward negative infinity)
plot(divResult, title = "Float Div", color = color.orange)
plot(truncated, title = "Truncated", color = color.blue)
plot(floored, title = "Floored", color = color.green)
3-B. int and na
Unlike bool, int can hold na. This makes it suitable for representing "not yet computed" states:
//@version=6
indicator("Int na Demo", overlay = false)
var int lastCrossBar = na // na until a cross occurs
bool crossed = ta.crossover(close, ta.sma(close, 20))
if crossed
lastCrossBar := bar_index
// Safe check: na(lastCrossBar) is valid for int
int barsSinceCross = na(lastCrossBar) ? na : bar_index - lastCrossBar
plot(barsSinceCross, title = "Bars Since Cross", color = color.purple)
4. The float Type
The float type is a 64-bit IEEE 754 double-precision floating-point number. It is the default numeric type for price data, indicator outputs, and most mathematical computations in Pine Script.
4-A. Precision and Representation
IEEE 754 double precision provides approximately 15–17 significant decimal digits. For financial calculations, this is sufficient for price arithmetic, but be aware of floating-point representation limits:
$$0.1 + 0.2 \neq 0.3 \quad (\text{IEEE 754 artifact})$$When comparing floats for equality, prefer a tolerance-based check:
//@version=6
indicator("Float Equality Demo", overlay = false)
float a = 0.1 + 0.2
float b = 0.3
float epsilon = 1e-10 // tolerance threshold
// Direct equality may fail due to IEEE 754 representation
bool directEqual = a == b // may be false
bool toleranceEqual = math.abs(a - b) < epsilon // robust check
plot(directEqual ? 1 : 0, title = "Direct ==", color = color.red)
plot(toleranceEqual ? 1 : 0, title = "Tolerance ==", color = color.green)
4-B. float and na
float variables can hold na, which represents a missing or undefined value. Built-in series like close are of type series float and may contain na on extended sessions or data gaps.
5. Type Conversion Rules
Pine Script v6 enforces explicit type conversion in several cases that were implicit in v5. The table below summarizes all legal and illegal conversion patterns:
| Conversion | Syntax | Legal in v6? | Notes |
|---|---|---|---|
| int → float | float(myInt) |
✅ Yes | Widening conversion, no data loss |
| float → int | int(myFloat) |
✅ Yes | Truncates toward zero |
| bool → int | myBool ? 1 : 0 |
✅ Yes (ternary only) | int(myBool) causes CE10123 |
| bool → float | myBool ? 1.0 : 0.0 |
✅ Yes (ternary only) | float(myBool) causes CE10123 |
| int → bool | myInt != 0 or bool(myInt) |
✅ Yes (explicit only) | Implicit cast (if myInt) removed in v6 |
| float → bool | myFloat != 0.0 or bool(myFloat) |
✅ Yes (explicit only) | Implicit cast removed in v6 |
| bool → na | bool b = na |
❌ No | Compile error in v6 |
6. Comprehensive Type Demonstration Script
The following script demonstrates all three types in a single indicator, including correct conversion patterns, na handling, and the three-state proxy pattern.
🔽 [Click to expand] View Full Pine Script Code
//@version=6
indicator("bool / float / int Type Demo", overlay = false)
// ─────────────────────────────────────────────
// SECTION 1: int type
// ─────────────────────────────────────────────
// Declare a persistent int counter using var
var int barCount = 0
barCount := barCount + 1 // increments every bar
// Integer division always returns float in Pine Script
// Use int() to truncate toward zero
int halfBars = int(barCount / 2) // truncated integer division
// int can hold na — useful for "not yet set" states
var int lastBullBar = na
bool isBullBar = close > open
if isBullBar
lastBullBar := bar_index // record the last bullish bar index
// Safe distance calculation: guard against na
int barsSinceBull = na(lastBullBar) ? na : bar_index - lastBullBar
// ─────────────────────────────────────────────
// SECTION 2: float type
// ─────────────────────────────────────────────
// float is the default type for price-based calculations
float sma20 = ta.sma(close, 20) // series float
// Ratio calculation — result is always float
float priceToSma = na(sma20) ? na : close / sma20
// Tolerance-based float comparison (robust against IEEE 754 artifacts)
float epsilon = 1e-9
bool nearSma = math.abs(close - sma20) < epsilon // true if close ≈ sma20
// ─────────────────────────────────────────────
// SECTION 3: bool type — v6 strict binary
// ─────────────────────────────────────────────
// bool is strictly true/false in v6 — cannot hold na
bool aboveSma = close > sma20 // series bool
// CORRECT: bool → int conversion via ternary (NOT int(myBool) → CE10123)
int aboveSmaInt = aboveSma ? 1 : 0
// CORRECT: int → bool conversion via explicit comparison (NOT implicit cast)
// if aboveSmaInt ← ILLEGAL in v6
// if aboveSmaInt != 0 ← LEGAL
bool aboveSmaBack = aboveSmaInt != 0
// Three-state proxy using int: 1=bullish, 0=bearish, na=insufficient data
var int regime = na
if bar_index >= 20 // only after enough bars for SMA
regime := aboveSma ? 1 : 0
// ─────────────────────────────────────────────
// SECTION 4: Plots
// ─────────────────────────────────────────────
plot(priceToSma, title = "Price/SMA Ratio", color = color.blue, linewidth = 2)
plot(aboveSmaInt, title = "Above SMA (0/1)", color = color.green, linewidth = 1)
plot(barsSinceBull, title = "Bars Since Bull Bar", color = color.orange, linewidth = 1)
plot(regime, title = "Regime (3-state)", color = color.purple, linewidth = 1)
// Reference line at 1.0 for the ratio
hline(1.0, "SMA Parity", color = color.gray, linestyle = hline.style_dashed)
7. Variable Declaration Keywords and Type Interaction
The choice of declaration keyword (=, var, varip) interacts with type behavior, especially for bool in v6.
| Keyword | Initialization | Persistence | bool bar-0 history |
|---|---|---|---|
= |
Every bar | None (resets each bar) | Returns false (v6) |
var |
Once on bar 0 | Persists across all bars | Returns false (v6) |
varip |
Once on bar 0 | Persists + updates on every real-time tick | Returns false (v6) |
Key implication: If you declare var bool flag = false and reference flag[1] on bar 0, you get false — not na. In v5, this returned na, which could cause different branching behavior. Always audit v5 → v6 migrations for this pattern.
8. Arithmetic Operator Behavior by Type
The following table documents how arithmetic operators behave when operand types are mixed:
| Expression | Result Type | Example Value |
|---|---|---|
int + int |
int | 3 + 2 = 5 |
int / int |
float | 7 / 2 = 3.5 |
int * float |
float | 3 * 1.5 = 4.5 |
float + float |
float | 1.1 + 2.2 = 3.3000...04 |
int % int |
int | 7 % 3 = 1 |
9. Conclusion
boolin v6 is strictly binary (true/false). It cannot holdna, and functions likena(),nz(), andfixnan()do not acceptboolarguments. Useintorfloatas a three-state proxy when a missing state is required.- The
/operator always returnsfloatin Pine Script, regardless of operand types. Useint()ormath.floor()explicitly when integer truncation is needed. - Type conversion between
booland numeric types requires explicit patterns: use the ternary operator (myBool ? 1 : 0) for bool→int/float, and explicit comparison (myInt != 0) orbool()cast for int/float→bool.int(myBool)andfloat(myBool)cause compile error CE10123 in v6.
Ideas for Script Advancement
- Type-safe signal encoding: Build a signal encoding system using
intas a multi-state variable (e.g., 2=strong buy, 1=buy, 0=neutral, -1=sell, -2=strong sell,na=no data) to replace multipleboolflags with a single compact representation. - Precision-aware comparison library: Create a reusable function library that wraps all float equality checks with configurable epsilon tolerance, preventing silent logic errors from IEEE 754 floating-point representation artifacts in price-level comparisons.
Comments
Post a Comment