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.

graph LR A["Script Loads"] --> B["input.*() functions execute"] B --> C["Settings Panel UI rendered"] C --> D{"User adjusts value?"} D -- Yes --> E["New input value resolved"] D -- No --> F["Default value used"] E --> G["Value qualifier: input"] F --> G G --> H["Passed to calculations as simple or series"] H --> I["Bar-by-bar execution begins"] I --> J["plot / bgcolor / drawing output"]

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 the input qualifier, which sits between const and simple in the hierarchy. They can be passed to parameters requiring simple or series, but not to parameters requiring const.
  • Each input function maps to a specific UI widget: input.int() and input.float() render numeric spinners with optional min/max/step constraints, while input.color() renders a full color picker with a transparency slider — all without any additional configuration code.
  • The group and tooltip parameters 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

  1. 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.
  2. 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.

Related Posts

Comments

Popular posts from this blog

Pine Script v6: indicator() vs strategy() — Core Functional Differences Explained

Pine Script v6 plot() Function: Complete Guide to Lines, Histograms, and Circles

Pine Script Variable Declaration: Mastering var, varip, and Proper Initialization Across Historical Bars