Navy: on the chart
Navy: what a script draws
The price chart or a pane of its own, plots and their styles, colors, levels and fills, backgrounds, markers, lines, boxes, labels and alerts.
On the price chart or in a pane

The declaration decides where a script draws.

overlay('Title')— the price chart: averages, bands, levels, signals.indicator('Title')— a pane below with its own scale: oscillators, volume, delta.- In a pane, mark a value with
marker.at(cond ? value : na):marker.above/.belowsit at the bar's high/low. - Up to 64 outputs; their
titlenames them in the legend.
| Option | What it does | Default |
|---|---|---|
precision | Digits after the point in the legend and on the scale | the symbol's |
maxBarsBack | How far back x[k] with a variable k reaches at first (up to 20 000) | 500 |
fuel | Loop iterations allowed per bar (up to 10 000 000) | 1 000 000 |
//@navy 2.0
indicator('RSI', { precision: 1 })
const r = ta.rsi(close, 14)
plot(r, { title: 'RSI', color: color.purple, width: 2 })
hline(50, { color: color.gray, style: 'dotted' })
// In its own pane the bar's high and low are not on this scale: mark the value itself
marker.at(ta.crossover(r, 50) ? r : na, '', { color: color.teal, size: 6 })plot and its styles
plot(series, { title, color, width, style }) draws a value on every bar; na leaves a gap.

colormay change per bar:hist >= 0 ? color.teal : color.red;width,style— constants; no color → the palette's next.base— wherecolumns/areastart;colorDown—areabelow it.const p = plot(…)can be filled; Pine'slinewidth,plot.style_steplinework.
//@navy 2.0
indicator('MACD in four styles')
const [macd, signal, hist] = ta.macd(close, 12, 26, 9)
const crossUp = ta.crossover(macd, signal)
plot(hist, { title: 'Histogram', style: 'columns', color: hist >= 0 ? color.teal : color.red })
plot(macd, { title: 'MACD', color: color.blue, width: 2 })
plot(signal, { title: 'Signal', color: color.orange, style: 'step' })
plot(crossUp ? macd : na, { title: 'Cross', style: 'circles', color: color.lime, width: 4 })
Colors
- Named:
color.red,green,blue,orange,yellow,purple,fuchsia,aqua,teal,lime,maroon,navy,olive,silver,gray,white,black. - Own:
color.rgb(255, 152, 0, 0.5),'#ff9800','#ff980080';color.new(c, opacity). - Per bar:
plot,fill,bgcolor, markers; constant:hline, a marker's text.

- Above 1 — read as Pine's transparency;
color.new(c, 1)is solid.
//@navy 2.0
indicator('Volume by strength')
const rel = volume / ta.sma(volume, 20) // 1 = an average bar
const strength = math.min(rel / 3, 1) // 0 … 1, full at 3× the average
const base = close >= open ? color.teal : color.red
// Opacity per bar: quiet bars fade, heavy ones are solid
plot(volume, { title: 'Volume', style: 'columns', color: color.new(base, 0.25 + 0.75 * strength) })Levels and fills
hline(70, { style })— a constant level:'solid','dashed'(default),'dotted'.fill(a, b, { color })— between plots or hlines kept in constants (const a = plot(…)).- A cloud: the fill's color changes per bar; hide the edges with
color.new(c, 0). - A gradient:
topValue,bottomValue,topColor,bottomColor, as in Pine.

