Wedge and Flag Finder (Multi - Zigzag)
Wedge and Flag Finder (Multi - Zigzag)
maxBarsBack = 2000
max_bars_back(open, maxBarsBack)
max_bars_back(high, maxBarsBack)
max_bars_back(low, maxBarsBack)
max_bars_back(close, maxBarsBack)
maxPatternsReference = 10
if(drawZigzag)
ab = line.new(bBar, b, aBar, a)
bc = line.new(cBar, c, bBar, b)
cd = line.new(dBar, d, cBar, c)
de = line.new(eBar, e, dBar, d)
line.set_extend(l1t, extend.none)
line.set_extend(l2t, extend.none)
line.set_x1(l1t, startBar)
line.set_y1(l1t, l1Start)
line.set_x2(l1t, endBar)
line.set_y2(l1t, l1End)
line.set_x1(l2t, startBar)
line.set_y1(l2t, l2Start)
line.set_x2(l2t, endBar)
line.set_y2(l2t, l2End)
l1Diff = math.abs(l1Start-l1End)
l2Diff = math.abs(l2Start-l2End)
find_wedge(a,b,c,d,e,f,aBar,bBar,cBar,dBar,eBar,fBar,zigzagpivots, zigzagpivotbars,
fIndex, wedgeSize=6)=>
existingPattern = false
lastPivot = wedgeSize == 6? f : e
lastPivotBar = wedgeSize == 6? fBar : eBar
llastPivot = wedgeSize == 6? e : d
for i=0 to array.size(aBarArray)==0? na: array.size(aBarArray)-1
commonPivots = (array.get(aBarArray, i) == aBar ? 1 : 0) +
(array.get(bBarArray, i) == bBar ? 1 : 0) +
(array.get(cBarArray, i) == cBar ? 1 : 0) +
(array.get(dBarArray, i) == dBar ? 1 : 0) +
(array.get(eBarArray, i) == eBar ? 1 : 0) +
(wedgeSize == 6 and array.get(fBarArray, i) == fBar ? 1 :
0)
if(not existingPattern)
aRatio = math.abs(a-b)/math.abs(b-c)
bRatio = math.abs(b-c)/math.abs(c-d)
cRatio = math.abs(c-d)/math.abs(d-e)
dRatio = math.abs(d-e)/math.abs(e-f)
zgColor = array.pop(themeColors)
[l1t, l2t, l1Angle, l2Angle, l1Diff, l2Diff] = wedgeLine(eBar, e, aBar, a,
wedgeSize == 6?fBar:dBar, wedgeSize == 6?f:d, bBar, b, zgColor)
isType1Wedge = aRatio >=1 and bRatio < 1 and cRatio >= 1 and (dRatio < 1 or
wedgeSize==5) and l1Diff < l2Diff
isType2Wedge = aRatio <1 and bRatio >= 1 and cRatio < 1 and (dRatio >=1 or
wedgeSize==5) and l1Diff > l2Diff
angleDiff = math.abs(l1Angle-l2Angle)
angleDiffInRange = (angleDiff >= minAngleDiff and angleDiff <=
maxAngleDiff) or not applyAngleDiff
angleInRange = (math.max(math.abs(l1Angle), math.abs(l2Angle)) >=
minAngleRange and math.min(math.abs(l1Angle), math.abs(l2Angle)) <= maxAngleRange)
or not applyAngleLimit
isWedge = (isType1Wedge or isType2Wedge) and angleDiffInRange and
angleInRange
if(isWedge)
for i = aBar to lastPivotBar
l = low[bar_index-i]
h = high[bar_index-i]
l1Price = line.get_price(l1t, i)
l2Price = line.get_price(l2t, i)
if(h < math.min(l1Price, l2Price) or l > math.max(l1Price,
l2Price))
isWedge := false
break
if(i == cBar and (l1Price > h or l1Price < l))
isWedge := false
break
if(i == dBar and (l2Price > h or l2Price < l))
isWedge := false
break
if isWedge
wedgeType = isType1Wedge? 1 : 2
add_new_wedge(a,b,c,d,e,f,aBar,bBar,cBar,dBar,eBar,fBar,l1Angle,
l2Angle, zgColor, wedgeSize)
length = array.size(zigzagpivots)
xIndexes = utils.get_trend_series(zigzagpivots, fIndex, length)
isFlag = false
for i=array.size(xIndexes)-1 to 0
xIndex = array.get(xIndexes, i)
x = array.get(zigzagpivots, xIndex)
xBar = array.get(zigzagpivotbars, xIndex)
flagRatio = math.abs(lastPivot-line.get_price(wedgeSize == 6?
l1t:l2t, lastPivotBar))/math.abs(x-lastPivot)
startIndex = 0
if(showZigZag1)
[zigzagpivots, zigzagpivotbars, zigzagpivotdirs, zigzagpivotratios, _, _, _, _,
_, newPivot, doublePivot] = zg.czigzag(zigzag1Length)
var lastABar = 0
lastABar := scan_patterns(startIndex+1, doublePivot, zigzagpivots,
zigzagpivotbars, zigzagpivotratios, zigzagpivotdirs, lastABar)
lastABar := scan_patterns(startIndex, newPivot, zigzagpivots, zigzagpivotbars,
zigzagpivotratios, zigzagpivotdirs, lastABar)
if(showZigZag2)
[zigzagpivots, zigzagpivotbars, zigzagpivotdirs, zigzagpivotratios, _, _, _, _,
_, newPivot, doublePivot] = zg.czigzag(zigzag2Length)
var lastABar = 0
lastABar := scan_patterns(startIndex+1, doublePivot, zigzagpivots,
zigzagpivotbars, zigzagpivotratios, zigzagpivotdirs, lastABar)
lastABar := scan_patterns(startIndex, newPivot, zigzagpivots, zigzagpivotbars,
zigzagpivotratios, zigzagpivotdirs, lastABar)
if(showZigZag3)
[zigzagpivots, zigzagpivotbars, zigzagpivotdirs, zigzagpivotratios, _, _, _, _,
_, newPivot, doublePivot] = zg.czigzag(zigzag3Length)
var lastABar = 0
lastABar := scan_patterns(startIndex+1, doublePivot, zigzagpivots,
zigzagpivotbars, zigzagpivotratios, zigzagpivotdirs, lastABar)
lastABar := scan_patterns(startIndex, newPivot, zigzagpivots, zigzagpivotbars,
zigzagpivotratios, zigzagpivotdirs, lastABar)
if(showZigZag4)
[zigzagpivots, zigzagpivotbars, zigzagpivotdirs, zigzagpivotratios, _, _, _, _,
_, newPivot, doublePivot] = zg.czigzag(zigzag4Length)
var lastABar = 0
lastABar := scan_patterns(startIndex+1, doublePivot, zigzagpivots,
zigzagpivotbars, zigzagpivotratios, zigzagpivotdirs, lastABar)
lastABar := scan_patterns(startIndex, newPivot, zigzagpivots, zigzagpivotbars,
zigzagpivotratios, zigzagpivotdirs, lastABar)
if not na(ph)
allPH.push(ph)
allPHIndex.push(bar_index[pivotLeg])
allPHIndex.shift()
allPH.shift()
if not na(pl)
allPL.push(pl)
allPLIndex.push(bar_index[pivotLeg])
allPL.shift()
allPLIndex.shift()
var rsIndex = 0
var rsPrice = 0.0
var headPrice = 0.0
rsIndex := allPHIndex.last()
rsPrice := allPH.last()
headPrice := allPH.get(1)
if shortCondition
alert("Confirm H & S Sell in : " + syminfo.ticker,
alert.freq_once_per_bar_close)
if shortCondition
HSNeckLineA := drawLine(neckIndex, neckPrice, bar_index, neckPrice, color.red)
HSNeckLineA.set_style(line.style_dotted)
//#endregion
var ivRSIndex = 0
var ivRSPrice = 0.0
var ivHeadPrice = 0.0
ivRSNeckIndex := allPHIndex.last()
ivRSNeckPrice := allPH.last()
ivRSIndex := allPLIndex.last()
ivRSPrice := allPL.last()
ivHeadPrice := allPL.get(1)
if longCondition
alert("Confirm H & S Buy in : " + syminfo.ticker,
alert.freq_once_per_bar_close)
if longCondition
ivHSNeckLineA := drawLine(ivRSNeckIndex, ivRSNeckPrice, bar_index,
ivRSNeckPrice)
ivHSNeckLineA.set_style(line.style_dotted)
//#endregion
int max_array_size = 10
max_bars_back(high, 1000)
max_bars_back(low, 1000)
zigzag(length) =>
[dir, ph, pl] = pivots(length)
dirchanged = ta.change(dir)
if ph or pl
add_to_zigzag(dir, dirchanged, ph, pl, bar_index)
calculate_double_pattern() =>
doubleTop = false
doubleTopConfirmation = 0
doubleBottom = false
doubleBottomConfirmation = 0
if array.size(zigzagvalues) >= 4
index = array.get(zigzagindexes, 1)
value = array.get(zigzagvalues, 1)
highLow = array.get(zigzagdir, 1)
lindex = array.get(zigzagindexes, 2)
lvalue = array.get(zigzagvalues, 2)
lhighLow = array.get(zigzagdir, 2)
llindex = array.get(zigzagindexes, 3)
llvalue = array.get(zigzagvalues, 3)
llhighLow = array.get(zigzagdir, 3)
risk = math.abs(value - llvalue)
reward = math.abs(value - lvalue)
riskPerReward = risk * 100 / (risk + reward)
if doubleTop or doubleBottom
array.set(doubleTopBottomValues, 0, value)
array.set(doubleTopBottomValues, 1, lvalue)
array.set(doubleTopBottomValues, 2, llvalue)
array.set(doubleTopBottomIndexes, 0, index)
array.set(doubleTopBottomIndexes, 1, lindex)
array.set(doubleTopBottomIndexes, 2, llindex)
array.set(doubleTopBottomDir, 0, highLow)
array.set(doubleTopBottomDir, 1, lhighLow)
array.set(doubleTopBottomDir, 2, llhighLow)
[doubleTop, doubleBottom]
llindex = array.get(doubleTopBottomIndexes, 2)
llvalue = array.get(doubleTopBottomValues, 2)
llhighLow = array.get(doubleTopBottomDir, 2)
latestDoubleTop = false
latestDoubleBottom = false
latestDoubleTop := doubleTop ? true : doubleBottom ? false : latestDoubleTop[1]
latestDoubleBottom := doubleBottom ? true : doubleTop ? false :
latestDoubleBottom[1]
doubleTopConfirmation = 0
doubleBottomConfirmation = 0
doubleTopConfirmation := latestDoubleTop ? ta.crossunder(low, lvalue) ? 1 :
ta.crossover(high, llvalue) ? -1 : 0 : 0
doubleBottomConfirmation := latestDoubleBottom ? ta.crossover(high, lvalue) ? 1
: ta.crossunder(low, llvalue) ? -1 : 0 : 0
[doubleTopConfirmation, doubleBottomConfirmation]
lindex = array.get(doubleTopBottomIndexes, 1)
lvalue = array.get(doubleTopBottomValues, 1)
lhighLow = array.get(doubleTopBottomDir, 1)
llindex = array.get(doubleTopBottomIndexes, 2)
llvalue = array.get(doubleTopBottomValues, 2)
llhighLow = array.get(doubleTopBottomDir, 2)
isBullish = true
isBullish := doubleTop or doubleBottom ? doubleTop : isBullish[1]
if not(doubleTop or doubleBottom)
line.delete(base)
line.delete(l1)
line.delete(l2)
label.delete(baseLabel)
var doubleTopCount = 0
var doubleBottomCount = 0
doubleTopCount := doubleTop ? nz(doubleTopCount[1], 0) + 1 :
nz(doubleTopCount[1], 0)
doubleBottomCount := doubleBottom ? nz(doubleBottomCount[1], 0) + 1 :
nz(doubleBottomCount[1], 0)
if line.get_x2(base) == line.get_x2(base[1])
line.delete(base[1])
line.delete(l1[1])
line.delete(l2[1])
label.delete(baseLabel[1])
doubleTopCount := doubleTop ? doubleTopCount - 1 : doubleTopCount
doubleBottomCount := doubleBottom ? doubleBottomCount - 1 :
doubleBottomCount
doubleBottomCount
if barstate.islast
lres = line.new(x1=bar_index, y1=lvalue, x2=lindex, y2=lvalue,
color=isBullish ? bearishColor : bullishColor, width=2, style=line.style_dashed,
extend=extend.left)
lsup = line.new(x1=bar_index, y1=llvalue, x2=llindex, y2=llvalue,
color=isBullish ? bullishColor : bearishColor, width=2, style=line.style_dashed,
extend=extend.left)
lsup
if doubleTopConfirmation != 0 or doubleBottomConfirmation != 0
if doubleTopConfirmation > 0 or doubleBottomConfirmation > 0
lresbreak = line.new(x1=lindex, y1=lvalue, x2=bar_index, y2=lvalue,
color=isBullish ? bearishColor : bullishColor, width=2, style=line.style_dashed)
if line.get_x1(lresbreak[1]) == line.get_x1(lresbreak)
doubleTopConfirmationCount := 0
doubleBottomConfirmationCount := 0
doubleTopInvalidationCount := 0
doubleBottomInvalidationCount := 0
line.delete(lresbreak)
lresbreak := lresbreak[1]
lresbreak
else if doubleTopConfirmation < 0 or doubleBottomConfirmation < 0
lsupbreak = line.new(x1=llindex, y1=llvalue, x2=bar_index, y2=llvalue,
color=isBullish ? bullishColor : bearishColor, width=2, style=line.style_dashed)
if line.get_x1(lsupbreak[1]) == line.get_x1(lsupbreak)
doubleTopInvalidationCount := 0
doubleBottomInvalidationCount := 0
doubleTopConfirmationCount := 0
doubleBottomConfirmationCount := 0
line.delete(lsupbreak)
lsupbreak := lsupbreak[1]
lsupbreak
doubleTopConfirmationCount := nz(doubleTopConfirmationCount[1], 0) +
doubleTopConfirmationCount
doubleBottomConfirmationCount := nz(doubleBottomConfirmationCount[1], 0) +
doubleBottomConfirmationCount
doubleTopInvalidationCount := nz(doubleTopInvalidationCount[1], 0) +
doubleTopInvalidationCount
doubleBottomInvalidationCount := nz(doubleBottomInvalidationCount[1], 0) +
doubleBottomInvalidationCount
[doubleTopCount, doubleBottomCount, doubleTopConfirmationCount,
doubleBottomConfirmationCount, doubleTopInvalidationCount,
doubleBottomInvalidationCount]
zigzag(length)
array.unshift(lineArray, l)
if array.size(lineArray) > 100
line.delete(array.pop(lineArray))
//alertcondition(doubleBottom, 'Double Bottom', 'Probable double bottom observed
for {{ticker}} on {{interval}} timeframe')
//alertcondition(doubleBottomConfirmation > 0, 'Double Bottom Confirmation',
'Double bottom confirmation observed for {{ticker}} on {{interval}} timeframe')
//alertcondition(doubleBottomConfirmation < 0, 'Double Bottom Invalidation',
'Double bottom invalidation observed for {{ticker}} on {{interval}} timeframe')
//alertcondition(doubleTop, 'Double Top', 'Probable double top observed for
{{ticker}} on {{interval}} timeframe')
//alertcondition(doubleTopConfirmation > 0, 'Double Top Confirmation', 'Double top
confirmation observed for {{ticker}} on {{interval}} timeframe')
//alertcondition(doubleTopConfirmation < 0, 'Double Top Invalidation', 'Double top
invalidation observed for {{ticker}} on {{interval}} timeframe')
//---------------------------------------------------------------------------------
----------------
var line l1 = na
var line l2 = na
bool alertcon = na
candle=math.abs(high-low)
body = math.abs(open - close)
EvnCan = body > candle * 0.6 and open > close and body[1] < candle[1] * 0.3 and
body[2] > candle[2] * 0.6 and open[2] < close[2]
BInBar = high < high[1] and low > low[1] and body[1] > candle[1] * 0.4
if PivotHigh > 0
if NoOfPivots == 2 and HighAtPivot < HighAtPivot1 and HighAtPivot >
UpperAtPivot1
RZoneH := HighAtPivot1
RZoneL := UpperAtPivot1
alertcon := true
l1 := line.new( IndexOfPivot1 , HighAtPivot1 , bar_index , HighAtPivot1 ,
color = color.red)
l2 := line.new( IndexOfPivot1 , UpperAtPivot1 , bar_index , UpperAtPivot1 ,
color = color.red)
BodyPerc = (body/candle)*100
tbc = low > (low[1] - bperc) and low < (low[1] + bperc) and (close > (low[1] +
bpercc )) and (open[1] > close[1]) and (close[1] - low[1] < bperc) and (open - low
< bperc) and (BodyPerc > 60) and ( BodyPerc[1] > 60 )
ttc = high > (high[1] - bperc) and high < (high[1] + bperc) and (close < (high[1]
- bpercc )) and (open[1] < close[1]) and ((high[1] - close[1]) < bperc) and
(( high - open) < bperc) and (BodyPerc > 60) and ( BodyPerc[1] > 60 )
TTopH = ta.valuewhen(ttc , math.max(high , high[1] ), 0)
line.set_x2(l1 , bar_index)
line.set_x2(l2 , bar_index)
linefill.new(l1, l2 , color = color.new(color.red, 80))
var line l4 = na
var line l3 = na
if PivotLow> 0
if NoOfPivots == 2 and LowAtPivot > LowAtPivot1 and LowAtPivot < LowerAtPivotl
alertcon := true
SZoneL := LowAtPivot1
SZoneH := LowerAtPivotl
MorCan = body > candle * 0.6 and open < close and body[1] < candle[1] * 0.3 and
body[2] > candle[2] * 0.6 and open[2] > close[2]
BullInBar = high < high[1] and low > low[1] and body[1] > candle[1] * 0.4
line.set_x2(l4 , bar_index)
line.set_x2(l3 , bar_index)
linefill.new(l4, l3 , color = color.new(color.green, 80))
//