Uptrick: Volatility Adjusted Trail

Uptrick · study · 161 行 · 点赞 2,985 · TradingView 原页

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

Pine Script

// This work is licensed under an Attribution-ShareAlike 4.0 International License (CC BY-SA 4.0) 
// https://creativecommons.org/licenses/by-sa/4.0/
// © Uptrick
//@version=6
 
 
//    ██╗   ██╗██████╗ ████████╗██████╗ ██╗ ██████╗██╗  ██╗
//    ██║   ██║██╔══██╗╚══██╔══╝██╔══██╗██║██╔════╝██║ ██╔╝
//    ██║   ██║██████╔╝   ██║   ██████╔╝██║██║     █████╔╝ 
//    ██║   ██║██╔═══╝    ██║   ██╔══██╗██║██║     ██╔═██╗ 
//    ╚██████╔╝██║        ██║   ██║  ██║██║╚██████╗██║  ██╗
//     ╚═════╝ ╚═╝        ╚═╝   ╚═╝  ╚═╝╚═╝ ╚═════╝╚═╝  ╚═╝
 
indicator("Uptrick: Volatility Adjusted Trail", overlay=true)
 
//== Inputs
emaLen      = input.int(8, "Basis EMA Length", minval=2)
atrLen      = input.int(14, "ATR Length", minval=1)
baseMult    = input.float(2.0, "Base ATR Mult", minval=0.1, step=0.1)
sensExp     = input.float(1.00, "Volatility Expansion Sensitivity", minval=0.10, step=0.05)
persLen     = input.int(20, "Trend Persistence Window", minval=2)
persGain    = input.float(0.30, "Persistence Impact (0..1)", minval=0.0, maxval=1.0, step=0.05)
multMin     = input.float(1.0, "Min Effective Mult", minval=0.1, step=0.1)
multMax     = input.float(4.0, "Max Effective Mult", minval=0.5, step=0.1)
confirmN    = input.int(1, "Bars Above/Below to Confirm Flip", minval=1)
 
//== Colors (Uptrick palette)
bullCol     = color.rgb(92,240,215)     // #5CF0D7
bearCol     = color.rgb(179,42,195)     // #B32AC3
midGray     = color.new(color.gray, 100)
fillBull    = color.new(color.rgb(88,237,212), 80)
fillBear    = color.new(color.rgb(177,41,192), 80)
 
//== Core series
basis       = ta.ema(close, emaLen)
atr         = ta.atr(atrLen)
atrMA       = ta.sma(atr, atrLen)
expRatio    = atrMA == 0.0 ? 1.0 : atr / atrMA                   // >1 = expansion, <1 = compression
expAdj      = math.pow(expRatio, sensExp)                        // sensitivity to expansion
 
slope       = basis - basis[1]
dirStep     = slope >= 0 ? 1.0 : -1.0
persist     = ta.ema(dirStep, persLen)                           // -1..+1 trend memory
persistAdj  = 1.0 + persGain * math.abs(persist)                 // widen when trend is consistent
 
dynMultRaw  = baseMult * expAdj * persistAdj
dynMult     = math.min(math.max(dynMultRaw, multMin), multMax)   // clamp to bounds
 
upperBand   = basis + dynMult * atr
lowerBand   = basis - dynMult * atr
 
//== Trailing bands (Supertrend-style)
var float trailUp = na
var float trailDn = na
var int   state   = 0    // 1 bull, -1 bear, 0 neutral
if na(trailUp)
    trailUp := lowerBand
if na(trailDn)
    trailDn := upperBand
 
if state == 1
    trailUp := math.max(lowerBand, nz(trailUp[1]))
    trailDn := upperBand                         // reset opposing side
if state == -1
    trailDn := math.min(upperBand, nz(trailDn[1]))
    trailUp := lowerBand
 
//== Flip conditions with persistence confirmation
var int upCnt = 0
var int dnCnt = 0
 
aboveDn = close > trailDn
belowUp = close < trailUp
 
if aboveDn
    upCnt += 1
else
    upCnt := 0
 
if belowUp
    dnCnt += 1
else
    dnCnt := 0
 
if state == 0
    if upCnt >= confirmN
        state := 1
    if dnCnt >= confirmN
        state := -1
else
    if state == 1 and dnCnt >= confirmN
        state := -1
    if state == -1 and upCnt >= confirmN
        state := 1
 
//== Visuals
isBull      = state == 1
isBear      = state == -1
ribColor    = isBull ? bullCol : isBear ? bearCol : midGray
 
pUpper      = plot(trailDn, "ASB Upper Trail", color=isBear ? bearCol : midGray, linewidth=2, style=plot.style_linebr)
pLower      = plot(trailUp, "ASB Lower Trail", color=isBull ? bullCol : midGray, linewidth=2, style=plot.style_linebr)
price = plot(close, color=midGray)
 
fill(pUpper, price, trailDn, close, isBear? color.new(bearCol,50): midGray, midGray,'FILL COLOR')
 
fill(pLower, price, close, trailUp, midGray, isBull? color.new(bullCol,50): midGray,'FILL COLOR')
 
 
 
barcolor(isBull ? bullCol : isBear ? bearCol : color.new(color.gray, 70))
 
//== Flip markers & alerts
bullFlip = ta.change(state) == 2   // -1 -> 1
bearFlip = ta.change(state) == -2  // 1 -> -1
 
 
 
 
// === Label settings
showLabels   = input.bool(true, "Show Flip Labels")
lblSize      = input.string("Normal", "Label Size", options=["Tiny","Small","Normal","Large","Huge"])
lblAtrOffset = input.float(0.60, "Label ATR Offset (× ATR)")
 
toSize(s) =>
    s == "Tiny"   ? size.tiny  :
     s == "Small"  ? size.small :
     s == "Normal" ? size.normal:
     s == "Large"  ? size.large :
     size.huge
 
 
 
// === Flip labels anchored to bands
if showLabels and bullFlip
    yDn = trailUp - lblAtrOffset * atr            // below lower band
    label.new(bar_index, yDn,
         text="𝓤𝓹",
         style=label.style_label_up,
         size=toSize(lblSize),
         color=color.new(bullCol, 0),
         textcolor=#000000)
 
if showLabels and bearFlip
    yUp = trailDn + lblAtrOffset * atr            // above upper band
    label.new(bar_index, yUp,
         text="𝓓𝓸𝔀𝓷",
         style=label.style_label_down,
         size=toSize(lblSize),
         color=color.new(bearCol, 0),
         textcolor=#ffffff)
 
 
alertcondition(bullFlip, "ASB Bull Flip", "ASB: Bullish flip on {{ticker}} {{interval}}")
alertcondition(bearFlip, "ASB Bear Flip", "ASB: Bearish flip on {{ticker}} {{interval}}")
 
 
 
 
 
plotcandle(open,high,low,close,'Plotcandle',isBull ? bullCol : isBear ? bearCol : color.new(color.gray, 70),isBull ? bullCol : isBear ? bearCol : color.new(color.gray, 70),bordercolor = isBull ? bullCol : isBear ? bearCol : color.new(color.gray, 70),force_overlay = true,display = display.pane)

← 返回列表