Appearance

Personalize your experience

Mode
Accent Color
Direction
MarketplacestrategiesTrend Prism Follower
QuaScript

Trend Prism Follower

Free

Trades only unanimous, clean regression trends

0.0(0)
0 installs 0 0 comments
Q
159 listings

The QuaTick team's QuaScript analyses, run by the native C++ engine.

View Profile
quascriptstrategyregressiontrendr-squared
Free
Backtest this strategy Open in QuaTick IDE Edit in IDE
Version
Updated
Compatible

Live engine preview

QuaScriptQuaScript

The QuaScript engine's own output on the chart the terminal uses. Change the settings or edit the code and press Run to recompute it.

Trend Prism Followerengine 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)

About

Follows trends only while they are both unanimous and clean. Eight linear regressions from `base` to eight times `base` bars vote on direction with their slopes, and their mean R squared measures how straight the trend is. A position opens when every slope agrees and the fits are clean, and closes as soon as quality decays or the shortest fits turn against it, so the system sits out the noisy middle of ranges where trend followers lose most. Entry: all eight slopes up (down) and mean R squared above `q_in`. Exit: mean R squared below `q_out`, the two shortest slopes turning against the position, or a stop `stop_k` ATR beyond the longest regression (trailed, never loosened). Risk: 1 % per trade at the initial stop.


Settings

Shortest window: 12

Entry quality (R squared): 0.6

Exit quality (R squared): 0.35

Stop beyond long fit (ATR): 1.5


Measured backtests

Run by the backtest engine on public candles, 2025-11-01 to 2026-11-01, with the script's own commission and slippage, on BTCUSDT 1h (Binance) and ETHUSDT 1h (Binance). The figures per market are in the Measured backtest panel below. Past results do not predict future returns.


Backtest it yourself

Open it on the backtesting page to run it on any symbol, interval and date range, then use Monte Carlo, optimisation, walk-forward and robustness tests.

Strategy Rules

Entry Conditions

  • ▸ all eight slopes up (down) and mean R squared above `q_in`

Exit Conditions

  • ▸ mean R squared below `q_out`, the two shortest slopes turning against the position, or a stop `stop_k` ATR beyond the longest regression (trailed, never loosened)

Measured backtest

BTCUSDT 1h (Binance), 2025-11-01 to 2026-11-01 · backtest engine, script costs included

Backtest this strategy

-8.9%

Return

-1.59

Sharpe

-10.2%

Max DD

22.0%

Win Rate

59

Trades

MarketTradesReturnSharpeMax DDWin rateProfit factor
BTCUSDT 1h59-8.9%-1.59-10.2%22.0%0.55
ETHUSDT 1h5211.3%1.13-8.3%25.0%1.67

Past results on historical data do not predict future returns.

Source Code

