Volatility Regimes | GainzAlgo

GainzAlgo · study · 384 行 · 点赞 4,617 · TradingView 原页

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

Pine Script

//@version=6
// © GainzAlgo
 
indicator("Volatility Regimes | GainzAlgo", overlay=true)
 
const int   DEFAULT_ATR_LENGTH = 14
const float ATR_MULTIPLIER_1   = 1.0
const float ATR_MULTIPLIER_2   = 2.0
const float ATR_MULTIPLIER_3   = 3.0
 
const color BULL_COLOR         = #26a69aff
const color BEAR_COLOR         = #ef5350ff
const color SIGNAL_COLOR       = #ffeb3bff
const color BAND_COLOR_UPPER   = #2196f380
const color BAND_COLOR_LOWER   = #f4433680
const color COMPRESSION_COLOR  = #4caf5015
const color EXPANSION_COLOR    = #ff980015
const color HIGH_VOL_COLOR     = #f4433615
const color EXHAUSTION_COLOR   = #9c27b015
 
var G1 = "ATR Settings"
int   atrLengthInput       = input.int(DEFAULT_ATR_LENGTH, "ATR Length", minval=1, maxval=100, group=G1, tooltip="Period for calculating Average True Range. Default 14 bars. Lower values = more sensitive, Higher values = smoother.")
 
var G2 = "ATR Bands Settings"
bool  showBandsInput       = input.bool(true, "Show ATR Bands", group=G2, tooltip="Display ATR-based dynamic support and resistance bands around price")
float band1MultInput       = input.float(ATR_MULTIPLIER_1, "Band 1 Multiplier", minval=0.1, maxval=10.0, step=0.1, group=G2, tooltip="ATR multiplier for closest band (1x ATR = first TP level)")
float band2MultInput       = input.float(ATR_MULTIPLIER_2, "Band 2 Multiplier", minval=0.1, maxval=10.0, step=0.1, group=G2, tooltip="ATR multiplier for middle band (2x ATR = second TP level)")
float band3MultInput       = input.float(ATR_MULTIPLIER_3, "Band 3 Multiplier", minval=0.1, maxval=10.0, step=0.1, group=G2, tooltip="ATR multiplier for outer band (3x ATR = extended TP level)")
 
var G3 = "Volatility Signals"
bool  showVolSignalsInput  = input.bool(true, "Show Volatility Signals", group=G3, tooltip="Display circle markers when volatility breaks above threshold")
float volThresholdInput    = input.float(1.5, "Volatility Threshold", minval=0.5, maxval=5.0, step=0.1, group=G3, tooltip="ATR multiplier threshold for volatility breakout signals. 1.5 = signal when ATR is 50% above its average")
 
var G4 = "Trend Detection"
bool  showTrendInput       = input.bool(true, "Show Trend Signals", group=G4, tooltip="Display up/down arrows when trend direction changes with increasing volatility")
int   trendLengthInput     = input.int(21, "Trend Smoothing", minval=5, maxval=50, group=G4, tooltip="Period for trend smoothing. Lower = more signals, Higher = stronger trends only")
 
var G5 = "Visual Settings"
color upperBandColorInput  = input.color(BAND_COLOR_UPPER, "Upper Band Color", group=G5)
color lowerBandColorInput  = input.color(BAND_COLOR_LOWER, "Lower Band Color", group=G5)
color signalColorInput     = input.color(SIGNAL_COLOR, "Volatility Signal Color", group=G5)
color bullTrendSignalInput = input.color(BULL_COLOR, "Bullish Trend Signal Color", group=G5)
color bearTrendSignalInput = input.color(BEAR_COLOR, "Bearish Trend Signal Color", group=G5)
 
var G6 = "════════ VOLATILITY REGIME DETECTION ════════"
bool  enableRegimeDetection = input.bool(true, "Enable Regime Detection", group=G6, tooltip="Activates volatility regime classification: Compression, Expansion, High Volatility, and Exhaustion phases")
 
var G7 = "Regime Calculation"
int   regimeBaselineLengthInput = input.int(50, "ATR Baseline Length", minval=20, maxval=200, group=G7, tooltip="Long-term ATR period for regime comparison. 50-100 recommended for most timeframes")
string regimeBaselineTypeInput  = input.string("SMA", "Baseline Type", options=["SMA", "EMA"], group=G7, tooltip="SMA = Simple Moving Average (balanced), EMA = Exponential (more responsive)")
 
