Pine Script v6 Input Functions: Building User-Friendly Settings Menus with input.int, input.float, and input.color
When building indicators in Pine Script v6, hardcoding values like period lengths or colors directly into your logic forces users to edit source code every time they want to adjust a parameter. The input.* family of functions solves this by exposing configurable controls in TradingView's built-in Settings panel, allowing any user to tune an indicator without touching a single line of code.
1. Why Input Functions Matter
Every value returned by an input.* function carries the input type qualifier — the second-narrowest qualifier in Pine Script's hierarchy (const → input → simple → series). This means input values are resolved once when the script loads, not recalculated on every bar. That makes them ideal for configuration parameters such as lookback periods, thresholds, and display colors.
2. The Type Qualifier Hierarchy
Understanding where input sits in the qualifier hierarchy is essential before using these functions. The four qualifiers, ordered from most restrictive to least restrictive, are:
| Qualifier | Resolved At | Typical Source | Can Widen To |
|---|---|---|---|
const |
Compile time | Literal values, compile-time expressions | input, simple, series |
input |
Script load | input.*() functions |
simple, series |
simple |
Bar 0 (first bar) | Runtime constants, some built-ins | series |
series |
Every bar | Price data, bar-by-bar calculations | — |
A parameter that requires simple will accept const, input, or simple values. A parameter that requires const accepts only const values — passing an input value to a const parameter is a compile error.
3. input.int — Integer Configuration
input.int() creates an integer input control in the Settings panel. It is most commonly used for lookback periods, bar counts, and any whole-number parameter. Key parameters include defval (the default integer), title (the label shown in Settings), minval (minimum allowed value), maxval (maximum allowed value), and step (increment size when using the up/down arrows). For the full parameter list, see the official Reference Manual: input.int reference.
🔽 [Click to expand] View input.int Example
//@version=6
indicator("input.int Demo", overlay = true)
// Create an integer input for the SMA period.
// defval: default value shown when the indicator is first added.
// minval: prevents the user from entering a period below 1.
// maxval: caps the period at 500 bars.
// step: each click of the arrow increments/decrements by 1.
int smaPeriod = input.int(
defval = 20,
title = "SMA Period",
minval = 1,
maxval = 500,
step = 1
)
// Calculate the simple moving average using the user-supplied period.
float smaValue = ta.sma(close, smaPeriod)
// Plot the SMA on the main chart pane.
plot(smaValue, title = "SMA", color = color.blue)
4. input.float — Decimal Configuration
input.float() creates a floating-point input control. It accepts the same structural parameters as input.int() — defval, title, minval, maxval, and step — but the values are floating-point numbers. This is the correct choice for multipliers, percentage thresholds, ATR factors, and any parameter that requires decimal precision. For the full parameter list, see: input.float reference.
🔽 [Click to expand] View input.float Example
//@version=6
indicator("input.float Demo", overlay = true)
// ATR period: integer input, whole bars only.
int atrPeriod = input.int(
defval = 14,
title = "ATR Period",
minval = 1
)
// ATR multiplier: float input, allows decimal precision.
// step = 0.1 means each arrow click changes the value by 0.1.
float atrMultiplier = input.float(
defval = 1.5,
title = "ATR Multiplier",
minval = 0.1,
maxval = 10.0,
step = 0.1
)
// Calculate ATR and derive upper/lower bands.
float atrValue = ta.atr(atrPeriod)
float upperBand = close + atrValue * atrMultiplier // Upper envelope
float lowerBand = close - atrValue * atrMultiplier // Lower envelope
// Plot both bands on the main chart pane.
plot(upperBand, title = "Upper Band", color = color.red)
plot(lowerBand, title = "Lower Band", color = color.green)
The mathematical relationship between the ATR bands and the multiplier is straightforward:
$$\text{Upper Band} = \text{Close} + \text{ATR}(n) \times k$$
$$\text{Lower Band} = \text{Close} - \text{ATR}(n) \times k$$
where $n$ is the ATR period (integer input) and $k$ is the multiplier (float input). Exposing both $n$ and $k$ as inputs lets users tune the band width without modifying source code.
5. input.color — Color Configuration
input.color() renders a color picker widget in the Settings panel. Users can select any color and adjust its transparency (opacity) directly from the UI. The defval parameter accepts any color value, including built-in color constants such as color.blue or colors constructed with color.new() to set a default transparency. For the full parameter list, see: input.color reference.
🔽 [Click to expand] View input.color Example
//@version=6
indicator("input.color Demo", overlay = true)
// SMA period input.
int smaPeriod = input.int(
defval = 20,
title = "SMA Period",
minval = 1
)
// Color input for the SMA line.
// color.new(color.blue, 0) sets the default to fully opaque blue.
// The user can change both the hue and transparency in the Settings panel.
color smaColor = input.color(
defval = color.new(color.blue, 0),
title = "SMA Line Color"
)
// Color input for the background fill.
// Default is a semi-transparent green (50% opacity).
color bgColor = input.color(
defval = color.new(color.green, 50),
title = "Background Color"
)
// Calculate and plot the SMA using the user-selected color.
float smaValue = ta.sma(close, smaPeriod)
plot(smaValue, title = "SMA", color = smaColor, linewidth = 2)
// Apply the background color to the chart pane.
bgcolor(bgColor, title = "Background")
6. Organizing Inputs with Groups and Tooltips
All input.* functions support a group parameter (a const string) that visually clusters related inputs under a collapsible section header in the Settings panel. They also support a tooltip parameter that displays a hover-over explanation icon next to the input label. Both parameters are purely cosmetic — they do not affect the returned value or its type qualifier.
🔽 [Click to expand] View Grouped Input Example
//@version=6
indicator("Grouped Inputs Demo", overlay = true)
// ── Group 1: Moving Average Settings ──────────────────────────
int fastPeriod = input.int(
defval = 10,
title = "Fast MA Period",
minval = 1,
group = "Moving Average Settings",
tooltip = "Number of bars for the fast moving average."
)
int slowPeriod = input.int(
defval = 50,
title = "Slow MA Period",
minval = 1,
group = "Moving Average Settings",
tooltip = "Number of bars for the slow moving average."
)
// ── Group 2: Visual Settings ───────────────────────────────────
color fastColor = input.color(
defval = color.new(color.blue, 0),
title = "Fast MA Color",
group = "Visual Settings"
)
color slowColor = input.color(
defval = color.new(color.orange, 0),
title = "Slow MA Color",
group = "Visual Settings"
)
// ── Group 3: Signal Settings ───────────────────────────────────
float crossThreshold = input.float(
defval = 0.0,
title = "Cross Threshold (points)",
step = 0.5,
group = "Signal Settings",
tooltip = "Minimum distance between MAs required to confirm a cross signal."
)
// ── Calculations ───────────────────────────────────────────────
float fastMA = ta.sma(close, fastPeriod) // Fast SMA
float slowMA = ta.sma(close, slowPeriod) // Slow SMA
// Determine if the gap between MAs exceeds the threshold.
bool gapSufficient = math.abs(fastMA - slowMA) >= crossThreshold
// ── Plots ──────────────────────────────────────────────────────
plot(fastMA, title = "Fast MA", color = fastColor, linewidth = 2)
plot(slowMA, title = "Slow MA", color = slowColor, linewidth = 2)
// Highlight bars where the gap condition is met.
bgcolor(gapSufficient ? color.new(color.yellow, 85) : na,
title = "Gap Highlight")
7. Common Pitfalls and Constraints
| Pitfall | Incorrect Pattern | Correct Pattern |
|---|---|---|
Passing input value to a const parameter |
indicator("X", timeframe = input.timeframe("D")) |
Use input.timeframe() only where simple or series is accepted |
| Calling input functions inside conditions or loops | if condition { int p = input.int(20) } |
Always declare inputs at the top-level scope of the script |
Using := to reassign an input variable |
smaPeriod := 30 |
Input values are immutable after load — never reassign them |
| Expecting input values to change bar-by-bar | Treating input.int() result as a series |
Input values are resolved once at script load, not per bar |
8. Conclusion
- Type qualifier awareness is critical: Values returned by
input.*functions carry theinputqualifier, which sits betweenconstandsimplein the hierarchy. They can be passed to parameters requiringsimpleorseries, but not to parameters requiringconst. - Each input function maps to a specific UI widget:
input.int()andinput.float()render numeric spinners with optional min/max/step constraints, whileinput.color()renders a full color picker with a transparency slider — all without any additional configuration code. - The
groupandtooltipparameters are purely cosmetic: They organize the Settings panel for end users but have zero effect on the returned value, its type qualifier, or script execution behavior.
Ideas for Further Development
- Combine with
input.bool(): Add toggle switches that enable or disable entire sections of your indicator logic (e.g., show/hide bands, enable alerts), creating a fully self-contained, no-code-edit indicator suite. - Combine with
input.source(): Allow users to select which price series (close, open, hl2, hlc3, or even an external indicator's output) feeds into your calculations, making a single script adaptable to dozens of use cases.
Comments
Post a Comment