Understanding Global Variables in Pine Script
When you're building Pine Script indicators or strategies, you'll often need variables that stick around throughout your entire script. That's exactly what global variables do - they're like having a shared notebook that every part of your code can read from and (with some rules) write to.
If you're new to Pine Script, you might want to check out our complete beginner's guide to writing Pine Script first. But if you're ready to dive into global variables, let's break it down.
What are global variables anyway?
Think of global variables as your script's memory bank. Unlike local variables that only exist inside specific functions, global variables live at the top level of your script and can be accessed from anywhere in your code.
Here's why they matter:
- They persist throughout your script's entire execution
- Any function in your script can read their values
- They're perfect for tracking state across multiple bars
- Essential for building complex indicators that need to remember things
Creating global variables the right way
The basic syntax is straightforward - just declare your variable outside any functions:
//@version=6
indicator(title="Global Variable Demo", overlay=true)
// This is a global variable
myCounter = 0
// Your indicator logic goes here
But here's the thing - this variable gets reset on every bar. Most of the time, that's not what you want. To make a variable truly "global" and persistent, use the var keyword:
//@version=6
indicator(title="Persistent Global Variable", overlay=true)
// This remembers its value across bars
var myCounter = 0
var totalVolume = 0.0
var highestPrice = 0.0
// Now these variables keep their values between bar updates
The var keyword is crucial - without it, Pine Script resets your variable to its initial value on every bar calculation.
The function limitation (and how to work around it)
Here's where Pine Script gets a bit quirky. You can read global variables from inside functions without any issues, but you can't directly modify them there. This is by design, and once you understand the workaround, it's actually pretty clean.
Here's what works:
//@version=6
indicator(title="Global Variable with Functions", overlay=false)
// Global variable that persists
var runningCount = 0
// Function that reads the global and returns a new value
calculateNewCount() =>
runningCount + math.abs(ta.change(close))
// Update the global variable in the main scope
runningCount := calculateNewCount()
// Plot the result
plot(runningCount, title="Running Count", color=color.blue)
The pattern is simple: functions can read globals and return new values, but the actual assignment happens in the main script body. It might seem weird at first, but it keeps your code organized and prevents unexpected side effects.
Real-world examples that actually make sense
Let's look at some practical uses for global variables:
Tracking consecutive conditions
//@version=6
indicator("Consecutive Bulls", overlay=false)
var consecutiveBulls = 0
var consecutiveBears = 0
if close > open
consecutiveBulls := consecutiveBulls + 1
consecutiveBears := 0
else if close < open
consecutiveBears := consecutiveBears + 1
consecutiveBulls := 0
plot(consecutiveBulls, title="Bull Count", color=color.green)
plot(consecutiveBears, title="Bear Count", color=color.red)
Building cumulative indicators
//@version=6
indicator("Volume Accumulation", overlay=false)
var totalBuyVolume = 0.0
var totalSellVolume = 0.0
if close > open
totalBuyVolume := totalBuyVolume + volume
else if close < open
totalSellVolume := totalSellVolume + volume
plot(totalBuyVolume - totalSellVolume, title="Net Volume", color=color.purple)
If you're looking for more advanced examples, our Pine Script v6 strategy examples article has tons of practical code you can learn from.
Best practices I wish I knew earlier
After writing hundreds of Pine Script indicators, here's what actually matters:
Use descriptive names: bullishBarsCount tells you way more than bbc or x. Your future self will thank you when you're debugging at midnight.
Always initialize your variables: Don't leave them hanging. Give every global variable a starting value that makes sense.
Group related globals together: Keep your variable declarations organized at the top of your script. It makes everything easier to find and maintain.
Document your globals: Add comments explaining what each variable tracks. Trust me on this one.
//@version=6
indicator("Well-Organized Globals", overlay=false)
// Price tracking variables
var float highestHigh = 0.0 // Tracks the highest price seen
var float lowestLow = 999999.0 // Tracks the lowest price seen
var int barsAboveMA = 0 // Counts bars above moving average
// Volume tracking variables
var float avgVolume = 0.0 // Running average of volume
var int volumeSpikes = 0 // Counts volume spikes above average
Common mistakes that'll trip you up
I've made all these mistakes, so you don't have to:
Trying to modify globals inside functions: This throws a compilation error. Always use the return-and-assign pattern I showed earlier.
Forgetting the var keyword: Without it, your "global" variable resets every bar, which usually isn't what you want.
Not initializing properly: Leaving variables undefined leads to weird behavior that's hard to debug.
Overusing globals: Not everything needs to be global. Only use them when you actually need to share data across functions or maintain state between bars.
How Pine Script functions really work with globals
Understanding Pine Script's function system helps you use globals more effectively. Functions in Pine Script are more like mathematical functions - they take inputs and return outputs without side effects.
This design choice makes your code more predictable and easier to debug. When you need to update a global variable based on some calculation, the pattern is always:
- Read the global variable in your function
- Calculate the new value
- Return the new value
- Assign it to the global variable in the main scope
Advanced global variable techniques
Once you're comfortable with the basics, you can use globals for more sophisticated patterns:
State machines
//@version=6
indicator("Trend State Machine", overlay=false)
var int trendState = 0 // 0=neutral, 1=uptrend, 2=downtrend
var int stateCounter = 0
// Simple state machine logic
if ta.crossover(ta.sma(close, 20), ta.sma(close, 50))
trendState := 1
stateCounter := 0
else if ta.crossunder(ta.sma(close, 20), ta.sma(close, 50))
trendState := 2
stateCounter := 0
else
stateCounter := stateCounter + 1
plot(trendState, title="Trend State")
Rolling calculations
//@version=6
indicator("Custom Rolling Average", overlay=false)
var array<float> priceArray = array.new<float>(20)
var float customAverage = 0.0
// Add new price and remove old ones
array.push(priceArray, close)
if array.size(priceArray) > 20
array.shift(priceArray)
// Calculate our custom average
if array.size(priceArray) == 20
customAverage := array.avg(priceArray)
plot(customAverage, title="Custom 20-bar Average")
For more advanced Pine Script techniques like this, check out our comprehensive Pine Script v6 cheat sheet.
Working with Pineify's visual editor
If you're using Pineify to build your indicators visually, the platform handles global variable management pretty smoothly. When you import existing Pine Script code, it preserves your global variable structure and makes it easy to modify them through the visual interface.
The drag-and-drop system understands the difference between local and global variables, so you don't have to worry about accidentally breaking your variable scope when making changes.
Wrapping it all up
Global variables in Pine Script are like the backbone of any serious indicator or strategy. They let you maintain state, track cumulative data, and build sophisticated logic that spans multiple bars.
The key things to remember:
- Use
varto make variables truly persistent - Always initialize with sensible default values
- You can read globals from functions, but update them in the main scope
- Keep your naming descriptive and your organization clean
Once you master global variables, you'll find yourself building much more powerful and flexible trading tools. They're one of those fundamental concepts that, once you get them, open up a whole new level of possibilities in your Pine Script journey.
Website: Pineify
Click here to view all the features of Pineify.