Coming from Pine Script

XFlow Script reads like Pine Script on purpose, and most indicators port line by line. These are the differences that matter.

Pine ScriptXFlow Script
//@version=6 and indicator("Name", overlay=true)//@xfscript 1 and indicator("Name"). Price drawings go on the chart, and panel drawings open the sub panel by themselves.
Indented blocksBraces, the opening brace on the same line: if close > open { }
A call wrapped over several linesNot allowed: every call on one line
x = 1 and x := 2let x: float = 1 for a value recomputed on every bar; var x: float = 1 and x := 2 for one that carries forward
cond ? a : b, for i = 0 to n, while, break, continue, +=The same
na, na(x), nz(x), hl2, hlc3, ohlc4, hlcc4The same
input.int(14, "Length")input.int(14, "length", "Length", 1, 500, 1): the key the setting is saved under, the title, then optional bounds and step
ta.sma, ta.ema, ta.wma, ta.hma, ta.vwma, ta.alma, ta.rsi, ta.atr, ta.tr, ta.stoch, ta.cci, ta.mfi, ta.cmo, ta.mom, ta.roc, ta.cum, ta.highest, ta.lowest, ta.change, ta.crossover, ta.crossunder, ta.cross, ta.barssince, ta.valuewhen, ta.pivothigh, ta.pivotlow, ta.linreg, ta.correlation, ta.percentrank, ta.median, ta.range, ta.sar, ta.tsiThe same names and arguments, except ta.sar, which is ta.psar(start, increment, maximum), and ta.obv, which is the call ta.obv()
[line, signal, hist] = ta.macd(close, 12, 26, 9)ta.macd_line(close, 12, 26), ta.macd_signal(close, 12, 26, 9), ta.macd_hist(close, 12, 26, 9)
[middle, upper, lower] = ta.bb(close, 20, 2)ta.sma(close, 20), ta.bb_upper(close, 20, 2), ta.bb_lower(close, 20, 2)
[middle, upper, lower] = ta.kc(close, 20, 2)ta.ema(close, 20), ta.kc_upper(close, 20, 2), ta.kc_lower(close, 20, 2)
[trend, direction] = ta.supertrend(3, 10)ta.supertrend(3, 10) and ta.supertrend_dir(3, 10). The direction is -1 in an up trend, as in Pine
[plus, minus, adx] = ta.dmi(14, 14)ta.plus_di(14), ta.minus_di(14), ta.adx(14, 14)
request.security(syminfo.tickerid, "60", close)mtf.close(60) for the hour this bar belongs to so far, mtf.prev_close(60) for the last finished hour; the chart instrument only
dayofmonth, dayofweek, hour, minute, month, yeartime.day(time, "America/New_York") and its siblings, with the zone stated; Pine reads the exchange clock, which for CME futures is "America/Chicago". dayofweek is time.weekday(time, zone) + 1. To read yesterday, store it first: let day: float = time.day(time, "America/Chicago"), then day[1]
plot, plotshape, barcolor, fill, hlineplot.line, plot.marker, plot.candle_color, plot.band, plot.hline or plot.panel_hline
label.new, line.new, box.new, table.cellplot.text, plot.segment, plot.box or plot.rect, plot.table
color.red, color.new(c, 50), color.rgb(r, g, b, t), color.from_gradient(v, lo, hi, c1, c2)The same
str.tostring, str.length, str.contains, str.upper, str.substringThe same; join text with str.concat, never with +
Arrays, matrices, maps, types, methods, libraries, request.*, strategy.*Not part of the language
  • A window with nan anywhere in it answers nan. Pine skips na inside some windows; XFlow Script does not, so wrap a source that can be absent in nz.
  • ta.supertrend and ta.supertrend_dir answer nan while the ATR warms up, where Pine starts with a value.
  • ta.rma on its own starts from the first value, where Pine starts from a simple average. ta.rsi, ta.atr and the directional indicators start the Pine way.
  • ta.tsi answers a ratio from -1 to 1, as Pine does. Multiply by 100 for a percent scale.
  • dayofweek counts Sunday as 1; time.weekday counts Sunday as 0.
  • mtf.* buckets are counted from midnight UTC, so mtf.close(1440) is the UTC calendar day, not the futures session. Use session.* for sessions.
  • Every typed declaration is checked on every bar. Annotate with float unless the value is always a whole number.
  • An unknown Pine name is refused with a line naming the XFlow Script equivalent, for example time.day for dayofmonth.

A port, line by line

Pine Script
//@version=6
indicator("Daily Typical Price", overlay = true)
mult = input.float(1.0, "Band multiplier")
newDay = dayofmonth != dayofmonth[1]
var float total = 0.0
var float count = 0.0
total := newDay ? hlc3 : total + hlc3
count := newDay ? 1 : count + 1
average = total / count
deviation = ta.atr(14) * mult
plot(average, color = close > average ? color.green : color.red, linewidth = 2)
plot(average + deviation, color = color.new(color.gray, 50))
plot(average - deviation, color = color.new(color.gray, 50))
XFlow Script
//@xfscript 1
indicator("Daily Typical Price")

let mult: float = input.float(1, "mult", "Band multiplier", 0.1, 5, 0.1)

let ny_day: float = time.day(time, "America/New_York")
let new_day: bool = ny_day != ny_day[1]

var total: float = 0
var count: float = 0
total := new_day ? hlc3 : total + hlc3
count := new_day ? 1 : count + 1

let average: float = total / count
let deviation: float = ta.atr(14) * mult

plot.line(average, close > average ? color.green : color.red, 2, "solid")
plot.line(average + deviation, color.new(color.gray, 50), 1, "solid")
plot.line(average - deviation, color.new(color.gray, 50), 1, "solid")

dayofmonth became a named series in a stated zone, so day[1] has something to read. The rest is the same line in the same order.

Every layer of the market, Orderflow to optionflow, on one chart.

Institutional grade Orderflow data with backtesting and journaling built in. Join the waitlist for early access.

Get Access