Skip to main content
On this page

Pine Script v4: Read Legacy Indicators and Plan Migration

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

Pine Script v4 is a legacy language version that still appears in published indicators and older projects. TradingView announced it on June 25, 2019. Reading v4 accurately means distinguishing its APIs from later versions: study() and input() belong in v4 code, while the indicator() declaration and specialized input functions are part of the v5 migration.

What v4 introduced​

TradingView's v4 announcement describes drawing objects, series strings, and language changes. Its color constants use names such as color.red, replacing older unqualified names. That does not mean every function moved into a namespace: plot() remains a function, and v4 technical-analysis calls include rsi() and sma() without the later ta. prefix.

The v4 migration guide also explains explicit typing when a variable starts with na. The compiler needs to know what kind of value that variable will hold. Declaring a type resolves that ambiguity; it does not eliminate missing values from later calculations or guarantee the absence of runtime errors.

Recognize the version boundary​

PurposeTypical v4 formLater migration consideration
Indicator declarationstudy()Renamed to indicator() in v5
Integer settinginput() with integer default or typeSpecialized input.int() function in v5
RSI calculationrsi()ta.rsi() in v5
Color constantcolor.redRetained in later versions
Drawing updatelabel.set_text(id, text)Do not assume newer method syntax works in v4

In v4, names such as input.integer are type constants used with input(), not a reason to paste newer input-function syntax into an old script. Use the archived input documentation when maintaining that version.

Read a legacy RSI example​

The following retained v4 example shows inputs, a plot, horizontal levels, and labels. It is an indicator, not a strategy, and contains no running alert configuration.

//@version=4
study("My Enhanced RSI", overlay=false)

// Input parameters
rsi_length = input(14, title="RSI Length")
oversold = input(30, title="Oversold Level")
overbought = input(70, title="Overbought Level")

// Calculate RSI
rsi_value = rsi(close, rsi_length)

// Plot RSI line
plot(rsi_value, color=color.blue, title="RSI")

// Add horizontal reference lines
hline(oversold, color=color.green, linestyle=hline.style_dashed)
hline(overbought, color=color.red, linestyle=hline.style_dashed)

// Dynamic labels for extreme levels
if rsi_value <= oversold
label.new(bar_index, rsi_value, text="OVERSOLD", style=label.style_label_up, color=color.green, textcolor=color.white)

if rsi_value >= overbought
label.new(bar_index, rsi_value, text="OVERBOUGHT", style=label.style_label_down, color=color.red, textcolor=color.white)

The code creates a label on every bar meeting either extreme condition. It does not restrict labels to the first crossing, confirm a reversal, or wait explicitly for bar close. A developing realtime RSI can change, so an extreme-zone label should not be interpreted as a confirmed trade recommendation.

Use a positive RSI length and keep the lower level below the upper level. These inputs do not enforce those relationships in this legacy example. A maintenance task should specify how invalid settings are handled before using the script as a reusable component.

Manage drawings deliberately​

Drawing objects have IDs and lifecycle rules. Keep an ID if you need to update or delete its object. Creating new labels continuously differs from updating one status label, both visually and in resource usage.

The v4 drawing documentation describes automatic removal of older objects and configurable per-type counts. The usual displayed count is about 50 unless increased; the maximum is not a default shared pool of 500 objects. The parameters for lines, labels, and boxes are separate. Deleting old objects deliberately can make the retained history match the script's intended behavior.

Series strings let calculated values become changing text, for example in a label. They do not remove the constant-string restrictions of every output function. In particular, an alert condition's message requirements must be checked independently from what a drawing can display.

Migrate in stages​

Keep a copy of the working v4 source and record its inputs, plots, and signal timing. Convert to v5 first, resolve compilation errors, then compare behavior before moving to v6. TradingView's v6 migration guide describes the version-by-version route for older scripts.

Do not treat replacing //@version=4 with a later annotation as a complete conversion. Renamed functions are only part of the work. Newer versions also change language and strategy behavior. Compare representative bars, input edge cases, and any multi-timeframe values after each step.

New projects should use the current documentation rather than inheriting a legacy version solely because an old example compiles. Retaining v4 temporarily can be useful when reproducing an existing script's behavior; it is not evidence that v4 covers a particular percentage of trading use cases or improves returns.