Skip to content
GetProfitable
Search

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:

  • group puts inputs under a collapsible heading. Defining the heading text once as a variable (g1) avoids typos that silently create a second group.
  • inline places several inputs on one row; the two colours share inline="cols".
  • tooltip shows a question-mark icon with your text. Write tooltips for anything that is not self-explanatory: they are cheaper than support questions later.
  • minval, maxval and step keep 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.ema happy with its simple int requirement.

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, a minval, a group and a tooltip. 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 bool that toggles the fill. Then add an input.timeframe and use it in a request.security call 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.time and input.price cover 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 a var if 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.

One daily candle broken into four six-hour candlesA tall daily candle on the left and the four six-hour candles that make it up on the right, with dashed lines linking the day's open to the first candle and the day's close to the last.ONE DAILY CANDLEFOUR 6-HOUR CANDLEScloseopenhighlow=00:0006:0012:0018:00one dayThe same trading, summed up in one bar or spelled out in four.
How timeframes stack up. A daily candle is not different data, only coarser data: it opens where the first six-hour candle opened, closes where the last one closed, and its wicks reach the highest and lowest prices any of the four touched.
Payoff of a long call at expiryA flat loss equal to the premium below the strike, turning upward at 45 degrees above it.Profit / loss per share08595115125Strike 105Max loss 3 — the premium paidBreakeven 108Profit keeps growingUnderlying price at expiry
Buying a call: payoff at expiry. A 105-strike call bought for 3 loses that whole 3 if the price finishes at or below 105, breaks even at 108, then gains a dollar for every dollar higher. The loss is capped at the premium; the upside is not capped.
A fast and a slow moving average crossingA jagged price line with two smoother average lines through it; the fast average dips below the slow one on the left and cuts back above it in the middle, where a circle marks the crossing.pricefast averageslow averagefast crosses belowfast crosses abovethe slow averageAverages of recent closes; the fast one reacts sooner than the slow one.
Fast and slow moving averages crossing. A moving average is the average of the last few closing prices, redrawn each period. An average over fewer periods turns sooner than one over many, so the two lines cross whenever the recent pace of the market changes.