
QuaScript Documentation
Language guide, engine API, 601 builtins and the preset library · v3.0.0-phase1
Multiple intervals
MTF Confluence Matrix
analysis · presets/analysis/mtf/confluence_matrix.qs
Trend and momentum on five intervals from completed bars only (no lookahead). Each interval is a heatmap row colored by its score (EMA trend plus RSI), the top row is the weighted confluence, and a table lists every interval with its RSI and direction.
QuaScriptengine result
Loading the engine result…
quatick-charts · QuaScript engine on synthetic 1-minute bars · drag to pan · scroll to zoom · Run executes the script on the engine (⌘/Ctrl+Enter while editing)
confluence_matrix.qs
analysis "MTF Confluence Matrix" {
pane = hpane
height = 0.22
}
/// Trend and momentum on five intervals from completed bars only (no lookahead). Each interval
/// is a heatmap row colored by its score (EMA trend plus RSI), the top row is the weighted
/// confluence, and a table lists every interval with its RSI and direction.
tf1 = param.interval("5", title = "Interval 1")
tf2 = param.interval("15", title = "Interval 2")
tf3 = param.interval("60", title = "Interval 3")
tf4 = param.interval("240", title = "Interval 4")
tf5 = param.interval("1D", title = "Interval 5")
len = param.int(21, title = "EMA length", min = 2, max = 300)
e1 = feed.series("", tf1, close - ta.ema(close, len))
e2 = feed.series("", tf2, close - ta.ema(close, len))
e3 = feed.series("", tf3, close - ta.ema(close, len))
e4 = feed.series("", tf4, close - ta.ema(close, len))
e5 = feed.series("", tf5, close - ta.ema(close, len))
r1 = feed.series("", tf1, ta.rsi(close, 14))
r2 = feed.series("", tf2, ta.rsi(close, 14))
r3 = feed.series("", tf3, ta.rsi(close, 14))
r4 = feed.series("", tf4, ta.rsi(close, 14))
r5 = feed.series("", tf5, ta.rsi(close, 14))
fn score(e: float, r: float) -> float {
return math.is_na(e) or math.is_na(r) ? 0 : math.clamp((e > 0 ? 0.5 : -0.5) + (r - 50) / 40, -1, 1)
}
s1 = score(e1, r1)
s2 = score(e2, r2)
s3 = score(e3, r3)
s4 = score(e4, r4)
s5 = score(e5, r5)
fn heat(s: float) -> color {
return s >= 0 ? color.gradient(s, 0, 1, color.slate.800, color.emerald.400) : color.gradient(s, -1, 0, color.rose.500, color.slate.800)
}
render.line(0, "Interval 1", color = heat(s1), width = 9)
render.line(1, "Interval 2", color = heat(s2), width = 9)
render.line(2, "Interval 3", color = heat(s3), width = 9)
render.line(3, "Interval 4", color = heat(s4), width = 9)
render.line(4, "Interval 5", color = heat(s5), width = 9)
conf = (s1 + s2 * 1.5 + s3 * 2 + s4 * 2.5 + s5 * 3) / 10
render.line(5.6, "Confluence", color = heat(conf), width = 13)
render.mark(conf > 0.6 and conf[1] <= 0.6, shape = shape.arrow_up, at = anchor.bottom, color = color.emerald.400, title = "Bullish confluence")
render.mark(conf < -0.6 and conf[1] >= -0.6, shape = shape.arrow_down, at = anchor.top, color = color.rose.400, title = "Bearish confluence")
persist t = draw.table.create(anchor.top_right, 6, 3)
if bar.is_last {
draw.table.cell(t, 0, 0, "Interval", text_color = color.slate.400)
draw.table.cell(t, 0, 1, "RSI", text_color = color.slate.400)
draw.table.cell(t, 0, 2, "Bias", text_color = color.slate.400)
draw.table.cell(t, 1, 0, tf1)
draw.table.cell(t, 1, 1, str.format("{:.0f}", r1))
draw.table.cell(t, 1, 2, s1 >= 0 ? "Up" : "Down", bg_color = heat(s1))
draw.table.cell(t, 2, 0, tf2)
draw.table.cell(t, 2, 1, str.format("{:.0f}", r2))
draw.table.cell(t, 2, 2, s2 >= 0 ? "Up" : "Down", bg_color = heat(s2))
draw.table.cell(t, 3, 0, tf3)
draw.table.cell(t, 3, 1, str.format("{:.0f}", r3))
draw.table.cell(t, 3, 2, s3 >= 0 ? "Up" : "Down", bg_color = heat(s3))
draw.table.cell(t, 4, 0, tf4)
draw.table.cell(t, 4, 1, str.format("{:.0f}", r4))
draw.table.cell(t, 4, 2, s4 >= 0 ? "Up" : "Down", bg_color = heat(s4))
draw.table.cell(t, 5, 0, tf5)
draw.table.cell(t, 5, 1, str.format("{:.0f}", r5))
draw.table.cell(t, 5, 2, s5 >= 0 ? "Up" : "Down", bg_color = heat(s5))
}
alert.rule(conf > 0.6 and conf[1] <= 0.6, "Bullish confluence", "Weighted interval score above 0.6")
alert.rule(conf < -0.6 and conf[1] >= -0.6, "Bearish confluence", "Weighted interval score below -0.6")Higher-Interval Trend Dashboard
analysis · presets/analysis/mtf/htf_trend_dashboard.qs · uses viz/palette
The trend of three higher intervals from closed bars only (no lookahead): an EMA of each interval is plotted as a step line and summarised in a table with RSI and direction.
QuaScriptengine result
Loading the engine result…
quatick-charts · QuaScript engine on synthetic 1-minute bars · drag to pan · scroll to zoom · Run executes the script on the engine (⌘/Ctrl+Enter while editing)
htf_trend_dashboard.qs
analysis "Higher-Interval Trend Dashboard" {
overlay = true
}
/// The trend of three higher intervals from closed bars only (no lookahead): an EMA of each
/// interval is plotted as a step line and summarised in a table with RSI and direction.
use "viz/palette" as pal
tf1 = param.interval("15", title = "Interval 1")
tf2 = param.interval("60", title = "Interval 2")
tf3 = param.interval("240", title = "Interval 3")
len = param.int(20, title = "EMA length", min = 2, max = 500)
e1 = feed.series("", tf1, ta.ema(close, len))
e2 = feed.series("", tf2, ta.ema(close, len))
e3 = feed.series("", tf3, ta.ema(close, len))
r1 = feed.series("", tf1, ta.rsi(close, 14))
r2 = feed.series("", tf2, ta.rsi(close, 14))
r3 = feed.series("", tf3, ta.rsi(close, 14))
render.step(e1, "EMA interval 1", color = color.sky.400, width = 1)
render.step(e2, "EMA interval 2", color = color.amber.400, width = 2)
render.step(e3, "EMA interval 3", color = color.violet.400, width = 3)
score = (close > e1 ? 1 : -1) + (close > e2 ? 1 : -1) + (close > e3 ? 1 : -1)
render.candle_color(score == 3 ? pal.BULL : score == -3 ? pal.BEAR : pal.NEUTRAL)
persist t = draw.table.create(anchor.top_right, 4, 3)
if bar.is_last {
draw.table.cell(t, 0, 0, "Interval", text_color = color.slate.400)
draw.table.cell(t, 0, 1, "Trend", text_color = color.slate.400)
draw.table.cell(t, 0, 2, "RSI", text_color = color.slate.400)
draw.table.cell(t, 1, 0, tf1)
draw.table.cell(t, 1, 1, close > e1 ? "Up" : "Down", bg_color = close > e1 ? pal.BULL : pal.BEAR)
draw.table.cell(t, 1, 2, str.format("{:.1f}", r1), bg_color = pal.osc_heat(r1))
draw.table.cell(t, 2, 0, tf2)
draw.table.cell(t, 2, 1, close > e2 ? "Up" : "Down", bg_color = close > e2 ? pal.BULL : pal.BEAR)
draw.table.cell(t, 2, 2, str.format("{:.1f}", r2), bg_color = pal.osc_heat(r2))
draw.table.cell(t, 3, 0, tf3)
draw.table.cell(t, 3, 1, close > e3 ? "Up" : "Down", bg_color = close > e3 ? pal.BULL : pal.BEAR)
draw.table.cell(t, 3, 2, str.format("{:.1f}", r3), bg_color = pal.osc_heat(r3))
}
alert.rule(score == 3 and score[1] != 3, "All intervals up", "Price is above the EMA on all three intervals")
alert.rule(score == -3 and score[1] != -3, "All intervals down", "Price is below the EMA on all three intervals")