Skip to main content

Series Float in Pine Script: What It Is and Why It Matters

· 11 min read
Pineify Team
Pine Script and AI trading workflow research team

Series float is Pine Script's data type for decimal numbers that change with every bar. Every price on TradingView — open, high, low, close — it's all series float. Get this wrong and your indicators throw type errors you can't make sense of.

I remember the first time I hit a "cannot call plot with argument series" error on a TSLA chart. I'd been assuming price values were plain numbers. They're not. They're sequences — one value per bar. That distinction changes everything.

Once series float clicks, most Pine Script concepts start falling into place.

What Series Float Actually Means

Think of a movie reel. Each frame is a moment in time. A series in Pine Script works the same way — each new candlestick adds a frame to the sequence. So close isn't one number. It's a timeline of closing prices going back to the first bar on your chart.

The "float" part is simpler: decimal numbers. 42.73, 156.89, 0.0015. Trading needs this precision — a penny move on a hundred-dollar stock is a real signal.

Series float = a timeline of decimal numbers that grows with every bar. That's it. Every price variable in Pine Script works this way. So does any indicator calculated from them.

I haven't found another trading platform that handles this as cleanly as Pine Script. Python libraries like pandas can do similar things, but the bar-by-bar execution model makes Pine Script's approach more intuitive once you've wrapped your head around it.

The Best Pine Script Generator

The Four Type Levels Pine Script Uses

Pine Script organizes data by how often it can change. This isn't academic — it directly determines what you can and can't do in your code.

const — Fixed forever. Pi. Your favorite moving average period. Set at compile time, never touched again.

input — User-configurable before the script runs. RSI period selector, alert threshold. Choose once, stays fixed for the run.

simple — Calculated at script start, doesn't change afterward. I've used this for initial reference levels on first-session breakouts.

series — Updates every bar. Price. Volume. Your SMA calculation. Anything that reacts to new market data.

Series is the most flexible type for a reason. It can do everything the others can, plus it tracks history. That's why your moving averages, RSI lines, and custom signals are all series values under the hood.

This is a good time to mention: I prefer declaring variables with explicit types when I'm building complex indicators. var float myVal = na is clearer than letting Pine Script infer the type, and it's saved me from several subtle bugs.

Why This Affects Your Trading Code

When I was building a Bollinger Bands and RSI combo strategy for a friend's day-trading setup on NVDA in March 2025, I kept getting wrong signals. The issue wasn't the logic — it was that I was comparing a series value against a const in a context where Pine Script needed both to be the same type.

Responsive indicators depend on series float working correctly. If your MACD line can't update with each tick, you'll miss crossovers. If your ATR doesn't recalculate bar by bar, your stop levels drift.

The practical takeaway: when you see a type error in Pine Script, nine times out of ten it means you're mixing a dynamic (series) value where the function expects a fixed type. Know your types, and these errors disappear.

The float() Function in Practice

The float() function converts values explicitly. Here's when I use it:

//@version=5
indicator("Series Float Example", overlay=true)

// Declare a variable that can hold float values
var float myPrice = na

// Convert the closing price to ensure it's treated as a float
myPrice := float(close)

// Plot it on the chart
plot(myPrice, title="Current Price", color=color.blue)

// You can also use it in calculations
float avgPrice = (float(high) + float(low)) / 2
plot(avgPrice, title="Mid Price", color=color.red)

The float() call tells Pine Script: "Treat this as a decimal, even if it could be na." I've found this essential when passing values from request.security() across timeframes — the function can return mixed types, and float() normalizes them.

That said, I haven't tested float() with every data type Pine Script supports. It works reliably on standard price and indicator outputs. For edge cases like custom string-to-number conversions, run your own tests.

Real Scenarios Where Series Float Matters

Custom indicators. When I wrote a custom MACD crossover for a friend's QQQ options strategy, every calculation — MACD line, signal line, histogram — was series float. Each bar adds a new value, and the crossover logic depends on that sequence.

Multi-timeframe analysis. Pulling data from different timeframes with request.security() returns series float values. This tripped me up initially — I assumed a daily close was a single number, but it's a series of daily closes. Fixing that alignment bug took me an afternoon. Here's a guide on multitimeframe Pine Script analysis if you're hitting the same wall.

Alert conditions. When you write ta.crossover(RSI, 70), you're comparing two series float values. RSI itself produces a series float, and 70 is a const. Pine Script handles the cross-type comparison here, but not all functions do.

Practical Tips I've Picked Up

Always guard for na. Series values can be undefined early in a chart's history. I wrap critical calculations:

if not na(close) and not na(ta.sma(close, 20))
// Your calculation here

Pick the right plot. plot() for continuous lines. plotshape() for discrete signals. Using the wrong one produces charts that look wrong at certain zoom levels.

Use the [] operator. close[1] gives you the previous bar's value. This works on any series float — built-in or custom. I use this for bar-to-bar comparisons in reversal strategies.

Newcomers often start with a Pine Script beginner tutorial and hit type errors on their second or third indicator. Understanding series float early makes that whole learning curve shallower.

Moving Past the Basics

Once series float feels natural, the next step is combining it with other Pine Script concepts. I've been experimenting with cross-timeframe divergence detection — pulling daily series float into a 15-minute script to catch momentum shifts before they appear on the lower timeframe.

Another area worth exploring: how series float interacts with Pine Script's execution model. Scripts run once per bar, from left to right on the chart. Each run, series values shift — the current bar becomes the previous bar next time. If you're not accounting for this, your indicator outputs wrong historical values.

Frequently Asked Questions

What does 'series float' mean in Pine Script?

Series float is a sequence of decimal numbers where each bar on your chart adds one entry. The "series" gives you a history — one value per bar going back to bar zero. The "float" means it uses decimal precision. Every price variable — close, high, low, open — is series float by default.

What is the difference between series and simple types in Pine Script?

A simple value is calculated once when the script loads and never changes. A series value recalculates every bar. Series is more flexible — you can use it anywhere a simpler type is expected, but not the other way around. Try passing close (series) to a parameter that expects simple, and you get an error.

When should I use the float() function in Pine Script?

Use float() when you need explicit decimal conversion. I reach for it most often with request.security() returns, values that might be na, and mixed-type arithmetic where Pine Script needs a clear hint. Without it, the compiler may refuse to combine a series int with a series float in the same expression.

Why does Pine Script show a 'series float' type error?

You're passing a series float where Pine Script expects a simpler type — const, input, or simple. Fix it by using a fixed value, wrapping it in input.*(), or restructuring your logic so the dynamic value lives elsewhere. If you see this repeatedly, check whether you're assigning a price-derived value to a parameter that only takes compile-time constants.

Can I access historical series float values in Pine Script?

Yes — the [] history operator. close[1] is the previous bar's close. close[5] is five bars ago. This works on any series float, including custom variables. I use it constantly for crossover detection and trailing stop calculations.

Are all price values in Pine Script series float?

Yes. open, high, low, close, volume — all series float (or series int for volume). Any indicator calculated from them, like ta.sma(close, 14), is also series float. You can't have a price-derived indicator that isn't series — Pine Script doesn't let you detach a calculation from its bar-by-bar context.