Pine Script input.string: Options, Dropdowns, and All Parameters

March 24, 2026

Pine Script input.string: Options, Dropdowns, and All Parameters

March 24, 2026

input.string() is the most flexible input function in Pine Script. Without the options parameter it renders a free-text field; add an options array and TradingView turns it into a dropdown — letting users choose between named modes, MA types, session filters, or any set of string values without touching code. This guide covers every parameter, the full dropdown pattern, and four complete working examples.

input.string() parameters defval string Default value shown on load title string Label in the settings panel options string[] Turns field into dropdown tooltip string Hover text on the (?) icon group string Groups inputs under a header
All parameters accepted by input.string()

1. Basic Syntax

pine
//@version=5
indicator("input.string Demo", overlay=true)

// Free-text input — user can type any string
label = input.string(
    defval  = "Buy",          // default text
    title   = "Signal Label", // shown in settings panel
    tooltip = "Text printed on the chart label",
    group   = "Display"
)

// Use the value anywhere a string is needed
if bar_index == last_bar_index
    label.new(bar_index, high, label, style=label.style_label_down)

Without options the field is an open text box. The user types any string and Pine Script uses it at runtime. This is useful for custom labels, alert message templates, and ticker prefixes.

2. Dropdown with options

Pass an array of strings to options and TradingView replaces the text box with a dropdown. defval must be one of the values in options, otherwise Pine Script throws a compile error.

pine
maType = input.string(
    defval  = "EMA",                          // must exist in options
    title   = "MA Type",
    options = ["EMA", "SMA", "RMA", "WMA"],   // renders as a dropdown
    tooltip = "Moving average calculation method"
)

// Switch on the selected string value
length = input.int(14, "Length")

maValue = switch maType
    "EMA" => ta.ema(close, length)
    "SMA" => ta.sma(close, length)
    "RMA" => ta.rma(close, length)
    "WMA" => ta.wma(close, length)
    =>       ta.ema(close, length)  // fallback (required by compiler)

plot(maValue, "MA", color.blue)

3. All Parameters Reference

pine
// Full parameter list for input.string()
myString = input.string(
    defval  = "EMA",                   // (required) default value
    title   = "MA Type",               // label shown left of the field
    options = ["EMA", "SMA", "WMA"],   // optional — creates a dropdown
    tooltip = "Choose calculation",    // shown when user hovers (?)
    group   = "MA Settings",           // groups inputs under a shared header
    confirm = false                    // if true, prompts user on add-to-chart
)

Parameter notes

  • defval — The only required parameter. Must be a compile-time constant string literal (not a variable).
  • title — Defaults to the variable name if omitted. Always set it explicitly for clarity.
  • options — When provided, defval must exactly match one of the entries (case-sensitive). Omit to allow free text.
  • tooltip — Renders a (?) icon next to the label. Useful for explaining non-obvious choices.
  • group — Strings that share the same group value are collected under a collapsible section header in the settings panel.
  • confirm — When true, TradingView shows a settings dialog the first time the script is added to a chart, forcing the user to review defaults.

4. Example: Signal Filter Dropdown

A common use case is a signal direction filter — let users choose whether the indicator fires long signals only, short only, or both.

pine
//@version=5
indicator("Signal Filter Demo", overlay=true)

signalDir = input.string(
    defval  = "Both",
    title   = "Signal Direction",
    options = ["Both", "Long Only", "Short Only"],
    tooltip = "Restrict which signals are plotted",
    group   = "Filters"
)

fast = ta.ema(close, 9)
slow = ta.ema(close, 21)

longSignal  = ta.crossover(fast, slow)  and signalDir != "Short Only"
shortSignal = ta.crossunder(fast, slow) and signalDir != "Long Only"

plotshape(longSignal,  "Long",  shape.triangleup,   location.belowbar, color.green, size=size.small)
plotshape(shortSignal, "Short", shape.triangledown, location.abovebar, color.red,   size=size.small)

5. Example: MA Type Selector with Groups

Use group to organise multiple string dropdowns so the settings panel stays readable as your script grows.

pine
//@version=5
indicator("Dual MA", overlay=true)

// ── Fast MA ──────────────────────────────────────────
fastType   = input.string("EMA", "Type",   options=["EMA","SMA","WMA"], group="Fast MA")
fastLength = input.int(9,        "Length", minval=1,                    group="Fast MA")

// ── Slow MA ──────────────────────────────────────────
slowType   = input.string("SMA", "Type",   options=["EMA","SMA","WMA"], group="Slow MA")
slowLength = input.int(21,       "Length", minval=1,                    group="Slow MA")

// Helper to resolve MA type string → value
ma(src, len, type) =>
    switch type
        "EMA" => ta.ema(src, len)
        "SMA" => ta.sma(src, len)
        "WMA" => ta.wma(src, len)
        =>       ta.ema(src, len)

fastMA = ma(close, fastLength, fastType)
slowMA = ma(close, slowLength, slowType)

plot(fastMA, "Fast", color.blue)
plot(slowMA, "Slow", color.orange)

bgcolor(ta.crossover(fastMA, slowMA)  ? color.new(color.green, 90) : na)
bgcolor(ta.crossunder(fastMA, slowMA) ? color.new(color.red,   90) : na)

6. Example: Alert Message Template

Free-text input.string (no options) lets users define the alert_message payload directly from the settings panel — useful for webhook bots where the JSON body varies per deployment.

pine
//@version=5
strategy("Webhook Strategy", overlay=true)

// Free-text: user pastes their own JSON body in the settings panel
longMsg  = input.string('{"action":"buy","qty":1}',  "Long Alert Message",  group="Alerts")
shortMsg = input.string('{"action":"sell","qty":1}', "Short Alert Message", group="Alerts")

fast = ta.ema(close, 9)
slow = ta.ema(close, 21)

if ta.crossover(fast, slow)
    strategy.entry("Long", strategy.long, alert_message=longMsg)

if ta.crossunder(fast, slow)
    strategy.entry("Short", strategy.short, alert_message=shortMsg)

7. Common Mistakes

  • defval not in options — Pine Script throws a compile error. Check for typos and case mismatches ("EMA""ema").
  • Using a variable as defvaldefval must be a compile-time constant. You cannot pass a calculated string or another variable.
  • Comparing with == inside a series contextinput.string returns a simple string, not a series, so comparisons like maType == "EMA" work without issues anywhere in the script.
  • Forgetting the fallback in switch — Pine Script v5 requires a default => branch in every switch expression that returns a value, even when you've covered all options.

Quick Reference

// Free-text (open input)
label = input.string("Buy", "Label")

// Dropdown (options array — defval must be one of the values)
mode = input.string("EMA", "Mode", options=["EMA","SMA","WMA"])

// With all parameters
full = input.string(
    defval  = "EMA",
    title   = "Mode",
    options = ["EMA", "SMA", "WMA"],
    tooltip = "MA calculation type",
    group   = "Settings",
    confirm = false
)

// Using the value: direct comparison
if mode == "EMA"
    // ...

// Using the value: switch expression
val = switch mode
    "EMA" => ta.ema(close, 14)
    "SMA" => ta.sma(close, 14)
    "WMA" => ta.wma(close, 14)
    =>       ta.ema(close, 14)