Pawn Algo
Pawn Algo
//Style
obStyleGroup = 'Order & Propulsion Blocks Style'
//---------------------------------------------------------------------------------
------------------------------------}
// User Defined Types
//---------------------------------------------------------------------------------
------------------------------------{
type BAR
float open = open
float high = high
float low = low
float close = close
int index = bar_index
type OrderBlock
int startIndex = bar_index
int endIndex = na
int confirmedIndex = na
float open = na
float high = na
float low = na
float close = na
line meanThresholdLine
label propulsionLabel
box orderblockLevelBox
bool isPropulsion
type SWING
float value = na
int index = na
bool cross = false
//---------------------------------------------------------------------------------
------------------------------------}
// Variables
//---------------------------------------------------------------------------------
------------------------------------{
if obBlockLabels
this.orderblockLevelBox.set_text((isPropulsion ? 'PB' : 'OB')) //
(isBullish? '▲' : '▼') +
this.orderblockLevelBox.set_text_color(color.new(color, 4))
if isPropulsion
this.meanThresholdLine.set_xy1(left , math.avg(obOpen, obClose))
this.meanThresholdLine.set_xy2(right, math.avg(obOpen, obClose))
this.meanThresholdLine.set_color(color.new(color, 4))
if pbPropulsionBlock
this.propulsionLabel.set_xy(left, isBullish ? obLow : obHigh)
this.propulsionLabel.set_textcolor(color.new(color, 4))
swings(length)=>
var os = 0
var SWING swingHigh = SWING.new(na, na)
var SWING swingLow = SWING.new(na, na)
upper = ta.highest(length)
lower = ta.lowest (length)
if os == 0 and os[1] != 0
swingHigh := SWING.new(high[length], bar_index[length])
if os == 1 and os[1] != 1
swingLow := SWING.new(low[length], bar_index[length])
[swingHigh, swingLow]
if obBullArray.size() > 0
currentOrderBlock = obBullArray.get(0)
if bar.low <= currentOrderBlock.high and bar.low > currentOrderBlock.low
and bar.index > currentOrderBlock.confirmedIndex and not
currentOrderBlock.isMitigated and currentOrderBlock.isActive and not
currentOrderBlock.isPropulsion and bar.open > currentOrderBlock.high
breachLow := math.min(bar.low, breachLow[1])
breachHigh := breachLow == bar.low ? bar.high : breachHigh[1]
breachIndex := breachLow == bar.low ? bar.index : breachIndex[1]
bullishBreachHigh := SWING.new(breachHigh, breachIndex)
//log.info("yaz_kizim {0} {1}", bar.low, bar.index)
if obBearArray.size() > 0
currentOrderBlock = obBearArray.get(0)
if bar.high >= currentOrderBlock.low and bar.high < currentOrderBlock.high
and bar.index > currentOrderBlock.confirmedIndex and not
currentOrderBlock.isMitigated and currentOrderBlock.isActive and not
currentOrderBlock.isPropulsion and bar.open < currentOrderBlock.low
breachHigh := math.max(bar.high, breachHigh[1])
breachLow := breachHigh == bar.high ? bar.low : breachLow[1]
breachIndex := breachHigh == bar.high ? bar.index : breachIndex[1]
bearishBreachLow := SWING.new(breachLow, breachIndex)
[bullishBreachHigh, bearishBreachLow]
//---------------------------------------------------------------------------------
------------------------------------}
// Calculations
//---------------------------------------------------------------------------------
------------------------------------{
if obShowBullish
if bar.close > swingHigh.value and not swingHigh.cross
swingHigh.cross := true
if bullishOrderBlockArray.size() > 0
recentOrderBlock = bullishOrderBlockArray.get(0)
recentOrderBlock := bullishOrderBlockArray.get(0)
previousOrderBlock = bullishOrderBlockArray.get(1)
previousOrderBlock.isActive := false
else
bullishOrderBlockArray.unshift(OrderBlock.new(obBar.index, bar.index,
bar.index, obBar.open, obBar.high, obBar.low, obBar.close,
line.new(na, na, na, na, color = color(na), style =
line.style_dotted),
label.new(na, na, '▲', style = label.style_label_up, color =
color(na), size = size.small, textcolor = color(na)),
box.new(na, na, na, na, color(na), text_size = obTextSize,
text_halign = text.align_right, text_valign = text.align_top), false))
if bullishOrderBlockArray.size() > 0
recentOrderBlock = bullishOrderBlockArray.get(0)
recentOrderBlock.isActive := false
recentOrderBlock.obSetRight(bar.index)
bullishOrderBlockArray.unshift(OrderBlock.new(bar.index[bar.index -
bullishBreachHigh.index], bar.index, bar.index, bar.open[bar.index -
bullishBreachHigh.index], bullishBreachHigh.value, bar.low[bar.index -
bullishBreachHigh.index], bar.close[bar.index - bullishBreachHigh.index],
line.new(na, na, na, na, color = color(na), style =
line.style_dotted),
label.new(na, na, '▲', style = label.style_label_up, color =
color(na), size = size.small, textcolor = color(na)),
box.new(na, na, na, na, color(na), text_size = obTextSize,
text_halign = text.align_right, text_valign = text.align_top), true))
if not currentOrderBlock.isProcessed
currentOrderBlock.obRender(currentOrderBlock.startIndex, bar.index,
currentOrderBlock.open, currentOrderBlock.high, currentOrderBlock.low,
currentOrderBlock.close, currentOrderBlock.isPropulsion ? pbBullishColor :
obBullishColor, currentOrderBlock.isPropulsion, true)
currentOrderBlock.isProcessed := true
currentOrderBlock.obSetRight(bar.index)
if obMostRecent
if bullishOrderBlockArray.size() > obMostRecentValue
currentOrderBlock = bullishOrderBlockArray.pop()
currentOrderBlock.obDelete()
else
if bullishOrderBlockArray.size() > 125
currentOrderBlock = bullishOrderBlockArray.pop()
currentOrderBlock.obDelete()
if obShowBearish
if bar.close < swingLow.value and not swingLow.cross
swingLow.cross := true
if bearishOrderBlockArray.size() > 0
recentOrderBlock = bearishOrderBlockArray.get(0)
recentOrderBlock := bearishOrderBlockArray.get(0)
previousOrderBlock = bearishOrderBlockArray.get(1)
previousOrderBlock.isActive := false
else
bearishOrderBlockArray.unshift(OrderBlock.new(obBar.index, bar.index,
bar.index, obBar.open, obBar.high, obBar.low, obBar.close,
line.new(na, na, na, na, color = color(na), style =
line.style_dotted),
label.new(na, na, '▼', style = label.style_label_down, color =
color(na), size = size.small, textcolor = color(na)),
box.new(na, na, na, na, color(na), text_size = obTextSize,
text_halign = text.align_right, text_valign = text.align_bottom), false))
if bearishOrderBlockArray.size() > 0
recentOrderBlock = bearishOrderBlockArray.get(0)
recentOrderBlock.isActive := false
recentOrderBlock.obSetRight(bar.index)
bearishOrderBlockArray.unshift(OrderBlock.new(bar.index[bar.index -
bearishBreachLow.index], bar.index, bar.index, bar.open[bar.index -
bearishBreachLow.index], bar.high[bar.index - bearishBreachLow.index],
bearishBreachLow.value, bar.close[bar.index - bearishBreachLow.index],
line.new(na, na, na, na, color = color(na), style =
line.style_dotted),
label.new(na, na, '▼', style = label.style_label_down, color =
color(na), size = size.small, textcolor = color(na)),
box.new(na, na, na, na, color(na), text_size = obTextSize,
text_halign = text.align_right, text_valign = text.align_bottom), true))
if not currentOrderBlock.isProcessed
currentOrderBlock.obRender(currentOrderBlock.startIndex, bar.index,
currentOrderBlock.open, currentOrderBlock.high, currentOrderBlock.low,
currentOrderBlock.close, currentOrderBlock.isPropulsion ? pbBearishColor :
obBearishColor, currentOrderBlock.isPropulsion, false)
currentOrderBlock.isProcessed := true
currentOrderBlock.obSetRight(bar.index)
if obMostRecent
if bearishOrderBlockArray.size() > obMostRecentValue
currentOrderBlock = bearishOrderBlockArray.pop()
currentOrderBlock.obDelete()
else
if bearishOrderBlockArray.size() > 125
currentOrderBlock = bearishOrderBlockArray.pop()
currentOrderBlock.obDelete()
//---------------------------------------------------------------------------------
------------------------------------}
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0
at https://mozilla.org/MPL/2.0/
// © Cleverchesstrading
// The Pawn Algo is a simple indicator that is useful for scalping in sync with a
higher timeframe should only be use in clear trending markets.
// The script is based of a simple pattern close above previous candle high means
higher prices we can see it in a green bar. Close below previous candle low means
lower prices we can see it in a red bar. Close inside previous candle range means
price is going to consolidate do some kind of retracement or reversal we mark it in
a black or dark color bar.
// It plot an arrow and a liquidity level when it detects a change in sentiment
from bullish to bearish or bearish to bullish.
// It plot the Higher timeframe previous completed candle range into the selected
Lower timeframe to easily see the HTF levels into the lower timeframe.
// The HTF range change colors depending of previous HTF candles closes following
the same idea, close above previous candle high means green range, close below
previous candle low means red range and close inside means a gray range. Finally it
plots the 50% of the HTF range and the previous close high and low.
// Finally it draws a yellow value zone that is the difference between the previous
candle close and 50% of the previous range. This zone is ideal for taking
continuation trades in favor of the HTF trend.
// last version improvements:We made available the HTF range in days,weeks,months
and we add some visual signature when price takes the HTF high or the low. And some
colors to the Close and HTF 50% labels. Finally a way to filter entries is added
//@version=5
//indicator("ThePawnAlgo", overlay=true)
//inputs
HTFenable= input.bool(true, "See HTF in LTF",group = "HTF/LTF range")
RangeType= input.string("minutes", "HTFtype min/days/weeks/Months?", options
=[ "minutes","days","weeks","Months"],group = "HTF/LTF range")
RangeTF= input.int(1440, "HTF minutes option", 1, 1440,tooltip = "Max valid number
is 1440minutes",group = "HTF/LTF range")//HTF min range
RangeTFday= input.int(1, "HTF Days/Weeks/Months", 1, 365,tooltip = "Max valid
numbers are 365Days, 52Weeks, 12Months",group = "HTF/LTF range")//HTF days range
RangeLTF= input.int(1200, "LTF visibility min", 1, 1440,tooltip = "This is the max
timeframe to see the HTF",group = "HTF/LTF range")//LTF range visible
//variables
var float stopvaluebuy=0.0
var float stopvalueshort=0.0
var string HTFrequest=""
var string BIAS=""
var string biasHTF=""
var string HTFclose=""
var bool slbuytaken=false
var bool slselltaken=false
var bool insideHTF=false
var float Midrange=0.0
var float Midrangecurrent=0.0
var bool HTFHtaken=false
var bool HTFLtaken=false
//Sentiment change
if longCondition
BIAS:="Long"
else if shortCondition
BIAS:="Short"
//HTF requested range is ajusted here for days weeks months or minutes option, be
aware of the limits
if RangeType=="days"
HTFrequest:=str.tostring(RangeTFday)+"D"
else if RangeType=="weeks"
if RangeTFday<=52
HTFrequest:=str.tostring(RangeTFday)+"W"
else
HTFrequest:="52W"
else if RangeType=="Months"
if RangeTFday<=12
HTFrequest:=str.tostring(RangeTFday)+"M"
else
HTFrequest:="12M"
else if RangeType=="minutes"
HTFrequest:=str.tostring(RangeTF)
//HTF plot visible only in selected lower times or below maximum levels
visibility=( (((timeframe.isdaily and timeframe.multiplier<RangeTFday*20) or
(timeframe.isweekly and timeframe.multiplier<RangeTFday*4)) and
RangeType=="Months") or ( ((timeframe.isdaily and
timeframe.multiplier<RangeTFday*5) or (timeframe.isweekly and
timeframe.multiplier<RangeTFday)) and RangeType=="weeks") or
(timeframe.multiplier<=RangeLTF and timeframe.isminutes )) and HTFenable
Mr=plot(Midrange, title="HTFMidrange", color=biasHTF=="long" and visibility?
color.rgb(0, 92, 3,80): biasHTF=="short" and visibility? color.rgb(131, 0,
0,80):na, linewidth = 2, style = plot.style_circles)
Rc=plot(RangeClose,title="HTFclose", color=HTFclose=="higher" and visibility?
color.rgb(2, 63, 0, 50):HTFclose=="lower" and visibility? color.rgb(117, 0, 0,
50):na, linewidth = 2, style = plot.style_line)
Rl=plot(RangeLow, color=insideHTF and visibility?color.rgb(255, 255, 255, 50):na)
Rh=plot(RangeHigh, color=insideHTF and visibility?color.rgb(255, 255, 255, 50):na)
//HRF range
fill(Rh, Rl, color=insideHTF and visibility? color.rgb(0, 0, 0, 90):biasHTF=="long"
and visibility? color.rgb(0, 131, 0, 95): biasHTF=="short" and visibility?
color.rgb(133, 3, 3, 90):na)
//Value zone
fill(Mr, Rc, visibility? color.rgb(129, 131, 0, 86):na)
//HTF labels
labelRangeHigh = label.new( visibility ? bar_index:na , RangeHigh,
text=RangeType=="Months"?'________________P'+str.tostring(RangeTFday)+"M
H":RangeType=="weeks"?'________________P'+str.tostring(RangeTFday)+"W
H":RangeType=="days"?'________________P'+str.tostring(RangeTFday)+"D
H":'________________P'+str.tostring(RangeTF)+"H", color=color.rgb(0, 0, 0, 80),
textcolor=color.rgb(0, 0, 0, 80),style=label.style_none, size=size.normal)
label.delete(labelRangeHigh[1])
labelRangeLow = label.new( visibility ? bar_index:na , RangeLow,
text=RangeType=="Months"?'________________P'+str.tostring(RangeTFday)+"M
L":RangeType=="weeks"?'________________P'+str.tostring(RangeTFday)+"W
L":RangeType=="days"?'________________P'+str.tostring(RangeTFday)+"D
L":'________________P'+str.tostring(RangeTF)+"L", color=color.rgb(0, 0, 0, 80),
textcolor=color.rgb(0, 0, 0, 80),style=label.style_none, size=size.normal)
label.delete(labelRangeLow[1])
labelRangeClose = label.new(visibility ? bar_index:na , RangeClose,
text=RangeType=="Months"?'_______________P'+str.tostring(RangeTFday)+"M
C":RangeType=="weeks"?'_______________P'+str.tostring(RangeTFday)+"W
C":RangeType=="days"?'_______________P'+str.tostring(RangeTFday)+"D
C":'_______________P'+str.tostring(RangeTF)+"C", color=color.rgb(0, 0, 0, 80),
textcolor=HTFclose=="higher"?color.rgb(0, 92, 3,50):HTFclose=="lower"?
color.rgb(131, 0, 0,50):color.rgb(0, 0, 0, 80),style=label.style_none,
size=size.normal)
label.delete(labelRangeClose[1])
labelRange50 = label.new(visibility ? bar_index:na , Midrange,
text='_______________'+" HTF 50%", color=color.rgb(0, 0, 0, 80),
textcolor=biasHTF=="long"?color.rgb(0, 92, 3,80):biasHTF=="short"?color.rgb(131, 0,
0,80):color.rgb(0, 0, 0, 80),style=label.style_none, size=size.normal)
label.delete(labelRange50[1])
//HTF High Low taken
if high>RangeHigh
HTFHtaken:=true
if low<RangeLow
HTFLtaken:=true
//Ploting the highs and lows taken
plot(HTFHtaken and HTFHtaken[1]==false and high>RangeHigh and (high>high[1] or
high[1]>RangeHigh) and hlbreaks and visibility? high:na, style=plot.style_circles,
color=biasHTF=="short"?color.rgb(216, 184, 4, 80):color.rgb(8, 228, 0, 80),
linewidth=10, title='hightaken')
plot(HTFLtaken and HTFLtaken[1]==false and low<RangeLow and (low<low[1] or
low[1]<RangeLow) and hlbreaks and visibility? low:na, style=plot.style_circles,
color=biasHTF=="long"?color.rgb(216, 184, 4, 80):color.rgb(216, 4, 50, 80),
linewidth=10, title='lowtaken')
//liquidity plot
plot(showstopbuy and BIAS=="Long" and discount and barstate.isconfirmed and
visibility?stopvaluebuy:showstopsell and BIAS=="Short" and premium and
barstate.isconfirmed and visibility?stopvalueshort:na, title='sl',
color=BIAS=="Long"?color.rgb(30, 53, 0, 47):BIAS=="Short"?color.rgb(102, 46, 0, 46)
: na, linewidth=1, style=plot.style_circles)
//@version=5
//indicator( 'Swing Failure Pattern [LuxAlgo]', 'LuxAlgo - Swing Failure Pattern',
max_labels_count = 500, max_lines_count = 500, max_boxes_count = 500, overlay =
true)
//---------------------------------------------------------------------------------
------------------------------------}
//Settings
//---------------------------------------------------------------------------------
------------------------------------{
sp = ' '
len = input.int ( 5 , 'Swings' , minval= 1
)
bull = input.bool ( true , 'Bullish SFP'
)
bear = input.bool ( true , 'Bearish SFP'
)
//-----------------------------------------------------------------------------}
//UDT
//-----------------------------------------------------------------------------{
type piv
float swing_prc // price
int swing_bix // bar_index
float oppos_prc // price
int oppos_bix // bar_index
bool active
bool confirmed
line swing_line
line oppos_line
line wicky_line
label wicky_label
type swing
int bix
float prc
//-----------------------------------------------------------------------------}
//Variables
//-----------------------------------------------------------------------------{
n = bar_index
INV = color(na)
FGc = chart.fg_color
var tb = table.new(table_position, 2, 3
, bgcolor = #1e222d
, border_color = #373a46
, border_width = 1
, frame_color = #373a46
, frame_width = 1)
//---------------------------------------------------------------------------------
------------------------------------}
//Method
//---------------------------------------------------------------------------------
------------------------------------{
method n(float piv) => bool out = not na(piv)
//---------------------------------------------------------------------------------
------------------------------------}
//Execution
//---------------------------------------------------------------------------------
------------------------------------{
tfS = timeframe.in_seconds( res )
tfC = timeframe.in_seconds(timeframe.period)
rs = auto ? tfC / mlt : tfS
if not validate
res := timeframe.period
else
rs := prem ? rs : math.max(60, rs)
res := timeframe.from_seconds(math.min(tfC, rs))
ph = ta.pivothigh(len, 1)
pl = ta.pivotlow (len, 1)
[ltf_close, ltf_volume] = request.security_lower_tf(syminfo.tickerid, res, [close,
volume])
ltf_size = ltf_close.size()
if validate
if ltf_size > 0 and ltf_size[1] == 0
line.new(n, close, n, close + syminfo.mintick, color=color.silver,
style=line.style_dotted, extend=extend.both)
//---------------------------------------------------------------------------------
------------------------------------}
//Bearish Pattern
//---------------------------------------------------------------------------------
------------------------------------{
if bear
if ph.n()
swingH.bix := n-1
swingH.prc := ph
sw = swingH.prc
bx = swingH.bix
if high > sw
and open < sw
and close < sw
valid = true
if validate
if ltf_close.size() > 0
outsideVolume = 0.
totalVolume = ltf_volume.sum()
for j = 0 to ltf_close.size() -1
if ltf_close.get(j) > sw
outsideVolume += ltf_volume.get(j)
if (valHigher ? 100 / totalVolume * outsideVolume < percent
: 100 / totalVolume * outsideVolume > percent
)
valid := false
//if valid
// label.new(n, high, text=str.format("Total Volume: {0}\nWick
Volume: {1}", totalVolume, outsideVolume))
if valid
opposL = sw
opposB = n
for i = 1 to n - bx -1
if low [i] < opposL
opposL := low [i]
opposB := n - i
if not pivH.confirmed
pivH.swing_line .delete()
pivH.oppos_line .delete()
pivH.wicky_line .delete()
pivH.wicky_label.delete()
pivH := piv.new(sw, bx, opposL, opposB, true, false)
if dSwingLine
pivH.swing_line := line.new (bx , sw , n, sw ,
color=colBr)
if dOpposLine
pivH.oppos_line := line.new (opposB, opposL, n, opposL,
color=colBr, style=line.style_dotted)
if dSFP_Line
pivH.wicky_line := line.new (n , high , n, sw ,
color=colBr2, width=3)
if dSFP_Label
pivH.wicky_label := label.new(n , high
, style=label.style_label_down
, text='SFP', textcolor=colBr
, color=INV, size=size.normal
)
pivH.swing_line.set_x2(n)
pivH.oppos_line.set_x2(n)
if pivH.wicky_label.get_x() == n
pivH.wicky_label.set_text('SFP\n▼')
else
label.new(n, high, style=label.style_label_down, text='▼',
textcolor=colBr, color=INV, size=size.normal)
//---------------------------------------------------------------------------------
------------------------------------}
//Bullish Pattern
//---------------------------------------------------------------------------------
------------------------------------{
if bull
if pl.n()
swingL.bix := n-1
swingL.prc := pl
sw = swingL.prc
bx = swingL.bix
if low < sw
and open > sw
and close > sw
valid = true
if validate
if ltf_close.size() > 0
outsideVolume = 0.
totalVolume = ltf_volume.sum()
for j = 0 to ltf_close.size() -1
if ltf_close.get(j) < sw
outsideVolume += ltf_volume.get(j)
if (valHigher ? 100 / totalVolume * outsideVolume < percent
: 100 / totalVolume * outsideVolume > percent
)
valid := false
if valid
opposH = sw
opposB = n
for i = 1 to n - bx -1
if high[i] > opposH
opposH := high[i]
opposB := n - i
if not pivL.confirmed
pivL.swing_line .delete()
pivL.oppos_line .delete()
pivL.wicky_line .delete()
pivL.wicky_label.delete()
if dSwingLine
pivL.swing_line := line.new (bx , sw , n, sw ,
color=colBl )
if dOpposLine
pivL.oppos_line := line.new (opposB, opposH, n, opposH,
color=colBl , style=line.style_dotted)
if dSFP_Line
pivL.wicky_line := line.new (n , low , n, sw ,
color=colBl2, width=3)
if dSFP_Label
pivL.wicky_label := label.new(n , low
, style=label.style_label_up
, text='SFP', textcolor=colBl
, color=INV, size=size.normal
)
pivL.swing_line.set_x2(n)
pivL.oppos_line.set_x2(n)
if pivL.wicky_label.get_x() == n
pivL.wicky_label.set_text('▲\nSFP')
else
label.new(n, low, style=label.style_label_up, text='▲',
textcolor=colBl, color=INV, size=size.normal)
//---------------------------------------------------------------------------------
------------------------------------}
//Dashboard
//---------------------------------------------------------------------------------
------------------------------------{
if barstate.islast and validate and showDash
tb.cell(0, 0, str.format("LTF: {0}", res), text_color=color.white,
text_size=table_size)
//---------------------------------------------------------------------------------
------------------------------------}
//
//@version=6
//ndicator('Multi TimeFrame OHLC Overlay @MaxMaserati', shorttitle = 'MTC OHLC
@MaxMaserati', overlay = true, max_boxes_count = 500, max_lines_count = 500)
DEFAULT_RESOLUTION = '240'
type OHLC
float o
float h
float l
float c
float prevC
makeOHLC(int bb = 0) =>
OHLC.new(open[bb], high[bb], low[bb], close[bb], close[bb + 1])
// Period calculations
isNewPeriod = ta.change(time(timeframeInput)) != 0
sec = barstate.islast ? isNewPeriod ? bar1 : bar0 : bar1
diff = sec.c - sec.o
left = prevBarIndex
right = barstate.islast ? isNewPeriod ? bar_index - 1 : bar_index : bar_index - 1
// Variable declarations
var box prevBodyBox = na
var box prevWickBox = na
var array<line> prevHighLines = array.new_line()
var array<line> prevOpenLines = array.new_line()
var array<line> prevCloseLines = array.new_line()
var array<line> prevLowLines = array.new_line()
var line extendedOpenLine = na
var line extendedHighLine = na
var line extendedLowLine = na
var line extendedCloseLine = na
var label extOpenLabel = na
var label extHighLabel = na
var label extLowLabel = na
var label extCloseLabel = na
var line curentHigLine = na
var line currentLowLine = na
var line currentOpenLine = na
var line currentCloseLine = na
tfPrefix = formatTimeframePrefix(extendedTimeframe)
rightExtend = bar_index + 25
if showExtendedOpen
extendedOpenLine := line.new(bar_index - 50, extOpen, rightExtend, extOpen,
color = extendedOpenColor, width = 2, extend = extend.none)
if showLabels and showOpenLabel
extOpenLabel := label.new(rightExtend, extOpen, tfPrefix + 'O', color =
color.new(color.black, 100), textcolor = openLabelColor, style =
label.style_label_left, size = size.small)
extOpenLabel
if showExtendedHigh
extendedHighLine := line.new(bar_index - 50, extHigh, rightExtend, extHigh,
color = extendedHighColor, width = 2, extend = extend.none)
if showLabels and showHighLabel
extHighLabel := label.new(rightExtend, extHigh, tfPrefix + 'H', color =
color.new(color.black, 100), textcolor = highLabelColor, style =
label.style_label_left, size = size.small)
extHighLabel
if showExtendedLow
extendedLowLine := line.new(bar_index - 50, extLow, rightExtend, extLow,
color = extendedLowColor, width = 2, extend = extend.none)
if showLabels and showLowLabel
extLowLabel := label.new(rightExtend, extLow, tfPrefix + 'L', color =
color.new(color.black, 100), textcolor = lowLabelColor, style =
label.style_label_left, size = size.small)
extLowLabel
if showExtendedClose
extendedCloseLine := line.new(bar_index - 50, extClose, rightExtend,
extClose, color = extendedCloseColor, width = 2, extend = extend.none)
if showLabels and showCloseLabel
extCloseLabel := label.new(rightExtend, extClose, tfPrefix + 'C', color
= color.new(color.black, 100), textcolor = closeLabelColor, style =
label.style_label_left, size = size.small)
extCloseLabel
if showCurrentLines
if showHighLine
line.delete(curentHigLine)
curentHigLine := line.new(left, sec.h, right, sec.h, color =
highLineColor, width = 1)
curentHigLine
//array.push(prevHighLines, line.new(left, sec.h, right, sec.h,
color=highLineColor, width=1))
if showOpenLine
line.delete(currentOpenLine)
currentOpenLine := line.new(left, sec.o, right, sec.o, color =
openLineColor, width = 1)
currentOpenLine
// array.push(prevOpenLines, line.new(left, sec.o, right, sec.o,
color=openLineColor, width=1))
if showCloseLine
line.delete(currentCloseLine)
currentCloseLine := line.new(left, sec.c, right, sec.c, color =
closeLineColor, width = 1)
currentCloseLine
// array.push(prevCloseLines, line.new(left, sec.c, right, sec.c,
color=closeLineColor, width=1))
if showLowLine
line.delete(currentLowLine)
currentLowLine := line.new(left, sec.l, right, sec.l, color =
lowLineColor, width = 1)
currentLowLine
// array.push(prevLowLines, line.new(left, sec.l, right, sec.l,
color=lowLineColor, width=1))
// Timeframe Table
var table tfTable = table.new(position.top_right, 1, 2, border_width = 1,
frame_color = color.gray, border_color = color.gray)
if barstate.islast
table.cell(tfTable, 0, 0, 'Time: ' + timeframeInput, text_color = color.white,
text_size = size.small, bgcolor = color.new(color.black, 0))
table.cell(tfTable, 0, 1, 'Ext Time: ' + extendedTimeframe, text_color =
color.white, text_size = size.small, bgcolor = color.new(color.black, 0))
// This source code is subject to the terms of the Mozilla Public License 2.0 at
https://mozilla.org/MPL/2.0/
// © tradeforopp
//@version=5
//ndicator("Protected Highs & Lows [TFO]", "Protected Highs & Lows [TFO]", true,
max_lines_count = 500, max_labels_count = 500, max_boxes_count = 500)
var ph = array.new_float()
var pl = array.new_float()
type pb
float price
int idx
bool valid = false
bool bull
type snd
box _box
line _30
line _50
line _70
type dwg
label[] _label
label[] _phl
line[] _line
bool[] _bull
method dwg_add(dwg d, label LB, label PHL, line LN, bool BL) =>
d._label.unshift(LB)
d._phl.unshift(PHL)
d._line.unshift(LN)
d._bull.unshift(BL)
clear_all() =>
pl.clear()
plt.clear()
ph.clear()
pht.clear()
if extra_valid_pbs
for i = 0 to 3
if close[ps + i] < open[ps + i]
pb_set(pb_from_low, high[ps + i], bar_index)
break
else
pb_set(pb_from_low, high[ps], bar_index)
if na(last_low)
last_low := low[ps]
last_low_idx := bar_index - ps
else
if low[ps] < last_low
last_low := low[ps]
last_low_idx := bar_index - ps
if ta.pivothigh(high, ps, ps) and ph.size() == 0
ph.unshift(high[ps])
pht.unshift(time[ps])
if extra_valid_pbs
for i = 0 to 3
if close[ps + i] > open[ps + i]
pb_set(pb_from_high, low[ps + i], bar_index)
break
else
pb_set(pb_from_high, low[ps], bar_index)
if na(last_high)
last_high := high[ps]
last_high_idx := bar_index - ps
else
if high[ps] > last_high
last_high := high[ps]
last_high_idx := bar_index - ps
check_pb(pb p) =>
if p.bull
if close < p.price and p.valid == false
p.valid := true
else
if close > p.price and p.valid == false
p.valid := true
check_pb(pb_from_high)
check_pb(pb_from_low)
bos_bear = false
bos_bull = false
mss_bear = false
mss_bull = false
change = false
maintain(snd s) =>
if not na(s._box)
s._box.set_right(time)
s._30.set_x2(time)
s._50.set_x2(time)
s._70.set_x2(time)
maintain(snd)
if ph.size() > 0
if close > ph.get(0)
label _label = na
label _phl = na
if show_labels
save = false
if label_type == 'MSS' and not bull
save := true
else if label_type == 'BOS' and bull
save := true
else if label_type == 'All'
save := true
if save
_label := label.new(math.floor(math.avg(time, pht.get(0))),
ph.get(0), bull ? "BOS" : "MSS", xloc = xloc.bar_time, style =
label.style_label_down, color = #ffffff00, textcolor = na)
if bull
bos_bull := true
else
mss_bull := true
clear_all()
if not na(track_low)
if show_phl
_phl := label.new(time[bar_index - track_low_idx], track_low, "▲",
xloc = xloc.bar_time, style = label.style_label_up, textcolor = na, color =
#ffffff00)
pl.unshift(track_low)
plt.unshift(time[bar_index - track_low_idx])
last_high := na
if pl.size() > 0
if close < pl.get(0)
label _label = na
label _phl = na
if show_labels
save = false
if label_type == 'MSS' and bull
save := true
else if label_type == 'BOS' and not bull
save := true
else if label_type == 'All'
save := true
if save
_label := label.new(math.floor(math.avg(time, plt.get(0))),
pl.get(0), not bull ? "BOS" : "MSS", xloc = xloc.bar_time, style =
label.style_label_up, color = #ffffff00, textcolor = na)
if not bull
bos_bear := true
else
mss_bear := true
clear_all()
if not na(track_high)
if show_phl
_phl := label.new(time[bar_index - track_high_idx], track_high,
"▼", xloc = xloc.bar_time, style = label.style_label_down, textcolor = na, color =
#ffffff00)
ph.unshift(track_high)
pht.unshift(time[bar_index - track_high_idx])
last_low := na
if change[1]
if bos_bear[1] or mss_bear[1]
trail_price := track_high
trail_color := ph_color
else if bos_bull[1] or mss_bull[1]
trail_price := track_low
trail_color := pl_color
_bull = dwgs._bull.get(0)
dwgs._label.get(0).set_textcolor(_bull ? bull_color : bear_color)
dwgs._phl.get(0).set_textcolor(_bull ? pl_color : ph_color)
dwgs._line.get(0).set_color(_bull ? bull_color : bear_color)
//@version=5
// ~~ Tooltips {
var t1 = "Sets the color for the 1-Hour Open line. Changing the color helps
distinguish it from other lines on the chart.
\n\nChoose between displaying the 1-Hour Open as a Line or a Zone. A zone shows an
area around the open price, providing a visual representation of a price range.
\n\nSets the line style for the 1-Hour Open (Solid, Dotted, Dashed). Different
styles can help visually differentiate the lines on your chart."
var t2 = "Sets the color for the 4-Hour Open line. Adjusting the color can help you
easily identify this line on your chart.
\n\nSets the line style for the 4-Hour Open (Solid, Dotted, Dashed). Different
styles can help visually differentiate the lines on your chart."
var t3 = "Specifies the width of the zone around the 1-Hour Open as a percentage.
Increasing this value widens the zone, showing a larger range around the open
price."
var t4 = "Enables or disables the display of retest markers. When enabled, markers
show where the price retested the 1-Hour Open line."
var t5 = "Sets the number of retests to display. Increasing this value shows more
retest markers on the chart."
var t6 = "Enables or disables the volume filter for retests. When enabled, only
retests with higher volume are displayed.
\n\nSets the length of the volume filter. Increasing this value smooths the volume
filter, potentially reducing the number of retest markers."
var t7 = "Enables or disables the 1-hour average line. This line shows the average
price over the past hour."
var t8 = "Enables or disables the display of hourly high and low labels. These
labels mark the highest and lowest prices within each hour."
\n\nEnables or disables bar coloring based on price direction. Up bars are colored
green and down bars are colored red."
var t10 = "Sets the timeframe for higher timeframe candles. Changing this value
adjusts the period over which higher timeframe candles are calculated."
var t11 = "Sets the number of higher timeframe candles to display. Increasing this
value shows more candles on the chart."
var t12 = "Sets the location for higher timeframe candles. Adjusting this value
moves the higher timeframe candles left or right on the chart."
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Settings {
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Functions {
Style(styleInput) =>
switch styleInput
line.delete(ver_line[1])
label.delete(lab[1])
Box(left,top,right,bot,width,col)=>box.new(left,top,right,bot,border_color=col,bord
er_style=Style(H_style),border_width=width,bgcolor=color.new(col,75),xloc=xloc.bar_
time)
bars_per_hour() =>
if (timeframe.isintraday)
if (timeframe.multiplier == 1)
bars_per_hour := 60
else if (timeframe.multiplier == 5)
bars_per_hour := 12
bars_per_hour := 4
else
bars_per_hour := na
else
bars_per_hour := na
bars_per_hour
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Line Style {
H_StyleOption = Style(H_style)
H4_StyleOption = Style(H4_style)
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Arrays {
open_l = array.new_line()
start_points = array.new_float()
end_points = array.new_float()
retest_counts = array.new_int()
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Var {
var count = 0
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Time {
time_hour = hour(time)
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
var hourHighi = 0
var hourLowi = 0
start_point := open
if H_line_box=="Line"
else
box2 := Box(time,open*(1+zoneDev),time+3600000,open*(1-
zoneDev),H_width,H_col)
count := 0
pos := true
if hourly_hl
if hourHL.size()>0
hourHL.get(i+1).set_text("H["+str.tostring(i/2+2)+"]")
hourHL.get(i).set_text("L["+str.tostring(i/2+2)+"]")
hourHL.unshift(label.new(hourHighi,hourHigh,"H[1]",xloc.bar_time,textcolor
= color.white, color=color.new(color.green,0),style=label.style_label_down))
hourHL.unshift(label.new(hourLowi,hourLow,"L[1]",xloc.bar_time,textcolor =
color.white, color=color.new(color.red,0), style=label.style_label_up))
hourHigh := high
hourLow := low
if hourly_hl
hourHigh := math.max(high,hourHigh)
hourLow := math.min(low,hourLow)
if hourHigh!=hourHigh[1]
Label(time,hourHigh,"High",color.green,label.style_label_down)
hourHighi := time
if hourLow!=hourLow[1]
Label(time,hourLow,"Low",color.red,label.style_label_up)
hourLowi := time
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
if time_4hour
count := 0
pos := true
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
bars_hour = bars_per_hour()
// Calculate how many bars are left until the next hour
bars_left = 0
if not na(bars_hour)
bars_passed = 0
if timeframe.isintraday
t = ""
if not na(bars_left)
t := str.tostring(math.round(bars_left))
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
time_avg() =>
if (time_hour != time_hour[1])
ma.set(0, close)
lena.set(0, 1)
else
lena.set(0, lena.get(0) + 1)
ma.get(0) / lena.get(0)
ma_hour = average?time_avg():na
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Direction {
dir(start_)=>
var dir = 0
if (not na(start_))
col = dir(start_point)==1?c_up:c_dn
ma_col = dir(start_point)==1?ma_up:ma_dn
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Plots {
plotcandle(candle?open:na,candle?high:na,candle?low:na,candle?close:na,
color=candle?col:na, bordercolor =candle?col:na, wickcolor=candle?col:na,
title="Candlesticks")
barcolor(bar?col:na, title="BarColor")
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Table {
if not na(prev_hour_close)
if not na(prev_4hour_close)
if not na(prev_daily_close)
H1_color = hourly_change>0?color.lime:color.red
H4_color = four_hour_change>0?color.lime:color.red
D_color = daily_change>0?color.lime:color.red
// Table
if barstate.islast
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ HFT Candle {
tfs = str.tonumber(tf)
if str.tostring(tf) == "1D"
tfs := 1440
error = str.tonumber(timeframe.period)>=tfs
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ UDT {
type HTF
array<box> candle
array<line> wickH
array<line> wickL
array<float> hl
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Variables {
b = bar_index
var candle1 =
HTF.new(array.new<box>(numb),array.new<line>(numb),array.new<line>(numb),array.new<
float>(numb*2))
[o,h,l,c] = request.security(syminfo.tickerid,tf,
[open,high,low,close],lookahead=barmerge.lookahead_on)
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Code {
if numb>0
candle1.candle.shift().delete()
candle1.wickH.shift().delete()
candle1.wickL.shift().delete()
candle1.hl.shift()
candle1.hl.shift()
candle1.candle.push(box.new(b+numb*4+loc,math.max(o,c),b+numb*4+loc+2,math.min(o,c)
,color(na),bgcolor=o>c?dn_col:up_col))
candle1.wickH.push(line.new(b+numb*4+loc+1,math.max(o,c),b+numb*4+loc+1,h,color=o>c
?dn_col:up_col))
candle1.wickL.push(line.new(b+numb*4+loc+1,math.min(o,c),b+numb*4+loc+1,l,color=o>c
?dn_col:up_col))
candle1.hl.push(h)
candle1.hl.push(l)
d = loc
x.set_left(b+d*2)
x.set_right(b+d*2+2)
candle1.wickH.get(i).set_x1(b+d*2+1)
candle1.wickH.get(i).set_x2(b+d*2+1)
candle1.wickL.get(i).set_x1(b+d*2+1)
candle1.wickL.get(i).set_x2(b+d*2+1)
else
x.set_lefttop(b+d*2,math.max(o,c))
x.set_rightbottom(b+d*2+2,math.min(o,c))
x.set_bgcolor(o>c?dn_col:up_col)
candle1.wickH.get(i).set_xy1(b+d*2+1,math.max(o,c))
candle1.wickH.get(i).set_xy2(b+d*2+1,h)
candle1.wickH.get(i).set_color(o>c?dn_wick:up_wick)
candle1.wickL.get(i).set_xy1(b+d*2+1,math.min(o,c))
candle1.wickL.get(i).set_xy2(b+d*2+1,l)
candle1.wickL.get(i).set_color(o>c?dn_wick:up_wick)
candle1.hl.set(numb*2-2,h)
candle1.hl.set(numb*2-1,l)
d += 2
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
linePrice1 = line2.get_y1()
var retest_count_1h = 0
repos_1 = false
reneg_1 = false
if pos and count > 1 and time <= end and retest_count_1h < retests and
close >= linePrice1 : low[1] > box2.get_top() and low <= box2.get_top()
repos_1 := true
pos := false
count := 0
retest_count_1h += 1
if pos and count > 1 and time <= end and retest_count_1h < retests and
reneg_1 := true
pos := false
count := 0
retest_count_1h += 1
count += 1
if (count > 1)
pos := true
if (hour(time) != hour(time[1]))
retest_count_1h := 0
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Plots {
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// © LuxAlgo
//@version=5
//------------------------------------------------------------------------------
// Settings
//-----------------------------------------------------------------------------{
//Colors
//Dashboard
//-----------------------------------------------------------------------------}
//Types
//-----------------------------------------------------------------------------{
type fractal
float value
int loc
bool iscrossed
//-----------------------------------------------------------------------------}
//Fractal Detection
//-----------------------------------------------------------------------------{
var p = int(length/2)
n = bar_index
dh = math.sum(math.sign(high - high[1]), p)
dl = math.sum(math.sign(low - low[1]), p)
bearf_count = ta.cum(bearf ? 1 : 0)
//-----------------------------------------------------------------------------}
//-----------------------------------------------------------------------------{
var bull_ms_count = 0
var os = 0
if bullf
upper.value := high[p]
upper.loc := n-p
upper.iscrossed := false
, color = color(na)
, style = label.style_label_down
, size = size.tiny)
//Set support
k = 2
min = low[1]
for i = 2 to (n - upper.loc)-1
k := low[i] == min ? i : k
if showSupport
broken_sup := false
upper.iscrossed := true
bull_ms_count += 1
os := 1
lower_lvl.set_x2(n)
broken_sup := true
//-----------------------------------------------------------------------------}
//-----------------------------------------------------------------------------{
var bear_ms_count = 0
if bearf
lower.value := low[p]
lower.loc := n-p
lower.iscrossed := false
, color = color(na)
, style = label.style_label_up
, size = size.tiny)
//Set resistance
k = 2
max = high[1]
for i = 2 to (n - lower.loc)-1
k := high[i] == max ? i : k
if showResistance
broken_res := false
lower.iscrossed := true
bear_ms_count += 1
os := -1
broken_res := true
//-----------------------------------------------------------------------------}
//Dashboard
//-----------------------------------------------------------------------------{
: position.bottom_right
: size.normal
var tb = table.new(table_position, 2, 3
, bgcolor = #1e222d
, border_color = #373a46
, border_width = 1
, frame_color = #373a46
, frame_width = 1)
if showDash
if barstate.isfirst
tb.merge_cells(0,0,1,0)
if barstate.islast
//-----------------------------------------------------------------------------}
//Plots
//-----------------------------------------------------------------------------{
//-----------------------------------------------------------------------------}
//@version=6
//indicator("FVG Breakout/Breakdown", overlay=true)
if (time == fridayCloseTime)
fridayClose := close
if (time == mondayOpenTime)
mondayOpen := open
// Calculate the NWOG gap (difference between Friday close and Monday open)
nwogGap = mondayOpen - fridayClose