Inputs, groups and tooltips
Lesson 10 · about 11 min
An input is a value the user can change in the script's settings dialog without touching code. Every length, threshold, session and colour that you might want to tune belongs in one. Inputs also carry the input qualifier, which satisfies functions that demand simple arguments, so they solve the qualifier problem from module 2 at the same time as they make the script usable by someone who is not you.
The input.* family
| Function | Returns | Typical use |
|---|---|---|
input.int |
int | lengths, counts |
input.float |
float | multipliers, percentages |
input.bool |
bool | on/off switches |
input.string |
string | a choice from a dropdown via options= |
input.source |
series | which price series to use (close, hl2, ...) |
input.color |
color | plot colours |
input.timeframe |
string | a timeframe picker for request.security |
input.session |
string | a session picker |
input.time |
int | a date and time picker, for backtest windows |
input.price |
float | a price level, selectable by clicking the chart |
input.text_area |
string | multi-line text, e.g. a webhook JSON template |
Every one takes the default value first and a title second, then named options. The common named options are minval, maxval, step, options (for input.string, input.int and input.float dropdowns), tooltip, group, inline, confirm and display.
A full settings panel
//@version=6
indicator("Inputs demo", overlay=true)
g1 = "Moving average"
maLen = input.int(20, "Length", minval=1, maxval=500, step=1, group=g1,
tooltip="Number of bars in the average.")
maType = input.string("EMA", "Type", options=["SMA", "EMA", "WMA"], group=g1)
src = input.source(close, "Source", group=g1)
g2 = "Volume filter"
useVol = input.bool(true, "Require above-average volume", group=g2)
volMult = input.float(1.5, "Volume multiple", minval=0.1, step=0.1, group=g2,
tooltip="Bar volume must exceed this multiple of the 20-bar average.")
g3 = "Style"
upCol = input.color(color.green, "Up", group=g3, inline="cols")
dnCol = input.color(color.red, "Down", group=g3, inline="cols")
smaV = ta.sma(src, maLen)
emaV = ta.ema(src, maLen)
wmaV = ta.wma(src, maLen)
ma = maType == "SMA" ? smaV : maType == "EMA" ? emaV : wmaV
volOk = not useVol or volume > ta.sma(volume, 20) * volMult
crossUp = ta.crossover(close, ma) and volOk
plot(ma, "MA", color=close > ma ? upCol : dnCol, linewidth=2)
plotshape(crossUp, "Cross up", style=shape.triangleup, location=location.belowbar, color=upCol, size=size.tiny)
Things to notice:
groupputs inputs under a collapsible heading. Defining the heading text once as a variable (g1) avoids typos that silently create a second group.inlineplaces several inputs on one row; the two colours shareinline="cols".tooltipshows a question-mark icon with your text. Write tooltips for anything that is not self-explanatory: they are cheaper than support questions later.minval,maxvalandstepkeep users out of values that would break the script, such as a zero length.- All three averages are computed every bar and one is selected, rather than selecting which function to call. That avoids the "should be called on each calculation" warning and keeps
ta.emahappy with itssimple intrequirement.
Dropdowns
options=[...] on input.string produces a dropdown and guarantees the value is one of the listed strings, so your comparisons never miss because of a typo in the settings dialog. input.int(14, "Length", options=[7, 14, 21]) does the same for numbers.
Timeframes, sessions and dates
htf = input.timeframe("D", "Higher timeframe", tooltip="Must be higher than the chart timeframe.")
sess = input.session("0930-1600", "Session")
startDay = input.time(timestamp("2022-01-01T00:00:00"), "Backtest start")
inWindow = time >= startDay
input.timeframe and input.session return correctly formatted strings and show pickers, so the user cannot type an invalid period. input.time shows a calendar and returns a timestamp; comparing time to it restricts a strategy to a date range, which module 7 uses for out-of-sample tests.
confirm and price inputs
confirm=true on any input makes TradingView show the settings dialog before the script is added, useful when a default would be wrong for most symbols. input.price(0.0, "Level", confirm=true) goes further: the user clicks a price on the chart to set it. Combined with a horizontal line, that is a manual support level with an alert on it in three lines of code.
Inputs are not variables
An input value is fixed for the whole run; you cannot reassign it with :=. If you need a starting value that later changes, copy it: var float level = input.float(100.0, "Start level") and then reassign level.
Inputs also have a limit. The settings dialog gets slow and unusable well before the technical cap, so keep a script to the inputs that a user would genuinely change and hard-code the rest as named constants at the top of the file.
Key idea: Make every tunable value an
input.*with a sensible default, aminval, agroupand atooltip. It fixes qualifier errors, documents the script, and stops you editing code to test a parameter.
Try it: Take the SMA script from module 1 and convert its length, colour and source to inputs under a group called "Average". Add a
boolthat toggles the fill. Then add aninput.timeframeand use it in arequest.securitycall for a higher-timeframe version of the same average.
Recap
input.int,input.float,input.bool,input.string,input.source,input.color,input.timeframe,input.session,input.timeandinput.pricecover every kind of setting.- Default first, title second, then
minval,maxval,step,options,tooltip,group,inline,confirm. - Compute every candidate series each bar and select with the input; do not select which
ta.*call to make. - Inputs are
simple-qualified and cannot be reassigned; copy into avarif you need a changing value. - Keep the settings panel small; name constants in code for the rest.
See it drawn
Original diagrams for the ideas on this page. Illustrative, not real market data.