OPEN = LOW + VWAP + Volume SurgeTradingView Pine Script that scans for OPEN = LOW, confirms VWAP support, and checks for volume surge — tailored for your intraday breakout strategy
Indicadores e estratégias
Morning Peak FadeMorning Peak Fade is an intraday analysis tool that identifies and measures the probability of early session rallies turning into sharp pullbacks.
📊 Core Idea
• Many stocks surge after the open, reaching an intraday peak before fading lower.
• This script anchors at the first significant morning high and tracks the drawdowns that follow within a customizable time window.
• It provides:
• Probability of a fade after the peak
• Average and maximum drawdown statistics
• Event-day hit rate (how often such setups occur)
🎯 Use Cases
• Spot potential “fade setups” where early enthusiasm exhausts quickly.
• Quantify how often chasing the morning high turns into a losing trade.
• Backtest opening range failure or fade strategies with hard data.
⚙️ Features
• Customizable thresholds for the initial surge (relative to prior close).
• Marks the peak (max) and subsequent low (min) used in calculations.
• Draws a reference line at the surge threshold to visualize when the fade triggers.
• Outputs summary stats directly on the chart.
Continuation Index [DCAUT]█ Continuation Index
📊 OVERVIEW
Continuation Index (CI) is an advanced trend analysis indicator developed by John F. Ehlers. This indicator provides early warning signals for trend onset, continuation, and exhaustion, with values oscillating between -1 and +1 to offer clear trend state identification for traders.
Based on the article TASC 2025.09 "Trend Onset And Trend Exhaustion - The Continuation Index" by John F. Ehlers.
💡 CORE VALUE
Unlike traditional trend indicators, the Continuation Index provides:
- Advanced dual-filter architecture (Ultimate Smoother + Laguerre Filter)
- Inverse Fisher Transform for enhanced signal-to-noise ratio
- Adaptive gamma parameter allowing market-specific tuning
- Binary state output (+1/-1) eliminating interpretation ambiguity
🎯 CONCEPTS
Signal Interpretation
CI > 0.5 : Strong bullish trend continuation - consider holding/adding long positions
CI = +1 : Maximum bullish signal - strong uptrend in progress
CI < -0.5 : Strong bearish trend continuation - consider holding/adding short positions
CI = -1 : Maximum bearish signal - strong downtrend in progress
CI near 0 : Neutral zone - trend uncertain, wait for clear signals
Brief pullbacks from extreme states : Potential reentry opportunities in trend direction
Primary Applications
Trend Onset Detection : Early warning signals for trend initiation
Trend Exhaustion Signals : Identify potential trend reversals
Position Management : Clear binary states for entry/exit decisions
Market Timing : Adaptive filtering reduces false signals
📋 PARAMETER SETUP
Source : Data source for calculation (default: close)
Length : The calculation length for the filters (default: 40, min: 1)
Gamma : Controls the phase response of the Laguerre filter. Smaller values increase responsiveness (default: 0.8, range: 0.0-1.0)
Laguerre Order : The order of the Laguerre filter, which directly affects its lag (default: 8, range: 1-10)
📊 COLOR CODING
Green : CI > 0.5 - Bullish trend continuation
Red : CI < -0.5 - Bearish trend continuation
Gray : Neutral zone - Trend unclear
Automatic Candle Date - BVKAutomatic Candle Date
It is related to automatic Date indicator , so you can fetch it
Guided Advisor with DXY ContextThis indicator will constantly will be looking for DXY direction in the background.
NY 14:30 High/Low - 1mThis indicator automatically draws horizontal lines for the High (green) and Low (red) of the 14:30 (Lisbon) candle on the 1-minute chart.
It is designed for traders who want to quickly identify the New York open levels (NY Open), allowing you to:
Visualize the NY market opening zone.
Use these levels as intraday support or resistance.
Plan entries and exits based on breakouts or pullbacks.
Features:
Works on any 1-minute chart.
Lines are drawn immediately after the 14:30 candle closes.
Lines extend automatically to the right.
Simple and lightweight, no complex variables or external dependencies.
Daily reset, always showing the current day’s levels.
Recommended Use:
Combine with support/resistance zones, order blocks, or fair value gaps.
Monitor price behavior during the NY open to identify breakout or rejection patterns.
MA Divergence中文介绍:
均线背离指标是一款用于分析价格与均线(如EMA或SMA)之间的背离情况的技术分析工具。该指标结合了标准差、波动性分析和背离信号的检测,旨在帮助交易者识别市场中的潜在反转信号。
主要功能:
背离检测: 该指标根据价格与指定均线(EMA或SMA)之间的乖离(百分比差异),绘制背离柱状图,便于快速识别背离信号。
标准差与阈值: 根据过去一段时间内的历史数据,自动计算标准差并设置动态阈值,用以判断价格背离的异常程度。当背离信号超出设定的阈值时,柱状图将标记为蓝色,突出显示潜在的反转信号。
警报功能: 为用户提供警报设置,当背离信号突破上阈值或下阈值时,能够及时提醒交易者,帮助做出决策。
适用对象:
短期交易者: 用于快速捕捉反转信号,帮助制定更具针对性的交易策略。
中长期交易者: 通过背离与均线的结合,帮助识别趋势的潜在转折点。
技术分析爱好者: 提供了一种新的背离分析视角,帮助用户理解市场行为。
英文介绍:
The Moving Average Divergence (MA Divergence) Indicator is a technical analysis tool designed to analyze the divergence between price and a moving average (such as EMA or SMA). The indicator combines standard deviation, volatility analysis, and divergence signal detection to help traders identify potential reversal signals in the market.
Key Features:
Divergence Detection: The indicator plots divergence histograms based on the percentage difference between price and the selected moving average (EMA or SMA), making it easy to spot divergence signals at a glance.
Standard Deviation & Thresholds: The indicator automatically calculates the standard deviation based on historical data over a specified period and sets dynamic thresholds to assess the abnormality of price divergence. When the divergence signal exceeds the set thresholds, the histogram is highlighted in blue, emphasizing potential reversal signals.
Alert Functionality: The indicator includes alert conditions, allowing users to receive notifications when the divergence breaks above or below a defined threshold, helping traders take timely actions.
Target Audience:
Short-term traders: Designed for quick identification of reversal signals to formulate more targeted trading strategies.
Mid-to-long-term traders: Helps to identify potential trend reversal points by combining divergence with moving averages.
Technical analysis enthusiasts: Provides a new perspective on divergence analysis, helping users better understand market behavior.
总结:
无论是短期的交易决策,还是长期的市场趋势判断,“均线背离”指标都能为交易者提供强大的支持。通过标准差、波动性分析、警报提醒等功能,帮助用户实时捕捉市场中的背离信号,并快速做出反应。
ShadowCorp ICT Extended Macros (Original by toodegrees)Based on “ICT Algorithmic Macro Tracker° (Open-Source) by toodegrees” (MPL-2.0), this version simply extends the original macro logic: it keeps the same left/right verticals and dynamic horizontal cap. In short, it’s just an extended macro compared to TooDegree’s
Daily ATR TrackerThis indicator calculates the daily ATR of the past 14 days. The ATR% indicates the range completed for the day. The ATR indicates the average daily range. The 20% ATR indicates the value of 20% of the daily ATR for retracement purposes.
Amritsingh Pinbar Candle GhostTrade Criteria//@version=5
indicator("Custom Candle with Asymmetric Wicks", overlay=true)
// === User Inputs ===
// Body percent thresholds (as % of full candle)
bodyMin = input.float(72.0, "Minimum Body %", minval=0.0, maxval=100.0)
bodyMax = input.float(85.0, "Maximum Body %", minval=0.0, maxval=100.0)
// Wick ratio threshold (e.g., 2.0 means one wick must be at least 2x the other)
wickRatio = input.float(2.0, "Min Wick Asymmetry Ratio", minval=1.0, step=0.1)
// === Candle Calculations ===
bodySize = math.abs(close - open)
candleRange = high - low
// Avoid divide-by-zero
validCandle = candleRange > 0
// Body as % of full candle
bodyPercent = validCandle ? (bodySize / candleRange) * 100 : 0
// Wick sizes
upperWick = high - math.max(close, open)
lowerWick = math.min(close, open) - low
// Ensure both wicks are present (non-zero)
bothWicksPresent = (upperWick > 0) and (lowerWick > 0)
// Wick asymmetry condition (either wick must be ≥ wickRatio × the other)
wickAsymmetry = (upperWick >= lowerWick * wickRatio) or (lowerWick >= upperWick * wickRatio)
// Final condition: all must be true
signal = validCandle and bothWicksPresent and wickAsymmetry and (bodyPercent >= bodyMin and bodyPercent <= bodyMax)
// === Plotting ===
plotshape(signal, title="Candle Signal", location=location.belowbar, style=shape.labelup, color=color.orange, size=size.small, text="⚡")
barcolor(signal ? color.orange : na)
55 ABR Currentcurrent bar range
abr
previous_bar ibs
当前K线范围 (Curr Bar Rng):显示当前正在形成的K线的价格幅度(最高价-最低价)
平均K线范围 (ABR):计算指定周期内(默认8根K线)的平均K线范围,这个数值可以帮助交易者了解市场的平均波动性
内部K线强度 (IBS):显示前一根已完成K线的内部强度百分比
This Pine Script indicator creates a real-time information panel in the top-right corner of TradingView charts, displaying three key trading metrics:Core Features:
Current Bar Range: Shows the price range (high - low) of the currently forming candlestick, providing immediate awareness of intraday volatility.
Average Bar Range (ABR): Calculates the mean candlestick range over a specified lookback period (default: 8 bars). This metric helps traders assess whether current market volatility is above or below recent norms.
Internal Bar Strength (IBS): Displays the previous completed bar's internal strength as a percentage,
Multi-Timeframe MACD Score(customizable)this is a momentum based indcator to know the direction of the market
Double Top/Bottom Screener - Today Only v2 //@version=6
indicator("Double Top/Bottom Screener - Today Only", overlay=true, max_lines_count=500)
// Inputs
leftBars = input.int(5, "Left Bars")
rightBars = input.int(5, "Right Bars")
tolerance = input.float(0.02, "Max Difference (e.g., 0.02 for 2 cents)", step=0.01)
atrLength = input.int(14, "ATR Length for Normalized Distance", minval=1)
requiredPeaks = input.int(3, "Required Identical Peaks", minval=2, maxval=5)
// Declarations of persistent variables and arrays
var array resistanceLevels = array.new(0)
var array resistanceCounts = array.new(0)
var array supportLevels = array.new(0)
var array supportCounts = array.new(0)
var array resLines = array.new(0)
var array supLines = array.new(0)
var bool hasDoubleTop = false
var bool hasDoubleBottom = false
var float doubleTopLevel = na
var float doubleBottomLevel = na
var int todayStart = na
// Step 1: Identify Swing Highs/Lows
swingHigh = ta.pivothigh(high, leftBars, rightBars)
swingLow = ta.pivotlow(low, leftBars, rightBars)
// Today's premarket start (04:00 AM ET)
todayStart := timestamp(syminfo.timezone, year, month, dayofmonth, 4, 0, 0)
// Clear arrays and delete lines on the first bar or new day
if barstate.isfirst or (dayofmonth != dayofmonth and time >= todayStart)
// Delete all existing lines only if arrays are not empty
if array.size(resLines) > 0
for i = array.size(resLines) - 1 to 0
line.delete(array.get(resLines, i))
if array.size(supLines) > 0
for i = array.size(supLines) - 1 to 0
line.delete(array.get(supLines, i))
// Clear arrays
array.clear(resistanceLevels)
array.clear(supportLevels)
array.clear(resistanceCounts)
array.clear(supportCounts)
array.clear(resLines)
array.clear(supLines)
// Reset flags
hasDoubleTop := false
hasDoubleBottom := false
doubleTopLevel := na
doubleBottomLevel := na
// Add new swings only if today and after premarket
if not na(swingHigh) and time >= todayStart and dayofmonth == dayofmonth
bool isEqualHigh = false
int peakIndex = -1
float prevLevel = na
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
prevLevel := array.get(resistanceLevels, i)
if math.abs(swingHigh - prevLevel) <= tolerance
isEqualHigh := true
peakIndex := i
break
if isEqualHigh and peakIndex >= 0
array.set(resistanceCounts, peakIndex, array.get(resistanceCounts, peakIndex) + 1)
if array.get(resistanceCounts, peakIndex) == requiredPeaks
hasDoubleTop := true
doubleTopLevel := prevLevel
else
array.push(resistanceLevels, swingHigh)
array.push(resistanceCounts, 1)
line newResLine = line.new(bar_index - rightBars, swingHigh, bar_index, swingHigh, color=color.red, width=2, extend=extend.none)
array.push(resLines, newResLine)
if not na(swingLow) and time >= todayStart and dayofmonth == dayofmonth
bool isEqualLow = false
int peakIndex = -1
float prevLevel = na
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
prevLevel := array.get(supportLevels, i)
if math.abs(swingLow - prevLevel) <= tolerance
isEqualLow := true
peakIndex := i
break
if isEqualLow and peakIndex >= 0
array.set(supportCounts, peakIndex, array.get(supportCounts, peakIndex) + 1)
if array.get(supportCounts, peakIndex) == requiredPeaks
hasDoubleBottom := true
doubleBottomLevel := prevLevel
else
array.push(supportLevels, swingLow)
array.push(supportCounts, 1)
line newSupLine = line.new(bar_index - rightBars, swingLow, bar_index, swingLow, color=color.green, width=2, extend=extend.none)
array.push(supLines, newSupLine)
// Monitor and remove broken levels/lines; reset pattern if the equal level breaks
if array.size(resistanceLevels) > 0
for i = array.size(resistanceLevels) - 1 to 0
float level = array.get(resistanceLevels, i)
if close > level
line.delete(array.get(resLines, i))
array.remove(resLines, i)
array.remove(resistanceLevels, i)
array.remove(resistanceCounts, i)
if level == doubleTopLevel
hasDoubleTop := false
doubleTopLevel := na
if array.size(supportLevels) > 0
for i = array.size(supportLevels) - 1 to 0
float level = array.get(supportLevels, i)
if close < level
line.delete(array.get(supLines, i))
array.remove(supLines, i)
array.remove(supportLevels, i)
array.remove(supportCounts, i)
if level == doubleBottomLevel
hasDoubleBottom := false
doubleBottomLevel := na
// Limit arrays (after removals)
if array.size(resistanceLevels) > 10
line oldLine = array.shift(resLines)
line.delete(oldLine)
array.shift(resistanceLevels)
array.shift(resistanceCounts)
if array.size(supportLevels) > 10
line oldLine = array.shift(supLines)
line.delete(oldLine)
array.shift(supportLevels)
array.shift(supportCounts)
// Pattern Signal: 1 only if the exact required number of peaks is met
patternSignal = (hasDoubleTop or hasDoubleBottom) ? 1 : 0
// New: Nearest Double Level Price
var float nearestDoubleLevel = na
if hasDoubleTop and not na(doubleTopLevel)
nearestDoubleLevel := doubleTopLevel
if hasDoubleBottom and not na(doubleBottomLevel)
nearestDoubleLevel := na(nearestDoubleLevel) ? doubleBottomLevel : (math.abs(close - doubleBottomLevel) < math.abs(close - nearestDoubleLevel) ? doubleBottomLevel : nearestDoubleLevel)
// New: Distance to Nearest Level (using ATR for normalization)
var float atr = ta.atr(atrLength)
var float distanceNormalizedATR = na
if not na(nearestDoubleLevel) and not na(atr) and atr > 0
distanceNormalizedATR := math.abs(close - nearestDoubleLevel) / atr
// Optional Bounce Signal (for reference)
bounceSignal = 0
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
float level = array.get(resistanceLevels, i)
if low <= level and high >= level and close < level
bounceSignal := 1
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
float level = array.get(supportLevels, i)
if high >= level and low <= level and close > level
bounceSignal := 1
// Outputs
plot(patternSignal, title="Pattern Signal", color=patternSignal == 1 ? color.purple : na, style=plot.style_circles)
plot(bounceSignal, title="Bounce Signal", color=bounceSignal == 1 ? color.yellow : na, style=plot.style_circles)
plot(nearestDoubleLevel, title="Nearest Double Level Price", color=color.orange)
plot(distanceNormalizedATR, title="Normalized Distance (ATR)", color=color.green)
bgcolor(patternSignal == 1 ? color.new(color.purple, 80) : na)
if patternSignal == 1 and barstate.isconfirmed
alert("Double Pattern detected on " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)
if barstate.islast
var table infoTable = table.new(position.top_right, 1, 4, bgcolor=color.new(color.black, 50))
table.cell(infoTable, 0, 0, "Pattern: " + str.tostring(patternSignal), bgcolor=patternSignal == 1 ? color.purple : color.gray)
table.cell(infoTable, 0, 1, "Bounce: " + str.tostring(bounceSignal), bgcolor=bounceSignal == 1 ? color.yellow : color.gray)
table.cell(infoTable, 0, 2, "Level: " + str.tostring(nearestDoubleLevel, "#.##"), bgcolor=color.orange)
table.cell(infoTable, 0, 3, "ATR Dist: " + str.tostring(distanceNormalizedATR, "#.##"), bgcolor=color.green)
Volume weighted Forex Overwiew True Strenght IndexAdding volume weighting to the FOTSI strategy improves its effectiveness by making the indicator more sensitive to periods of high market activity. Here’s how:
Market Relevance: Futures volume reflects institutional and large trader participation. When volume is high, price moves are more likely to be meaningful and less likely to be noise.
Dynamic Weighting: By multiplying each currency’s momentum by its normalized futures volume, the indicator gives more weight to currencies that are actively traded at that moment, making signals more robust.
Filtering Out Noise: Low-volume periods are down-weighted, reducing the impact of illiquid or less relevant price changes.
Better Timing: Signals generated during high-volume periods are more likely to coincide with real market moves, improving entry and exit timing.
Diamond-Triangle Strategy - Dynamic Trailing v2This had an adaptive exit strategy added with diamond entries not working well
EMA 20/40 Crossover//@version=5
indicator(title="EMA 20/40 Crossover", shorttitle="EMA Cross", overlay=true)
// Calculate EMAs
ema20 = ta.ema(close, 20)
ema40 = ta.ema(close, 40)
// Detect crossovers
bullCross = ta.crossover(ema20, ema40) // EMA20 crosses above EMA40 (Buy signal)
bearCross = ta.crossunder(ema20, ema40) // EMA20 crosses below EMA40 (Sell signal)
// Plot EMA lines
plot(ema20, color=color.blue, title="EMA 20", linewidth=2)
plot(ema40, color=color.red, title="EMA 40", linewidth=2)
// Plot signals
plotshape(series=bullCross, title="Buy Signal", location=location.belowbar, style=shape.labelup, size=size.small, color=color.green, text="BUY")
plotshape(series=bearCross, title="Sell Signal", location=location.abovebar, style=shape.labeldown, size=size.small, color=color.red, text="SELL")
// Alert setup (optional)
alertcondition(bullCross, title="EMA Bullish Cross", message="EMA 20 crossed above EMA 40 - BUY!")
alertcondition(bearCross, title="EMA Bearish Cross", message="EMA 20 crossed below EMA 40 - SELL!")
Adaptive Jump Moving AverageAdaptive Jump Moving Average - Description
This indicator solves the classic moving average lag problem during significant price moves. Traditional MAs (like the 200-day) take forever to catch up after a major drop or rally because they average across all historical periods equally.
How it works:
Tracks price smoothly during normal market conditions
When price moves 20%+ away from the MA, it immediately "resets" to the current price level
Treats that new level as the baseline and continues smooth tracking from there
Advantages over normal MA:
No lag on major moves: A 40% crash doesn't get diluted over 200 days - the MA instantly adapts
Reduces false signals: You won't get late "death cross" signals months after a crash already happened
Better support/resistance: The MA stays relevant to current price action instead of reflecting outdated levels
Keeps the smoothness: During normal volatility, it behaves like a traditional MA without the noise of shorter periods
Double Top/Bottom Screener V1//@version=6
indicator("Double Top/Bottom Screener", overlay=true, max_lines_count=500)
// Inputs
leftBars = input.int(5, "Left Bars")
rightBars = input.int(5, "Right Bars")
tolerance = input.float(0.02, "Max Difference (e.g., 0.02 for 2 cents)", step=0.01)
atrLength = input.int(14, "ATR Length for Normalized Distance", minval=1)
requiredPeaks = input.int(3, "Required Identical Peaks", minval=2, maxval=5)
// Declarations of persistent variables and arrays
var array resistanceLevels = array.new(0)
var array resistanceCounts = array.new(0)
var array supportLevels = array.new(0)
var array supportCounts = array.new(0)
var array resLines = array.new(0)
var array supLines = array.new(0)
var bool hasDoubleTop = false
var bool hasDoubleBottom = false
var float doubleTopLevel = na
var float doubleBottomLevel = na
var int todayStart = na
var bool isNewDay = false
// Step 1: Identify Swing Highs/Lows
swingHigh = ta.pivothigh(high, leftBars, rightBars)
swingLow = ta.pivotlow(low, leftBars, rightBars)
// Today's premarket start (04:00 AM ET)
if dayofmonth != dayofmonth
todayStart := timestamp(syminfo.timezone, year, month, dayofmonth, 4, 0, 0)
isNewDay := true
else
isNewDay := false
// Clear arrays and reset flags only once at premarket start
if isNewDay and time >= todayStart
array.clear(resistanceLevels)
array.clear(supportLevels)
array.clear(resistanceCounts)
array.clear(supportCounts)
array.clear(resLines)
array.clear(supLines)
hasDoubleTop := false
hasDoubleBottom := false
doubleTopLevel := na
doubleBottomLevel := na
// Add new swings and check for identical peaks
if not na(swingHigh) and time >= todayStart
bool isEqualHigh = false
int peakIndex = -1
float prevLevel = na
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
prevLevel := array.get(resistanceLevels, i)
if math.abs(swingHigh - prevLevel) <= tolerance
isEqualHigh := true
peakIndex := i
break
if isEqualHigh and peakIndex >= 0
array.set(resistanceCounts, peakIndex, array.get(resistanceCounts, peakIndex) + 1)
if array.get(resistanceCounts, peakIndex) == requiredPeaks
hasDoubleTop := true
doubleTopLevel := prevLevel
else
array.push(resistanceLevels, swingHigh)
array.push(resistanceCounts, 1)
line newResLine = line.new(bar_index - rightBars, swingHigh, bar_index, swingHigh, color=color.red, width=2, extend=extend.right)
array.push(resLines, newResLine)
if not na(swingLow) and time >= todayStart
bool isEqualLow = false
int peakIndex = -1
float prevLevel = na
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
prevLevel := array.get(supportLevels, i)
if math.abs(swingLow - prevLevel) <= tolerance
isEqualLow := true
peakIndex := i
break
if isEqualLow and peakIndex >= 0
array.set(supportCounts, peakIndex, array.get(supportCounts, peakIndex) + 1)
if array.get(supportCounts, peakIndex) == requiredPeaks
hasDoubleBottom := true
doubleBottomLevel := prevLevel
else
array.push(supportLevels, swingLow)
array.push(supportCounts, 1)
line newSupLine = line.new(bar_index - rightBars, swingLow, bar_index, swingLow, color=color.green, width=2, extend=extend.right)
array.push(supLines, newSupLine)
// Monitor and remove broken levels/lines; reset pattern if the equal level breaks
if array.size(resistanceLevels) > 0
for i = array.size(resistanceLevels) - 1 to 0
float level = array.get(resistanceLevels, i)
if close > level
line.delete(array.get(resLines, i))
array.remove(resLines, i)
array.remove(resistanceLevels, i)
array.remove(resistanceCounts, i)
if level == doubleTopLevel
hasDoubleTop := false
doubleTopLevel := na
if array.size(supportLevels) > 0
for i = array.size(supportLevels) - 1 to 0
float level = array.get(supportLevels, i)
if close < level
line.delete(array.get(supLines, i))
array.remove(supLines, i)
array.remove(supportLevels, i)
array.remove(supportCounts, i)
if level == doubleBottomLevel
hasDoubleBottom := false
doubleBottomLevel := na
// Limit arrays (after removals)
if array.size(resistanceLevels) > 10
line oldLine = array.shift(resLines)
line.delete(oldLine)
array.shift(resistanceLevels)
array.shift(resistanceCounts)
if array.size(supportLevels) > 10
line oldLine = array.shift(supLines)
line.delete(oldLine)
array.shift(supportLevels)
array.shift(supportCounts)
// Pattern Signal: 1 only if the exact required number of peaks is met
patternSignal = (hasDoubleTop or hasDoubleBottom) and (array.size(resistanceCounts) > 0 and array.get(resistanceCounts, array.size(resistanceCounts) - 1) == requiredPeaks or array.size(supportCounts) > 0 and array.get(supportCounts, array.size(supportCounts) - 1) == requiredPeaks) ? 1 : 0
// New: Nearest Double Level Price
var float nearestDoubleLevel = na
if hasDoubleTop and not na(doubleTopLevel)
nearestDoubleLevel := doubleTopLevel
if hasDoubleBottom and not na(doubleBottomLevel)
nearestDoubleLevel := na(nearestDoubleLevel) ? doubleBottomLevel : (math.abs(close - doubleBottomLevel) < math.abs(close - nearestDoubleLevel) ? doubleBottomLevel : nearestDoubleLevel)
// New: Distance to Nearest Level (using ATR for normalization)
var float atr = ta.atr(atrLength)
var float distanceNormalizedATR = na
if not na(nearestDoubleLevel) and not na(atr) and atr > 0
distanceNormalizedATR := math.abs(close - nearestDoubleLevel) / atr
// Optional Bounce Signal (for reference)
bounceSignal = 0
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
float level = array.get(resistanceLevels, i)
if low <= level and high >= level and close < level
bounceSignal := 1
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
float level = array.get(supportLevels, i)
if high >= level and low <= level and close > level
bounceSignal := 1
// Outputs
plot(patternSignal, title="Pattern Signal", color=patternSignal == 1 ? color.purple : na, style=plot.style_circles)
plot(bounceSignal, title="Bounce Signal", color=bounceSignal == 1 ? color.yellow : na, style=plot.style_circles)
plot(nearestDoubleLevel, title="Nearest Double Level Price", color=color.orange)
plot(distanceNormalizedATR, title="Normalized Distance (ATR)", color=color.green)
bgcolor(patternSignal == 1 ? color.new(color.purple, 80) : na)
if patternSignal == 1 and barstate.isconfirmed
alert("Double Pattern detected on " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)
if barstate.islast
var table infoTable = table.new(position.top_right, 1, 4, bgcolor=color.new(color.black, 50))
table.cell(infoTable, 0, 0, "Pattern: " + str.tostring(patternSignal), bgcolor=patternSignal == 1 ? color.purple : color.gray)
table.cell(infoTable, 0, 1, "Bounce: " + str.tostring(bounceSignal), bgcolor=bounceSignal == 1 ? color.yellow : color.gray)
table.cell(infoTable, 0, 2, "Level: " + str.tostring(nearestDoubleLevel, "#.##"), bgcolor=color.orange)
table.cell(infoTable, 0, 3, "ATR Dist: " + str.tostring(distanceNormalizedATR, "#.##"), bgcolor=color.green)
Highlight Selected WeekdaysThis indicator allows you to highlight selected trading days of the week directly on the chart with customizable colors.
Features:
Choose which weekdays to highlight (Sunday through Saturday).
Assign a different background color to each selected day.
Option to calculate the weekday based on the daily close or the active bar’s time.
Double Top/Bottom Screener 3-5 peaks //@version=6
indicator("Double Top/Bottom Screener", overlay=true, max_lines_count=500)
// Inputs
leftBars = input.int(5, "Left Bars")
rightBars = input.int(5, "Right Bars")
tolerance = input.float(0.02, "Max Difference (e.g., 0.02 for 2 cents)", step=0.01)
atrLength = input.int(14, "ATR Length for Normalized Distance", minval=1)
maxPeaks = input.int(5, "Max Identical Peaks", minval=2, maxval=5)
// Declarations of persistent variables and arrays
var array resistanceLevels = array.new(0)
var array resistanceCounts = array.new(0)
var array supportLevels = array.new(0)
var array supportCounts = array.new(0)
var array resLines = array.new(0)
var array supLines = array.new(0)
var bool hasDoubleTop = false
var bool hasDoubleBottom = false
var float doubleTopLevel = na
var float doubleBottomLevel = na
var int todayStart = na
var bool isNewDay = false
// Step 1: Identify Swing Highs/Lows
swingHigh = ta.pivothigh(high, leftBars, rightBars)
swingLow = ta.pivotlow(low, leftBars, rightBars)
// Today's premarket start (04:00 AM ET)
if dayofmonth != dayofmonth
todayStart := timestamp(syminfo.timezone, year, month, dayofmonth, 4, 0, 0)
isNewDay := true
else
isNewDay := false
// Clear arrays and reset flags only once at premarket start
if isNewDay and time >= todayStart
array.clear(resistanceLevels)
array.clear(supportLevels)
array.clear(resistanceCounts)
array.clear(supportCounts)
array.clear(resLines)
array.clear(supLines)
hasDoubleTop := false
hasDoubleBottom := false
doubleTopLevel := na
doubleBottomLevel := na
// Add new swings and check for identical peaks
if not na(swingHigh) and time >= todayStart
bool isEqualHigh = false
int peakIndex = -1
float prevLevel = na // Declare prevLevel with initial value
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
prevLevel := array.get(resistanceLevels, i)
if math.abs(swingHigh - prevLevel) <= tolerance
isEqualHigh := true
peakIndex := i
break
if isEqualHigh and peakIndex >= 0
array.set(resistanceCounts, peakIndex, array.get(resistanceCounts, peakIndex) + 1)
if array.get(resistanceCounts, peakIndex) >= maxPeaks
hasDoubleTop := true
doubleTopLevel := prevLevel
else
array.push(resistanceLevels, swingHigh)
array.push(resistanceCounts, 1)
line newResLine = line.new(bar_index - rightBars, swingHigh, bar_index, swingHigh, color=color.red, width=2, extend=extend.right)
array.push(resLines, newResLine)
if not na(swingLow) and time >= todayStart
bool isEqualLow = false
int peakIndex = -1
float prevLevel = na // Declare prevLevel with initial value
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
prevLevel := array.get(supportLevels, i)
if math.abs(swingLow - prevLevel) <= tolerance
isEqualLow := true
peakIndex := i
break
if isEqualLow and peakIndex >= 0
array.set(supportCounts, peakIndex, array.get(supportCounts, peakIndex) + 1)
if array.get(supportCounts, peakIndex) >= maxPeaks
hasDoubleBottom := true
doubleBottomLevel := prevLevel
else
array.push(supportLevels, swingLow)
array.push(supportCounts, 1)
line newSupLine = line.new(bar_index - rightBars, swingLow, bar_index, swingLow, color=color.green, width=2, extend=extend.right)
array.push(supLines, newSupLine)
// Monitor and remove broken levels/lines; reset pattern if the equal level breaks
if array.size(resistanceLevels) > 0
for i = array.size(resistanceLevels) - 1 to 0
float level = array.get(resistanceLevels, i)
if close > level
line.delete(array.get(resLines, i))
array.remove(resLines, i)
array.remove(resistanceLevels, i)
array.remove(resistanceCounts, i)
if level == doubleTopLevel
hasDoubleTop := false
doubleTopLevel := na
if array.size(supportLevels) > 0
for i = array.size(supportLevels) - 1 to 0
float level = array.get(supportLevels, i)
if close < level
line.delete(array.get(supLines, i))
array.remove(supLines, i)
array.remove(supportLevels, i)
array.remove(supportCounts, i)
if level == doubleBottomLevel
hasDoubleBottom := false
doubleBottomLevel := na
// Limit arrays (after removals)
if array.size(resistanceLevels) > 10
line oldLine = array.shift(resLines)
line.delete(oldLine)
array.shift(resistanceLevels)
array.shift(resistanceCounts)
if array.size(supportLevels) > 10
line oldLine = array.shift(supLines)
line.delete(oldLine)
array.shift(supportLevels)
array.shift(supportCounts)
// Pattern Signal: 1 if any pattern with maxPeaks is active and unbroken
patternSignal = (hasDoubleTop or hasDoubleBottom) ? 1 : 0
// New: Nearest Double Level Price
var float nearestDoubleLevel = na
if hasDoubleTop and not na(doubleTopLevel)
nearestDoubleLevel := doubleTopLevel
if hasDoubleBottom and not na(doubleBottomLevel)
nearestDoubleLevel := na(nearestDoubleLevel) ? doubleBottomLevel : (math.abs(close - doubleBottomLevel) < math.abs(close - nearestDoubleLevel) ? doubleBottomLevel : nearestDoubleLevel)
// New: Distance to Nearest Level (using ATR for normalization)
var float atr = ta.atr(atrLength)
var float distanceNormalizedATR = na
if not na(nearestDoubleLevel) and not na(atr) and atr > 0
distanceNormalizedATR := math.abs(close - nearestDoubleLevel) / atr
// Optional Bounce Signal (for reference)
bounceSignal = 0
if array.size(resistanceLevels) > 0
for i = 0 to array.size(resistanceLevels) - 1
float level = array.get(resistanceLevels, i)
if low <= level and high >= level and close < level
bounceSignal := 1
if array.size(supportLevels) > 0
for i = 0 to array.size(supportLevels) - 1
float level = array.get(supportLevels, i)
if high >= level and low <= level and close > level
bounceSignal := 1
// Outputs
plot(patternSignal, title="Pattern Signal", color=patternSignal == 1 ? color.purple : na, style=plot.style_circles)
plot(bounceSignal, title="Bounce Signal", color=bounceSignal == 1 ? color.yellow : na, style=plot.style_circles)
plot(nearestDoubleLevel, title="Nearest Double Level Price", color=color.orange)
plot(distanceNormalizedATR, title="Normalized Distance (ATR)", color=color.green)
bgcolor(patternSignal == 1 ? color.new(color.purple, 80) : na)
if patternSignal == 1 and barstate.isconfirmed
alert("Double Pattern detected on " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)
if barstate.islast
var table infoTable = table.new(position.top_right, 1, 4, bgcolor=color.new(color.black, 50))
table.cell(infoTable, 0, 0, "Pattern: " + str.tostring(patternSignal), bgcolor=patternSignal == 1 ? color.purple : color.gray)
table.cell(infoTable, 0, 1, "Bounce: " + str.tostring(bounceSignal), bgcolor=bounceSignal == 1 ? color.yellow : color.gray)
table.cell(infoTable, 0, 2, "Level: " + str.tostring(nearestDoubleLevel, "#.##"), bgcolor=color.orange)
table.cell(infoTable, 0, 3, "ATR Dist: " + str.tostring(distanceNormalizedATR, "#.##"), bgcolor=color.green)
Anchored VWAP (Triple) MYRAXESAnchored VWAP Triple Indicator
The Anchored VWAP Triple indicator is a powerful tool for technical analysis, allowing traders to plot three customizable anchored Volume Weighted Average Price (VWAP) lines on a chart. Unlike traditional VWAP, which resets daily, this indicator lets you anchor each VWAP to a specific date and time, providing a unique perspective on price action relative to key market events.
Features
Three Independent VWAPs: Plot up to three VWAP lines, each anchored to a user-defined date and time.
Customizable Inputs: Set the year, month, day, hour, and minute for each VWAP anchor point. Choose distinct colors for easy identification.
Pure Anchored Design: VWAP lines start only from the anchor point, with no pre-anchor extensions, ensuring a clean and focused analysis.
Debug Mode: Optional display of hour and minute for troubleshooting or educational purposes.
Default Settings: Pre-configured with practical defaults (e.g., September 2025 dates) for immediate use.
How to Use
Add the indicator to your TradingView chart.
Adjust the anchor dates and times for each VWAP (VWAP 1, VWAP 2, VWAP 3) via the input settings.
Select custom colors for each VWAP line to differentiate them on the chart.
Enable Debug Mode if needed to verify time alignment.
Analyze price movements relative to the anchored VWAPs to identify support, resistance, or trend shifts.
Benefits
Ideal for swing traders and long-term analysts who need to anchor VWAP to significant price levels or events.
Enhances decision-making by comparing multiple VWAPs from different anchor points.
Fully compatible with TradingView’s Pine Script v6 for smooth performance.
This indicator is perfect for traders looking to deepen their market analysis with a flexible, multi-VWAP approach. Share your feedback or custom setups in the comments!
PubLibPivotLibrary "PubLibPivot"
Pivot detection library for harmonic pattern analysis - Fractal and ZigZag methods with validation and utility functions
fractalPivotHigh(depth)
Fractal pivot high condition
Parameters:
depth (int)
Returns: bool
fractalPivotLow(depth)
Fractal pivot low condition
Parameters:
depth (int)
Returns: bool
fractalPivotHighPrice(depth, occurrence)
Get fractal pivot high price
Parameters:
depth (int)
occurrence (simple int)
Returns: float
fractalPivotLowPrice(depth, occurrence)
Get fractal pivot low price
Parameters:
depth (int)
occurrence (simple int)
Returns: float
fractalPivotHighBarIndex(depth, occurrence)
Get fractal pivot high bar index
Parameters:
depth (int)
occurrence (simple int)
Returns: int
fractalPivotLowBarIndex(depth, occurrence)
Get fractal pivot low bar index
Parameters:
depth (int)
occurrence (simple int)
Returns: int
zigzagPivotHigh(deviation, backstep, useATR, atrLength)
ZigZag pivot high condition
Parameters:
deviation (float)
backstep (int)
useATR (bool)
atrLength (simple int)
Returns: bool
zigzagPivotLow(deviation, backstep, useATR, atrLength)
ZigZag pivot low condition
Parameters:
deviation (float)
backstep (int)
useATR (bool)
atrLength (simple int)
Returns: bool
zigzagPivotHighPrice(deviation, backstep, useATR, atrLength, occurrence)
Get ZigZag pivot high price
Parameters:
deviation (float)
backstep (int)
useATR (bool)
atrLength (simple int)
occurrence (simple int)
Returns: float
zigzagPivotLowPrice(deviation, backstep, useATR, atrLength, occurrence)
Get ZigZag pivot low price
Parameters:
deviation (float)
backstep (int)
useATR (bool)
atrLength (simple int)
occurrence (simple int)
Returns: float
zigzagPivotHighBarIndex(deviation, backstep, useATR, atrLength, occurrence)
Get ZigZag pivot high bar index
Parameters:
deviation (float)
backstep (int)
useATR (bool)
atrLength (simple int)
occurrence (simple int)
Returns: int
zigzagPivotLowBarIndex(deviation, backstep, useATR, atrLength, occurrence)
Get ZigZag pivot low bar index
Parameters:
deviation (float)
backstep (int)
useATR (bool)
atrLength (simple int)
occurrence (simple int)
Returns: int
isValidPivotVolume(pivotPrice, pivotBarIndex, minVolumeRatio, volumeLength)
Validate pivot quality based on volume
Parameters:
pivotPrice (float)
pivotBarIndex (int)
minVolumeRatio (float)
volumeLength (int)
Returns: bool
isValidPivotATR(pivotPrice, lastPivotPrice, minATRMultiplier, atrLength)
Validate pivot based on minimum ATR movement
Parameters:
pivotPrice (float)
lastPivotPrice (float)
minATRMultiplier (float)
atrLength (simple int)
Returns: bool
isValidPivotTime(pivotBarIndex, lastPivotBarIndex, minBars)
Validate pivot based on minimum time between pivots
Parameters:
pivotBarIndex (int)
lastPivotBarIndex (int)
minBars (int)
Returns: bool
isPivotConfirmed(pivotBarIndex, depth)
Check if pivot is not repainting (confirmed)
Parameters:
pivotBarIndex (int)
depth (int)
Returns: bool
addPivotToArray(pivotArray, barArray, pivotPrice, pivotBarIndex, maxSize)
Add pivot to array with validation
Parameters:
pivotArray (array)
barArray (array)
pivotPrice (float)
pivotBarIndex (int)
maxSize (int)
Returns: array - updated pivot array
getPivotFromArray(pivotArray, barArray, index)
Get pivot from array by index
Parameters:
pivotArray (array)
barArray (array)
index (int)
Returns: tuple - (price, bar_index)
getPivotsInRange(pivotArray, barArray, startIndex, count)
Get all pivots in range
Parameters:
pivotArray (array)
barArray (array)
startIndex (int)
count (int)
Returns: tuple, array> - (prices, bar_indices)
pivotDistance(barIndex1, barIndex2)
Calculate distance between two pivots in bars
Parameters:
barIndex1 (int)
barIndex2 (int)
Returns: int - distance in bars
pivotPriceRatio(price1, price2)
Calculate price ratio between two pivots
Parameters:
price1 (float)
price2 (float)
Returns: float - price ratio
pivotRetracementRatio(startPrice, endPrice, currentPrice)
Calculate retracement ratio
Parameters:
startPrice (float)
endPrice (float)
currentPrice (float)
Returns: float - retracement ratio (0-1)
pivotExtensionRatio(startPrice, endPrice, currentPrice)
Calculate extension ratio
Parameters:
startPrice (float)
endPrice (float)
currentPrice (float)
Returns: float - extension ratio (>1 for extension)
isInFibZone(startPrice, endPrice, currentPrice, fibLevel, tolerance)
Check if price is in Fibonacci retracement zone
Parameters:
startPrice (float)
endPrice (float)
currentPrice (float)
fibLevel (float)
tolerance (float)
Returns: bool - true if in zone
getPivotType(pivotPrice, pivotBarIndex, lookback)
Get pivot type (high/low) based on surrounding prices
Parameters:
pivotPrice (float)
pivotBarIndex (int)
lookback (int)
Returns: string - "high", "low", or "unknown"
calculatePivotStrength(pivotPrice, pivotBarIndex, lookback)
Calculate pivot strength based on volume and price action
Parameters:
pivotPrice (float)
pivotBarIndex (int)
lookback (int)
Returns: float - strength score (0-100)