本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © BOSWaves - Modified
//@version=6
indicator("ADX Volatility Waves [BOSWaves]", overlay=true)
// ============================================================================
// Inputs
// ============================================================================
// Bollinger Bands Settings
bbLength = input.int(20, "BB Length", minval=1, group="Bollinger Bands",
tooltip="Number of bars used to calculate the Bollinger Bands moving average and standard deviation")
bbMult = input.float(1.5, "BB StdDev", minval=0.1, step=0.1, group="Bollinger Bands",
tooltip="Standard deviation multiplier for Bollinger Bands width. Higher values create wider bands")
// ADX Settings
adxLength = input.int(14, "ADX Length", minval=1, group="ADX",
tooltip="Period for calculating the Average Directional Index (ADX)")
adxSmooth = input.int(14, "ADX Smoothing", minval=1, group="ADX",
tooltip="Smoothing period applied to the ADX calculation")
adxStrong = input.int(25, "Strong Trend Threshold", minval=1, group="ADX",
tooltip="ADX value above which the trend is considered strong")
adxWeak = input.int(20, "Weak Trend Threshold", minval=1, group="ADX",
tooltip="ADX value below which the trend is considered weak")
adxInfluence = input.float(0.8, "ADX Band Multiplier", minval=0.5, maxval=3.0, step=0.1, group="ADX",
tooltip="Controls how much ADX affects the Bollinger Band width. Higher values = more ADX influence on volatility zones")
// Zone Settings
zoneOffset = input.float(1, "Zone Offset from Price", minval=0.0, maxval=3.0, step=0.1, group="Zones",
tooltip="Distance of zones from Bollinger Bands as a multiple of BB range. Higher = zones further from price")
zoneExpansion = input.float(1, "Zone Width", minval=0.5, maxval=5.0, step=0.1, group="Zones",
tooltip="Width of the colored zones as a multiple of BB range. Higher = wider zones")
smoothLength = input.int(50, "Zone Smoothing Length", minval=10, maxval=200, group="Zones",
tooltip="Smoothing period for zone boundaries. Higher values create smoother, less reactive zones")
// Visual Options
showSignals = input.bool(true, "Show Entry Signals", group="Display",
tooltip="Toggle visibility of BUY/SELL labels and diamond entry markers")
fillTransparency = input.int(50, "Fill Transparency", minval=0, maxval=100, group="Display",
tooltip="Transparency level for zone fills. 0=opaque, 100=invisible")
// Signal Settings
signalCooldown = input.int(20, "Signal Cooldown (bars)", minval=5, maxval=100, group="Display",
tooltip="Minimum number of bars between signals to prevent excessive alerts")
minNeutralBars = input.int(5, "Min Bars in Neutral Zone", minval=1, maxval=20, group="Display",
tooltip="Number of consecutive bars price must stay in neutral zone before generating a reversal signal")
// ============================================================================
// Color Definitions
// ============================================================================
// Color Scheme for signals
bullColorTop = #00ff88
bearColorTop = #ff3366
// Red gradient for top zone (light to dark red)
topBand1Color = #FFE5E5 // Very light red
topBand2Color = #FFCCCC
topBand3Color = #FFB3B3
topBand4Color = #FF9999
topBand5Color = #FF8080
topBand6Color = #FF6666
topBand7Color = #FF4D4D
topBand8Color = #FF3333
topBand9Color = #FF1A1A
topBand10Color = #FF0000 // Pure red
// Green gradient for bottom zone (light to dark green)
bottomBand1Color = #E5FFE5 // Very light green
bottomBand2Color = #CCFFCC
bottomBand3Color = #B3FFB3
bottomBand4Color = #99FF99
bottomBand5Color = #80FF80
bottomBand6Color = #66FF66
bottomBand7Color = #4DFF4D
bottomBand8Color = #33FF33
bottomBand9Color = #1AFF1A
bottomBand10Color = #00FF00 // Pure green
// ============================================================================
// ADX Calculation
// ============================================================================
[diPlus, diMinus, adx] = ta.dmi(adxLength, adxSmooth)
adxNormalized = adx / 100
// ============================================================================
// ADX-Adjusted Bollinger Bands Calculation
// ============================================================================
bbBasis = ta.sma(close, bbLength)
bbDev = ta.stdev(close, bbLength)
// Apply ADX multiplier to standard deviation
adxMultiplier = 1 + (adxNormalized * adxInfluence)
bbDevAdjusted = bbMult * bbDev * adxMultiplier
bbUpper = bbBasis + bbDevAdjusted
bbLower = bbBasis - bbDevAdjusted
bbWidth = (bbUpper - bbLower) / bbBasis * 100
// ============================================================================
// Zone Creation Based on Bollinger Bands
// ============================================================================
// Smooth the BB values for zone positioning
bbUpperSmooth = ta.sma(bbUpper, smoothLength)
bbLowerSmooth = ta.sma(bbLower, smoothLength)
bbRangeSmooth = bbUpperSmooth - bbLowerSmooth
// Calculate offset distance
offsetDistance = bbRangeSmooth * zoneOffset
// Top zone - starts offset distance above upper BB, then expands outward
topZoneBottom = bbUpperSmooth + offsetDistance
topZoneTop = topZoneBottom + (bbRangeSmooth * zoneExpansion)
// Bottom zone - starts offset distance below lower BB, then expands outward
bottomZoneTop = bbLowerSmooth - offsetDistance
bottomZoneBottom = bottomZoneTop - (bbRangeSmooth * zoneExpansion)
// ============================================================================
// Fusion Logic - Trend and Price Analysis
// ============================================================================
trendStrong = adx > adxStrong
trendWeak = adx < adxWeak
bullishTrend = diPlus > diMinus
bearishTrend = diMinus > diPlus
priceAboveBB = close > bbUpper
priceBelowBB = close < bbLower
priceInBB = not priceAboveBB and not priceBelowBB
isSqueeze = bbWidth < ta.sma(bbWidth, 50)
// ============================================================================
// Signal Logic - Zone Detection and State Tracking
// ============================================================================
// Define zones more clearly
priceInTopZone = close > topZoneBottom
priceInBottomZone = close < bottomZoneTop
priceInNeutralZone = close <= topZoneBottom and close >= bottomZoneTop
// State tracking
var int lastBuySignalBar = -999
var int lastSellSignalBar = -999
var int neutralZoneCount = 0
var bool wasInTopZone = false
var bool wasInBottomZone = false
// Count consecutive bars in neutral zone
if priceInNeutralZone
neutralZoneCount += 1
wasInTopZone := false
wasInBottomZone := false
else
neutralZoneCount := 0
// Track zone entries
if priceInTopZone
wasInTopZone := true
if priceInBottomZone
wasInBottomZone := true
// Diamond signals - entering extreme zones for first time
bool enterTopZone = priceInTopZone and not priceInTopZone[1] and (bar_index - lastSellSignalBar >= signalCooldown)
bool enterBottomZone = priceInBottomZone and not priceInBottomZone[1] and (bar_index - lastBuySignalBar >= signalCooldown)
// Update last signal bars
if enterBottomZone
lastBuySignalBar := bar_index
if enterTopZone
lastSellSignalBar := bar_index
// ============================================================================
// Gradient Array Creation
// ============================================================================
var array<float> topLevels = array.new<float>(11)
var array<float> bottomLevels = array.new<float>(11)
// Update top zone levels (gradient from bottom to top)
for i = 0 to 10
ratio = i / 10.0
array.set(topLevels, i, topZoneBottom + (topZoneTop - topZoneBottom) * ratio)
// Update bottom zone levels (gradient from top to bottom)
for i = 0 to 10
ratio = i / 10.0
array.set(bottomLevels, i, bottomZoneTop - (bottomZoneTop - bottomZoneBottom) * ratio)
// ============================================================================
// Top Zone Plots
// ============================================================================
topLevel0 = plot(array.get(topLevels, 0), display=display.none)
topLevel1 = plot(array.get(topLevels, 1), display=display.none)
topLevel2 = plot(array.get(topLevels, 2), display=display.none)
topLevel3 = plot(array.get(topLevels, 3), display=display.none)
topLevel4 = plot(array.get(topLevels, 4), display=display.none)
topLevel5 = plot(array.get(topLevels, 5), display=display.none)
topLevel6 = plot(array.get(topLevels, 6), display=display.none)
topLevel7 = plot(array.get(topLevels, 7), display=display.none)
topLevel8 = plot(array.get(topLevels, 8), display=display.none)
topLevel9 = plot(array.get(topLevels, 9), display=display.none)
topLevel10 = plot(array.get(topLevels, 10), display=display.none)
// ============================================================================
// Bottom Zone Plots
// ============================================================================
bottomLevel0 = plot(array.get(bottomLevels, 0), display=display.none)
bottomLevel1 = plot(array.get(bottomLevels, 1), display=display.none)
bottomLevel2 = plot(array.get(bottomLevels, 2), display=display.none)
bottomLevel3 = plot(array.get(bottomLevels, 3), display=display.none)
bottomLevel4 = plot(array.get(bottomLevels, 4), display=display.none)
bottomLevel5 = plot(array.get(bottomLevels, 5), display=display.none)
bottomLevel6 = plot(array.get(bottomLevels, 6), display=display.none)
bottomLevel7 = plot(array.get(bottomLevels, 7), display=display.none)
bottomLevel8 = plot(array.get(bottomLevels, 8), display=display.none)
bottomLevel9 = plot(array.get(bottomLevels, 9), display=display.none)
bottomLevel10 = plot(array.get(bottomLevels, 10), display=display.none)
// ============================================================================
// Top Zone Gradient Fills (Red gradient - light to dark)
// ============================================================================
fill(topLevel1, topLevel0, color.new(topBand1Color, fillTransparency))
fill(topLevel2, topLevel1, color.new(topBand2Color, fillTransparency))
fill(topLevel3, topLevel2, color.new(topBand3Color, fillTransparency))
fill(topLevel4, topLevel3, color.new(topBand4Color, fillTransparency))
fill(topLevel5, topLevel4, color.new(topBand5Color, fillTransparency))
fill(topLevel6, topLevel5, color.new(topBand6Color, fillTransparency))
fill(topLevel7, topLevel6, color.new(topBand7Color, fillTransparency))
fill(topLevel8, topLevel7, color.new(topBand8Color, fillTransparency))
fill(topLevel9, topLevel8, color.new(topBand9Color, fillTransparency))
fill(topLevel10, topLevel9, color.new(topBand10Color, fillTransparency))
// ============================================================================
// Bottom Zone Gradient Fills (Green gradient - light to dark)
// ============================================================================
fill(bottomLevel0, bottomLevel1, color.new(bottomBand1Color, fillTransparency))
fill(bottomLevel1, bottomLevel2, color.new(bottomBand2Color, fillTransparency))
fill(bottomLevel2, bottomLevel3, color.new(bottomBand3Color, fillTransparency))
fill(bottomLevel3, bottomLevel4, color.new(bottomBand4Color, fillTransparency))
fill(bottomLevel4, bottomLevel5, color.new(bottomBand5Color, fillTransparency))
fill(bottomLevel5, bottomLevel6, color.new(bottomBand6Color, fillTransparency))
fill(bottomLevel6, bottomLevel7, color.new(bottomBand7Color, fillTransparency))
fill(bottomLevel7, bottomLevel8, color.new(bottomBand8Color, fillTransparency))
fill(bottomLevel8, bottomLevel9, color.new(bottomBand9Color, fillTransparency))
fill(bottomLevel9, bottomLevel10, color.new(bottomBand10Color, fillTransparency))
// ============================================================================
// Signal Labels
// ============================================================================
// Buy signal when entering bottom zone (oversold)
if showSignals and enterBottomZone
label.new(bar_index, low, "BUY", style=label.style_label_up, color=bullColorTop, textcolor=color.black, size=size.normal, yloc=yloc.belowbar)
// Sell signal when entering top zone (overbought)
if showSignals and enterTopZone
label.new(bar_index, high, "SELL", style=label.style_label_down, color=bearColorTop, textcolor=color.white, size=size.normal, yloc=yloc.abovebar)
// ============================================================================
// Alerts
// ============================================================================
alertcondition(enterBottomZone, "Buy Signal", "ADX+BB: Buy Signal - Price Entered Bottom Zone (Oversold)")
alertcondition(enterTopZone, "Sell Signal", "ADX+BB: Sell Signal - Price Entered Top Zone (Overbought)")
alertcondition(isSqueeze and not isSqueeze[1], "Squeeze Started", "ADX+BB: Volatility Squeeze Detected")