var G8 = "Regime Thresholds"
float compressionThresholdInput = input.float(0.70, "Compression Threshold", minval=0.3, maxval=0.9, step=0.05, group=G8, tooltip="ATR ratio below this = COMPRESSION phase. 0.70 = ATR is 30% below baseline (tight consolidation)")
float expansionThresholdInput   = input.float(1.15, "Expansion Threshold", minval=1.0, maxval=1.5, step=0.05, group=G8, tooltip="ATR ratio above this = EXPANSION phase. 1.15 = ATR is 15% above baseline (breakout starting)")
float highVolThresholdInput     = input.float(1.40, "High Volatility Threshold", minval=1.2, maxval=2.0, step=0.05, group=G8, tooltip="ATR ratio above this = HIGH VOLATILITY. 1.40 = ATR is 40% above baseline (strong trend)")
int   exhaustionLookbackInput   = input.int(5, "Exhaustion Lookback", minval=3, maxval=20, group=G8, tooltip="Bars required to confirm declining ATR after high volatility = EXHAUSTION phase")
 
var G9 = "Regime Visuals"
bool  showRegimeBackgroundInput = input.bool(true, "Show Regime Background", group=G9, tooltip="Color chart background based on current volatility regime for quick visual identification")
bool  showRegimeLabelInput      = input.bool(true, "Show Regime Label", group=G9, tooltip="Display current regime name and ATR ratio in a label on the chart")
string regimeLabelPositionInput = input.string("Top Right", "Label Position", options=["Top Left", "Top Right", "Bottom Left", "Bottom Right"], group=G9, tooltip="Choose where to display the regime information label")
color compressionBgColorInput = input.color(COMPRESSION_COLOR, "Compression Background", group=G9, tooltip="Background color for Compression regime (low volatility consolidation)")
color expansionBgColorInput   = input.color(EXPANSION_COLOR, "Expansion Background", group=G9, tooltip="Background color for Expansion regime (volatility breakout phase)")
color highVolBgColorInput     = input.color(HIGH_VOL_COLOR, "High Volatility Background", group=G9, tooltip="Background color for High Volatility regime (strong trending)")
color exhaustionBgColorInput  = input.color(EXHAUSTION_COLOR, "Exhaustion Background", group=G9, tooltip="Background color for Exhaustion regime (trend maturity/pause)")
 
