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.
サイクル
30-10-3 MAX,min dynamicsSupported timeframes: The script works only on timeframes of 1 minute or lower (including second-based timeframes).
Displayed levels: The highs and lows of the last closed candle are plotted for the 30-minute, 10-minute, and 3-minute timeframes.
Updates: The levels update only when a candle closes in the respective timeframe (e.g., every 30 minutes for the 30m levels).
Visualization: Dashed lines for highs and lows (blue for 30m, green for 10m, red for 3m).
Labels indicating "Max 30m", "Min 30m", etc., positioned above the highs and below the lows.
30-10-3 MAX,min dinamici Supported timeframes: The script works only on timeframes of 1 minute or lower (including second-based timeframes).
Displayed levels: The highs and lows of the last closed candle are plotted for the 30-minute, 10-minute, and 3-minute timeframes.
Updates: The levels update only when a candle closes in the respective timeframe (e.g., every 30 minutes for the 30m levels).
Visualization: Dashed lines for highs and lows (blue for 30m, green for 10m, red for 3m).
Labels indicating "Max 30m", "Min 30m", etc., positioned above the highs and below the lows.
By Gadirov Best Big Candle Change Indicator for binary 1 minuteBy Gadirov Best Big Candle Change Indicator for binary 1 minute
by Gadirov Trend Change Strategy 9/21/50 for binaryby Gadirov Trend Change Strategy 9/21/50 for binary
Multi-Timeframe MACD Score(Customizable)this is a momentum based indicator to know the direction of the market
Double Top/Bottom Screener with ATR otential Issues in the Latest Script
Based on the code and your previous feedback, here are possible mistakes:
Syntax or Compilation Error:
The script might have a typo or incomplete logic, especially with the new nearestDoubleLevel and distanceNormalizedATR additions.
Check: The table definition in the if barstate.islast block has 4 columns defined but tries to access a 5th with table.cell(infoTable, 0, 4, ...), which causes an "index out of bounds" error. This is a clear mistake.
Distance or Level Calculation:
If "Dist: NaN%" or "Level: NaN" appears, it might indicate that doubleTopLevel or doubleBottomLevel isn’t being set correctly, possibly due to the tolerance or array logic.
Check: The ATR-normalized distance (distanceNormalizedATR) might fail if atr is na due to insufficient bars.
Screener Column Issue:
The new columns ("Nearest Double Level Price" and "Normalized Distance (ATR)") might not display or sort correctly in the Pine Screener due to plotting or naming conflicts.
LibbyThis script is a refined chopzone index script with additional functionalities.
it produce buy and sell signals as directed by chopzone
How to use:
BUY: Look for buy signal on the chart and proceed to place buy or long orders
SELL: Look for sell on the chart and proceed to place sell or short orders.
NOTE: i recommend you set alerts and make it activate on bar close to avoid fadeouts and sideways.
expect sideways market and multiple opposite signals within a short time during news or when economic data are released.
as always, no indicator is failproof, it is recommended to always pair more than 1 indicator for more clarity and practice safe trading.
Double Top/Bottom Screener with Distance. Thank you for providing the error messages! There are two issues to address based on your input:
Error: "Value with NA type cannot be assigned to a variable that was defined without type keyword"
This occurs because in Pine Script, when a variable like distanceToNearest is used without an explicit type declaration (e.g., var float distanceToNearest), assigning na directly to it can cause a type mismatch error if the variable’s type isn’t pre-defined. The fix is to either declare distanceToNearest with a type (e.g., var float) or ensure the assignment aligns with Pine Script’s typing rules.
Warning: "Version 5 of Pine Script® is outdated. We recommend using the current version, which is 6. (PINE_VERSION_OUTDATED)"
TradingView has updated to Pine Script version 6, which includes new features and improvements. While version 5 still works, upgrading to version 6 is recommended for better compatibility and future support. The transition is mostly seamless, but we’ll need to adjust the script accordingly.
HPS VariablesThis script will provide a chart with a list of the 4 HPS variables for trading TCT models.
Double Top/Bottom Screener v2How to Test and Use
On Charts:
Add to a 1min chart (e.g., reload EVAX or your 256-level stock).
Adjust inputs via the gear icon: Set "Absolute Tolerance ($)" to 0.01 (or 0.005 for stricter).
Scroll/zoom to see: Lines only on today's swings; purple signal only on true doubles (e.g., two red lines at exact 256.00). No more false positives from slight drifts.
Table now shows the active level—helps verify.
In Pine Screener:
Reload the indicator (select "Double Top/Bottom Screener v2").
Set timeframe to 1min, watchlist to your high-volume US list.
Filter: "Pattern Signal" equals 1.
Click Scan—results should drop significantly (only clean doubles). If still too many, increase "Min Bars Between" to 20+ in script inputs (rescan).
For persistence: Rescans will keep showing unbroken patterns (signal stays 1 until break).
This should match your "cent by cent" ideal—e.g., two swings at exactly 256.00 or 256.01 will trigger, but 256.02 won't. If EVAX now fails (tops not within 0.01), tweak tolerance up slightly. Test on a few charts; if issues persist, share a specific symbol/screenshot for further tweaks!
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)
Multi-Timeframe MACD Score(customizable)this is a momentum based indcator to know the direction of the market
Shadow Corp 90min Boxes90-min cycle boxes, marks 90min session highs and lows with color coded boxes.
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)
Opening Range BoxThis indicator, called the "Opening Range Box," is a visual tool that helps you track the start of key trading sessions like London and New York.
It does three main things:
Finds the Daily 'First Move': It automatically calculates the High and Low reached during the first 30 minutes (or whatever time you set) of each defined session.
Draws a Box: It immediately draws a colored, transparent box on your chart from the moment the session starts. This box acts as a clear reference for the session's initial boundaries.
Extends the Levels: After the initial 30 minutes are over, the box stops growing vertically (it locks in the OR High/Low) but continues to stretch out horizontally for the rest of the trading session. This allows you to easily see how the price reacts to the opening levels throughout the day.
In short: It visually highlights the most important price levels established at the very beginning of the major market sessions.
By Gadirov Hyper-Aggressive Multi-Timeframe Binary SignalsBy Gadirov Hyper-Aggressive Multi-Timeframe Binary Signals
By Gadirov best Aggressive Binary Signals back onlyBy Gadirov best Aggressive Binary Signals back only
Double Pattern Screener v7 //@version=6
indicator("Double Pattern Screener", shorttitle="DPS", overlay=false)
// Screener Inputs
leftBars = input.int(5, "Left Bars", minval=3, maxval=10)
rightBars = input.int(5, "Right Bars", minval=3, maxval=10)
tolerance = input.float(0.02, "Max Difference", step=0.01)
atrLength = input.int(14, "ATR Length", minval=1)
// NEW: Filter for number of equal peaks
filterPeaks = input.int(3, "Filter: Show Only X Equal Peaks", minval=2, maxval=5)
enableFilter = input.bool(true, "Enable Peak Count Filter")
// Arrays for tracking swings
var array todaySwingLevels = array.new(0)
var array swingCounts = array.new(0)
var array isResistance = array.new(0)
var array swingBars = array.new(0)
var int maxEqualPeaks = 0
var float nearestEqualLevel = na
var float distanceToNearest = na
var bool hasPattern = false
// Detect swings
swingHigh = ta.pivothigh(high, leftBars, rightBars)
swingLow = ta.pivotlow(low, leftBars, rightBars)
// Track current day
currentDay = dayofmonth
isNewDay = currentDay != currentDay
// Clear on new day
if barstate.isfirst or isNewDay
array.clear(todaySwingLevels)
array.clear(swingCounts)
array.clear(isResistance)
array.clear(swingBars)
maxEqualPeaks := 0
nearestEqualLevel := na
distanceToNearest := na
hasPattern := false
// Function to find matching level
findMatchingLevel(newLevel, isHigh) =>
matchIndex = -1
if array.size(todaySwingLevels) > 0
for i = 0 to array.size(todaySwingLevels) - 1
existingLevel = array.get(todaySwingLevels, i)
existingIsResistance = array.get(isResistance, i)
if math.abs(newLevel - existingLevel) <= tolerance and existingIsResistance == isHigh
matchIndex := i
break
matchIndex
// Process swing highs
if not na(swingHigh)
matchIndex = findMatchingLevel(swingHigh, true)
if matchIndex >= 0
newCount = array.get(swingCounts, matchIndex) + 1
array.set(swingCounts, matchIndex, newCount)
// Update max equal peaks
if newCount > maxEqualPeaks
maxEqualPeaks := newCount
else
array.push(todaySwingLevels, swingHigh)
array.push(swingCounts, 1)
array.push(isResistance, true)
array.push(swingBars, bar_index)
// Process swing lows
if not na(swingLow)
matchIndex = findMatchingLevel(swingLow, false)
if matchIndex >= 0
newCount = array.get(swingCounts, matchIndex) + 1
array.set(swingCounts, matchIndex, newCount)
// Update max equal peaks
if newCount > maxEqualPeaks
maxEqualPeaks := newCount
else
array.push(todaySwingLevels, swingLow)
array.push(swingCounts, 1)
array.push(isResistance, false)
array.push(swingBars, bar_index)
// Remove broken levels
if array.size(todaySwingLevels) > 0
for i = array.size(todaySwingLevels) - 1 to 0
level = array.get(todaySwingLevels, i)
isRes = array.get(isResistance, i)
levelBroken = isRes ? close > level : close < level
if levelBroken
removedCount = array.get(swingCounts, i)
array.remove(todaySwingLevels, i)
array.remove(swingCounts, i)
array.remove(isResistance, i)
array.remove(swingBars, i)
// Recalculate max if we removed the highest count
if removedCount == maxEqualPeaks
maxEqualPeaks := 0
if array.size(swingCounts) > 0
for j = 0 to array.size(swingCounts) - 1
count = array.get(swingCounts, j)
if count > maxEqualPeaks
maxEqualPeaks := count
// Calculate nearest equal level and distance
nearestEqualLevel := na
distanceToNearest := na
smallestDistance = 999999.0
if array.size(todaySwingLevels) > 0
for i = 0 to array.size(todaySwingLevels) - 1
count = array.get(swingCounts, i)
level = array.get(todaySwingLevels, i)
// Only consider levels with 2+ touches
if count >= 2
distance = math.abs(close - level)
if distance < smallestDistance
smallestDistance := distance
nearestEqualLevel := level
distanceToNearest := distance
// Pattern detection with filter
hasPattern := false
if maxEqualPeaks >= 2
if enableFilter
hasPattern := maxEqualPeaks == filterPeaks
else
hasPattern := true
// Screener outputs
patternSignal = hasPattern ? 1 : 0
numberEqualPeaks = maxEqualPeaks
nearestLevelPrice = nearestEqualLevel
distanceCents = distanceToNearest
// Calculate ATR normalized distance
atr = ta.atr(atrLength)
atrDistance = not na(distanceToNearest) and not na(atr) and atr > 0 ? distanceToNearest / atr : na
// Plot screener values
plot(patternSignal, title="Pattern Signal", display=display.data_window)
plot(numberEqualPeaks, title="Number Equal Peaks", display=display.data_window)
plot(nearestLevelPrice, title="Nearest Equal Level Price", display=display.data_window)
plot(distanceCents, title="Distance to Nearest (Price Units)", display=display.data_window)
plot(atrDistance, title="ATR Normalized Distance", display=display.data_window)
// Table for current symbol info
if barstate.islast
var table infoTable = table.new(position.top_right, 2, 6, bgcolor=color.new(color.black, 70))
table.cell(infoTable, 0, 0, "Symbol:", bgcolor=color.new(color.gray, 50), text_color=color.white)
table.cell(infoTable, 1, 0, syminfo.ticker, bgcolor=color.new(color.blue, 50), text_color=color.white)
table.cell(infoTable, 0, 1, "Pattern:", bgcolor=color.new(color.gray, 50), text_color=color.white)
table.cell(infoTable, 1, 1, str.tostring(patternSignal), bgcolor=patternSignal == 1 ? color.new(color.purple, 50) : color.new(color.gray, 50), text_color=color.white)
table.cell(infoTable, 0, 2, "Equal Peaks:", bgcolor=color.new(color.gray, 50), text_color=color.white)
table.cell(infoTable, 1, 2, str.tostring(numberEqualPeaks), bgcolor=color.new(color.yellow, 50), text_color=color.black)
table.cell(infoTable, 0, 3, "Nearest Level:", bgcolor=color.new(color.gray, 50), text_color=color.white)
table.cell(infoTable, 1, 3, str.tostring(nearestLevelPrice, "#.####"), bgcolor=color.new(color.orange, 50), text_color=color.white)
table.cell(infoTable, 0, 4, "Distance:", bgcolor=color.new(color.gray, 50), text_color=color.white)
table.cell(infoTable, 1, 4, str.tostring(distanceCents, "#.####"), bgcolor=color.new(color.green, 50), text_color=color.white)
table.cell(infoTable, 0, 5, "Filter Active:", bgcolor=color.new(color.gray, 50), text_color=color.white)
filterText = enableFilter ? str.tostring(filterPeaks) + " peaks" : "OFF"
table.cell(infoTable, 1, 5, filterText, bgcolor=enableFilter ? color.new(color.red, 50) : color.new(color.gray, 50), text_color=color.white)
By Gadirov Reliable 3M Binary Signals for binary codeBy Gadirov Reliable 3M Binary Signals for binary code
Double Top/Bottom Screener - Today Only v6 I want to create screener for stock that are traded on Nysa, nasdaq and amex. there will be filter by volume shares traded today more then 1mln, and this screener need to search among all that stocks (approximately 1000 symbols) on 1 minute timeframe, for 2 equal highs/ or lows, I will want set parameters what I mean by "equal", and I want to regulate setting by 2 -3-4-5 equal highs or lows searching. when there will be such stock I want to see it on the list, or have alert, .how can I create such screener If I don;t now coding and with low budget, and with less time
Pattern Match & Forward Projection – Weekly (EN)
Overview
This indicator searches for recurring price patterns in weekly data and projects their average forward performance.
The logic is based on historical pattern repetition: it scans past price sequences similar to the most recent one, then aggregates their forward returns to estimate potential outcomes.
⚠️ Important: The indicator is designed for weekly timeframe only. Using it on daily or intraday charts will trigger an error message.
Settings (Inputs)
Pattern Settings
Pattern length (weeks): Number of weeks used to define the reference pattern.
Forward length (weeks): Number of weeks into the future to evaluate after each pattern match.
Lookback (weeks): Historical window to scan for past pattern matches.
Normalize by shape (z-score): If enabled, patterns are normalized by z-score, focusing on shape similarity rather than absolute values.
Distance threshold (Euclidean): Maximum allowed Euclidean distance between the reference pattern and historical candidates. Smaller values = stricter matching.
Min. required matches: Minimum number of valid matches needed for analysis.
Quality Filters
Min required Hit%: Minimum percentage of positive outcomes (upside forward returns) required for the pattern to be considered valid.
Return filter mode:
Either: absolute average return ≥ threshold
Long only: average return ≥ threshold
Short only: average return ≤ -threshold
Min avg return (%): Minimum average forward return threshold for validation.
Visual Options
Highlight historical matches (labels): Marks where in history similar patterns occurred.
Max match labels to draw: Caps the number of match markers shown to avoid clutter.
Draw average projection: Displays the average projected forward curve if conditions are met.
Show summary panel: Enables/disables the information panel.
Show weekly avg curve in panel: Adds a breakdown of average returns week by week.
Projection color: Choose the color of the projected forward curve.
What the Screen Shows
Summary Panel (top-left by default)
Total matches found in history
Matches with valid forward data
Average, minimum, and maximum distance (similarity measure)
Average forward return and Hit%
Distance threshold and normalization setting
Weekly average forward curve (if enabled)
Quality filter results (pass/fail)
Projection Curve (dotted line on price chart)
Drawn only if enough valid matches are found and filters are satisfied
Represents the average forward performance of historical matches, anchored at the current bar
Historical Match Labels (▲ markers)
Small arrows below past bars where similar patterns occurred
Tooltip: “Historical match”
Forecast Logic
The indicator does not predict the future in a deterministic way.
Instead, it relies on a pattern-matching algorithm:
The most recent N weeks (defined by Pattern length) are taken as the reference.
The algorithm scans the last Lookback (weeks) for segments with similar shape and magnitude.
Similarity is measured using Euclidean distance (optionally z-score normalized).
For each valid match, the subsequent Forward length weeks are collected.
These forward paths are averaged to generate a composite forward projection.
The summary panel reports whether the current setup passes the quality filters (Hit% and minimum average return).
Usage Notes
Best used as a contextual tool, not a standalone trading system.
Works only on weekly timeframe.
Quality filters help distinguish between noisy and statistically meaningful patterns.
A higher number of matches usually improves reliability, but very strict thresholds may reduce sample size.
📊 This tool is useful for traders who want to evaluate how similar historical setups have behaved and to visualize potential forward paths in a statistically aggregated way.