ProRealCode - Trading & Coding with ProRealTime™
// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © LuxAlgo
//@version=5
indicator(‘Swing Breakout Sequence [LuxAlgo]’, ‘LuxAlgo – Swing Breakout Sequence’, overlay = true, max_lines_count = 500, max_labels_count = 500, max_polylines_count = 100, max_boxes_count = 500)
//———————————————————————————————————————}
//CONSTANTS & STRINGS & INPUTS
//———————————————————————————————————————{
BULLISH_LEG = 1
BEARISH_LEG = 0
HIGH = 1
LOW = 0
GREEN = #089981
RED = #F23645
GRAY = color.gray
BULLISH_BOX_COLOR = color.new(GREEN,90)
BEARISH_BOX_COLOR = color.new(RED,90)
DOUBLE_GROUP = ‘DETECTION’
STYLE_GROUP = ‘STYLE’
pivotLengthTooltip = ‘Number of candles to confirm a swing high or swing low. A higher number detects larger swings.’
internalLengthTooltip = ‘Number of candles to confirm a internal high or internal low. A lower number detects smaller swings. It must be the same size or smaller than the swing length.’
point4Beyond2Tooltip = ‘It only detects sequences where Point 4 is beyond Point 2.’
detectPoint5Tooltip = ‘Enable/disable Point 5 detection.’
strictThresholdTooltip = ‘Enable/Disable double top/bottom detection at Point 5 within a given threshold. A bigger value detects more sequences.’
showPathTooltip = ‘Enable/disable a line between sequence points.’
bearishBoxColorTooltip = ‘Enable/disable colored boxes for each sequence.’
showLinesTooltip = ‘Enable/disable horizontal lines from each point of the sequence.’
autoColorTooltip = ‘Define the color or enable/disable auto color.’
pivotLengthInput = input.int( 5, ‘Swing Length’, group = ”, tooltip = pivotLengthTooltip, minval = 2)
internalLengthInput = input.int( 2, ‘Internal Length’, group = ”, tooltip = internalLengthTooltip, minval = 2)
point4Beyond2Input = input.bool( false, ‘Point 4 Beyond Point 2’, group = DOUBLE_GROUP, tooltip = point4Beyond2Tooltip)
detectPoint5Input = input.bool( true, ‘Show Point 5’, group = DOUBLE_GROUP, tooltip = detectPoint5Tooltip)
strictModeInput = input.bool( true, ‘Require Equal H/L at Point 5’, group = DOUBLE_GROUP, tooltip = ”, inline = ‘strict’)
strictThresholdInput = input.float( 0.50, ”, group = DOUBLE_GROUP, tooltip = strictThresholdTooltip, inline = ‘strict’, step = 0.05) * ta.atr(200)
showPathInput = input.bool( false, ‘Show Sequence Path’, group = STYLE_GROUP, tooltip = showPathTooltip)
showBoxInput = input.bool( true, ‘Show Boxes’, group = STYLE_GROUP, tooltip = ”, inline = ‘box’)
bullishBoxColorInput = input.color( BULLISH_BOX_COLOR, ”, group = STYLE_GROUP, tooltip = ”, inline = ‘box’)
bearishBoxColorInput = input.color( BEARISH_BOX_COLOR, ”, group = STYLE_GROUP, tooltip = bearishBoxColorTooltip, inline = ‘box’)
showLinesInput = input.bool( true, ‘Show Lines’, group = STYLE_GROUP, tooltip = showLinesTooltip)
defaultColorInput = input.color( GRAY, ‘Default Color’, group = STYLE_GROUP, tooltip = ”, inline = ‘color’)
autoColorInput = input.bool( true, ‘Auto’, group = STYLE_GROUP, tooltip = autoColorTooltip, inline = ‘color’)
//———————————————————————————————————————}
//DATA STRUCTURES & VARIABLES
//———————————————————————————————————————{
// @type Storage UDT for pivot points
// @field barTime Time index of the privot point
// @field barIndex Bar index of the privot point
// @field priceLevel Price level of the pivot point
// @field leg Bullish or bearish bias (1 or 0)
type swingPoint
int barTime
int barIndex
float priceLevel
int swing
// @type Storage UDT for sequences
// @field points storage array for chart.point
type sbs
array<chart.point> points
// @variable storage array for sbs UDTs
var array<sbs> sequences = array.new<sbs>()
// @variable storage array for swingPoint UDTs
var array<swingPoint> swingPoints = array.new<swingPoint>()
// @variable storage array for swingPoint UDTs
var array<swingPoint> internalPoints = array.new<swingPoint>()
// @variable current leg bullish or bearish bias (1 or 0)
int currentLeg = na
// @variable true if there is a new pivot
bool newPivot = na
// @variable true if there is a new pivot low
bool pivotLow = na
// @variable true if there is a new pivot high
bool pivotHigh = na
// @variable current internal leg bullish or bearish bias (1 or 0)
int internalLeg = na
// @variable true if there is a new internal pivot
bool newInternalPivot = na
// @variable true if there is a new internal pivot low
bool internalLow = na
// @variable true if there is a new internal pivot high
bool internalHigh = na
// @variable last swing bar index
var int legIndex = bar_index
// @variable last swing high
var float legHigh = high
// @variable last swing low
var float legLow = low
// @variable last swing bar time
var int legTime = time
// @variable last internal bar index
var int internalLegIndex = bar_index
// @variable last internal high
var float internalLegHigh = high
// @variable last internal low
var float internalLegLow = low
// @variable last internal bar time
var int internalLegTime = time
//———————————————————————————————————————}
//USER-DEFINED FUNCTIONS
//———————————————————————————————————————{
// @function Get the value of the current leg, it can be 0 (bearish) or 1 (bullish)
// @returns int
leg(int length) =>
var leg = 0
newLegHigh = high == ta.highest( length)
newLegLow = low == ta.lowest( length)
if newLegHigh
leg := BULLISH_LEG
else if newLegLow
leg := BEARISH_LEG
leg
// @function Identify whether the current value is the start of a new leg (swing)
// @param leg (int) Current leg value
// @returns bool
startOfNewLeg(int leg) => ta.change(leg) != 0
// @function Identify whether the current level is the start of a new bearish leg (swing)
// @param leg (int) Current leg value
// @returns bool
startOfBearishLeg(int leg) => ta.change(leg) == -1
// @function Identify whether the current level is the start of a new bullish leg (swing)
// @param leg (int) Current leg value
// @returns bool
startOfBullishLeg(int leg) => ta.change(leg) == +1
// @function Parses swingPoint to chart.point
// @param point swingPoint to parse
// @returns chart.point ID
chartPoint(swingPoint point) => chart.point.new(point.barTime, point.barIndex, point.priceLevel)
// @function True if point price is between top and bottom prices
// @param point swingPoint to check
// @param top top swingPoint
// @param bottom bottom swingPoint
// @returns bool
inside(swingPoint point, swingPoint top, swingPoint bottom) => point.priceLevel <= top.priceLevel and point.priceLevel >= bottom.priceLevel
// @function True if point price is between top and bottom prices
// @param point swingPoint to check
// @param top top price
// @param bottom bottom price
// @returns bool
insideLevel(swingPoint point, float top, float bottom) => point.priceLevel <= top and point.priceLevel >= bottom
// @function Detects and returns a swingPoint after point4 with similar price within top and bottom swingPoints
// @param point4 swingPoint to check
// @param top top swingPoint
// @param bottom bottom swingPoint
// @returns swingPoint ID
doubleTopBottom(swingPoint point4,swingPoint top,swingPoint bottom) =>
swingPoint point5 = na
for eachPoint in internalPoints
if eachPoint.barIndex > point4.barIndex and eachPoint.swing == point4.swing and (strictModeInput ? insideLevel(eachPoint,point4.priceLevel+strictThresholdInput,point4.priceLevel-strictThresholdInput) : inside(eachPoint,top,bottom))
point5 := eachPoint
break
point5
// @function Draws last detected SBS
// @returns void
plotLastSBS() =>
color defaultColor = autoColorInput ? chart.fg_color : defaultColorInput
int concurrentSequences = 0
string textFix = ”
sbs lastSBS = sequences.last()
bool bullishSequence = lastSBS.points.first().price > lastSBS.points.get(1).price
for [index,eachSBS] in sequences
if index >= 1
if eachSBS.points.first().index < sequences.get(index – 1).points.last().index
concurrentSequences += 1
else
concurrentSequences := 0
if concurrentSequences > 0
baseString = str.tostring(array.new<string>(concurrentSequences,’\n’))
textFix := str.replace_all(str.substring(baseString,1,str.length(baseString)-1),’, ‘,”)
if showBoxInput
color boxColor = bullishSequence ? BULLISH_BOX_COLOR : BEARISH_BOX_COLOR
float top = bullishSequence ? lastSBS.points.first().price : lastSBS.points.get(1).price
float bottom = bullishSequence ? lastSBS.points.get(1).price : lastSBS.points.first().price
box.new(lastSBS.points.first().time,top,lastSBS.points.last().time,bottom,xloc = xloc.bar_time,bgcolor = boxColor,border_width = 0)
if showPathInput
polyline.new(lastSBS.points, false, false, xloc.bar_time, color.new(defaultColor,50), line_style = line.style_solid, line_width = 2)
if showLinesInput
line.new(lastSBS.points.first().time,lastSBS.points.first().price,lastSBS.points.get(2).time,lastSBS.points.first().price,xloc.bar_time,color = defaultColor,style = line.style_dotted)
line.new(lastSBS.points.get(1).time,lastSBS.points.get(1).price,lastSBS.points.last().time,lastSBS.points.get(1).price,xloc.bar_time,color = defaultColor,style = line.style_dotted)
line.new(lastSBS.points.get(2).time,lastSBS.points.get(2).price,lastSBS.points.last().time,lastSBS.points.get(2).price,xloc.bar_time,color = defaultColor,style = line.style_dotted)
line.new(lastSBS.points.get(3).time,lastSBS.points.get(3).price,lastSBS.points.last().time,lastSBS.points.get(3).price,xloc.bar_time,color = defaultColor,style = line.style_dotted)
line.new(lastSBS.points.get(4).time,lastSBS.points.get(4).price,lastSBS.points.last().time,lastSBS.points.get(4).price,xloc.bar_time,color = defaultColor,style = line.style_dotted)
if detectPoint5Input
line.new(lastSBS.points.get(5).time,lastSBS.points.get(5).price,lastSBS.points.last().time,lastSBS.points.get(5).price,xloc.bar_time,color = defaultColor,style = line.style_dotted)
label.new(lastSBS.points.first(),bullishSequence ? ‘Swing High’ + textFix : textFix + ‘Swing Low’,xloc.bar_time,color = color(na),style = bullishSequence ? label.style_label_down : label.style_label_up,textcolor = defaultColor)
label.new(lastSBS.points.get(1),bullishSequence ? textFix + ‘Swing Low’ : ‘Swing High’ + textFix,xloc.bar_time,color = color(na),style = bullishSequence ? label.style_label_up : label.style_label_down,textcolor = defaultColor)
label.new(lastSBS.points.get(2),bullishSequence ? ‘1’ + textFix : textFix + ‘1’,xloc.bar_time,color = color(na),style = bullishSequence ? label.style_label_down : label.style_label_up,textcolor = defaultColor)
label.new(lastSBS.points.get(3),bullishSequence ? textFix + ‘2’ : ‘2’ + textFix,xloc.bar_time,color = color(na),style = bullishSequence ? label.style_label_up : label.style_label_down,textcolor = defaultColor)
label.new(lastSBS.points.get(4),bullishSequence ? ‘3’ + textFix : textFix + ‘3’,xloc.bar_time,color = color(na),style = bullishSequence ? label.style_label_down : label.style_label_up,textcolor = defaultColor)
label.new(lastSBS.points.get(5),bullishSequence ? textFix + ‘4’ : ‘4’ + textFix,xloc.bar_time,color = color(na),style = bullishSequence ? label.style_label_up : label.style_label_down,textcolor = defaultColor)
if detectPoint5Input
label.new(lastSBS.points.last(),bullishSequence ? textFix + ‘5’ : ‘5’ + textFix,xloc.bar_time,color = color(na),style = bullishSequence ? label.style_label_up : label.style_label_down,textcolor = defaultColor)
// @function Finds and plots sequences with internal swing detector
// @returns void
gatherInternalSBS() =>
size = array.size(swingPoints)
if size >= 6
A = array.get(swingPoints, size – 6)
B = array.get(swingPoints, size – 5)
point1 = array.get(swingPoints, size – 4)
point2 = array.get(swingPoints, size – 3)
point3 = array.get(swingPoints, size – 2)
point4 = array.get(swingPoints, size – 1)
swingPoint doubleTopPoint = na
swingPoint doubleBottomPoint = na
if detectPoint5Input
doubleTopPoint := doubleTopBottom(point4,B,A)
doubleBottomPoint := doubleTopBottom(point4,A,B)
bearishSBS = point1.swing == LOW and inside(point1,A,point3) and inside(point2,B,A) and (point4Beyond2Input ? inside(point4,B,point2) : inside(point4,B,A)) and (detectPoint5Input ? not na(doubleTopPoint) : true)
bullishSBS = point1.swing == HIGH and inside(point1,point3,A) and inside(point2,A,B) and (point4Beyond2Input ? inside(point4,point2,B) : inside(point4,A,B)) and (detectPoint5Input ? not na(doubleBottomPoint) : true)
if bullishSBS or bearishSBS
bool addSequence = false
if sequences.size() == 0
addSequence := true
else if sequences.last().points.first().time < A.barTime
addSequence := true
if addSequence
sequences.push(sbs.new(array.from(chartPoint(A),chartPoint(B),chartPoint(point1),chartPoint(point2),chartPoint(point3),chartPoint(point4))))
if detectPoint5Input
sequences.last().points.push(chartPoint(bullishSBS ? doubleBottomPoint : doubleTopPoint))
plotLastSBS()
// @function Finds and plots sequences with swing detector
// @returns void
gatherSwingSBS() =>
size = array.size(swingPoints)
if size >= 8
A = array.get(swingPoints, size – 8)
B = array.get(swingPoints, size – 7)
point1 = array.get(swingPoints, size – 6)
point2 = array.get(swingPoints, size – 5)
point3 = array.get(swingPoints, size – 4)
point4 = array.get(swingPoints, size – 3)
point5 = array.get(swingPoints, size – 2)
point6 = array.get(swingPoints, size – 1)
bearishSBS = point1.swing == LOW and inside(point1,A,point3) and inside(point2,B,A) and (point4Beyond2Input ? inside(point4,B,point2) : inside(point4,B,A)) and (detectPoint5Input ? (strictModeInput ? insideLevel(point6,point4.priceLevel+strictThresholdInput,point4.priceLevel-strictThresholdInput) : inside(point6,B,A)) : true)
bullishSBS = point1.swing == HIGH and inside(point1,point3,A) and inside(point2,A,B) and (point4Beyond2Input ? inside(point4,point2,B) : inside(point4,A,B)) and (detectPoint5Input ? (strictModeInput ? insideLevel(point6,point4.priceLevel+strictThresholdInput,point4.priceLevel-strictThresholdInput) : inside(point6,A,B)) : true)
if bullishSBS or bearishSBS
bool addSequence = false
if sequences.size() == 0
addSequence := true
else if sequences.last().points.first().time < A.barTime
addSequence := true
if addSequence
sequences.push(sbs.new(array.from(chartPoint(A),chartPoint(B),chartPoint(point1),chartPoint(point2),chartPoint(point3),chartPoint(point4))))
if detectPoint5Input
sequences.last().points.push(chartPoint(point6))
plotLastSBS()
// @function Add a swingPoint point to an array points with a provided max number of elements
// @param point swingPoint to add
// @param points array of swingPoint
// @param size max size of array
// @returns void
addPoint(swingPoint point, array<swingPoint> points, int size) =>
if points.size() >= size
points.shift()
points.push(point)
//———————————————————————————————————————}
//MUTABLE VARIABLES & EXECUTION
//———————————————————————————————————————{
currentLeg := leg(pivotLengthInput)
newPivot := startOfNewLeg(currentLeg)
pivotLow := startOfBullishLeg(currentLeg)
pivotHigh := startOfBearishLeg(currentLeg)
internalLeg := leg(internalLengthInput)
newInternalPivot := startOfNewLeg(internalLeg)
internalLow := startOfBullishLeg(internalLeg)
internalHigh := startOfBearishLeg(internalLeg)
// we execute the logic only once per bar close
if barstate.isconfirmed
// if there is a new swing point execute the logic
if newInternalPivot
priceLevel = internalLegHigh
legBias = HIGH
// if the new swing point is a pivot low change the values
if internalLow
priceLevel := internalLegLow
legBias := LOW
// we store the new swing point
addPoint(swingPoint.new(internalLegTime,internalLegIndex,priceLevel,legBias),internalPoints,pivotLengthInput)
// we check and plot new sequence
gatherInternalSBS()
// we update the current leg values: high, low, index and time
internalLegHigh := internalLow ? high : math.max(high,internalLegHigh)
internalLegLow := internalHigh ? low : math.min(low, internalLegLow)
internalLegIndex := (internalLeg == BULLISH_LEG and internalLegHigh == high) or (internalLeg == BEARISH_LEG and internalLegLow == low) ? bar_index : internalLegIndex
internalLegTime := (internalLeg == BULLISH_LEG and internalLegHigh == high) or (internalLeg == BEARISH_LEG and internalLegLow == low) ? time : internalLegTime
// if there is a new swing point execute the logic
if newPivot
priceLevel = legHigh
legBias = HIGH
// if the new swing point is a pivot low change the values
if pivotLow
priceLevel := legLow
legBias := LOW
// we store the new swing point
addPoint(swingPoint.new(legTime,legIndex,priceLevel,legBias),swingPoints,8)
// we check and plot new sequence
gatherSwingSBS()
// we update the current leg values: high, low, index and time
legHigh := pivotLow ? high : math.max(high,legHigh)
legLow := pivotHigh ? low : math.min(low, legLow)
legIndex := (currentLeg == BULLISH_LEG and legHigh == high) or (currentLeg == BEARISH_LEG and legLow == low) ? bar_index : legIndex
legTime := (currentLeg == BULLISH_LEG and legHigh == high) or (currentLeg == BEARISH_LEG and legLow == low) ? time : legTime
//———————————————————————————————————————}
//---------------------------------------------//
//PRC_Ultimate RSI
//version = 0
//14.03.25
//Iván González @ www.prorealcode.com
//Sharing ProRealTime knowledge
//---------------------------------------------//
// inputs
//---------------------------------------------//
length=14
smotype1=3
src=close
smooth=14
smotype2=1
obValue=80
osValue=20
//---------------------------------------------//
// Augmented RSI
//---------------------------------------------//
upper=highest[length](src)
lower=lowest[length](src)
r=upper-lower
d=src-src[1]
if upper>upper[1] then
diff=r
else
if lower<lower[1] then
diff=-r
else
diff=d
endif
endif
//---------------------------------------------//
// Moving average
//---------------------------------------------//
if smotype1=1 then
num=average[length,1](diff)
den=average[length,1](abs(diff))
elsif smotype1=2 then
num=average[length,0](diff)
den=average[length,0](abs(diff))
elsif smotype1=3 then
alpha = 1/length
if barindex = length then
num = average[length](diff)
den = average[length](abs(diff))
else
num = alpha*diff + (1-alpha)*num[1]
den = alpha*abs(diff) + (1-alpha)*den[1]
endif
elsif smotype1=4 then
num=average[length](average[length](diff))
den=average[length](average[length](abs(diff)))
endif
arsi=num/den*50+50
//---------------------------------------------//
// Signal
//---------------------------------------------//
if smotype2=1 then
signal=average[smooth,1](arsi)
elsif smotype2=2 then
signal=average[smooth,0](arsi)
elsif smotype2=2 then
alpha = 1/smooth
if barindex = smooth then
signal = average[smooth](arsi)
else
signal = alpha*arsi + (1-alpha)*signal[1]
endif
elsif smotype1=3 then
signal=average[smooth](average[smooth](arsi))
endif
//---------------------------------------------//
// Plot
//---------------------------------------------//
if arsi>obvalue then
r1=0
g1=255
b1=0
a1=255
a3=0
elsif arsi<osvalue then
r3=255
g3=0
b3=0
a3=255
a1=0
else
a1=0
a3=0
endif
colorbetween(obvalue,arsi,r1,g1,b1,a1*0.3)
colorbetween(osvalue,arsi,r3,g3,b3,a3*0.3)
//---------------------------------------------//
return obValue style(dottedline),osValue style(dottedline),50 style(dottedline), arsi, signal as "Signal line"coloured("orange")style(line,2)
Better late than never… here’s the indicator.
//-----------------------------------------------
// PRC_Swing Breakout Sequence (by LuxAlgo)
// version = 0
// 10.03.2026
// Iván González @ www.prorealcode.com
// Sharing ProRealTime knowledge
//-----------------------------------------------
//=== PARAMETERS ===
//-----------------------------------------------
swingLen = 5 // Swing Length (min 2)
internalLen = 2 // Internal Length (min 2, <= swingLen)
pt4Beyond2 = 0 // Point 4 must be beyond Point 2 (0=off, 1=on)
showPt5 = 1 // Show Point 5 (0=off, 1=on)
strictMode = 1 // Require equal H/L at Point 5 (0=off, 1=on)
strictPct = 0.50 // Threshold multiplier (x ATR200)
showPath = 0 // Show path connecting points (0=off, 1=on)
showBox = 1 // Show zone boxes (0=off, 1=on)
showLines = 1 // Show horizontal lines (0=off, 1=on)
maxIntPts = 20 // Max internal points stored
//-----------------------------------------------
//=== INITIALIZATION ===
//-----------------------------------------------
once atrVal = 0
once lastSeqABar = -1
// Main swing FIFO (8 slots: index 0=oldest, 7=newest)
once sw0Bar = -1
once sw0Price = 0
once sw0Type = -1
once sw1Bar = -1
once sw1Price = 0
once sw1Type = -1
once sw2Bar = -1
once sw2Price = 0
once sw2Type = -1
once sw3Bar = -1
once sw3Price = 0
once sw3Type = -1
once sw4Bar = -1
once sw4Price = 0
once sw4Type = -1
once sw5Bar = -1
once sw5Price = 0
once sw5Type = -1
once sw6Bar = -1
once sw6Price = 0
once sw6Type = -1
once sw7Bar = -1
once sw7Price = 0
once sw7Type = -1
once swCount = 0
// Internal points buffer ($arrays)
once intCount = 0
//-----------------------------------------------
//=== ATR THRESHOLD ===
//-----------------------------------------------
atrVal = averagetruerange[200]
strictThresh = strictPct * atrVal
//-----------------------------------------------
//=== MAIN SWING DETECTION ===
//-----------------------------------------------
upperMain = highest[swingLen](high)
lowerMain = lowest[swingLen](low)
if high = upperMain then
mainLeg = 1
elsif low = lowerMain then
mainLeg = 0
else
mainLeg = mainLeg[1]
endif
if barindex > 0 then
newMainPivot = (mainLeg <> mainLeg[1])
mainPivotLow = 0
mainPivotHigh = 0
if mainLeg > mainLeg[1] then
mainPivotLow = 1
endif
if mainLeg < mainLeg[1] then
mainPivotHigh = 1
endif
else
newMainPivot = 0
mainPivotLow = 0
mainPivotHigh = 0
endif
//-----------------------------------------------
//=== INTERNAL SWING DETECTION ===
//-----------------------------------------------
upperInt = highest[internalLen](high)
lowerInt = lowest[internalLen](low)
if high = upperInt then
intLeg = 1
elsif low = lowerInt then
intLeg = 0
else
intLeg = intLeg[1]
endif
if barindex > 0 then
newIntPivot = (intLeg <> intLeg[1])
intPivotLow = 0
intPivotHigh = 0
if intLeg > intLeg[1] then
intPivotLow = 1
endif
if intLeg < intLeg[1] then
intPivotHigh = 1
endif
else
newIntPivot = 0
intPivotLow = 0
intPivotHigh = 0
endif
//-----------------------------------------------
// PROCESS INTERNAL PIVOT
//-----------------------------------------------
if newIntPivot then
// Determine price and type of the internal swing point
if intPivotLow then
intNewPrice = iLegLow
intNewBar = iLegBar
intNewType = 0 // LOW
else
intNewPrice = iLegHigh
intNewBar = iLegBar
intNewType = 1 // HIGH
endif
// Store in internal buffer (circular, no shift)
if intCount < maxIntPts then
$intBar[intCount] = intNewBar
$intPrice[intCount] = intNewPrice
$intType[intCount] = intNewType
intCount = intCount + 1
else
// Shift buffer: remove oldest, add at end
for si = 0 to maxIntPts - 2 do
$intBar[si] = $intBar[si + 1]
$intPrice[si] = $intPrice[si + 1]
$intType[si] = $intType[si + 1]
next
$intBar[maxIntPts - 1] = intNewBar
$intPrice[maxIntPts - 1] = intNewPrice
$intType[maxIntPts - 1] = intNewType
endif
//--- gatherInternalSBS: needs last 6 MAIN swing points ---
// After N pivots, valid data is in slots (8-N)..7
// Last 6 are ALWAYS sw2..sw7 once swCount >= 6
if swCount >= 6 then
aBar = sw2Bar
aPrice = sw2Price
bBar = sw3Bar
bPrice = sw3Price
p1Bar = sw4Bar
p1Price = sw4Price
p1Type = sw4Type
p2Bar = sw5Bar
p2Price = sw5Price
p3Bar = sw6Bar
p3Price = sw6Price
p4Bar = sw7Bar
p4Price = sw7Price
p4Type = sw7Type
// Determine bullish or bearish ranges
if aPrice > bPrice then
topPrice = aPrice
botPrice = bPrice
else
topPrice = bPrice
botPrice = aPrice
endif
// inside() checks for each point
// Bearish SBS: pt1.swing=LOW, pt1 inside(A,pt3), pt2 inside(B,A), pt4 inside(B,A) or inside(B,pt2)
// Bullish SBS: pt1.swing=HIGH, pt1 inside(pt3,A), pt2 inside(A,B), pt4 inside(A,B) or inside(pt2,B)
bearishSBS = 0
bullishSBS = 0
// Bearish: A=top, B=bottom initially
// pt1 is LOW, inside(A, pt3) means pt1 <= A and pt1 >= pt3
if p1Type = 0 then
if p1Price <= aPrice and p1Price >= p3Price then
if p2Price <= bPrice and p2Price >= aPrice then
if pt4Beyond2 then
if p4Price <= bPrice and p4Price >= p2Price then
bearishSBS = 1
endif
else
if p4Price <= bPrice and p4Price >= aPrice then
bearishSBS = 1
endif
endif
endif
endif
endif
// Bullish: A=bottom, B=top conceptually
// pt1 is HIGH, inside(pt3, A) means pt1 <= pt3 and pt1 >= A...
// Wait: inside(point, top, bottom) = price <= top.price AND price >= bottom.price
// bullishSBS: inside(pt1, pt3, A) => pt1 <= pt3 AND pt1 >= A
// inside(pt2, A, B) => pt2 <= A AND pt2 >= B
// inside(pt4, A, B) or inside(pt4, pt2, B)
if p1Type = 1 then
if p1Price <= p3Price and p1Price >= aPrice then
if p2Price <= aPrice and p2Price >= bPrice then
if pt4Beyond2 then
if p4Price <= p2Price and p4Price >= bPrice then
bullishSBS = 1
endif
else
if p4Price <= aPrice and p4Price >= bPrice then
bullishSBS = 1
endif
endif
endif
endif
endif
// Point 5: search internal points for double top/bottom
pt5Found = 0
pt5Bar = -1
pt5Price = 0
if showPt5 and (bearishSBS or bullishSBS) then
// Search internal points after pt4
for si = 0 to intCount - 1 do
if $intBar[si] > p4Bar and $intType[si] = p4Type then
if strictMode then
if $intPrice[si] <= p4Price + strictThresh and $intPrice[si] >= p4Price - strictThresh then
pt5Bar = $intBar[si]
pt5Price = $intPrice[si]
pt5Found = 1
break
endif
else
// inside the A-B range
if $intPrice[si] <= topPrice and $intPrice[si] >= botPrice then
pt5Bar = $intBar[si]
pt5Price = $intPrice[si]
pt5Found = 1
break
endif
endif
endif
next
// If no Point 5 found, cancel sequence
if pt5Found = 0 then
bearishSBS = 0
bullishSBS = 0
endif
endif
// Draw if valid and new
if (bearishSBS or bullishSBS) and aBar > lastSeqABar then
lastSeqABar = aBar
isBull = bullishSBS
// Determine right edge of drawings
drawRightEdge = p4Bar
if showPt5 and pt5Found then
drawRightEdge = pt5Bar
endif
// --- BOX ---
if showBox then
if isBull then
boxTop = aPrice
boxBot = bPrice
else
boxTop = bPrice
boxBot = aPrice
endif
if isBull then
drawrectangle(aBar, boxBot, drawRightEdge, boxTop) coloured(8, 153, 129) fillcolor(8, 153, 129, 25)
else
drawrectangle(aBar, boxBot, drawRightEdge, boxTop) coloured(242, 54, 69) fillcolor(242, 54, 69, 25)
endif
endif
// --- HORIZONTAL LINES ---
if showLines then
drawsegment(aBar, aPrice, drawRightEdge, aPrice) style(dottedline, 1) coloured(128, 128, 128)
drawsegment(bBar, bPrice, drawRightEdge, bPrice) style(dottedline, 1) coloured(128, 128, 128)
drawsegment(p1Bar, p1Price, drawRightEdge, p1Price) style(dottedline, 1) coloured(128, 128, 128)
drawsegment(p2Bar, p2Price, drawRightEdge, p2Price) style(dottedline, 1) coloured(128, 128, 128)
drawsegment(p3Bar, p3Price, drawRightEdge, p3Price) style(dottedline, 1) coloured(128, 128, 128)
drawsegment(p4Bar, p4Price, drawRightEdge, p4Price) style(dottedline, 1) coloured(128, 128, 128)
if showPt5 and pt5Found then
drawsegment(pt5Bar, pt5Price, drawRightEdge, pt5Price) style(dottedline, 1) coloured(128, 128, 128)
endif
endif
// --- PATH (connecting segments) ---
if showPath then
drawsegment(aBar, aPrice, bBar, bPrice) coloured(128, 128, 128)
drawsegment(bBar, bPrice, p1Bar, p1Price) coloured(128, 128, 128)
drawsegment(p1Bar, p1Price, p2Bar, p2Price) coloured(128, 128, 128)
drawsegment(p2Bar, p2Price, p3Bar, p3Price) coloured(128, 128, 128)
drawsegment(p3Bar, p3Price, p4Bar, p4Price) coloured(128, 128, 128)
if showPt5 and pt5Found then
drawsegment(p4Bar, p4Price, pt5Bar, pt5Price) coloured(128, 128, 128)
endif
endif
// --- LABELS ---
if isBull then
drawtext("SH", aBar, aPrice + atrVal * 0.3) coloured(128, 128, 128)
drawtext("SL", bBar, bPrice - atrVal * 0.3) coloured(128, 128, 128)
drawtext("1", p1Bar, p1Price + atrVal * 0.3) coloured(128, 128, 128)
drawtext("2", p2Bar, p2Price - atrVal * 0.3) coloured(128, 128, 128)
drawtext("3", p3Bar, p3Price + atrVal * 0.3) coloured(128, 128, 128)
drawtext("4", p4Bar, p4Price - atrVal * 0.3) coloured(128, 128, 128)
if showPt5 and pt5Found then
drawtext("5", pt5Bar, pt5Price - atrVal * 0.3) coloured(128, 128, 128)
endif
else
drawtext("SL", aBar, aPrice - atrVal * 0.3) coloured(128, 128, 128)
drawtext("SH", bBar, bPrice + atrVal * 0.3) coloured(128, 128, 128)
drawtext("1", p1Bar, p1Price - atrVal * 0.3) coloured(128, 128, 128)
drawtext("2", p2Bar, p2Price + atrVal * 0.3) coloured(128, 128, 128)
drawtext("3", p3Bar, p3Price - atrVal * 0.3) coloured(128, 128, 128)
drawtext("4", p4Bar, p4Price + atrVal * 0.3) coloured(128, 128, 128)
if showPt5 and pt5Found then
drawtext("5", pt5Bar, pt5Price + atrVal * 0.3) coloured(128, 128, 128)
endif
endif
endif
endif
endif
//-----------------------------------------------
// PROCESS MAIN PIVOT
//-----------------------------------------------
if newMainPivot then
// Determine price and type
if mainPivotLow then
swNewPrice = mLegLow
swNewBar = mLegBar
swNewType = 0 // LOW
else
swNewPrice = mLegHigh
swNewBar = mLegBar
swNewType = 1 // HIGH
endif
// FIFO shift: 0<-1, 1<-2, ..., 6<-7, then write to 7
sw0Bar = sw1Bar
sw0Price = sw1Price
sw0Type = sw1Type
sw1Bar = sw2Bar
sw1Price = sw2Price
sw1Type = sw2Type
sw2Bar = sw3Bar
sw2Price = sw3Price
sw2Type = sw3Type
sw3Bar = sw4Bar
sw3Price = sw4Price
sw3Type = sw4Type
sw4Bar = sw5Bar
sw4Price = sw5Price
sw4Type = sw5Type
sw5Bar = sw6Bar
sw5Price = sw6Price
sw5Type = sw6Type
sw6Bar = sw7Bar
sw6Price = sw7Price
sw6Type = sw7Type
sw7Bar = swNewBar
sw7Price = swNewPrice
sw7Type = swNewType
if swCount < 8 then
swCount = swCount + 1
endif
//--- gatherSwingSBS: needs last 8 MAIN swing points ---
if swCount >= 8 then
// A=sw0, B=sw1, pt1=sw2, pt2=sw3, pt3=sw4, pt4=sw5, pt5_=sw6, pt6_=sw7
gsABar = sw0Bar
gsAPrice = sw0Price
gsBBar = sw1Bar
gsBPrice = sw1Price
gsP1Bar = sw2Bar
gsP1Price = sw2Price
gsP1Type = sw2Type
gsP2Bar = sw3Bar
gsP2Price = sw3Price
gsP3Bar = sw4Bar
gsP3Price = sw4Price
gsP4Bar = sw5Bar
gsP4Price = sw5Price
gsP4Type = sw5Type
gsP5Bar = sw6Bar
gsP5Price = sw6Price
gsP6Bar = sw7Bar
gsP6Price = sw7Price
gsP6Type = sw7Type
gsBearSBS = 0
gsBullSBS = 0
// Bearish: pt1=LOW, inside(pt1,A,pt3), inside(pt2,B,A), pt4 check, pt6 for Point5
if gsP1Type = 0 then
if gsP1Price <= gsAPrice and gsP1Price >= gsP3Price then
if gsP2Price <= gsBPrice and gsP2Price >= gsAPrice then
pt4ok = 0
if pt4Beyond2 then
if gsP4Price <= gsBPrice and gsP4Price >= gsP2Price then
pt4ok = 1
endif
else
if gsP4Price <= gsBPrice and gsP4Price >= gsAPrice then
pt4ok = 1
endif
endif
if pt4ok then
if showPt5 then
if strictMode then
if gsP6Price <= gsP4Price + strictThresh and gsP6Price >= gsP4Price - strictThresh then
gsBearSBS = 1
endif
else
if gsP6Price <= gsBPrice and gsP6Price >= gsAPrice then
gsBearSBS = 1
endif
endif
else
gsBearSBS = 1
endif
endif
endif
endif
endif
// Bullish: pt1=HIGH, inside(pt1,pt3,A), inside(pt2,A,B), pt4 check, pt6 for Point5
if gsP1Type = 1 then
if gsP1Price <= gsP3Price and gsP1Price >= gsAPrice then
if gsP2Price <= gsAPrice and gsP2Price >= gsBPrice then
pt4ok = 0
if pt4Beyond2 then
if gsP4Price <= gsP2Price and gsP4Price >= gsBPrice then
pt4ok = 1
endif
else
if gsP4Price <= gsAPrice and gsP4Price >= gsBPrice then
pt4ok = 1
endif
endif
if pt4ok then
if showPt5 then
if strictMode then
if gsP6Price <= gsP4Price + strictThresh and gsP6Price >= gsP4Price - strictThresh then
gsBullSBS = 1
endif
else
if gsP6Price <= gsAPrice and gsP6Price >= gsBPrice then
gsBullSBS = 1
endif
endif
else
gsBullSBS = 1
endif
endif
endif
endif
endif
// Draw swing SBS
if (gsBearSBS or gsBullSBS) and gsABar > lastSeqABar then
lastSeqABar = gsABar
gsIsBull = gsBullSBS
lastPtBar = gsP4Bar
if showPt5 then
lastPtBar = gsP6Bar
endif
// BOX
if showBox then
if gsIsBull then
gsBoxTop = gsAPrice
gsBoxBot = gsBPrice
else
gsBoxTop = gsBPrice
gsBoxBot = gsAPrice
endif
if gsIsBull then
drawrectangle(gsABar, gsBoxBot, lastPtBar, gsBoxTop) coloured(8, 153, 129) fillcolor(8, 153, 129, 25)
else
drawrectangle(gsABar, gsBoxBot, lastPtBar, gsBoxTop) coloured(242, 54, 69) fillcolor(242, 54, 69, 25)
endif
endif
// HORIZONTAL LINES
if showLines then
drawsegment(gsABar, gsAPrice, lastPtBar, gsAPrice) style(dottedline, 1) coloured(128, 128, 128)
drawsegment(gsBBar, gsBPrice, lastPtBar, gsBPrice) style(dottedline, 1) coloured(128, 128, 128)
drawsegment(gsP1Bar, gsP1Price, lastPtBar, gsP1Price) style(dottedline, 1) coloured(128, 128, 128)
drawsegment(gsP2Bar, gsP2Price, lastPtBar, gsP2Price) style(dottedline, 1) coloured(128, 128, 128)
drawsegment(gsP3Bar, gsP3Price, lastPtBar, gsP3Price) style(dottedline, 1) coloured(128, 128, 128)
drawsegment(gsP4Bar, gsP4Price, lastPtBar, gsP4Price) style(dottedline, 1) coloured(128, 128, 128)
if showPt5 then
drawsegment(gsP6Bar, gsP6Price, lastPtBar, gsP6Price) style(dottedline, 1) coloured(128, 128, 128)
endif
endif
// PATH
if showPath then
drawsegment(gsABar, gsAPrice, gsBBar, gsBPrice) coloured(128, 128, 128)
drawsegment(gsBBar, gsBPrice, gsP1Bar, gsP1Price) coloured(128, 128, 128)
drawsegment(gsP1Bar, gsP1Price, gsP2Bar, gsP2Price) coloured(128, 128, 128)
drawsegment(gsP2Bar, gsP2Price, gsP3Bar, gsP3Price) coloured(128, 128, 128)
drawsegment(gsP3Bar, gsP3Price, gsP4Bar, gsP4Price) coloured(128, 128, 128)
if showPt5 then
drawsegment(gsP4Bar, gsP4Price, gsP6Bar, gsP6Price) coloured(128, 128, 128)
endif
endif
// LABELS
if gsIsBull then
drawtext("SH", gsABar, gsAPrice + atrVal * 0.3) coloured(128, 128, 128)
drawtext("SL", gsBBar, gsBPrice - atrVal * 0.3) coloured(128, 128, 128)
drawtext("1", gsP1Bar, gsP1Price + atrVal * 0.3) coloured(128, 128, 128)
drawtext("2", gsP2Bar, gsP2Price - atrVal * 0.3) coloured(128, 128, 128)
drawtext("3", gsP3Bar, gsP3Price + atrVal * 0.3) coloured(128, 128, 128)
drawtext("4", gsP4Bar, gsP4Price - atrVal * 0.3) coloured(128, 128, 128)
if showPt5 then
drawtext("5", gsP6Bar, gsP6Price - atrVal * 0.3) coloured(128, 128, 128)
endif
else
drawtext("SL", gsABar, gsAPrice - atrVal * 0.3) coloured(128, 128, 128)
drawtext("SH", gsBBar, gsBPrice + atrVal * 0.3) coloured(128, 128, 128)
drawtext("1", gsP1Bar, gsP1Price - atrVal * 0.3) coloured(128, 128, 128)
drawtext("2", gsP2Bar, gsP2Price + atrVal * 0.3) coloured(128, 128, 128)
drawtext("3", gsP3Bar, gsP3Price - atrVal * 0.3) coloured(128, 128, 128)
drawtext("4", gsP4Bar, gsP4Price + atrVal * 0.3) coloured(128, 128, 128)
if showPt5 then
drawtext("5", gsP6Bar, gsP6Price + atrVal * 0.3) coloured(128, 128, 128)
endif
endif
endif
endif
endif
//-----------------------------------------------
// UPDATE LEG TRACKING (after pivot processing)
//-----------------------------------------------
//--- Internal leg extremes ---
if intPivotLow then
iLegHigh = high
iLegLow = iLegLow[1]
elsif intPivotHigh then
iLegLow = low
iLegHigh = iLegHigh[1]
else
iLegHigh = max(high, iLegHigh[1])
iLegLow = min(low, iLegLow[1])
endif
if (intLeg = 1 and iLegHigh = high) or (intLeg = 0 and iLegLow = low) then
iLegBar = barindex
else
iLegBar = iLegBar[1]
endif
//--- Main leg extremes ---
if mainPivotLow then
mLegHigh = high
mLegLow = mLegLow[1]
elsif mainPivotHigh then
mLegLow = low
mLegHigh = mLegHigh[1]
else
mLegHigh = max(high, mLegHigh[1])
mLegLow = min(low, mLegLow[1])
endif
if (mainLeg = 1 and mLegHigh = high) or (mainLeg = 0 and mLegLow = low) then
mLegBar = barindex
else
mLegBar = mLegBar[1]
endif
return
This topic contains 6 replies,
has 2 voices, and was last updated by
Iván González
4 hours, 58 minutes ago.
| Forum: | TradingView to ProRealTime Translation Center Forum |
| Started: | 02/27/2025 |
| Status: | Active |
| Attachments: | No files |
The information collected on this form is stored in a computer file by ProRealCode to create and access your ProRealCode profile. This data is kept in a secure database for the duration of the member's membership. They will be kept as long as you use our services and will be automatically deleted after 3 years of inactivity. Your personal data is used to create your private profile on ProRealCode. This data is maintained by SAS ProRealCode, 407 rue Freycinet, 59151 Arleux, France. If you subscribe to our newsletters, your email address is provided to our service provider "MailChimp" located in the United States, with whom we have signed a confidentiality agreement. This company is also compliant with the EU/Swiss Privacy Shield, and the GDPR. For any request for correction or deletion concerning your data, you can directly contact the ProRealCode team by email at privacy@prorealcode.com If you would like to lodge a complaint regarding the use of your personal data, you can contact your data protection supervisory authority.