SuperTrend Confluence Signals [AlgoAlpha]

AlgoAlpha · study · 228 行 · 点赞 3,532 · TradingView 原页

本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。

Pine Script

//@version=6
indicator("SuperTrend Confluence Signals [AlgoAlpha]", "AlgoAlpha - SuperTrend Confluence", overlay=true, max_bars_back=500, max_lines_count=500)
 
atrLength   = input.int(10,   "ATR Length",     minval=1, maxval=100,        group="Supertrend", tooltip="ATR calculation period. Decrease for more sensitive signals, increase for smoother trends.")
factor      = input.float(3.0, "Multiplier",     minval=0.1, maxval=10.0, step=0.1, group="Supertrend", tooltip="Band distance from price. Decrease for more frequent signals, increase for stronger trends.")
maxScale    = input.float(4.0, "Volume Scale",   minval=0.1, maxval=10.0, group="Volume", tooltip="Volume bar height. Increase for taller bars, decrease for compact display.")
volThreshold = input.float(3.0, "Volume TP",  minval=0.7, maxval=10.0, step=0.5, group="Volume", tooltip="Volume alert level. Decrease for more markers, increase for only extreme volume.")
arrowThreshold = input.float(0.5, "Retracement Sensitivity", minval=0.1, maxval=3.0, step=0.1, group="Signals", tooltip="Retracement sensitivity. increase for more arrows, Decrease for fewer arrows.")
expiry_age = input.int(1000, "Max Level Age", minval=1, group="Level Management", tooltip="Number of bars after which a level will be automatically removed")
mitigate = input.string("body", "Sweep Type", options=["wick", "body"], group="Level Management", tooltip="Body: level removed when price body (close) crosses it; Wick: level removed when price wick crosses it")
allow_rejection = input.bool(false, "Allow Rejection", group="Level Management", tooltip="When enabled with body sweep type, requires two consecutive closes beyond level to remove it")
asset1 = input.symbol("AAPL", "Asset 1", group="Multi-Asset Table", inline="assets1")
asset2 = input.symbol("MSFT", "Asset 2", group="Multi-Asset Table", inline="assets1")
asset3 = input.symbol("GOOGL", "Asset 3", group="Multi-Asset Table", inline="assets2")
asset4 = input.symbol("TSLA", "Asset 4", group="Multi-Asset Table", inline="assets2")
asset5 = input.symbol("NVDA", "Asset 5", group="Multi-Asset Table", inline="assets3")
tf1 = input.timeframe("5", "Timeframe 1", group="Multi-Asset Table", inline="timeframes1")
tf2 = input.timeframe("15", "Timeframe 2", group="Multi-Asset Table", inline="timeframes1")
tf3 = input.timeframe("60", "Timeframe 3", group="Multi-Asset Table", inline="timeframes2")
tf4 = input.timeframe("240", "Timeframe 4", group="Multi-Asset Table", inline="timeframes2")
tf5 = input.timeframe("1D", "Timeframe 5", group="Multi-Asset Table", inline="timeframes3")
showTable = input.bool(true, "Show Table", group="Multi-Asset Table", tooltip="Display multi-asset trend table.")
colBull     = input.color(#00FFBB, "Bull Color", group="Appearance", tooltip="Color for uptrend elements.")
colBear     = input.color(#FF1100, "Bear Color", group="Appearance", tooltip="Color for downtrend elements.")
 
 
[supertrend, direction] = ta.supertrend(factor, atrLength)
supertrend := barstate.isfirst ? na : supertrend
 
offset      = ta.sma(ta.atr(14), 300) * 1.2
supertrend_u = supertrend + offset
supertrend_l = supertrend - offset
 
dist_to_upper = math.abs(((high + low) / 2) - supertrend_u)
dist_to_lower = math.abs(((high + low) / 2) - supertrend_l)
max_dist      = ta.sma(ta.atr(14), 300) * 3
 
transp_up   = math.min(90, 50 + math.round((dist_to_upper / max_dist) * 40))
transp_down = math.min(90, 50 + math.round((dist_to_lower / max_dist) * 40))
 
volLen = 200
heightMult = 1.5
minAlpha = 20
maxAlpha = 80
 
volumeAvailable = not na(volume)
hlRange = high - low
avgHLRange = ta.sma(hlRange, volLen)
hlVolatility = hlRange / ta.stdev(hlRange, volLen)
 
n_vol       = volumeAvailable ? math.min(maxScale, volume / ta.stdev(volume, volLen)) : math.min(maxScale, hlVolatility)
step        = offset * heightMult / maxScale
trendChange = direction != direction[1]
trend_col   = direction < 0 ? colBull : colBear
alphaVol    = math.round(maxAlpha - (n_vol / maxScale) * (maxAlpha - minAlpha))
histCol     = color.new(trend_col, alphaVol)
 
var float histTop    = na
var float histBottom = na
histTop    := na
histBottom := na
if not trendChange
    if direction < 0
        histBottom := supertrend_l
        histTop    := supertrend_l + step * n_vol
    else
        histTop    := supertrend_u
        histBottom := supertrend_u - step * n_vol
 
dist_to_upper_norm = dist_to_upper / max_dist
dist_to_lower_norm = dist_to_lower / max_dist
volatility         = ta.atr(14)
 
bullishRetracement = direction < 0 and dist_to_lower_norm <= arrowThreshold
bearishRetracement = direction >= 0 and dist_to_upper_norm <= arrowThreshold
 
highVolumeThreshold = n_vol >= volThreshold
 
bodyMiddle  = plot(barstate.isfirst ? na : (open + close) / 2, display=display.none)
upTrend     = plot(direction < 0 ? supertrend_l : na, "Up Trend",   color=colBull, style=plot.style_linebr, linewidth=2)
downTrend   = plot(direction >= 0 ? supertrend_u : na, "Down Trend", color=colBear, style=plot.style_linebr, linewidth=2)
 
fill(bodyMiddle, upTrend,   color=color.new(colBull, transp_down), fillgaps=false)
fill(bodyMiddle, downTrend, color=color.new(colBear, transp_up),  fillgaps=false)
 
plotcandle(
     histTop,
     histTop,
     histBottom,
     histBottom,
     "",
     histCol,
     histCol,
     bordercolor=histCol
 )
 
plotchar(bullishRetracement ? supertrend_l - (volatility * 1.2) : na, "Bullish Retracements", "▲", location.absolute, colBull, size=size.tiny)
plotchar(bearishRetracement ? supertrend_u + (volatility * 1.2) : na, "Bearish Retracements", "▼", location.absolute, colBear, size=size.tiny)
plotchar(highVolumeThreshold and direction < 0 ? 1 : na, "High Volume - Uptrend", "◆", location.abovebar, color.new(color.orange, 30), size=size.tiny)
plotchar(highVolumeThreshold and direction >= 0 ? 1 : na, "High Volume - Downtrend", "◆", location.belowbar, color.new(color.orange, 30), size=size.tiny)
 
getTrend(asset, tf) =>
    request.security(asset, tf, direction < 0 ? 1 : -1)
 
if barstate.islast and showTable
    var multiAssetTable = table.new(position=position.top_right, columns=6, rows=6, bgcolor=chart.bg_color, border_width=1, border_color=chart.fg_color, frame_color=chart.fg_color, frame_width=1)
    
    table.cell(multiAssetTable, 0, 0, "TF\\Asset", text_color=chart.fg_color, text_halign=text.align_center, text_size=size.tiny)
    table.cell(multiAssetTable, 1, 0, array.get(str.split(asset1, ":"), 1), text_color=chart.fg_color, text_halign=text.align_center, text_size=size.tiny)
    table.cell(multiAssetTable, 2, 0, array.get(str.split(asset2, ":"), 1), text_color=chart.fg_color, text_halign=text.align_center, text_size=size.tiny)
    table.cell(multiAssetTable, 3, 0, array.get(str.split(asset3, ":"), 1), text_color=chart.fg_color, text_halign=text.align_center, text_size=size.tiny)
    table.cell(multiAssetTable, 4, 0, array.get(str.split(asset4, ":"), 1), text_color=chart.fg_color, text_halign=text.align_center, text_size=size.tiny)
    table.cell(multiAssetTable, 5, 0, array.get(str.split(asset5, ":"), 1), text_color=chart.fg_color, text_halign=text.align_center, text_size=size.tiny)
    
    timeframes = array.from(tf1, tf2, tf3, tf4, tf5)
    assets = array.from(asset1, asset2, asset3, asset4, asset5)
    
    for i = 0 to 4
        tf = array.get(timeframes, i)
        table.cell(multiAssetTable, 0, i + 1, tf, text_color=chart.fg_color, text_halign=text.align_center, text_size=size.tiny)
        
        for j = 0 to 4
            asset = array.get(assets, j)
            trendValue = getTrend(asset, tf)
            trendText = trendValue == 1 ? "▲" : "▼"
            cellColor = trendValue == 1 ? color.new(colBull, 70) : color.new(colBear, 70)
            table.cell(multiAssetTable, j + 1, i + 1, trendText, text_color=chart.fg_color, bgcolor=cellColor, text_halign=text.align_center, text_size=size.tiny)
 
var lowest = 0.0
var highest = 0.0
 
var lowest_ = 0
var highest_ = 0
 
var new = 1
 
var levelHighArray = array.new_line()
var levelLowArray = array.new_line()
var levelHighArray1 = array.new_line()
var levelLowArray1 = array.new_line()
 
timing = math.max(nz(ta.barssince(direction != direction[1])), 1)
timing := math.min(timing, 250)
 
x = ta.lowest(low, timing)
x_ = ta.highest(high, timing)
 
y = math.min(ta.lowestbars(low, timing)-1, 250)
y_ = math.min(ta.highestbars(high, timing)-1, 250)
 
if direction < 0 and direction[1] >= 0
    if new == 1
        new := 0
        lowest := x[1]
        lowest_ := bar_index + y[1]
    else
        lowest := x[1]
        lowest_ := bar_index + y[1]
        line.new(highest_,highest,lowest_,lowest, color = colBear, width = 1)
        
        levelHighArray.unshift(line.new(highest_, highest, bar_index+1, highest, color = colBear, width = 1))
        levelHighArray1.unshift(line.new(highest_, highest-volatility/2, bar_index+1, highest-volatility/2, color = color.new(colBear, 80), width = 1))
        linefill.new(levelHighArray.first(), levelHighArray1.first(), color.new(colBear, 80))
 
if direction >= 0 and direction[1] < 0
    if new == 1
        new := 0
        highest := x_[1]
        highest_ := bar_index + y_[1]
    else
        highest := x_[1]
        highest_ := bar_index + y_[1]
        line.new(lowest_,lowest,highest_,highest, color = colBull, width = 1)
        
        levelLowArray.unshift(line.new(lowest_, lowest, bar_index+1, lowest, color = colBull, width = 1))
        levelLowArray1.unshift(line.new(lowest_, lowest+volatility/2, bar_index+1, lowest+volatility/2, color = color.new(colBull, 80), width = 1))
        linefill.new(levelLowArray.first(), levelLowArray1.first(), color.new(colBull, 80))
 
if levelHighArray.size() > 0
    for ln = levelHighArray.size() - 1 to 0
        if ln < levelHighArray.size()
            cL = levelHighArray.get(ln)
            cL_ = levelHighArray1.get(ln)
            yL = cL.get_y1()
            x1 = cL.get_x1()
            age = bar_index - x1
            is_body = mitigate == "body"
            cross_body = close > yL
            cross_body_confirmed = close > yL and close[1] > yL
            cross_wick = high > yL
            remove_by_mitigation = is_body ? (allow_rejection ? cross_body_confirmed : cross_body) : cross_wick
            
            if remove_by_mitigation or age > expiry_age
                levelHighArray.remove(ln)
                levelHighArray1.remove(ln)
            else
                cL.set_x2(bar_index + 1)
                cL_.set_x2(bar_index + 1)
 
if levelLowArray.size() > 0
    for ln = levelLowArray.size() - 1 to 0
        if ln < levelLowArray.size()
            cL = levelLowArray.get(ln)
            cL_ = levelLowArray1.get(ln)
            yL = cL.get_y1()
            x1 = cL.get_x1()
            age = bar_index - x1
            is_body = mitigate == "body"
            cross_body = close < yL
            cross_body_confirmed = close < yL and close[1] < yL
            cross_wick = low < yL
            remove_by_mitigation = is_body ? (allow_rejection ? cross_body_confirmed : cross_body) : cross_wick
            
            if remove_by_mitigation or age > expiry_age
                levelLowArray.remove(ln)
                levelLowArray1.remove(ln)
            else
                cL.set_x2(bar_index + 1)
                cL_.set_x2(bar_index + 1)
 
// Alerts
alertcondition(direction[1] > direction, title="Downtrend to Uptrend")
alertcondition(direction[1] < direction, title="Uptrend to Downtrend")
alertcondition(direction[1] != direction, title="Universal Trend Change")
alertcondition(bullishRetracement, title="Bullish Retracement Entries")
alertcondition(bearishRetracement, title="Bearish Retracement Entries")
alertcondition(highVolumeThreshold and direction < 0, title="Uptrend Volume TP")
alertcondition(highVolumeThreshold and direction >= 0, title="Downtrend Volume TP")

← 返回列表