//@navy 2.0
indicator('RSI with zones', { precision: 1 })
const r = ta.rsi(close, input.int('Length', 14, { min: 2 }))
const top = hline(70, { title: 'Overbought', color: color.gray })
const bottom = hline(30, { title: 'Oversold', color: color.gray })
fill(top, bottom, { color: color.new(color.purple, 0.06) })
// A glow where the RSI leaves the zone: invisible edges held at 70 / 30, gradient fills
const hot = plot(math.max(r, 70), { title: 'Overbought edge', color: color.new(color.red, 0) })
const cold = plot(math.min(r, 30), { title: 'Oversold edge', color: color.new(color.teal, 0) })
fill(hot, top, { topValue: 85, bottomValue: 70, topColor: color.new(color.red, 0.8), bottomColor: color.new(color.red, 0) })
fill(bottom, cold, { topValue: 30, bottomValue: 15, topColor: color.new(color.teal, 0), bottomColor: color.new(color.teal, 0.8) })
plot(r, { title: 'RSI', color: color.purple, width: 2 })
Background and bar colors
bgcolor(color)— the full height of the script's pane behind a bar;na— clear. Opacity 0.05–0.2.- No
barcolor: use a background, a marker or columns.
//@navy 2.0
indicator('Liquidation bars', { precision: 0 })
const longs = nz(liq.long) // na on spot and before the loaded history → 0
const shorts = nz(liq.short)
const avg = ta.sma(longs + shorts, 50)
const spike = avg[1] > 0 && longs + shorts > avg[1] * 3 // against the previous bars' average
plot(longs, { title: 'Longs liquidated', style: 'columns', color: color.red })
plot(-shorts, { title: 'Shorts liquidated', style: 'columns', color: color.teal })
bgcolor(spike ? color.new(color.orange, 0.15) : na, { title: 'Spike' })
Markers
marker.above(cond, 'text', { shape, size, color })— over the high;marker.below— under the low;marker.at(price)— at a price.size: pixels or'tiny'…'huge';colormay change per bar.- The text is a constant: a price goes into
label.new. Pine'sshape.*,size.*work.

//@navy 2.0
overlay('Engulfing candles')
const bull = close > open && close[1] < open[1] && close >= open[1] && open <= close[1]
const bear = close < open && close[1] > open[1] && close <= open[1] && open >= close[1]
marker.below(bull, 'Bull', { shape: 'label', color: color.teal, textColor: color.white, size: 'small' })
marker.above(bear, '', { shape: 'triangleDown', color: color.red, size: 'small' })Lines, boxes and labels
Unlike plots, objects are created where something happens — in if, loops, functions — and stay until deleted.

line.new(x1, y1, x2, y2),box.new(left, top, right, bottom),label.new(x, y, text);bar_index + 10is in the future.- Text from values:
'Breakout ' + str.tostring(top, format.mintick). - A handle in
varto change it:lvl.setXY2(…),lvl.delete(). - «Current state» goes in
if (barstate.islast): redrawn on every update, not piled up. - 500 of each kind; past that the oldest goes.

//@navy 2.0
overlay('Range breakout')
const len = input.int('Range, bars', 30, { min: 5 })
const hh = ta.highest(high, len)
const ll = ta.lowest(low, len)
const top = hh[1] // the range of the previous len bars
const bottom = ll[1]
const breakUp = ta.crossover(close, top)
if (breakUp) {
// The broken range as a box, the level written on the breakout bar
box.new(bar_index - len, top, bar_index - 1, bottom, { color: color.new(color.blue, 0.1), borderColor: color.blue })
label.new(bar_index, high, 'Breakout ' + str.tostring(top, format.mintick), { style: 'down', color: color.teal, textColor: color.white, size: 'small' })
}
// The current range: redrawn on every update of the last bar, never piled up
if (barstate.islast) {
line.new(bar_index - len, top, bar_index + 10, top, { color: color.gray, style: 'dashed' })
line.new(bar_index - len, bottom, bar_index + 10, bottom, { color: color.gray, style: 'dashed' })
}
alert(breakUp, '{{ticker}}: range breakout at {{close}}', { freq: 'close' })Options and methods: Scripts → Lines, boxes and labels, the reference.
Alerts
alert(condition, 'message', { freq, title }) notifies you when the condition holds on a live bar; written at the top level.

'bar'(default) — early;'close'— no false alarms from a wick;'all'— level touches.- Placeholders:
{{ticker}},{{exchange}},{{interval}},{{open}}…{{volume}},{{time}},{{plot_0}},{{plot("RSI")}}. - An event found in a block: a top-level flag, set in the block (below).
- Never on history or replay;
alertconditionis silent for now.
//@navy 2.0
overlay('Price near a density')
const maxDist = input.float('Distance, %', 0.3, { min: 0.05, step: 0.05 })
// An event found inside a block: a top-level flag, set in the block
let near = false
if (barstate.islast) {
for (let i = 0; i < walls.size(); i++) {
if (walls.dist(i) <= maxDist) {
near = true
line.new(bar_index - 20, walls.price(i), bar_index + 5, walls.price(i), { color: walls.side(i) > 0 ? color.teal : color.red, width: 2 })
}
}
}
// Outputs stay at the top level and read the flag
alert(near, '{{ticker}}: the price is near a density', { title: 'Near a density' })
How alerts arrive and their sound: Scripts → Alerts.