Files
QuanTAlib/lib/dynamics/super/super.pine
T

67 lines
2.8 KiB
Plaintext

// Licensed under the Apache License, Version 2.0
// © mihakralj
//@version=6
indicator("SuperTrend", "SUPER", overlay=true)
//@function Calculates SuperTrend using ATR-based dynamic support/resistance
//@param source Price series for calculation (typically hlc3 or close)
//@param atr_period Lookback period for ATR calculation
//@param multiplier Multiplier applied to ATR for band calculation
//@returns Tuple [supertrend, direction] where direction is 1 (bullish) or -1 (bearish)
//@optimized O(1) with proper warmup handling
super(series float source, simple int atr_period, simple float multiplier) =>
if atr_period <= 0
runtime.error("ATR period must be greater than 0")
if multiplier <= 0.0
runtime.error("Multiplier must be greater than 0")
float hl2_value = (high + low) / 2.0
float tr = math.max(high - low, math.max(math.abs(high - nz(close[1])), math.abs(low - nz(close[1]))))
float alpha = 1.0 / atr_period
float beta = 1.0 - alpha
var bool warmup = true
var float e = 1.0
var float atr = 0.0
var float compensated_atr = tr
atr := alpha * (tr - atr) + atr
if warmup
e *= beta
float c = 1.0 / (1.0 - e)
compensated_atr := c * atr
warmup := e > 1e-10
else
compensated_atr := atr
float basic_ub = hl2_value + (multiplier * compensated_atr)
float basic_lb = hl2_value - (multiplier * compensated_atr)
var float final_ub = basic_ub
var float final_lb = basic_lb
var int trend = 1
final_ub := basic_ub < final_ub or nz(close[1]) > final_ub ? basic_ub : final_ub
final_lb := basic_lb > final_lb or nz(close[1]) < final_lb ? basic_lb : final_lb
int prev_trend = nz(trend[1], 1)
trend := close > final_ub ? 1 : close < final_lb ? -1 : prev_trend
float supertrend = trend == 1 ? final_lb : final_ub
[supertrend, trend]
// ---------- Main loop ----------
// Inputs
i_atr_period = input.int(10, "ATR Period", minval=1, maxval=100)
i_multiplier = input.float(3.0, "Multiplier", minval=0.1, step=0.1)
i_source = input.source(close, "Source")
// Calculation
[st_line, st_direction] = super(i_source, i_atr_period, i_multiplier)
// Colors
color bullish_color = color.new(color.green, 0)
color bearish_color = color.new(color.red, 0)
color line_color = st_direction == 1 ? bullish_color : bearish_color
// Plot
plot(st_line, "SuperTrend", color=line_color, linewidth=2, style=plot.style_line)
// Optional: Plot buy/sell signals when direction changes
bool direction_changed = st_direction != nz(st_direction[1])
plotshape(direction_changed and st_direction == 1, "Buy Signal", shape.labelup, location.belowbar, color=bullish_color, text="BUY", textcolor=color.white, size=size.small)
plotshape(direction_changed and st_direction == -1, "Sell Signal", shape.labeldown, location.abovebar, color=bearish_color, text="SELL", textcolor=color.white, size=size.small)