Skip to main content

Porting from Pine Script

The main differences​

  1. Declarations go at top level, calculations in onBar(). Pine runs the whole script per bar. Here the top level runs once and onBar() runs per bar.
  2. Types are explicit. f64 for prices, i32 for lengths. na is NaN.
  3. var needs care. A module variable behaves like Pine varip, not var. See the bar model before porting any var.
  4. History uses [n] on series only. To keep history of your own value, put it in a series().

Name mapping​

PineCoinray
indicator("Name"), strategy("Name")config.title("Name"). One script is both indicator and strategy
input.int/float/bool/string/source/timeframeparam.int float bool_ text source timeframe
input.string(options=...)param.options(name, defaultIndex, labels)
input.color(c)param.color(name, c)
input.time(t)param.time(name, t): unix seconds, Pine's time is milliseconds
group, tooltip, inline input argumentsparam.meta(name, group, tooltip, inline)
max_bars_back, lookbackconfig.warmup(bars)
close, open, hl2, time, ...src.close, src.open, src.hl2, src.time
close[1]src.close[1]
ta.sma(close, 20)ta.sma(src.close, 20)
ta.crossover(a, b)new Cross() at top level, cross.update(a, b) > 0
ta.barssince(cond)new BarsSince(), .update(cond)
ta.valuewhen(cond, src, n)new ValueWhen(), .update(cond, value, n)
ta.rising(x, n), ta.falling(x, n)new Rising(), new Falling()
ta.cum(x)ta.cum(series)
ta.vwap with bandsta.vwapBands(source, Anchor.Week, mult)
request.security(syminfo.tickerid, "240", close)const h = request.timeframe("240"), then h.close[1]
request.security(syminfo.tickerid, "240", ta.atr(14))h.atr(14) (also h.dmi, h.supertrend, h.sar, h.tr)
request.security("BINANCE:ETHUSDT", "60", close)const eth = request.security("ETH/USDT", "60"), then eth.close[1]
na(x), nz(x)na(x), nz(x)
math.*math.*
color.new(c, transp)color.withTransp(c, transp)
color.rgb, color.from_gradientcolor.rgb, color.fromGradient
plot(x, color=..., linewidth=...)declarePlot(name, color, width, style) once, plot(name, x) per bar
plot(x, color = cond ? a : b)plot(name, x, cond ? a : b)
plot(x, offset = n)declarePlot(name, ..., offset = n) (last argument)
plot(x, display=pane) / separate paneplotPane(name, x, pane)
fill(p1, p2)declarePlot(name1, ..., fillTo = name2, fillColor)
hline(70)hline(70, color, Stroke.Dashed, pane)
fill(hline1, hline2, color)fillLevels(price1, price2, color, pane)
bgcolor(c, transp = 90)bgcolor(color.withTransp(c, 90)), on the bars it applies to
barcolor(c)barcolor(c), on the bars it applies to (offset is not supported)
plotshape, label.newdraw.marker, draw.label / draw.labelEx
line.new, box.new, polyline.newdraw.line / lineEx, draw.box / boxEx, draw.polyline
(no Pine equivalent)draw.shapeEx(name) — place one of the chart's own drawing tools (callout, price label, Fibonacci). Pine has no API for these either; a Pine script rebuilds them from line.new + label.new
line.delete(id)draw.remove(id)
alertcondition(cond, title, message)declareAlertMessage(name, message) (or declareAlert(name)), then alert(name, message)
alert(message)alert(name, message)
strategy.entry("L", strategy.long)strategy.long("L") or strategy.order("L", Side.Long)...submit()
strategy.exit(stop=, limit=, trail_offset=).stopLoss(p), .takeProfit(p), .trailingStop(pct) on the order
strategy.close(id), strategy.close_all()strategy.close(id), strategy.closeAll()
strategy.position_size, strategy.equitystrategy.positionSize(), strategy.equity()
barstate.isconfirmed, isrealtime, islastbarstate.isConfirmed(), isRealtime(), isLast()
bar_indexbarIndex()
syminfo.mintick, syminfo.tickersyminfo.mintick(), syminfo.ticker()
timeframe.in_seconds(), timeframe.periodtimeframe.inSeconds(), timeframe.period()
hour, dayofweekhour(), dayOfWeek()
runtime.error(msg)runtimeError(msg)
var x = 0A series(), or change it only when isNewBar(). See the bar model
varip x = 0A module-level let

Not supported​

table.*, matrix.*, request.security on another exchange, timeframes above 1 day, lower timeframes (request.security_lower_tf, or request.security to a timeframe below the chart's), lookahead_on, process_orders_on_close, libraries, and drawing getters such as line.get_price. Keep the values you need in your own variables instead of reading them back from drawings.