var G10 = "════════ DYNAMIC STOP LOSS ════════"
bool  enableDynamicSL      = input.bool(true, "Enable Dynamic Stop Loss", group=G10, tooltip="Automatically calculates optimal stop loss distance based on current market volatility")
float slMultiplierInput    = input.float(2.0, "Stop Loss ATR Multiplier", minval=0.5, maxval=5.0, step=0.1, group=G10, tooltip="ATR multiplier for stop loss distance. 2.0 = stop loss is 2x ATR away from entry. Higher = wider stops, Lower = tighter stops")
bool  showSLLinesInput     = input.bool(true, "Show SL Lines", group=G10, tooltip="Display stop loss levels as cross markers on the chart")
color slBullColorInput     = input.color(#26a69a80, "Bullish SL Color", group=G10, tooltip="Color for bullish (long) stop loss markers")
color slBearColorInput     = input.color(#ef535080, "Bearish SL Color", group=G10, tooltip="Color for bearish (short) stop loss markers")
 
var G11 = "════════ TAKE PROFIT LEVELS ════════"
bool  enableMultipleTP     = input.bool(true, "Enable Multiple TP Levels", group=G11, tooltip="Shows three progressive take profit targets based on ATR multiples for scaling out of positions")
float tp1MultiplierInput   = input.float(1.5, "TP1 Multiplier", minval=0.5, maxval=5.0, step=0.1, group=G11, tooltip="First take profit target. 1.5 = 1.5x ATR from entry. Use for partial profit taking (e.g., 33% position)")
float tp2MultiplierInput   = input.float(2.5, "TP2 Multiplier", minval=1.0, maxval=10.0, step=0.5, group=G11, tooltip="Second take profit target. 2.5 = 2.5x ATR from entry. Use for additional scaling (e.g., another 33%)")
float tp3MultiplierInput   = input.float(4.0, "TP3 Multiplier", minval=2.0, maxval=15.0, step=0.5, group=G11, tooltip="Final take profit target. 4.0 = 4x ATR from entry. Use for remaining position or runners")
bool  showTPLabelsInput    = input.bool(true, "Show TP Labels", group=G11, tooltip="Display TP1, TP2, TP3 labels on the chart for easy identification")
color tpColorInput         = input.color(#ffeb3b80, "TP Color", group=G11, tooltip="Color for all take profit level lines and labels")
 
var G12 = "════════ SUPPORT & RESISTANCE ════════"
bool  enableSRLevels       = input.bool(true, "Enable S/R Levels", group=G12, tooltip="Identifies dynamic support and resistance zones based on recent price action and ATR volatility")
int   srLookbackInput      = input.int(20, "S/R Lookback Period", minval=10, maxval=100, group=G12, tooltip="Number of bars to analyze for finding support/resistance. 20 = short-term levels, 50+ = major levels")
float srStrengthInput      = input.float(1.5, "S/R Strength (ATR)", minval=0.5, maxval=3.0, step=0.1, group=G12, tooltip="ATR multiplier for determining significant S/R zones. Higher = only shows stronger levels")
color supportColorInput    = input.color(#4caf5060, "Support Color", group=G12, tooltip="Color for support level circles")
color resistanceColorInput = input.color(#f4433660, "Resistance Color", group=G12, tooltip="Color for resistance level circles")
 
var G13 = "════════ RISK MANAGEMENT ════════"
bool  enableRiskCalc       = input.bool(true, "Enable Risk Calculator", group=G13, tooltip="Calculates proper position size based on your account size, risk percentage, and current ATR stop loss")
float accountSizeInput     = input.float(10000, "Account Size", minval=100, group=G13, tooltip="Your total trading account balance in dollars (or your currency). Used to calculate position sizes")
float riskPercentInput     = input.float(1.0, "Risk Per Trade (%)", minval=0.1, maxval=10.0, step=0.1, group=G13, tooltip="Maximum % of account to risk per trade. 1% = risk $100 on $10,000 account. Conservative: 0.5-1%, Moderate: 1-2%, Aggressive: 2-5%")
bool  showPositionSizeInput = input.bool(true, "Show Position Size", group=G13, tooltip="Display calculated position size and dollar risk amount on chart")
 
var G14 = "════════ ATR PERCENTILE RANKING ════════"
bool  enableATRPercentile  = input.bool(true, "Enable ATR Percentile", group=G14, tooltip="Shows where current ATR ranks historically. Helps identify extreme volatility conditions vs. normal market behavior")
int   percentileLookback   = input.int(100, "Percentile Lookback", minval=50, maxval=500, group=G14, tooltip="Historical period for percentile calculation. 100 = compare ATR to last 100 bars. Higher = longer-term comparison")
bool  showPercentileLabel  = input.bool(true, "Show Percentile Label", group=G14, tooltip="Display ATR percentile ranking on chart. >80% = extremely high volatility, <20% = extremely low volatility")
 
var G15 = "════════ VOLATILITY CONTRACTION ════════"
bool  enableVolContraction = input.bool(true, "Enable Contraction Pattern", group=G15, tooltip="Detects periods of tight consolidation (volatility squeeze) that typically precede major breakout moves")
int   contractionBars      = input.int(7, "Contraction Bars", minval=3, maxval=20, group=G15, tooltip="Number of consecutive bars required to confirm contraction pattern. 7 = one week of consolidation")
float contractionThreshold = input.float(0.5, "Contraction Threshold", minval=0.3, maxval=0.8, step=0.05, group=G15, tooltip="Maximum ATR ratio during contraction. 0.5 = ATR must stay below 50% of average. Lower = tighter squeeze required")
bool  showContractionAlert = input.bool(true, "Show Contraction Alerts", group=G15, tooltip="Display yellow triangle when contraction pattern completes. Indicates potential imminent breakout")
 
getBands(float src, float atrValue, float multiplier) =>
    upperBand = src + (atrValue * multiplier)
    lowerBand = src - (atrValue * multiplier)
    [upperBand, lowerBand]
 
isVolatilityBreakout(float atrValue, float atrSma, float threshold) =>
    atrValue > (atrSma * threshold)
 
getTrendDirection(float src, float atrValue, int length) =>
    srcSma = ta.sma(src, length)
    atrSma = ta.sma(atrValue, length)
    priceAboveSma = src > srcSma
    atrRising = atrValue > atrSma
    if priceAboveSma and atrRising
        1
    else if not priceAboveSma and atrRising
        -1
    else
        0
 
getATRBaseline(float atrValue, int length, string baselineType) =>
    baselineType == "EMA" ? ta.ema(atrValue, length) : ta.sma(atrValue, length)
 
getATRRatio(float atrValue, float atrBaseline) =>
    atrBaseline > 0 ? atrValue / atrBaseline : 1.0
 
isATRDeclining(float atrValue, int lookback) =>
    declined = true
    for i = 1 to lookback
        if atrValue[i] <= atrValue[i + 1]
            declined := false
            break
    declined
 
detectVolatilityRegime(float atrRatio, float atrValue, float compressionThreshold, float expansionThreshold, float highVolThreshold, int exhaustionLookback) =>
    int regime = 0
    bool wasRecentlyHighVol = false
    for i = 1 to 10
        if atrValue[i] / ta.sma(atrValue[i], 50) >= highVolThreshold
            wasRecentlyHighVol := true
            break
    if atrRatio >= highVolThreshold
        regime := 3
    else if atrRatio >= expansionThreshold
        regime := 2
    else if atrRatio < compressionThreshold
        regime := 1
    else if wasRecentlyHighVol and isATRDeclining(atrValue, exhaustionLookback)
        regime := 4
    else
        regime := 2
    regime
 
getRegimeName(int regime) =>
    switch regime
        1 => "COMPRESSION"
        2 => "EXPANSION"
        3 => "HIGH VOLATILITY"
        4 => "EXHAUSTION"
        => "NEUTRAL"
 
getRegimeColor(int regime) =>
    switch regime
        1 => compressionBgColorInput
        2 => expansionBgColorInput
        3 => highVolBgColorInput
        4 => exhaustionBgColorInput
        => color(na)
 
getDynamicStopLoss(float entryPrice, float atrValue, float multiplier, bool isBullish) =>
    if isBullish
        entryPrice - (atrValue * multiplier)
    else
        entryPrice + (atrValue * multiplier)
 
getTakeProfitLevels(float entryPrice, float atrValue, bool isBullish) =>
    tp1 = isBullish ? entryPrice + (atrValue * tp1MultiplierInput) : entryPrice - (atrValue * tp1MultiplierInput)
    tp2 = isBullish ? entryPrice + (atrValue * tp2MultiplierInput) : entryPrice - (atrValue * tp2MultiplierInput)
    tp3 = isBullish ? entryPrice + (atrValue * tp3MultiplierInput) : entryPrice - (atrValue * tp3MultiplierInput)
    [tp1, tp2, tp3]
 
findSupportResistance(float atrValue, float strength, int lookback) =>
    highestHigh = ta.highest(high, lookback)
    lowestLow = ta.lowest(low, lookback)
    resistance = highestHigh
    support = lowestLow
    [support, resistance]
 
calculatePositionSize(float accountSize, float riskPercent, float entryPrice, float stopLoss) =>
    riskAmount = accountSize * (riskPercent / 100)
    stopDistance = math.abs(entryPrice - stopLoss)
    positionSize = stopDistance > 0 ? riskAmount / stopDistance : 0
    positionSize
 
getATRPercentile(float currentATR, int lookback) =>
    float sum = 0
    int count = 0
    for i = 0 to lookback - 1
        if not na(ta.atr(atrLengthInput)[i])
            if ta.atr(atrLengthInput)[i] < currentATR
                count := count + 1
            sum := sum + 1
    percentile = sum > 0 ? (count / sum) * 100 : 50
    percentile
 
isVolatilityContraction(float atrValue, int bars, float threshold) =>
    contracted = true
    avgATR = ta.sma(atrValue, bars * 2)
    for i = 0 to bars - 1
        if atrValue[i] > avgATR * threshold
            contracted := false
            break
    contracted
 
float atrValue = ta.atr(atrLengthInput)
float atrSma = ta.sma(atrValue, atrLengthInput)
 
[upperBand1, lowerBand1] = getBands(close, atrValue, band1MultInput)
[upperBand2, lowerBand2] = getBands(close, atrValue, band2MultInput)
[upperBand3, lowerBand3] = getBands(close, atrValue, band3MultInput)
 
bool volBreakout = isVolatilityBreakout(atrValue, atrSma, volThresholdInput)
bool volSignal = volBreakout and not volBreakout[1]
 
int trendDirection = getTrendDirection(close, atrValue, trendLengthInput)
bool bullishTrend = trendDirection == 1 and trendDirection[1] != 1
bool bearishTrend = trendDirection == -1 and trendDirection[1] != -1
 
float atrBaseline = getATRBaseline(atrValue, regimeBaselineLengthInput, regimeBaselineTypeInput)
float atrRatio = getATRRatio(atrValue, atrBaseline)
int currentRegime = enableRegimeDetection ? detectVolatilityRegime(atrRatio, atrValue, compressionThresholdInput, expansionThresholdInput, highVolThresholdInput, exhaustionLookbackInput) : 0
string regimeName = getRegimeName(currentRegime)
color regimeColor = getRegimeColor(currentRegime)
bool regimeChanged = currentRegime != currentRegime[1] and currentRegime > 0
 
float bullStopLoss = enableDynamicSL ? getDynamicStopLoss(close, atrValue, slMultiplierInput, true) : na
float bearStopLoss = enableDynamicSL ? getDynamicStopLoss(close, atrValue, slMultiplierInput, false) : na
 
[bullTP1_calc, bullTP2_calc, bullTP3_calc] = getTakeProfitLevels(close, atrValue, true)
[bearTP1_calc, bearTP2_calc, bearTP3_calc] = getTakeProfitLevels(close, atrValue, false)
 
float bullTP1 = enableMultipleTP ? bullTP1_calc : na
float bullTP2 = enableMultipleTP ? bullTP2_calc : na
float bullTP3 = enableMultipleTP ? bullTP3_calc : na
float bearTP1 = enableMultipleTP ? bearTP1_calc : na
float bearTP2 = enableMultipleTP ? bearTP2_calc : na
float bearTP3 = enableMultipleTP ? bearTP3_calc : na
 
[support_calc, resistance_calc] = findSupportResistance(atrValue, srStrengthInput, srLookbackInput)
float supportLevel = enableSRLevels ? support_calc : na
float resistanceLevel = enableSRLevels ? resistance_calc : na
 
float positionSize = enableRiskCalc ? calculatePositionSize(accountSizeInput, riskPercentInput, close, bullStopLoss) : na
 
float atrPercentile = enableATRPercentile ? getATRPercentile(atrValue, percentileLookback) : na
 
bool contractionPattern = enableVolContraction ? isVolatilityContraction(atrValue, contractionBars, contractionThreshold) : false
bool contractionSignal = contractionPattern and not contractionPattern[1]
 
plot(showBandsInput ? upperBand1 : na, title="Upper Band 1", color=upperBandColorInput, linewidth=1)
plot(showBandsInput ? lowerBand1 : na, title="Lower Band 1", color=lowerBandColorInput, linewidth=1)
plot(showBandsInput ? upperBand2 : na, title="Upper Band 2", color=color.new(upperBandColorInput, 60), linewidth=1)
plot(showBandsInput ? lowerBand2 : na, title="Lower Band 2", color=color.new(lowerBandColorInput, 60), linewidth=1)
plot(showBandsInput ? upperBand3 : na, title="Upper Band 3", color=color.new(upperBandColorInput, 80), linewidth=1)
plot(showBandsInput ? lowerBand3 : na, title="Lower Band 3", color=color.new(lowerBandColorInput, 80), linewidth=1)
 
plotshape(series=showVolSignalsInput and volSignal, title="Volatility Breakout", style=shape.circle, location=location.abovebar, color=signalColorInput, size=size.tiny)
plotshape(series=showTrendInput and bullishTrend, title="Bullish Trend Signal", style=shape.labelup, location=location.belowbar, color=bullTrendSignalInput, text="↑", textcolor=color.white, size=size.tiny)
plotshape(series=showTrendInput and bearishTrend, title="Bearish Trend Signal", style=shape.labeldown, location=location.abovebar, color=bearTrendSignalInput, text="↓", textcolor=color.white, size=size.tiny)
 
bgcolor(enableRegimeDetection and showRegimeBackgroundInput ? regimeColor : na, title="Regime Background")
 
var line tpLineUpper = na
var line tpLineLower = na
if barstate.islast
    line.delete(tpLineUpper)
    line.delete(tpLineLower)
    tpLineUpper := line.new(x1=bar_index - 2, y1=upperBand1, x2=bar_index + 2, y2=upperBand1, color=upperBandColorInput, width=2, style=line.style_dotted)
    tpLineLower := line.new(x1=bar_index - 2, y1=lowerBand1, x2=bar_index + 2, y2=lowerBand1, color=lowerBandColorInput, width=2, style=line.style_dotted)
 
var label regimeLabel = na
if enableRegimeDetection and showRegimeLabelInput
    if barstate.islast
        label.delete(regimeLabel)
        labelY = regimeLabelPositionInput == "Top Left" or regimeLabelPositionInput == "Top Right" ? high * 1.02 : low * 0.98
        labelStyle = regimeLabelPositionInput == "Top Left" or regimeLabelPositionInput == "Top Right" ? label.style_label_down : label.style_label_up
        labelText = "REGIME: " + regimeName + "\nRatio: " + str.tostring(atrRatio, "#.##")
        labelColor = switch currentRegime
            1 => color.new(#4caf50, 10)
            2 => color.new(#ff9800, 10)
            3 => color.new(#f44336, 10)
            4 => color.new(#9c27b0, 10)
            => color.new(color.gray, 10)
        regimeLabel := label.new(x=bar_index, y=labelY, text=labelText, style=labelStyle, color=labelColor, textcolor=color.white, size=size.normal)
 
plotshape(series=enableRegimeDetection and regimeChanged, title="Regime Change", style=shape.diamond, location=location.top, color=regimeColor, text="R", size=size.tiny)
 
plot(enableDynamicSL and showSLLinesInput and trendDirection == 1 ? bullStopLoss : na, title="Bull Stop Loss", color=slBullColorInput, linewidth=2, style=plot.style_cross)
plot(enableDynamicSL and showSLLinesInput and trendDirection == -1 ? bearStopLoss : na, title="Bear Stop Loss", color=slBearColorInput, linewidth=2, style=plot.style_cross)
 
var line tp1Line = na
var line tp2Line = na
var line tp3Line = na
if enableMultipleTP and barstate.islast
    line.delete(tp1Line)
    line.delete(tp2Line)
    line.delete(tp3Line)
    
    if trendDirection == 1
        tp1Line := line.new(bar_index - 3, bullTP1, bar_index + 3, bullTP1, color=tpColorInput, width=1, style=line.style_dashed)
        tp2Line := line.new(bar_index - 3, bullTP2, bar_index + 3, bullTP2, color=tpColorInput, width=1, style=line.style_dashed)
        tp3Line := line.new(bar_index - 3, bullTP3, bar_index + 3, bullTP3, color=tpColorInput, width=1, style=line.style_dashed)
    else if trendDirection == -1
        tp1Line := line.new(bar_index - 3, bearTP1, bar_index + 3, bearTP1, color=tpColorInput, width=1, style=line.style_dashed)
        tp2Line := line.new(bar_index - 3, bearTP2, bar_index + 3, bearTP2, color=tpColorInput, width=1, style=line.style_dashed)
        tp3Line := line.new(bar_index - 3, bearTP3, bar_index + 3, bearTP3, color=tpColorInput, width=1, style=line.style_dashed)
 
var label tp1Label = na
var label tp2Label = na
var label tp3Label = na
if enableMultipleTP and showTPLabelsInput and barstate.islast
    label.delete(tp1Label)
    label.delete(tp2Label)
    label.delete(tp3Label)
    
    if trendDirection == 1
        tp1Label := label.new(bar_index, bullTP1, "TP1", style=label.style_label_left, color=tpColorInput, textcolor=color.black, size=size.tiny)
        tp2Label := label.new(bar_index, bullTP2, "TP2", style=label.style_label_left, color=tpColorInput, textcolor=color.black, size=size.tiny)
        tp3Label := label.new(bar_index, bullTP3, "TP3", style=label.style_label_left, color=tpColorInput, textcolor=color.black, size=size.tiny)
    else if trendDirection == -1
        tp1Label := label.new(bar_index, bearTP1, "TP1", style=label.style_label_left, color=tpColorInput, textcolor=color.black, size=size.tiny)
        tp2Label := label.new(bar_index, bearTP2, "TP2", style=label.style_label_left, color=tpColorInput, textcolor=color.black, size=size.tiny)
        tp3Label := label.new(bar_index, bearTP3, "TP3", style=label.style_label_left, color=tpColorInput, textcolor=color.black, size=size.tiny)
 
plot(enableSRLevels ? supportLevel : na, title="Support", color=supportColorInput, linewidth=2, style=plot.style_circles)
plot(enableSRLevels ? resistanceLevel : na, title="Resistance", color=resistanceColorInput, linewidth=2, style=plot.style_circles)
 
var label riskLabel = na
if enableRiskCalc and showPositionSizeInput and barstate.islast
    label.delete(riskLabel)
    riskText = "Position Size: " + str.tostring(positionSize, "#.##") + "\nRisk: $" + str.tostring(accountSizeInput * riskPercentInput / 100, "#.##")
    riskLabel := label.new(bar_index, low * 0.95, riskText, style=label.style_label_up, color=color.new(color.blue, 10), textcolor=color.white, size=size.small)
 
var label percentileLabel = na
if enableATRPercentile and showPercentileLabel and barstate.islast
    label.delete(percentileLabel)
    percentileText = "ATR Percentile: " + str.tostring(atrPercentile, "#") + "%"
    percentileColor = atrPercentile > 80 ? color.new(color.red, 10) : atrPercentile < 20 ? color.new(color.green, 10) : color.new(color.orange, 10)
    percentileLabel := label.new(bar_index, high * 1.05, percentileText, style=label.style_label_down, color=percentileColor, textcolor=color.white, size=size.small)
 
plotshape(series=enableVolContraction and showContractionAlert and contractionSignal, title="Volatility Contraction", style=shape.triangleup, location=location.belowbar, color=color.new(color.yellow, 0), text="VC", size=size.small)
 
atrCrossover = ta.crossover(close, upperBand1)
atrCrossunder = ta.crossunder(close, lowerBand1)
 
if volSignal
    alert("ATR Volatility Breakout", alert.freq_once_per_bar_close)
if bullishTrend
    alert("ATR Bullish Trend Signal", alert.freq_once_per_bar_close)
if bearishTrend
    alert("ATR Bearish Trend Signal", alert.freq_once_per_bar_close)
if atrCrossover
    alert("Price Above ATR Band 1", alert.freq_once_per_bar_close)
if atrCrossunder
    alert("Price Below ATR Band 1", alert.freq_once_per_bar_close)
if enableRegimeDetection and currentRegime == 1 and currentRegime[1] != 1
    alert("Volatility Regime: COMPRESSION", alert.freq_once_per_bar_close)
if enableRegimeDetection and currentRegime == 2 and currentRegime[1] != 2
    alert("Volatility Regime: EXPANSION", alert.freq_once_per_bar_close)
if enableRegimeDetection and currentRegime == 3 and currentRegime[1] != 3
    alert("Volatility Regime: HIGH VOLATILITY", alert.freq_once_per_bar_close)
if enableRegimeDetection and currentRegime == 4 and currentRegime[1] != 4
    alert("Volatility Regime: EXHAUSTION", alert.freq_once_per_bar_close)
if enableVolContraction and contractionSignal
    alert("Volatility Contraction Pattern Detected - Breakout Imminent", alert.freq_once_per_bar_close)
if enableATRPercentile and atrPercentile > 90 and atrPercentile[1] <= 90
    alert("ATR at Extreme High (>90th Percentile)", alert.freq_once_per_bar_close)
if enableATRPercentile and atrPercentile < 10 and atrPercentile[1] >= 10
    alert("ATR at Extreme Low (<10th Percentile)", alert.freq_once_per_bar_close)

← 返回列表