customStrongLevels.txt
Copy
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ashwagamma
//@version=6
indicator("customStrongLevels", overlay=true, max_boxes_count = 100, max_lines_count = 200, max_labels_count = 200)
type Level
float level = na
int bar_time = na
int bar_index = na
float pts = 0
bool is_breached = false
float move1_len = 0
float max_allowed_slope = 100000
type intrabarData
float[] _open = na
float[] _high = na
float[] _low = na
float[] _close = na
float[] _volume = na
bool[] _barstateisconfirmed = na
int[] _baridx = na
var intrabarData lastBarData = na
var intrabarData cumBarData = na
var float highestHigh = 0
var float lowestLow = 100000
var int lastLowBarTime = 0
var int lastHighBarTime = 0
var int lastLowBarIndex = 0
var int lastHighBarIndex = 0
var bool isLastFoundLow = false
colorRes = input.color(color.blue, title = "Resistance Color", group = "Style Settings")
colorSup = input.color(color.fuchsia, title = "Support Color", group = "Style Settings")
bool flag_enTLs = input.bool(true, "Enable Trendlines?")
int NP = timeframe.period == "15" ? 30: (timeframe.period == "60" ? 100: (timeframe.period == "240" ? 175: timeframe.period == "480" ? 250: 20))
//log.info('NP={0}', NP)
int nearTermPeriod = input.int(21, 'nearTermPeriod')
int numMaxLevels = input.int(20, 'Max Levels')
int numMaxTLs = input.int(20, 'Num Max Trendlines')
//int MinRallyLength = input.int(NP, 'Min Rally Length')
//int MinDipLength = input.int(NP, 'Min Dip Length')
//int numPtsTLLow = input.int(NP, 'Num pts for TL lows')
int numErrorMarginPoints = input.int(3, 'Number of Error Margin Points')
int MinRallyLength = NP
int MinDipLength = NP
int numPtsTLLow = NP
var Level[] listStrongLowObj = array.new<Level>(0)
var float[] listStrongLowLevels = array.new_float(0)
var Level[] listStrongHighObj = array.new<Level>(0)
var float[] listStrongHighLevels = array.new_float(0)
var line[] listSupLines = array.new_line(0)
var label[] listSupLabels = array.new_label(0)
var line[] listResLines = array.new_line(0)
var label[] listResLabels = array.new_label(0)
var line[] listTLsConnectLows = array.new_line(0)
var line[] listTLsConnectLowsOrigin = array.new_line(0)
var label[] listTLLabelConnectLows = array.new_label(0)
var line[] listTLsConnectHighs = array.new_line(0)
var float[] listLowTLLevels = array.new_float(0)
var line[] listLineTLLows = array.new_line(0)
var label[] listLabelTLLows = array.new_label(0)
var bool isTLPlotted = false
line _line = na
color[] TLColorList = array.from(color.green,color.blue,color.fuchsia,color.orange,color.red,color.black)
var float trigger_low = na
var float last_trigger_low = na
var float trigger_low_time = na
var int[] buy_triggered_bar_idx = array.new_int(0)
var line _trendline = line.new(time, 0, time+1, 0, xloc=xloc.bar_time, color=color.blue, extend = extend.right)
[open_ltf,high_ltf,low_ltf,close_ltf,volume_ltf,bic_ltf,bidx_ltf] = request.security_lower_tf(syminfo.tickerid, "1", [open, high, low, close, volume, barstate.isconfirmed, bar_index])
//log.info("test2={0}", o1)
float[] _close = array.new_float(0)
float[] _open = array.new_float(0)
float[] _high = array.new_float(0)
if not na(lastBarData)
cumBarData := intrabarData.new(array.concat(array.copy(lastBarData._open), array.copy(open_ltf)), array.concat(array.copy(lastBarData._high), array.copy(high_ltf)), array.concat(array.copy(lastBarData._low), array.copy(low_ltf)), array.concat(array.copy(lastBarData._close), array.copy(close_ltf)), array.concat(array.copy(lastBarData._volume), array.copy(volume_ltf)), array.concat(array.copy(lastBarData._barstateisconfirmed), array.copy(bic_ltf)), array.concat(array.copy(lastBarData._baridx), array.copy(bidx_ltf)))
//log.info('test={0}', cumBarData._open)
if array.size(cumBarData._close) > 3
for i = 0 to array.size(cumBarData._barstateisconfirmed)-1
if cumBarData._barstateisconfirmed.get(i)
_close.push(cumBarData._close.get(i))
_open.push(cumBarData._open.get(i))
_high.push(cumBarData._high.get(i))
int tct = ta.change(time)
var int startTimePrevTradingDay = na
var int startTime1D = na
var int startTime = na
var int endTime = na
if timeframe.change("1D") and (timenow-time < 7*24*60*60*1000)
startTime1D := time
startTime := time - timeframe.in_seconds("1D") * 10000
endTime := time + timeframe.in_seconds("1D") * 1000
startTimePrevTradingDay := time - tct
if tct > 0
lastBarData := intrabarData.new(open_ltf, high_ltf, low_ltf, close_ltf, volume_ltf, bic_ltf, bidx_ltf)
//[open_1,high_1,low_1,hml_1,close_1,volume_1,bic_1,bidx_1] = request.security_lower_tf(syminfo.tickerid, "1", [open, high, low, high-low, close, volume, barstate.isconfirmed, bar_index])
//[open_5,high_5,low_5,close_5,volume_5,bic_5,bidx_5] = request.security_lower_tf(syminfo.tickerid, "5", [open, high, low, close, volume, barstate.isconfirmed, bar_index])
//sz = open_1.size()
//plot(5950+array.max(hml_1), color=color.red)
var float lastPush = na
if barstate.isconfirmed and tct > 0 and open_ltf.size()>0
//log.info('barchange, index={0}',bar_index)
//if not na(cumBarData)
// log.info("cumBarData._open={0}", cumBarData._open)
//log.info('hH={0}, LL={1}, h-LL={2}, HH-l={3}, high={4}, low={5}, isLastFoundLow={6}, bar_index={7}', highestHigh, lowestLow, high-lowestLow, highestHigh-low, high, low, isLastFoundLow, bar_index)
if low < lowestLow
lowestLow := low
lastLowBarTime := time
lastLowBarIndex := bar_index
if isLastFoundLow
if (highestHigh-low > MinDipLength)
if not(array.includes(listStrongHighLevels, highestHigh))
listStrongHighObj.push(Level.new(highestHigh, lastHighBarTime, lastHighBarIndex, 0))
listStrongHighLevels.push(highestHigh)
listResLines.push(line.new(lastHighBarTime, highestHigh, time, highestHigh, xloc=xloc.bar_time, color=colorRes))
listResLabels.push(label.new((lastHighBarTime+time)/2, highestHigh, "", xloc=xloc.bar_time, size=size.small, color=na, textcolor = colorRes, style=label.style_label_up))
isLastFoundLow := false
//log.info('listStrongHighLevels={0}', listStrongHighLevels)
while array.size(listStrongHighLevels) > numMaxLevels
listStrongHighLevels.shift()
listStrongHighObj.shift()
listResLines.shift()
listResLabels.shift()
else
highestHigh := high
if high > highestHigh
highestHigh := high
lastHighBarTime := time
lastHighBarIndex := bar_index
if not(isLastFoundLow)
if(high-lowestLow>MinRallyLength)
if(not(array.includes(listStrongLowLevels, lowestLow)))
if listStrongLowObj.size()>0
for i = 0 to listStrongLowObj.size()-1
Level _level = listStrongLowObj.get(i)
_level.max_allowed_slope := math.min(_level.max_allowed_slope, (lowestLow-_level.level)/(lastLowBarIndex-_level.bar_index))
listStrongLowObj.push(Level.new(lowestLow, lastLowBarTime, lastLowBarIndex, 0))
listStrongLowLevels.push(lowestLow)
listSupLines.push(line.new(lastLowBarTime, lowestLow, lastLowBarTime, lowestLow, xloc=xloc.bar_time, color=colorSup))
listSupLabels.push(label.new(lastLowBarTime, lowestLow, "", xloc=xloc.bar_time, size=size.small, color=na, textcolor = colorSup, style=label.style_label_up))
isLastFoundLow := true
lastPush := lowestLow
N = listStrongLowLevels.size()
if N > 2
float max_high_between = 0
if listStrongHighObj.size() > 0
for k = 0 to listStrongHighObj.size()-1
if listStrongHighObj.get(k).bar_index > listStrongLowObj.get(N-2).bar_index and listStrongHighObj.get(k).bar_index < listStrongLowObj.get(N-1).bar_index
max_high_between := math.max(max_high_between, listStrongHighObj.get(k).level)
Level _level = listStrongLowObj.get(N-2)
_level.move1_len := max_high_between-_level.level
//log.info('listStrongLowLevels={0}', listStrongLowLevels)
while array.size(listStrongLowLevels) > numMaxLevels
listStrongLowLevels.shift()
listStrongLowObj.shift()
listSupLines.shift()
listSupLabels.shift()
else
lowestLow := low
// Increment rally length and max allowed slope
if listStrongLowObj.size()>0
for i = 0 to listStrongLowObj.size()-1
Level _level = listStrongLowObj.get(i)
if not(_level.is_breached)
_level.pts := math.max(_level.pts, high-_level.level)
if listStrongHighObj.size()>0
for i = 0 to listStrongHighObj.size()-1
Level _level = listStrongHighObj.get(i)
if not(_level.is_breached)
_level.pts := math.max(_level.pts, _level.level-low)
// Eliminating levels
if listStrongLowLevels.size() > 0
for j = 0 to listStrongLowLevels.size()-1
i = listStrongLowLevels.size()-1-j
if low - listStrongLowLevels.get(i) < -1*listStrongLowObj.get(i).pts/5
//line _line1 = listSupLines.get(i).copy()
array.remove(listStrongLowLevels,i)
array.remove(listStrongLowObj,i)
array.remove(listSupLines,i)
array.remove(listSupLabels,i)
else if low < listStrongLowLevels.get(i)
Level _level = listStrongLowObj.get(i)
_level.is_breached := true
// Update labels
if listStrongLowObj.size() > 0
for i = 0 to listStrongLowObj.size()-1
array.get(listSupLines, i).set_x2(time)
array.get(listSupLabels, i).set_x((listStrongLowObj.get(i).bar_time+time)/2)
array.get(listSupLabels, i).set_text(str.tostring(math.round(listStrongLowObj.get(i).level))+"("+str.tostring(math.round(listStrongLowObj.get(i).pts))+":"+str.tostring(math.round((time-listStrongLowObj.get(i).bar_time)/(1000*60*60)))+")")
// Eliminating levels
if listStrongHighLevels.size() > 0
for j = 0 to listStrongHighLevels.size()-1
i = listStrongHighLevels.size()-1-j
if high - listStrongHighLevels.get(i) > numErrorMarginPoints
//line _line1 = listResLines.get(i).copy()
array.remove(listStrongHighLevels,i)
array.remove(listStrongHighObj,i)
array.remove(listResLines,i)
array.remove(listResLabels,i)
else if high > listStrongHighLevels.get(i)
Level _level = listStrongHighObj.get(i)
_level.is_breached := true
if listStrongHighLevels.size() > 0
for i = 0 to listStrongHighLevels.size()-1
array.get(listResLines, i).set_x2(time)
array.get(listResLabels, i).set_x((listStrongHighObj.get(i).bar_time+time)/2)
array.get(listResLabels, i).set_text(str.tostring(math.round(listStrongHighObj.get(i).level))+"("+str.tostring(math.round(listStrongHighObj.get(i).pts))+")")
if barstate.islast or (not(isTLPlotted) and barstate.islastconfirmedhistory)
isTLPlotted := true
if listTLsConnectLows.size() > 0
for i = 0 to listTLsConnectLows.size()-1
listTLsConnectLows.get(i).delete()
listTLsConnectLowsOrigin.get(i).delete()
listTLLabelConnectLows.get(i).delete()
listLineTLLows.get(i).delete()
listLabelTLLows.get(i).delete()
listTLsConnectLows.clear()
listTLsConnectLowsOrigin.clear()
listTLLabelConnectLows.clear()
listLowTLLevels.clear()
listLineTLLows.clear()
listLabelTLLows.clear()
//Construct the TLs
if listStrongLowLevels.size() > 1 and flag_enTLs
idx = 0
for i = 0 to listStrongLowObj.size()-2
if listStrongLowObj.get(i).pts > numPtsTLLow
if idx > numMaxTLs
if listTLsConnectLows.size() > 0
//log.info('how did i get here??')
listTLsConnectLows.get(0).delete()
listTLsConnectLowsOrigin.get(0).delete()
listLineTLLows.get(0).delete()
listLabelTLLows.get(0).delete()
listTLLabelConnectLows.get(0).delete()
listTLsConnectLows.shift()
listTLsConnectLowsOrigin.shift()
listLineTLLows.shift()
listLabelTLLows.shift()
listTLLabelConnectLows.shift()
listLowTLLevels.shift()
idx := idx - 1
//break
for j = i+1 to listStrongLowObj.size()-1
if listStrongLowObj.get(j).pts > numPtsTLLow
// check if any lows between i and j are below this TL, if not can add this TL
x1 = listStrongLowObj.get(i).bar_index
y1 = listStrongLowObj.get(i).level
x2 = listStrongLowObj.get(j).bar_index
y2 = listStrongLowObj.get(j).level
slope = (y2-y1)/(x2-x1)
intercept = y1-slope*x1
bool isTLok = true
//log.info('listStrong LowLevels={0}', str.tostring(listStrongLowLevels))
//log.info('listStrongHighLevels={0}', str.tostring(listStrongHighLevels))
//log.info('max_high_between_ij={0},{1},{2}', listStrongLowObj.get(i).move1_len, listStrongLowObj.get(i).level, listStrongLowObj.get(j).level)
//isTLok := isTLok and (listStrongLowObj.get(j).pts > 0.8*listStrongLowObj.get(i).move1_len)
// check if there is any strong low inbetween the lows, TL won't be plotted if there is
if j-i > 1
for k = i+1 to j-1
x3 = listStrongLowObj.get(k).bar_index
y3 = listStrongLowObj.get(k).level
determinant = (x2-x1)*(y3-y1)-(y2-y1)*(x3-x1)
isTLok := isTLok and (determinant > 0)
//log.info('det={0},{1}::{2},{3}::{4},{5},{6},{7}',str.tostring(x1),str.tostring(y1),str.tostring(x2),str.tostring(y2),str.tostring(x3),str.tostring(y3),str.tostring(determinant),isTLok)
//log.info('det={0},{1},{2},{3},{4},{5}',str.tostring(y1),str.tostring(y2),str.tostring(y3),str.tostring(determinant),isTLok,numMaxTLs)
levelTL_curbar = math.round((slope*bar_index+intercept)*4)/4
isTLok := isTLok and (levelTL_curbar - low < numPtsTLLow)
//log.info('isTLok={0},a,{1},{2}', isTLok, slope, listStrongLowObj.get(i).max_allowed_slope)
isTLok := isTLok and (slope <= listStrongLowObj.get(i).max_allowed_slope)
isTLok := isTLok and (listStrongLowObj.get(i).pts/listStrongLowObj.get(j).pts < 2)
//log.info('isTLok={0},b,{1},{2}', isTLok, slope, listStrongLowObj.get(i).max_allowed_slope)
if isTLok
//log.info('isTLok={0},Y_tlpushed,{1},{2}',isTLok,i,j)
listTLsConnectLows.push(line.new(listStrongLowObj.get(i).bar_time, y1, listStrongLowObj.get(j).bar_time, y2, xloc=xloc.bar_time, color=color.green, extend = extend.right, style = line.style_dashed))
listTLsConnectLowsOrigin.push(line.new(listStrongLowObj.get(i).bar_time, y1, listStrongLowObj.get(j).bar_time, y2, xloc=xloc.bar_time, color=color.green, width=2))
listLowTLLevels.push(levelTL_curbar)
listLineTLLows.push(line.new(bar_index, levelTL_curbar, bar_index+10, levelTL_curbar, xloc=xloc.bar_index, color=color.green))
listLabelTLLows.push(label.new(bar_index+11, levelTL_curbar, str.tostring(levelTL_curbar), xloc=xloc.bar_index, size=size.small, color=na, textcolor = color.green, style=label.style_label_lower_left, textalign = text.align_center))
//listTLLabelConnectLows.push(label.new((listStrongLowObj.get(i).bar_time+listStrongLowObj.get(j).bar_time)/2, (y1+y2)/2, str.tostring(math.round(slope,2))+"["+str.tostring(math.round(listStrongLowObj.get(i).max_allowed_slope,2))+"]", xloc=xloc.bar_time, size=size.small, color=na, textcolor = color.green, style=label.style_label_up))
listTLLabelConnectLows.push(label.new((listStrongLowObj.get(i).bar_time+listStrongLowObj.get(j).bar_time)/2, (y1+y2)/2, "", xloc=xloc.bar_time, size=size.small, color=na, textcolor = color.green, style=label.style_label_up))
idx := idx+1
//else
// log.info('N_tlpushed,{0},{1}',i,j)
//log.info("{0}, {1}:{2}=",idx, i,j)
//log.info('listStrongLowLevelsA={0},listTLsConnectLows.size()={1}', str.tostring(listStrongLowLevels), listTLsConnectLows.size())
//log.info("listLowTLLevels={0}",listLowTLLevels)
Show all 316 lines