Add all project files

This commit is contained in:
2025-08-02 01:54:08 +00:00
parent 26cf6efef3
commit bbdaee1d1a

684
auto_trendlines.pine Normal file
View File

@@ -0,0 +1,684 @@
//@version=5
indicator("Auto Trend Lines - Long Period", overlay=true, max_lines_count=500)
// Input parameters
lookback_period = input.int(50, "Lookback Period for Pivot Detection", minval=10, maxval=200)
min_touches = input.int(2, "Minimum Touches for Valid Trend Line", minval=2, maxval=5)
max_lines = input.int(20, "Maximum Number of Trend Lines", minval=5, maxval=50)
max_bars_back = input.int(500, "Maximum Bars Back for Lines", minval=100, maxval=2000)
merge_similar_lines = input.bool(true, "Merge Similar Lines")
slope_tolerance = input.float(0.1, "Slope Tolerance for Merging (%)", minval=0.01, maxval=1.0)
price_tolerance = input.float(0.5, "Price Tolerance for Merging (%)", minval=0.1, maxval=2.0)
line_extend = input.string("right", "Line Extension", options=["none", "left", "right", "both"])
show_support = input.bool(true, "Show Support Lines")
show_resistance = input.bool(true, "Show Resistance Lines")
// Enhanced K-line features
show_close_based_lines = input.bool(true, "Show Close-Based Trend Lines (Thick)")
show_wick_based_lines = input.bool(true, "Show Wick-Based Trend Lines (Thin)")
show_current_hl = input.bool(true, "Show Current Bar High/Low Points")
// Volume filtering
use_volume_filter = input.bool(true, "Enable Volume Filtering")
volume_threshold_multiplier = input.float(1.5, "Volume Threshold Multiplier", minval=0.5, maxval=5.0)
volume_lookback = input.int(20, "Volume Average Lookback", minval=5, maxval=100)
// Line styling
support_color = input.color(color.green, "Support Line Color")
resistance_color = input.color(color.red, "Resistance Line Color")
close_support_color = input.color(color.lime, "Close-Based Support Color")
close_resistance_color = input.color(color.maroon, "Close-Based Resistance Color")
thin_line_width = input.int(2, "Thin Line Width (Wick-Based)", minval=1, maxval=5)
thick_line_width = input.int(5, "Thick Line Width (Close-Based)", minval=3, maxval=15)
line_style = input.string("solid", "Line Style", options=["solid", "dashed", "dotted"])
current_hl_color = input.color(color.yellow, "Current High/Low Point Color")
// Convert line style
get_line_style() =>
switch line_style
"solid" => line.style_solid
"dashed" => line.style_dashed
"dotted" => line.style_dotted
=> line.style_solid
// Pivot detection
pivot_high = ta.pivothigh(high, lookback_period, lookback_period)
pivot_low = ta.pivotlow(low, lookback_period, lookback_period)
// Arrays to store pivot points with time
var array<float> high_prices = array.new<float>()
var array<int> high_bars = array.new<int>()
var array<int> high_times = array.new<int>()
var array<float> low_prices = array.new<float>()
var array<int> low_bars = array.new<int>()
var array<int> low_times = array.new<int>()
// Arrays to store close-based pivot points
var array<float> high_close_prices = array.new<float>()
var array<int> high_close_bars = array.new<int>()
var array<float> low_close_prices = array.new<float>()
var array<int> low_close_bars = array.new<int>()
// Arrays to store volume data for pivots
var array<float> high_volumes = array.new<float>()
var array<float> low_volumes = array.new<float>()
var array<float> high_close_volumes = array.new<float>()
var array<float> low_close_volumes = array.new<float>()
// Calculate volume average for filtering
volume_avg = ta.sma(volume, volume_lookback)
// Store pivot points (high/low based) with volume data
if not na(pivot_high)
pivot_bar = bar_index - lookback_period
pivot_time = math.round(time[lookback_period])
pivot_volume = volume[lookback_period]
// Only store if within reasonable distance
if bar_index - pivot_bar <= max_bars_back
array.push(high_prices, pivot_high)
array.push(high_bars, pivot_bar)
array.push(high_times, pivot_time)
array.push(high_volumes, pivot_volume)
// Keep only recent pivots to manage memory
if array.size(high_prices) > 50
array.shift(high_prices)
array.shift(high_bars)
array.shift(high_times)
array.shift(high_volumes)
if not na(pivot_low)
pivot_bar = bar_index - lookback_period
pivot_time = math.round(time[lookback_period])
pivot_volume = volume[lookback_period]
// Only store if within reasonable distance
if bar_index - pivot_bar <= max_bars_back
array.push(low_prices, pivot_low)
array.push(low_bars, pivot_bar)
array.push(low_times, pivot_time)
array.push(low_volumes, pivot_volume)
// Keep only recent pivots to manage memory
if array.size(low_prices) > 50
array.shift(low_prices)
array.shift(low_bars)
array.shift(low_times)
array.shift(low_volumes)
// Store close-based pivot points (always calculate for close-based trend lines) with volume data
pivot_high_close = ta.pivothigh(close, lookback_period, lookback_period)
pivot_low_close = ta.pivotlow(close, lookback_period, lookback_period)
if not na(pivot_high_close)
pivot_bar = bar_index - lookback_period
pivot_volume = volume[lookback_period]
if bar_index - pivot_bar <= max_bars_back
array.push(high_close_prices, pivot_high_close)
array.push(high_close_bars, pivot_bar)
array.push(high_close_volumes, pivot_volume)
if array.size(high_close_prices) > 50
array.shift(high_close_prices)
array.shift(high_close_bars)
array.shift(high_close_volumes)
if not na(pivot_low_close)
pivot_bar = bar_index - lookback_period
pivot_volume = volume[lookback_period]
if bar_index - pivot_bar <= max_bars_back
array.push(low_close_prices, pivot_low_close)
array.push(low_close_bars, pivot_bar)
array.push(low_close_volumes, pivot_volume)
if array.size(low_close_prices) > 50
array.shift(low_close_prices)
array.shift(low_close_bars)
array.shift(low_close_volumes)
// Function to calculate line slope and y-intercept
get_line_params(x1, y1, x2, y2) =>
slope = (y2 - y1) / (x2 - x1)
intercept = y1 - slope * x1
[slope, intercept]
// Function to get y value at given x using line equation
get_y_at_x(slope, intercept, x) =>
slope * x + intercept
// Structure to store trend line data
type TrendLineData
float slope
float intercept
int bar1
float price1
int bar2
float price2
int touches
bool is_resistance
// Function to check if two lines are similar and should be merged
lines_are_similar(line1, line2, slope_tol, price_tol) =>
// Check slope similarity
slope_diff = math.abs(line1.slope - line2.slope)
avg_slope = (math.abs(line1.slope) + math.abs(line2.slope)) / 2
slope_similar = avg_slope == 0 ? slope_diff < 0.001 : (slope_diff / avg_slope) < (slope_tol / 100)
// Check price level similarity at a common point
mid_bar = math.round((line1.bar1 + line1.bar2 + line2.bar1 + line2.bar2) / 4)
price1_at_mid = get_y_at_x(line1.slope, line1.intercept, mid_bar)
price2_at_mid = get_y_at_x(line2.slope, line2.intercept, mid_bar)
price_diff = math.abs(price1_at_mid - price2_at_mid)
avg_price = (price1_at_mid + price2_at_mid) / 2
price_similar = (price_diff / avg_price) < (price_tol / 100)
slope_similar and price_similar
// Function to merge two similar trend lines
merge_lines(line1, line2) =>
// Choose the line with more touches, or the longer one
if line1.touches > line2.touches
line1
else if line2.touches > line1.touches
line2
else
// If same touches, choose the longer line
length1 = math.abs(line1.bar2 - line1.bar1)
length2 = math.abs(line2.bar2 - line2.bar1)
length1 >= length2 ? line1 : line2
// Function to check if pivot has sufficient volume
has_sufficient_volume(pivot_volume, avg_volume) =>
not use_volume_filter or pivot_volume >= (avg_volume * volume_threshold_multiplier)
// Function to count touches for wick-based trend lines with volume filtering
count_wick_touches(slope, intercept, start_bar, end_bar, is_resistance, tolerance_pct = 0.5) =>
touches = 0
current_bar = bar_index
pivot_prices = is_resistance ? high_prices : low_prices
pivot_bars_array = is_resistance ? high_bars : low_bars
pivot_volumes_array = is_resistance ? high_volumes : low_volumes
if array.size(pivot_prices) > 0
for i = 0 to array.size(pivot_prices) - 1
bar_idx = array.get(pivot_bars_array, i)
price = array.get(pivot_prices, i)
pivot_volume = array.get(pivot_volumes_array, i)
if bar_idx >= start_bar and bar_idx <= end_bar and (current_bar - bar_idx) <= max_bars_back
// Check volume filter
if has_sufficient_volume(pivot_volume, volume_avg)
expected_price = get_y_at_x(slope, intercept, bar_idx)
tolerance = expected_price * tolerance_pct / 100
if is_resistance
if math.abs(price - expected_price) <= tolerance and price >= expected_price - tolerance
touches += 1
else
if math.abs(price - expected_price) <= tolerance and price <= expected_price + tolerance
touches += 1
touches
// Function to count touches for close-based trend lines with volume filtering
count_close_touches(slope, intercept, start_bar, end_bar, is_resistance, tolerance_pct = 0.5) =>
touches = 0
current_bar = bar_index
close_prices = is_resistance ? high_close_prices : low_close_prices
close_bars_array = is_resistance ? high_close_bars : low_close_bars
close_volumes_array = is_resistance ? high_close_volumes : low_close_volumes
if array.size(close_prices) > 0
for i = 0 to array.size(close_prices) - 1
bar_idx = array.get(close_bars_array, i)
price = array.get(close_prices, i)
pivot_volume = array.get(close_volumes_array, i)
if bar_idx >= start_bar and bar_idx <= end_bar and (current_bar - bar_idx) <= max_bars_back
// Check volume filter
if has_sufficient_volume(pivot_volume, volume_avg)
expected_price = get_y_at_x(slope, intercept, bar_idx)
tolerance = expected_price * tolerance_pct / 100
if is_resistance
if math.abs(price - expected_price) <= tolerance and price >= expected_price - tolerance
touches += 1
else
if math.abs(price - expected_price) <= tolerance and price <= expected_price + tolerance
touches += 1
touches
// Function to draw trend lines
draw_trend_lines() =>
var array<line> wick_resistance_lines = array.new<line>()
var array<line> wick_support_lines = array.new<line>()
var array<line> close_resistance_lines = array.new<line>()
var array<line> close_support_lines = array.new<line>()
// Clear old lines
for line_obj in wick_resistance_lines
line.delete(line_obj)
for line_obj in wick_support_lines
line.delete(line_obj)
for line_obj in close_resistance_lines
line.delete(line_obj)
for line_obj in close_support_lines
line.delete(line_obj)
array.clear(wick_resistance_lines)
array.clear(wick_support_lines)
array.clear(close_resistance_lines)
array.clear(close_support_lines)
current_bar = bar_index
// Arrays to store trend line candidates
var array<TrendLineData> wick_resistance_candidates = array.new<TrendLineData>()
var array<TrendLineData> wick_support_candidates = array.new<TrendLineData>()
var array<TrendLineData> close_resistance_candidates = array.new<TrendLineData>()
var array<TrendLineData> close_support_candidates = array.new<TrendLineData>()
array.clear(wick_resistance_candidates)
array.clear(wick_support_candidates)
array.clear(close_resistance_candidates)
array.clear(close_support_candidates)
// Collect WICK-based resistance line candidates (thin lines)
if show_wick_based_lines and show_resistance and array.size(high_prices) >= 2
for i = 0 to array.size(high_prices) - 2
for j = i + 1 to array.size(high_prices) - 1
bar1 = array.get(high_bars, i)
price1 = array.get(high_prices, i)
volume1 = array.get(high_volumes, i)
bar2 = array.get(high_bars, j)
price2 = array.get(high_prices, j)
volume2 = array.get(high_volumes, j)
if bar2 - bar1 < lookback_period or (current_bar - bar1) > max_bars_back or (current_bar - bar2) > max_bars_back
continue
// Apply volume filter to both pivot points
if use_volume_filter and (not has_sufficient_volume(volume1, volume_avg) or not has_sufficient_volume(volume2, volume_avg))
continue
[slope, intercept] = get_line_params(bar1, price1, bar2, price2)
touches = count_wick_touches(slope, intercept, bar1, current_bar, true)
if touches >= min_touches
trend_line = TrendLineData.new(slope, intercept, bar1, price1, bar2, price2, touches, true)
array.push(wick_resistance_candidates, trend_line)
// Collect CLOSE-based resistance line candidates (thick lines)
if show_close_based_lines and show_resistance and array.size(high_close_prices) >= 2
for i = 0 to array.size(high_close_prices) - 2
for j = i + 1 to array.size(high_close_prices) - 1
bar1 = array.get(high_close_bars, i)
price1 = array.get(high_close_prices, i)
volume1 = array.get(high_close_volumes, i)
bar2 = array.get(high_close_bars, j)
price2 = array.get(high_close_prices, j)
volume2 = array.get(high_close_volumes, j)
if bar2 - bar1 < lookback_period or (current_bar - bar1) > max_bars_back or (current_bar - bar2) > max_bars_back
continue
// Apply volume filter to both pivot points
if use_volume_filter and (not has_sufficient_volume(volume1, volume_avg) or not has_sufficient_volume(volume2, volume_avg))
continue
[slope, intercept] = get_line_params(bar1, price1, bar2, price2)
touches = count_close_touches(slope, intercept, bar1, current_bar, true)
if touches >= min_touches
trend_line = TrendLineData.new(slope, intercept, bar1, price1, bar2, price2, touches, true)
array.push(close_resistance_candidates, trend_line)
// Collect WICK-based support line candidates (thin lines)
if show_wick_based_lines and show_support and array.size(low_prices) >= 2
for i = 0 to array.size(low_prices) - 2
for j = i + 1 to array.size(low_prices) - 1
bar1 = array.get(low_bars, i)
price1 = array.get(low_prices, i)
volume1 = array.get(low_volumes, i)
bar2 = array.get(low_bars, j)
price2 = array.get(low_prices, j)
volume2 = array.get(low_volumes, j)
if bar2 - bar1 < lookback_period or (current_bar - bar1) > max_bars_back or (current_bar - bar2) > max_bars_back
continue
// Apply volume filter to both pivot points
if use_volume_filter and (not has_sufficient_volume(volume1, volume_avg) or not has_sufficient_volume(volume2, volume_avg))
continue
[slope, intercept] = get_line_params(bar1, price1, bar2, price2)
touches = count_wick_touches(slope, intercept, bar1, current_bar, false)
if touches >= min_touches
trend_line = TrendLineData.new(slope, intercept, bar1, price1, bar2, price2, touches, false)
array.push(wick_support_candidates, trend_line)
// Collect CLOSE-based support line candidates (thick lines)
if show_close_based_lines and show_support and array.size(low_close_prices) >= 2
for i = 0 to array.size(low_close_prices) - 2
for j = i + 1 to array.size(low_close_prices) - 1
bar1 = array.get(low_close_bars, i)
price1 = array.get(low_close_prices, i)
volume1 = array.get(low_close_volumes, i)
bar2 = array.get(low_close_bars, j)
price2 = array.get(low_close_prices, j)
volume2 = array.get(low_close_volumes, j)
if bar2 - bar1 < lookback_period or (current_bar - bar1) > max_bars_back or (current_bar - bar2) > max_bars_back
continue
// Apply volume filter to both pivot points
if use_volume_filter and (not has_sufficient_volume(volume1, volume_avg) or not has_sufficient_volume(volume2, volume_avg))
continue
[slope, intercept] = get_line_params(bar1, price1, bar2, price2)
touches = count_close_touches(slope, intercept, bar1, current_bar, false)
if touches >= min_touches
trend_line = TrendLineData.new(slope, intercept, bar1, price1, bar2, price2, touches, false)
array.push(close_support_candidates, trend_line)
// Process and draw lines separately for wick-based and close-based
if merge_similar_lines
// Process WICK-based resistance lines (thin)
if array.size(wick_resistance_candidates) > 0
merged_wick_resistance = array.new<TrendLineData>()
for i = 0 to array.size(wick_resistance_candidates) - 1
current_line = array.get(wick_resistance_candidates, i)
should_merge = false
if array.size(merged_wick_resistance) > 0
for j = 0 to array.size(merged_wick_resistance) - 1
existing_line = array.get(merged_wick_resistance, j)
if lines_are_similar(current_line, existing_line, slope_tolerance, price_tolerance)
merged_line = merge_lines(current_line, existing_line)
array.set(merged_wick_resistance, j, merged_line)
should_merge := true
break
if not should_merge
array.push(merged_wick_resistance, current_line)
// Draw wick-based resistance lines (thin)
lines_drawn = 0
if array.size(merged_wick_resistance) > 0
for i = 0 to array.size(merged_wick_resistance) - 1
if lines_drawn >= max_lines
break
trend_line = array.get(merged_wick_resistance, i)
extend_type = switch line_extend
"left" => extend.left
"right" => extend.right
"both" => extend.both
=> extend.none
line_obj = line.new(trend_line.bar1, trend_line.price1, trend_line.bar2, trend_line.price2,
color=resistance_color,
width=thin_line_width,
style=get_line_style(),
extend=extend_type)
array.push(wick_resistance_lines, line_obj)
lines_drawn += 1
// Process CLOSE-based resistance lines (thick)
if array.size(close_resistance_candidates) > 0
merged_close_resistance = array.new<TrendLineData>()
for i = 0 to array.size(close_resistance_candidates) - 1
current_line = array.get(close_resistance_candidates, i)
should_merge = false
if array.size(merged_close_resistance) > 0
for j = 0 to array.size(merged_close_resistance) - 1
existing_line = array.get(merged_close_resistance, j)
if lines_are_similar(current_line, existing_line, slope_tolerance, price_tolerance)
merged_line = merge_lines(current_line, existing_line)
array.set(merged_close_resistance, j, merged_line)
should_merge := true
break
if not should_merge
array.push(merged_close_resistance, current_line)
// Draw close-based resistance lines (thick)
lines_drawn = 0
if array.size(merged_close_resistance) > 0
for i = 0 to array.size(merged_close_resistance) - 1
if lines_drawn >= max_lines
break
trend_line = array.get(merged_close_resistance, i)
extend_type = switch line_extend
"left" => extend.left
"right" => extend.right
"both" => extend.both
=> extend.none
line_obj = line.new(trend_line.bar1, trend_line.price1, trend_line.bar2, trend_line.price2,
color=close_resistance_color,
width=thick_line_width,
style=get_line_style(),
extend=extend_type)
array.push(close_resistance_lines, line_obj)
lines_drawn += 1
// Process WICK-based support lines (thin)
if array.size(wick_support_candidates) > 0
merged_wick_support = array.new<TrendLineData>()
for i = 0 to array.size(wick_support_candidates) - 1
current_line = array.get(wick_support_candidates, i)
should_merge = false
if array.size(merged_wick_support) > 0
for j = 0 to array.size(merged_wick_support) - 1
existing_line = array.get(merged_wick_support, j)
if lines_are_similar(current_line, existing_line, slope_tolerance, price_tolerance)
merged_line = merge_lines(current_line, existing_line)
array.set(merged_wick_support, j, merged_line)
should_merge := true
break
if not should_merge
array.push(merged_wick_support, current_line)
// Draw wick-based support lines (thin)
lines_drawn = 0
if array.size(merged_wick_support) > 0
for i = 0 to array.size(merged_wick_support) - 1
if lines_drawn >= max_lines
break
trend_line = array.get(merged_wick_support, i)
extend_type = switch line_extend
"left" => extend.left
"right" => extend.right
"both" => extend.both
=> extend.none
line_obj = line.new(trend_line.bar1, trend_line.price1, trend_line.bar2, trend_line.price2,
color=support_color,
width=thin_line_width,
style=get_line_style(),
extend=extend_type)
array.push(wick_support_lines, line_obj)
lines_drawn += 1
// Process CLOSE-based support lines (thick)
if array.size(close_support_candidates) > 0
merged_close_support = array.new<TrendLineData>()
for i = 0 to array.size(close_support_candidates) - 1
current_line = array.get(close_support_candidates, i)
should_merge = false
if array.size(merged_close_support) > 0
for j = 0 to array.size(merged_close_support) - 1
existing_line = array.get(merged_close_support, j)
if lines_are_similar(current_line, existing_line, slope_tolerance, price_tolerance)
merged_line = merge_lines(current_line, existing_line)
array.set(merged_close_support, j, merged_line)
should_merge := true
break
if not should_merge
array.push(merged_close_support, current_line)
// Draw close-based support lines (thick)
lines_drawn = 0
if array.size(merged_close_support) > 0
for i = 0 to array.size(merged_close_support) - 1
if lines_drawn >= max_lines
break
trend_line = array.get(merged_close_support, i)
extend_type = switch line_extend
"left" => extend.left
"right" => extend.right
"both" => extend.both
=> extend.none
line_obj = line.new(trend_line.bar1, trend_line.price1, trend_line.bar2, trend_line.price2,
color=close_support_color,
width=thick_line_width,
style=get_line_style(),
extend=extend_type)
array.push(close_support_lines, line_obj)
lines_drawn += 1
else
// Original behavior without merging - draw all valid candidates
// Draw wick-based resistance lines (thin)
lines_drawn = 0
if array.size(wick_resistance_candidates) > 0
for i = 0 to array.size(wick_resistance_candidates) - 1
if lines_drawn >= max_lines
break
trend_line = array.get(wick_resistance_candidates, i)
extend_type = switch line_extend
"left" => extend.left
"right" => extend.right
"both" => extend.both
=> extend.none
line_obj = line.new(trend_line.bar1, trend_line.price1, trend_line.bar2, trend_line.price2,
color=resistance_color,
width=thin_line_width,
style=get_line_style(),
extend=extend_type)
array.push(wick_resistance_lines, line_obj)
lines_drawn += 1
// Draw close-based resistance lines (thick)
lines_drawn := 0
if array.size(close_resistance_candidates) > 0
for i = 0 to array.size(close_resistance_candidates) - 1
if lines_drawn >= max_lines
break
trend_line = array.get(close_resistance_candidates, i)
extend_type = switch line_extend
"left" => extend.left
"right" => extend.right
"both" => extend.both
=> extend.none
line_obj = line.new(trend_line.bar1, trend_line.price1, trend_line.bar2, trend_line.price2,
color=close_resistance_color,
width=thick_line_width,
style=get_line_style(),
extend=extend_type)
array.push(close_resistance_lines, line_obj)
lines_drawn += 1
// Draw wick-based support lines (thin)
lines_drawn := 0
if array.size(wick_support_candidates) > 0
for i = 0 to array.size(wick_support_candidates) - 1
if lines_drawn >= max_lines
break
trend_line = array.get(wick_support_candidates, i)
extend_type = switch line_extend
"left" => extend.left
"right" => extend.right
"both" => extend.both
=> extend.none
line_obj = line.new(trend_line.bar1, trend_line.price1, trend_line.bar2, trend_line.price2,
color=support_color,
width=thin_line_width,
style=get_line_style(),
extend=extend_type)
array.push(wick_support_lines, line_obj)
lines_drawn += 1
// Draw close-based support lines (thick)
lines_drawn := 0
if array.size(close_support_candidates) > 0
for i = 0 to array.size(close_support_candidates) - 1
if lines_drawn >= max_lines
break
trend_line = array.get(close_support_candidates, i)
extend_type = switch line_extend
"left" => extend.left
"right" => extend.right
"both" => extend.both
=> extend.none
line_obj = line.new(trend_line.bar1, trend_line.price1, trend_line.bar2, trend_line.price2,
color=close_support_color,
width=thick_line_width,
style=get_line_style(),
extend=extend_type)
array.push(close_support_lines, line_obj)
lines_drawn += 1
// Execute trend line drawing every 10 bars to optimize performance
if bar_index % 10 == 0
draw_trend_lines()
// Show current bar high/low points
if show_current_hl
var line current_high_line = na
var line current_low_line = na
// Delete previous lines
if not na(current_high_line)
line.delete(current_high_line)
if not na(current_low_line)
line.delete(current_low_line)
// Draw current bar high/low points
current_high_line := line.new(bar_index, high, bar_index, high, color=current_hl_color, width=3, style=line.style_solid)
current_low_line := line.new(bar_index, low, bar_index, low, color=current_hl_color, width=3, style=line.style_solid)
// Plot pivot points for reference (optional)
plot_pivots = input.bool(false, "Show Pivot Points")
plotshape(plot_pivots and not na(pivot_high), style=shape.triangledown, location=location.abovebar, color=color.red, size=size.small)
plotshape(plot_pivots and not na(pivot_low), style=shape.triangleup, location=location.belowbar, color=color.green, size=size.small)
// Plot close-based pivot points (moved to global scope)
plotshape(plot_pivots and not na(pivot_high_close), style=shape.diamond, location=location.abovebar, color=color.orange, size=size.small)
plotshape(plot_pivots and not na(pivot_low_close), style=shape.diamond, location=location.belowbar, color=color.blue, size=size.small)
// Volume filtering visualization
show_volume_info = input.bool(false, "Show Volume Information")
if show_volume_info
// Plot volume threshold line
volume_threshold = volume_avg * volume_threshold_multiplier
// Create a table to show volume information
var table volume_table = table.new(position.top_right, 2, 4, bgcolor=color.white, border_width=1)
if barstate.islast
table.cell(volume_table, 0, 0, "Volume Info", text_color=color.black, text_size=size.small)
table.cell(volume_table, 1, 0, "", text_color=color.black, text_size=size.small)
table.cell(volume_table, 0, 1, "Avg Volume:", text_color=color.black, text_size=size.small)
table.cell(volume_table, 1, 1, str.tostring(math.round(volume_avg)), text_color=color.black, text_size=size.small)
table.cell(volume_table, 0, 2, "Threshold:", text_color=color.black, text_size=size.small)
table.cell(volume_table, 1, 2, str.tostring(math.round(volume_threshold)), text_color=color.black, text_size=size.small)
table.cell(volume_table, 0, 3, "Current:", text_color=color.black, text_size=size.small)
table.cell(volume_table, 1, 3, str.tostring(math.round(volume)), text_color=volume >= volume_threshold ? color.green : color.red, text_size=size.small)
// Alert conditions
resistance_break = ta.crossover(close, ta.highest(high, 5))
support_break = ta.crossunder(close, ta.lowest(low, 5))
alertcondition(resistance_break, title="Resistance Break", message="Price broke above resistance level")
alertcondition(support_break, title="Support Break", message="Price broke below support level")