Porting from Pine Script
The main differences
- Declarations go at top level, calculations in
onBar(). Pine runs the whole script per bar. Here the top level runs once andonBar()runs per bar. - Types are explicit.
f64for prices,i32for lengths.naisNaN. varneeds care. A module variable behaves like Pinevarip, notvar. See the bar model before porting anyvar.- History uses
[n]on series only. To keep history of your own value, put it in aseries().
Name mapping
| Pine | Coinray |
|---|---|
indicator("Name"), strategy("Name") | config.title("Name"). One script is both indicator and strategy |
input.int/float/bool/string/source/timeframe | param.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 arguments | param.meta(name, group, tooltip, inline) |
max_bars_back, lookback | config.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 bands | ta.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_gradient | color.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 pane | plotPane(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.new | draw.marker, draw.label / draw.labelEx |
line.new, box.new, polyline.new | draw.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.equity | strategy.positionSize(), strategy.equity() |
barstate.isconfirmed, isrealtime, islast | barstate.isConfirmed(), isRealtime(), isLast() |
bar_index | barIndex() |
syminfo.mintick, syminfo.ticker | syminfo.mintick(), syminfo.ticker() |
timeframe.in_seconds(), timeframe.period | timeframe.inSeconds(), timeframe.period() |
hour, dayofweek | hour(), dayOfWeek() |
runtime.error(msg) | runtimeError(msg) |
var x = 0 | A series(), or change it only when isNewBar(). See the bar model |
varip x = 0 | A 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.