Edit in IDE
quascript
1strategy "Trend Prism Follower" {
2 overlay = true
3 capital = 100000
4 commission = 0.05
5 slippage = 1
6 sizing = risk_percent
7 max_leverage = 1
8 size = 1
9 pyramiding = 1
10}
11/// Follows trends only while they are both unanimous and clean. Eight linear regressions from
12/// `base` to eight times `base` bars vote on direction with their slopes, and their mean R squared
13/// measures how straight the trend is. A position opens when every slope agrees and the fits are
14/// clean, and closes as soon as quality decays or the shortest fits turn against it, so the system
15/// sits out the noisy middle of ranges where trend followers lose most.
16/// Entry: all eight slopes up (down) and mean R squared above `q_in`. Exit: mean R squared below
17/// `q_out`, the two shortest slopes turning against the position, or a stop `stop_k` ATR beyond
18/// the longest regression (trailed, never loosened). Risk: 1 % per trade at the initial stop.
19use "viz/premium" as pr
20base = param.int(12, title = "Shortest window", min = 4, max = 200, group = "Prism")
21q_in = param.float(0.6, title = "Entry quality (R squared)", min = 0.1, max = 0.95, step = 0.05, group = "Signals")
22q_out = param.float(0.35, title = "Exit quality (R squared)", min = 0.05, max = 0.9, step = 0.05, group = "Signals")
23stop_k = param.float(1.5, title = "Stop beyond long fit (ATR)", min = 0.2, max = 6, step = 0.1, group = "Risk")
24pos = 0
25neg = 0
26q_sum = 0.0
27s1 = 0.0
28s2 = 0.0
29v8 = na
30prev = render.line(close, "Facet edge 0", color = color.transparent, width = 0)
31for k in 1..=8 {
32 (v, sl, _) = stat.linreg(close, base * k, 0)
33 q = math.coalesce(stat.r_squared(close, base * k), 0)
34 if sl > 0 { pos := pos + 1 }
35 if sl < 0 { neg := neg + 1 }
36 if k == 1 { s1 := sl }
37 if k == 2 { s2 := sl }
38 if k == 8 { v8 := v }
39 q_sum := q_sum + q
40 edge = render.line(v, str.format("Regression {}", k), color = color.transparent, width = 0)
41 render.band(prev, edge, color = color.ramp(q, 0, 1, "viridis", 45 + k * 4), opacity = 1, title = str.format("Facet {}", k))
42 prev := edge
43}
44quality = q_sum / 8
45a = ta.atr(14)
46go_l = pos == 8 and quality >= q_in
47go_s = neg == 8 and quality >= q_in
48persist used = 0
49if quality < q_out { used := 0 }
50persist trail = na
51flat = position.size == 0
52if flat and go_l and used != 1 {
53 trail := math.min(v8 - stop_k * a, close - a)
54 order.market("L", side.long)
55 exit.bracket("L stop", entry = "L", stop = trail)
56 used := 1
57}
58if flat and go_s and used != -1 {
59 trail := math.max(v8 + stop_k * a, close + a)
60 order.market("S", side.short)
61 exit.bracket("S stop", entry = "S", stop = trail)
62 used := -1
63}
64if position.size > 0 {
65 trail := math.max(trail, v8 - stop_k * a)
66 exit.bracket("L stop", entry = "L", stop = trail)
67 if quality < q_out or (s1 < 0 and s2 < 0) { exit.close("L") }
68}
69if position.size < 0 {
70 trail := math.min(trail, v8 + stop_k * a)
71 exit.bracket("S stop", entry = "S", stop = trail)
72 if quality < q_out or (s1 > 0 and s2 > 0) { exit.close("S") }
73}
74risk.max_drawdown(25)
75render.step(position.size != 0 ? trail : na, "Trailing stop", color = color.translucent(color.white, 30), width = 1, stroke = style.dashed)
76render.mark(go_l and flat and used[1] != 1, shape = shape.triangle_up, at = anchor.below_bar, color = color.yellow.300, text = "Prism", title = "Long entry")
77render.mark(go_s and flat and used[1] != -1, shape = shape.triangle_down, at = anchor.above_bar, color = color.violet.300, text = "Prism", title = "Short entry")
78persist t = draw.table.create(anchor.top_right, 5, 2)
79if bar.is_last {
80 pr.heading(t, 2, "Trend Prism Follower", "Strategy · regression consensus and quality")
81 pr.row(t, 2, "Slopes up / down", str.format("{} / {}", pos, neg), pos > neg ? pr.BULL : pr.BEAR)
82 pr.row(t, 3, "Mean R squared", str.format("{:.2f}", quality), quality >= q_in ? color.yellow.300 : pr.LABEL)
83 pr.row(t, 4, "Stance", position.size > 0 ? "Long" : position.size < 0 ? "Short" : "Flat", color.white)
84}
85 
Read-only preview. Open in the QuaTick IDE to edit and deploy.

Reviews

No reviews yet. Be the first to review this listing.

Discussion

Sign in to join the discussion. Your posts and replies show up on your profile.