0% found this document useful (0 votes)
37 views

HAHA

Uploaded by

originspica
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
37 views

HAHA

Uploaded by

originspica
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 54

//@version=5

strategy ("Addon HAHA", 'HAHA', true


, max_labels_count = 500
, max_lines_count = 500
, max_boxes_count = 500
, max_bars_back = 500)

// Settings
display = display.all - display.status_line

// Short Term Settings


stGroup = 'Short Term Structures'
stSwings = input.string('Disabled', 'Swings', options = ['⦁', 'ST(H/L)',
'Disabled'], inline = 'NA', group = stGroup, display = display)
stSwingsSZ = input.string('Tiny', 'Size', options = ['Tiny', 'Small', 'Normal',
'Large'], inline = 'NA', group = stGroup, display = display)
stMarketStructures = input.bool(true, 'Market Structures', group = stGroup)
stMSTextT = input.string('Disabled', ' Market Structure Labels', options =
['Enabled', 'Disabled'], group = stGroup, display = display), stMSText = stMSTextT
== 'Enabled'
stMSLineStyle = input.string('Dotted', ' Line Style', options = ['Solid',
'Dashed', 'Dotted'], group = stGroup, inline = 'LN', display = display)
stMSLineWidth = input.int(1, 'Width', minval = 1, group = stGroup, inline = 'LN',
display = display)
stBullMSColor = input.color(#089981, 'Swing and Line Colors, Bullish', group =
stGroup, inline = 'MS')
stBearMSColor = input.color(#f23645, 'Bearish', group = stGroup, inline = 'MS')
stShowPoints = input.bool(true, 'Show Points', group = stGroup)

// Intermediate Term Settings


itGroup = 'Intermediate Term Structures'
itSwings = input.string('Disabled', 'Swings', options = ['◈', '△▽', 'IT(H/L)',
'Disabled'], inline = 'NA', group = itGroup, display = display)
itSwingsSZ = input.string('Small', 'Size', options = ['Tiny', 'Small', 'Normal',
'Large'], inline = 'NA', group = itGroup, display = display)
itMarketStructures = input.bool(true, 'Market Structures', group = itGroup)
itMSTextT = input.string('Disabled', ' Market Structure Labels', options =
['Enabled', 'Disabled'], group = itGroup, display = display), itMSText = itMSTextT
== 'Enabled'
itMSLineStyle = input.string('Dashed', ' Line Style', options = ['Solid',
'Dashed', 'Dotted'], group = itGroup, inline = 'LN', display = display)
itMSLineWidth = input.int(1, 'Width', minval = 1, group = itGroup, inline = 'LN',
display = display)
itBullMSColor = input.color(#089981, 'Swing and Line Colors, Bullish', group =
itGroup, inline = 'MS')
itBearMSColor = input.color(#f23645, 'Bearish', group = itGroup, inline = 'MS')
itShowPoints = input.bool(true, 'Show Points', group = itGroup)

// Long Term Settings


ltGroup = 'Long Term Structures'
ltSwings = input.string('◉', 'Swings', options = ['◉', '▲▼', 'LT(H/L)',
'Disabled'], inline = 'NA', group = ltGroup, display = display)
ltSwingsSZ = input.string('Normal', 'Size', options = ['Tiny', 'Small', 'Normal',
'Large'], inline = 'NA', group = ltGroup, display = display)
ltMarketStructures = input.bool(true, 'Market Structures', group = ltGroup)
ltMSTextT = input.string('Enabled', ' Market Structure Labels', options =
['Enabled', 'Disabled'], group = ltGroup, display = display), ltMSText = ltMSTextT
== 'Enabled'
ltMSLineStyle = input.string('Solid', ' Line Style', options = ['Solid',
'Dashed', 'Dotted'], group = ltGroup, inline = 'LN', display = display)
ltMSLineWidth = input.int(1, 'Width', minval = 1, group = ltGroup, inline = 'LN',
display = display)
ltBullMSColor = input.color(#089981, 'Swing and Line Colors, Bullish', group =
ltGroup, inline = 'MS')
ltBearMSColor = input.color(#f23645, 'Bearish', group = ltGroup, inline = 'MS')
ltShowPoints = input.bool(true, 'Show Points', group = ltGroup)

// Moving Averages
maShort1 = ta.sma(close, 14)
maShort2 = ta.sma(close, 21)
maShort3 = ta.sma(close, 50)
maShort4 = ta.sma(close, 67)
maLong1 = ta.sma(close, 100)
maLong2 = ta.sma(close, 200)

// User Defined Types


type BAR
float open = open
float high = high
float low = low
float close = close
int index = bar_index

type ICTMS
float lastPrice
float midPrice
float prevPrice

int lastIndex
int midIndex
int prevIndex

label lastLabel
label midLabel
label prevLabel

bool isCrossed

int marketStructure

line msLine
box msLabel

type MS
int type = 0

// Generic Variables
BAR bar = BAR.new()

var int stPoints = 0


var int itPoints = 0
var int ltPoints = 0

var int stViolations = 0


var int itViolations = 0
var int ltViolations = 0
// RSI and QQE Settings
rsiLength = input.int(14, title="RSI Length")
volumeMaLength = input.int(20, title="Volume MA Length")
qqeLength = input.int(14, title="QQE Length")

// RSI Overbought and Oversold Levels


rsiOverbought = input.int(70, title="RSI Overbought Level")
rsiOversold = input.int(30, title="RSI Oversold Level")

// Functions / Methods
textSize(sizeInText) =>
switch sizeInText
'Tiny' => size.tiny
'Small' => size.small
'Normal' => size.normal
=> size.large

lineStyle(styleInText) =>
switch styleInText
'Solid' => line.style_solid
'Dotted' => line.style_dotted
'Dashed' => line.style_dashed

queryPatterns(lastPrice, midPrice, prevPrice, isSwingHigh) =>


if isSwingHigh
prevPrice < midPrice and midPrice >= lastPrice
else
prevPrice > midPrice and midPrice <= lastPrice

method queryPatterns(ICTMS this, isSwingHigh) =>


if isSwingHigh
this.prevPrice < this.midPrice and this.midPrice >= this.lastPrice
else
this.prevPrice > this.midPrice and this.midPrice <= this.lastPrice

method updatePattern(ICTMS this, price, index) =>


this.isCrossed := false
this.prevPrice := this.midPrice
this.midPrice := this.lastPrice
this.lastPrice := price
this.prevIndex := this.midIndex
this.midIndex := this.lastIndex
this.lastIndex := index
this.prevLabel := this.midLabel
this.midLabel := this.lastLabel

method setType(MS this, value) =>


this.type := value

method renderStructures(ICTMS this, isBullish, marketStructure, termText, color,


style, width, labelEnabled) =>
condition = isBullish ? bar.close > this.lastPrice : bar.close < this.lastPrice

if condition and not this.isCrossed


this.isCrossed := true
this.msLine := line.new(this.lastIndex, this.lastPrice, bar.index,
this.lastPrice, color = color, style = lineStyle(style), width = width)

if labelEnabled
this.msLabel := box.new(this.lastIndex, this.lastPrice, bar.index,
this.lastPrice, color(na), bgcolor = color(na),
text = marketStructure.type == (isBullish ? -1 : 1) ? termText + '-
MSS' : termText + '-BOS', text_size = textSize('Tiny'), text_halign =
text.align_left, text_valign = isBullish ? text.align_bottom : text.align_top,
text_color = color.new(color, 17))

marketStructure.setType(isBullish ? 1 : -1)

// Short-Term Market Structures


var ICTMS stLow = ICTMS.new()
var ICTMS stHigh = ICTMS.new()
var MS stMS = MS.new()

if queryPatterns(bar.low, bar.low[1], bar.low[2], false)


stLow.updatePattern(bar.low[1], bar.index[1])
TX = stSwings == '⦁' ? '⦁' : stLow.midPrice > stLow.lastPrice ? 'ST-LL' : 'ST-
LH'
stLow.lastLabel := label.new(stLow.lastIndex, stLow.lastPrice, TX, color =
color(na), textcolor = stSwings != 'Disabled' ? stBearMSColor : color(na), style =
label.style_label_up, size = textSize(stSwingsSZ))

if queryPatterns(bar.high, bar.high[1], bar.high[2], true)


stHigh.updatePattern(bar.high[1], bar.index[1])
TX = stSwings == '⦁' ? '⦁' : stHigh.midPrice > stHigh.lastPrice ? 'ST-HL' :
'ST-HH'
stHigh.lastLabel := label.new(bar.index[1], bar.high[1], TX, color = color(na),
textcolor = stSwings != 'Disabled' ? stBullMSColor : color(na), style =
label.style_label_down, size = textSize(stSwingsSZ))

if stMarketStructures
if not stLow.isCrossed
stViolations += 1
if stHigh.isCrossed
stPoints := stPoints + 10 - stViolations
stViolations := 0
stLow.renderStructures(false, stMS, 'ST', stBearMSColor, stMSLineStyle,
stMSLineWidth, stMSText)
stHigh.renderStructures(true, stMS, 'ST', stBullMSColor, stMSLineStyle,
stMSLineWidth, stMSText)

// Display points for Short-Term Structures if enabled


if stShowPoints and bar_index == ta.highest(bar_index, 10)
label.new(bar.index, bar.close, str.tostring(stPoints), color = color.red,
textcolor = color.white, style = label.style_label_down, size = textSize('Tiny'))

// Intermediate-Term Market Structures


var ICTMS itLow = ICTMS.new()
var ICTMS itHigh = ICTMS.new()
var MS itMS = MS.new()

cITL = stLow.queryPatterns(false)

if cITL and cITL != cITL[1]


itLow.updatePattern(stLow.midPrice, stLow.midIndex)
itLow.lastLabel := stLow.midLabel

if itSwings != 'Disabled'
TX = itSwings == '△▽' ? '△' : itSwings == '◈' ? '◈' : itLow.lastPrice >
itLow.midPrice ? 'IT-LH' : 'IT-LL'
stLow.midLabel.set_text(TX)
stLow.midLabel.set_size(textSize(itSwingsSZ))
stLow.midLabel.set_textcolor(itBearMSColor)

cITH = stHigh.queryPatterns(true)

if cITH and cITH != cITH[1]


itHigh.updatePattern(stHigh.midPrice, stHigh.midIndex)
itHigh.lastLabel := stHigh.midLabel

if itSwings != 'Disabled'
TX = itSwings == '△▽' ? '▽' : itSwings == '◈' ? '◈' : itHigh.lastPrice >
itHigh.midPrice ? 'IT-HH' : 'IT-HL'
stHigh.midLabel.set_text(TX)
stHigh.midLabel.set_size(textSize(itSwingsSZ))
stHigh.midLabel.set_textcolor(itBullMSColor)

if itMarketStructures
if not itLow.isCrossed
itViolations += 1
if itHigh.isCrossed
itPoints := itPoints + 10 - itViolations
itViolations := 0
itLow.renderStructures(false, itMS, 'IT', itBearMSColor, itMSLineStyle,
itMSLineWidth, itMSText)
itHigh.renderStructures(true, itMS, 'IT', itBullMSColor, itMSLineStyle,
itMSLineWidth, itMSText)

// Display points for Intermediate-Term Structures if enabled


if itShowPoints and bar_index == ta.highest(bar_index, 10)
label.new(bar.index, bar.close, str.tostring(itPoints), color =
color.green, textcolor = color.white, style = label.style_label_down, size =
textSize('Small'))

// Long-Term Market Structures


var ICTMS ltLow = ICTMS.new()
var ICTMS ltHigh = ICTMS.new()
var MS ltMS = MS.new()

cLTL = itLow.queryPatterns(false)

if cLTL and cLTL != cLTL[1]


ltLow.isCrossed := false

TX = ltSwings == '▲▼' ? '▲' : ltSwings == '◉' ? '◉' : ltLow.lastPrice >


itLow.midPrice ? 'LT-LL' : 'LT-LH'

ltLow.lastPrice := itLow.midPrice
ltLow.lastIndex := itLow.midIndex

if ltSwings != 'Disabled'
itLow.midLabel.set_text(TX)
itLow.midLabel.set_size(textSize(ltSwingsSZ))
itLow.midLabel.set_textcolor(ltBearMSColor)

cLTH = itHigh.queryPatterns(true)

if cLTH and cLTH != cLTH[1]


ltHigh.isCrossed := false

TX = ltSwings == '▲▼' ? '▼' : ltSwings == '◉' ? '◉' : ltHigh.lastPrice >


itHigh.midPrice ? 'LT-HL' : 'LT-HH'

ltHigh.lastPrice := itHigh.midPrice
ltHigh.lastIndex := itHigh.midIndex

if ltSwings != 'Disabled'
itHigh.midLabel.set_text(TX)
itHigh.midLabel.set_size(textSize(ltSwingsSZ))
itHigh.midLabel.set_textcolor(ltBullMSColor)

if ltMarketStructures
if not ltLow.isCrossed
ltViolations += 1
if ltHigh.isCrossed
ltPoints := ltPoints + 10 - ltViolations
ltViolations := 0
ltLow.renderStructures(false, ltMS, 'LT', ltBearMSColor, ltMSLineStyle,
ltMSLineWidth, ltMSText)
ltHigh.renderStructures(true, ltMS, 'LT', ltBullMSColor, ltMSLineStyle,
ltMSLineWidth, ltMSText)

// Calculate RSI
rsi = ta.rsi(close, rsiLength)

// Calculate Volume MA
volumeMa = ta.sma(volume, volumeMaLength)

// Calculate QQE (placeholder, should be replaced with actual QQE calculation if


available)
qqeLine = ta.sma(close, qqeLength)
qqeSignal = ta.sma(qqeLine, 3)

// Plot QQE
plot(qqeLine, title="QQE Line", color=color.blue)
plot(qqeSignal, title="QQE Signal", color=color.red)

// Plot RSI
plot(rsi, title="RSI", color=color.green)
hline(rsiOverbought, "RSI Overbought", color=color.red)
hline(rsiOversold, "RSI Oversold", color=color.blue)

// Plot Volume MA
plot(volumeMa, title="Volume MA", color=color.orange, linewidth=2)

// Plot Volume
plot(volume, title="Volume", color=color.purple, style=plot.style_columns,
linewidth=1)

// Optionally add background color for RSI levels


bgcolor(rsi > rsiOverbought ? color.new(color.red, 90) : na, title="RSI Overbought
Background")
bgcolor(rsi < rsiOversold ? color.new(color.blue, 90) : na, title="RSI Oversold
Background")

// Plot Trade Signals (example)


longCondition = ta.crossover(rsi, rsiOversold)
shortCondition = ta.crossunder(rsi, rsiOverbought)

plotshape(longCondition, title="Long Signal", location=location.belowbar,


color=color.green, style=shape.labelup, text="BUY")
plotshape(shortCondition, title="Short Signal", location=location.abovebar,
color=color.red, style=shape.labeldown, text="SELL")

// Alert Conditions
alertcondition(longCondition, title="Long Signal Alert", message="RSI has crossed
above the oversold level. Consider buying.")
alertcondition(shortCondition, title="Short Signal Alert", message="RSI has crossed
below the overbought level. Consider selling.")

// Displaying Market Structures on the Chart


plot(stLow.lastPrice, color=color.red, title="ST Low")
plot(stHigh.lastPrice, color=color.green, title="ST High")

//---------------------------------------------------------------------------------
-----------------//

display1 = display.all - display.status_line

msGroup = 'Market Structures'


msShow = input.bool (true, 'Market Structures', group = msGroup)
msTerm = input.string('Intermediate Term', ' Detection', options = ['Short
Term', 'Intermediate Term', 'Long Term'], group = msGroup)
msTextT = input.string('Enabled', ' Market Structure Labels', options =
['Enabled', 'Disabled'], group = msGroup, display = display), msText = msTextT ==
'Enabled'
msLineStyle = input.string('Solid', ' Line Style', options = ['Solid', 'Dashed',
'Dotted'], group = msGroup, display = display)
msBullColor = input.color(#089981, ' Line Colors, Bullish', group = msGroup,
inline = 'MS')
msBearColor = input.color(#f23645, 'Bearish', group = msGroup, inline = 'MS')

obbGroup = 'Order & Breaker Blocks'


obbShow = input.bool (true, 'Order & Breaker Blocks', group = obbGroup)
obbTerm = input.string('Long Term', ' Detection', options = ['Short Term',
'Intermediate Term', 'Long Term'], group = obbGroup, display = display)
obbBullLast = input.int(3, ' Last Bullish Blocks', minval = 0, group = obbGroup,
display = display)
obbBearLast = input.int(3, ' Last Bearish Blocks', minval = 0, group = obbGroup,
display = display)
obbUseBodyT = input.string('Enabled', ' Use Candle Body', options = ['Enabled',
'Disabled'], group = obbGroup, display = display), obbUseBody = obbUseBodyT ==
'Enabled'
obbBullColor = input(color.new(#089981, 73), ' Bullish OB ' , inline =
'bullC', group = obbGroup)
obbBullBreakColor = input(color.new(#f23645, 41), 'Bullish Break ', inline =
'bullC', group = obbGroup)
obbBearColor = input(color.new(#f23645, 73), ' Bearish OB' , inline =
'bearC', group = obbGroup)
obbBearBreakColor = input(color.new(#089981, 41), 'Bearish Break', inline =
'bearC', group = obbGroup)

liqGroup = 'Buyside & Sellside Liquidity'


liqBuySell = input.bool (true, 'Buyside & Sellside Liquidity', group = liqGroup)
liqTerm = input.string('Intermediate Term', ' Detection', options = ['Short
Term', 'Intermediate Term', 'Long Term'], group = liqGroup)
liqMar = 10 / input.float (6.9, ' Margin', minval = 4, maxval = 9, step = 0.1,
group = liqGroup, display = display)
cLIQ_B = input.color (#089981, ' Line Colors, Buyside', inline = 'LIQ', group =
liqGroup)
cLIQ_S = input.color (#f23645, 'Sellside', inline = 'LIQ', group = liqGroup)
visLiq = input.int (3, ' Visible Levels', minval = 1, maxval = 50, group =
liqGroup, display = display)

liqGrp = 'Liquidity Voids'


lqVoid = input.bool (true, 'Liquidity Voids', group = liqGrp)
lqThresh = input.float(.75, ' Threshold Multiplier', minval = .05, step = .05,
group = liqGrp, display = display)
lqMode = input.string('Present', ' Mode', options =['Present', 'Historical'],
inline = 'MD', group = liqGrp, display = display)
lqPeriod = input.int(360, ' ', inline = 'MD', group = liqGrp, display = display)
cLQV_B = input.color (#B2B5BE41, ' Bullish Zones', inline = 'void', group =
liqGrp)
cLQV_S = input.color (#5D606B41, ' Bearish Zones', inline = 'void', group =
liqGrp)
lqTextT = input.string('Disabled', ' Liquidity Void Labels', options =
['Enabled', 'Disabled'], group = liqGrp, display = display), lqText = lqTextT ==
'Enabled'

swGroup = 'Swing Highs/Lows'


swShow = input.bool (true, 'Swing Highs/Lows', group = swGroup)
swTerm = input.string('Long Term', ' Detection', options = ['Short Term',
'Intermediate Term', 'Long Term'], group = swGroup)
swSwingsSZ = input.string('Tiny', ' Label Size', options = ['Tiny', 'Small',
'Normal'], group = swGroup, display = display)
swBullColor = input.color(#089981, ' Label Colors, Bullish', group = swGroup,
inline = 'MS')
swBearColor = input.color(#f23645, 'Bearish', group = swGroup, inline = 'MS')

//---------------------------------------------------------------------------------
------------------------------------}
// User Defined Types
//---------------------------------------------------------------------------------
------------------------------------{

type ICTMS1
float lastPrice
float midPrice
float prevPrice

int lastIndex
int midIndex
int prevIndex

label lastLabel
label midLabel
label prevLabel

bool isCrossed
bool isConfirmed

int marketStructure

line msLine
box msLabel
box swpBox

type MS1
int type = 0

type ZZ
int [] d
int [] x
float [] y

type liq
box bx
box bxz
box bxt
bool brZ
bool brL
line ln
line lne

type ob
float top = na
float btm = na
int loc = bar_index
bool breaker = false
int break_loc = na

type SWING
float y = na
int x = na
bool crossed = false

type vector
array<SWING> v

type htfBar
float price = na
int index = na

//---------------------------------------------------------------------------------
------------------------------------}
// Generic Variables
//---------------------------------------------------------------------------------
------------------------------------{

BAR bar1 = BAR.new()


var bxOBB = array.new_box()
var lnOBB = array.new_line()

//---------------------------------------------------------------------------------
------------------------------------}
// Functions / Methods
//---------------------------------------------------------------------------------
------------------------------------{

timeframe(userTimeframe) =>
float chartTFinM = timeframe.in_seconds() / 60

switch
userTimeframe == "Auto" and chartTFinM <= 60 => 'D'
userTimeframe == "Auto" and chartTFinM <= 1440 => 'W'
userTimeframe == "5 Minutes" and chartTFinM <= 5 => '5'
userTimeframe == "15 Minutes" and chartTFinM <= 15 => '15'
userTimeframe == "1 Hour" and chartTFinM <= 60 => '60'
userTimeframe == "4 Hours" and chartTFinM <= 240 => '240'
userTimeframe == "1 Day" and timeframe.isintraday => 'D'
(userTimeframe == "Auto" or userTimeframe == "1 Week") and
(timeframe.isdaily or timeframe.isintraday) => 'W'
(userTimeframe == "Auto" or userTimeframe == "1 Month") and
(timeframe.isweekly or timeframe.isdaily or timeframe.isintraday) => 'M'
=> timeframe.period

queryPatterns1(lastPrice, midPrice, prevPrice, isSwingHigh) =>


if isSwingHigh
prevPrice < midPrice and midPrice >= lastPrice
else
prevPrice > midPrice and midPrice <= lastPrice

method queryPatterns1(ICTMS1 this, isSwingHigh) =>


if isSwingHigh
this.prevPrice < this.midPrice and this.midPrice >= this.lastPrice
else
this.prevPrice > this.midPrice and this.midPrice <= this.lastPrice

method updatePattern1(ICTMS1 this, price, index) =>


this.isCrossed := false
this.prevPrice := this.midPrice, this.midPrice := this.lastPrice,
this.lastPrice := price
this.prevIndex := this.midIndex, this.midIndex := this.lastIndex,
this.lastIndex := index
this.prevLabel := this.midLabel, this.midLabel := this.lastLabel

method setType(MS1 this, value) =>


this.type := value

method renderStructures1(ICTMS1 this, isBullish, marketStructure, color, style,


labelEnabled) =>

condition = isBullish ? bar.close > this.lastPrice : bar.close < this.lastPrice

if condition and not this.isCrossed


this.isCrossed := true
this.isConfirmed := false
this.msLine := line.new(this.lastIndex, this.lastPrice, bar.index,
this.lastPrice, color = color, style = lineStyle(style))
this.swpBox := box.new(bar.index, this.lastPrice, bar.index,
this.lastPrice, color.new(color, 73), bgcolor = color.new(color, 73))

if labelEnabled
this.msLabel := box.new(this.lastIndex, this.lastPrice, bar.index,
this.lastPrice, color(na), bgcolor = color(na),
text = marketStructure.type == (isBullish ? -1 : 1) ? 'MSS' : 'BOS',
text_size = size.tiny, text_halign = text.align_left, text_valign = isBullish ?
text.align_bottom : text.align_top, text_color = color.new(color, 17))
marketStructure.setType(isBullish ? 1 : -1)

method in_out(ZZ aZZ, int _d, int _x, float _y) =>
aZZ.d.unshift(_d), aZZ.x.unshift(_x), aZZ.y.unshift(_y), aZZ.d.pop(),
aZZ.x.pop(), aZZ.y.pop()

method detectSwings(array<vector> id, mode, depth)=>


var SWING swingLevel = SWING.new(na, na)
for i = 0 to depth - 1
get_v = id.get(i).v

if get_v.size() == 3
pivot = switch mode
'bull' => math.max(get_v.get(0).y, get_v.get(1).y, get_v.get(2).y)
'bear' => math.min(get_v.get(0).y, get_v.get(1).y, get_v.get(2).y)

if pivot == get_v.get(1).y
if i < depth - 1
id.get(i+1).v.unshift(get_v.get(1))

if id.get(i+1).v.size() > 3
id.get(i+1).v.pop()
else
swingLevel := SWING.new(get_v.get(1).y, get_v.get(1).x)

get_v.pop()
get_v.pop()
swingLevel

method renderBlocks(ob id, color, breakColor)=>


avg = math.avg(id.top, id.btm)

if id.breaker
bxOBB.push(box.new(id.loc, id.top, id.break_loc, id.btm, color, bgcolor =
color, xloc = xloc.bar_time))
lnOBB.push(line.new(id.break_loc, id.top, timenow, id.top, xloc.bar_time,
extend.none, breakColor))
lnOBB.push(line.new(id.break_loc, id.btm, timenow, id.btm, xloc.bar_time,
extend.none, breakColor))
lnOBB.push(line.new(id.loc, avg, timenow, avg, xloc.bar_time, extend.none,
breakColor, style = line.style_dotted))

if not id.breaker
bxOBB.push(box.new(id.loc, id.top, timenow, id.btm, na, bgcolor = color,
extend = extend.none, xloc = xloc.bar_time))
lnOBB.push(line.new(id.loc, id.top, timenow, id.top, xloc.bar_time,
extend.none, color))
lnOBB.push(line.new(id.loc, id.btm, timenow, id.btm, xloc.bar_time,
extend.none, color))
lnOBB.push(line.new(id.loc, avg, timenow, avg, xloc.bar_time, extend.none,
breakColor, style = line.style_dotted))

//---------------------------------------------------------------------------------
------------------------------------}
// Calculations - Swings
//---------------------------------------------------------------------------------
------------------------------------{

var ICTMS1 stLow1 = ICTMS1.new()


var ICTMS1 stHigh1 = ICTMS1.new()
var MS1 stMS1 = MS1.new()

if queryPatterns1(bar.low, bar.low[1], bar.low[2], false)


stLow1.updatePattern1(bar.low[1], bar.index[1])
stLow1.lastLabel := label.new(stLow.lastIndex, stLow.lastPrice, '⦁', color =
color(na), textcolor = swShow and swTerm == 'Short Term' ? swBearColor : color(na),
style = label.style_label_up, size = textSize(swSwingsSZ), tooltip =
str.tostring(stLow1.lastPrice, format.mintick))

if queryPatterns(bar.high, bar.high[1], bar.high[2], true)


stHigh1.updatePattern1(bar.high[1], bar.index[1])
stHigh1.lastLabel := label.new(bar.index[1], bar.high[1], '⦁', color =
color(na), textcolor = swShow and swTerm == 'Short Term' ? swBullColor : color(na),
style = label.style_label_down, size = textSize(swSwingsSZ), tooltip =
str.tostring(bar.high[1], format.mintick))

var ICTMS1 itLow1 = ICTMS1.new()


var ICTMS1 itHigh1 = ICTMS1.new()
var MS1 itMS1 = MS1.new()

cITL1 = stLow1.queryPatterns1(false)

if cITL1 and cITL1 != cITL1[1]


itLow1.updatePattern1(stLow.midPrice, stLow.midIndex)

itLow1.lastLabel := stLow1.midLabel

if swShow and swTerm == 'Intermediate Term'


stLow1.midLabel.set_size(textSize(swSwingsSZ))
stLow1.midLabel.set_textcolor(swBearColor)

cITH1 = stHigh1.queryPatterns1(true)

if cITH1 and cITH1 != cITH1[1]


itHigh1.updatePattern1(stHigh1.midPrice, stHigh1.midIndex)

itHigh1.lastLabel := stHigh1.midLabel

if swShow and swTerm == 'Intermediate Term'


stHigh1.midLabel.set_size(textSize(swSwingsSZ))
stHigh1.midLabel.set_textcolor(swBullColor)

var ICTMS1 ltLow1 = ICTMS1.new()


var ICTMS1 ltHigh1 = ICTMS1.new()
var MS1 ltMS1 = MS1.new()

cLTL1 = itLow1.queryPatterns1(false)

if cLTL1 and cLTL1 != cLTL1[1]


ltLow1.isCrossed := false

ltLow1.lastPrice := itLow1.midPrice
ltLow1.lastIndex := itLow1.midIndex

if swShow and swTerm == 'Long Term'


itLow1.midLabel.set_size(textSize(swSwingsSZ))
itLow1.midLabel.set_textcolor(swBearColor)
cLTH1 = itHigh1.queryPatterns1(true)

if cLTH1 and cLTH1 != cLTH1[1]


ltHigh1.isCrossed := false

ltHigh1.lastPrice := itHigh1.midPrice
ltHigh1.lastIndex := itHigh1.midIndex

if swShow and swTerm == 'Long Term'


itHigh1.midLabel.set_size(textSize(swSwingsSZ))
itHigh1.midLabel.set_textcolor(swBullColor)

//---------------------------------------------------------------------------------
------------------------------------}
// Calculations - Market Structures
//---------------------------------------------------------------------------------
------------------------------------{

if msShow
if msTerm == 'Short Term'
stLow1.renderStructures1(false, stMS1, msBearColor, msLineStyle, msText)
stHigh1.renderStructures1(true, stMS1, msBullColor, msLineStyle, msText)

if msTerm == 'Intermediate Term'


itLow1.renderStructures1(false, itMS1, msBearColor, msLineStyle, msText)
itHigh1.renderStructures1(true, itMS1, msBullColor, msLineStyle, msText)

if msTerm == 'Long Term'


ltLow1.renderStructures1(false, ltMS1, msBearColor, msLineStyle, msText)
ltHigh1.renderStructures1(true, ltMS1, msBullColor, msLineStyle, msText)

//---------------------------------------------------------------------------------
------------------------------------}
// Calculations - Buyside & Sellside Liquidity
//---------------------------------------------------------------------------------
------------------------------------{

maxSize = 50
atr = ta.atr(10)

var ZZ aZZ = ZZ.new(


array.new <int> (maxSize, 0),
array.new <int> (maxSize, 0),
array.new <float>(maxSize, na)
)

var liq[] b_liq_B = array.new<liq> (1, liq.new(box(na), box(na), box(na), false,


false, line(na), line(na)))
var liq[] b_liq_S = array.new<liq> (1, liq.new(box(na), box(na), box(na), false,
false, line(na), line(na)))

var b_liq_V = array.new_box()

var int dir = na, var int x1 = na, var float y1 = na, var int x2 = na, var float y2
= na

[topLQ, btmLQ] = switch liqTerm


'Short Term' => [SWING.new(stHigh.lastPrice, stHigh.lastIndex),
SWING.new(stLow.lastPrice, stLow.lastIndex)]
'Intermediate Term' => [SWING.new(itHigh.lastPrice, itHigh.lastIndex),
SWING.new(itLow.lastPrice, itLow.lastIndex)]
'Long Term' => [SWING.new(ltHigh.lastPrice, ltHigh.lastIndex),
SWING.new(ltLow.lastPrice, ltLow.lastIndex)]

if not liqBuySell
topLQ := SWING.new(0, 0)
btmLQ := SWING.new(0, 0)

swingHigh = topLQ.y
swingLow = btmLQ.y

x2 := bar.index - 1

if swingHigh > 0 and swingHigh != swingHigh[1]


dir := aZZ.d.get(0)
x1 := aZZ.x.get(0)
x2 := topLQ.x
y1 := aZZ.y.get(0)
y2 := swingHigh//nz(bar.high[1])

if dir < 1
aZZ.in_out(1, x2, y2)
else
if dir == 1 and swingHigh > y1
aZZ.x.set(0, x2), aZZ.y.set(0, y2)

if true
count = 0
st_P = 0.
st_B = 0
minP = 0.
maxP = 10e6

for i = 0 to maxSize - 1
if aZZ.d.get(i) == 1
if aZZ.y.get(i) > swingHigh + (atr / liqMar)
break
else
if aZZ.y.get(i) > swingHigh - (atr / liqMar) and aZZ.y.get(i) <
swingHigh + (atr / liqMar)
count += 1
st_B := aZZ.x.get(i)
st_P := aZZ.y.get(i)
if aZZ.y.get(i) > minP
minP := aZZ.y.get(i)
if aZZ.y.get(i) < maxP
maxP := aZZ.y.get(i)

if count > 2
getB = b_liq_B.get(0)

if st_B == getB.bx.get_left()
getB.bx.set_top(math.avg(minP, maxP) + (atr / liqMar))
getB.bx.set_rightbottom(bar.index + 10, math.avg(minP, maxP) - (atr
/ liqMar))
else
b_liq_B.unshift(
liq.new(
box.new(st_B, math.avg(minP, maxP) + (atr / liqMar), bar.index +
10, math.avg(minP, maxP) - (atr / liqMar), bgcolor=color(na),
border_color=color(na)),
box.new(na, na, na, na, bgcolor = color(na), border_color =
color(na)),
box.new(st_B, st_P, bar.index + 10, st_P, text = 'Buyside
liquidity', text_size = size.tiny, text_halign = text.align_left, text_valign =
text.align_bottom, text_color = color.new(cLIQ_B, 25), bgcolor = color(na),
border_color = color(na)),
false,
false,
line.new(st_B , st_P, bar.index - 1, st_P, color =
color.new(cLIQ_B, 0)),
line.new(bar.index - 1, st_P, na , st_P, color =
color.new(cLIQ_B, 0), style = line.style_dotted))
)

if b_liq_B.size() > visLiq


getLast = b_liq_B.pop()
getLast.bx.delete()
getLast.bxz.delete()
getLast.bxt.delete()
getLast.ln.delete()
getLast.lne.delete()

if swingLow > 0 and swingLow != swingLow[1]


dir := aZZ.d.get (0)
x1 := aZZ.x.get (0)
x2 := btmLQ.x
y1 := aZZ.y.get (0)
y2 := swingLow//nz(bar.low[1])

if dir > -1
aZZ.in_out(-1, x2, y2)
else
if dir == -1 and swingLow < y1
aZZ.x.set(0, x2), aZZ.y.set(0, y2)

if true
count = 0
st_P = 0.
st_B = 0
minP = 0.
maxP = 10e6

for i = 0 to maxSize - 1
if aZZ.d.get(i) == -1
if aZZ.y.get(i) < swingLow - (atr / liqMar)
break
else
if aZZ.y.get(i) > swingLow - (atr / liqMar) and aZZ.y.get(i) <
swingLow + (atr / liqMar)
count += 1
st_B := aZZ.x.get(i)
st_P := aZZ.y.get(i)
if aZZ.y.get(i) > minP
minP := aZZ.y.get(i)
if aZZ.y.get(i) < maxP
maxP := aZZ.y.get(i)

if count > 2
getB = b_liq_S.get(0)

if st_B == getB.bx.get_left()
getB.bx.set_top(math.avg(minP, maxP) + (atr / liqMar))
getB.bx.set_rightbottom(bar.index + 10, math.avg(minP, maxP) - (atr
/ liqMar))
else
b_liq_S.unshift(
liq.new(
box.new(st_B, math.avg(minP, maxP) + (atr / liqMar), bar.index +
10, math.avg(minP, maxP) - (atr / liqMar), bgcolor=color(na),
border_color=color(na)),
box.new(na, na, na, na, bgcolor=color(na),
border_color=color(na)),
box.new(st_B, st_P, bar.index + 10, st_P, text = 'Sellside
liquidity', text_size = size.tiny, text_halign = text.align_left, text_valign =
text.align_top, text_color = color.new(cLIQ_S, 25), bgcolor=color(na),
border_color=color(na)),
false,
false,
line.new(st_B , st_P, bar.index - 1, st_P, color =
color.new(cLIQ_S, 0)),
line.new(bar.index - 1, st_P, na , st_P, color =
color.new(cLIQ_S, 0), style = line.style_dotted))
)

if b_liq_S.size() > visLiq


getLast = b_liq_S.pop()
getLast.bx.delete()
getLast.bxz.delete()
getLast.bxt.delete()
getLast.ln.delete()
getLast.lne.delete()

for i = 0 to b_liq_B.size() - 1
x = b_liq_B.get(i)

if not x.brL
x.lne.set_x2(bar.index)

if bar.high > x.bx.get_top()


x.brL := true

for i = 0 to b_liq_S.size() - 1
x = b_liq_S.get(i)

if not x.brL
x.lne.set_x2(bar.index)

if bar.low < x.bx.get_bottom()


x.brL := true

//---------------------------------------------------------------------------------
------------------------------------}
// Calculations - Liquidity Voids
//---------------------------------------------------------------------------------
------------------------------------{

atr200 = ta.atr(200) * lqThresh


dispPeriod = lqMode == 'Present' ? last_bar_index - bar_index <= lqPeriod : true

if lqVoid and dispPeriod


bull = bar.low - bar.high[2] > atr200 and bar.low > bar.high[2] and
bar.close[1] > bar.high[2]
bear = bar.low[2] - bar.high > atr200 and bar.high < bar.low[2] and
bar.close[1] < bar.low[2]

if bull
l = 13
if bull[1]
st = math.abs(bar.low - bar.low[1]) / l
for i = 0 to l - 1
b_liq_V.push(box.new(bar.index - 2, bar.low[1] + i * st, bar.index,
bar.low[1] + (i + 1) * st, border_color = na, bgcolor = cLQV_B ))
else
st = math.abs(bar.low - bar.high[2]) / l
for i = 0 to l - 1
if lqText and i == 0
array.push(b_liq_V, box.new(bar.index - 2, bar.high[2] + i *
st, bar.index, bar.high[2] + (i + 1) * st, text = 'Liquidity Void ', text_size =
size.tiny, text_halign = text.align_right, text_valign = text.align_bottom,
text_color = na, border_color = na, bgcolor = cLQV_B ))
else
array.push(b_liq_V, box.new(bar.index - 2, bar.high[2] + i *
st, bar.index, bar.high[2] + (i + 1) * st, border_color = na, bgcolor = cLQV_B ))

if bear
l = 13
if bear[1]
st = math.abs(bar.high[1] - bar.high) / l
for i = 0 to l - 1
array.push(b_liq_V, box.new(bar.index - 2, bar.high + i * st,
bar.index, bar.high + (i + 1) * st, border_color = na, bgcolor = cLQV_S ))
else
st = math.abs(bar.low[2] - bar.high) / l
for i = 0 to l - 1
if lqText and i == l - 1
array.push(b_liq_V, box.new(bar.index - 2, bar.high + i * st,
bar.index, bar.high + (i + 1) * st, text = 'Liquidity Void ', text_size =
size.tiny, text_halign = text.align_right, text_valign = text.align_top, text_color
= na, border_color = na, bgcolor = cLQV_S ))
else
array.push(b_liq_V, box.new(bar.index - 2, bar.high + i * st,
bar.index, bar.high + (i + 1) * st, border_color = na, bgcolor = cLQV_S ))

if b_liq_V.size() > 0
qt = b_liq_V.size()
for bn = qt - 1 to 0
if bn < b_liq_V.size()
cb = b_liq_V.get(bn)
ba = math.avg(cb.get_bottom(), cb.get_top())

if math.sign(bar.close[1] - ba) != math.sign(bar.close - ba) or


math.sign(bar.close[1] - ba) != math.sign(bar.low - ba) or math.sign(bar.close[1] -
ba) != math.sign(bar.high - ba)
b_liq_V.remove(bn)
else
cb.set_right(bar.index + 1)

if bar.index - cb.get_left() > 21


cb.set_text_color(color.new(chart.fg_color, 25))

//---------------------------------------------------------------------------------
------------------------------------}
// Order & Breaker Blocks
//---------------------------------------------------------------------------------
------------------------------------{

depth = switch obbTerm


'Short Term' => 1
'Intermediate Term' => 2
'Long Term' => 3

var fractalHigh = array.new<vector>(0)


var fractalLow = array.new<vector>(0)

if barstate.isfirst
for i = 0 to depth - 1
fractalHigh.push(vector.new(array.new<SWING>(0)))
fractalLow.push(vector.new(array.new<SWING>(0)))

fractalHigh.get(0).v.unshift(SWING.new(bar.high, bar.index))
fractalLow.get(0).v.unshift(SWING.new(bar.low, bar.index))

if fractalHigh.get(0).v.size() > 3
fractalHigh.get(0).v.pop()

if fractalLow.get(0).v.size() > 3
fractalLow.get(0).v.pop()

top = fractalHigh.detectSwings('bull', depth)


btm = fractalLow.detectSwings('bear', depth)

if obbShow

max = obbUseBody ? math.max(bar.close, bar.open) : bar.high


min = obbUseBody ? math.min(bar.close, bar.open) : bar.low

var bullish_ob = array.new<ob>(0)

if bar.close > top.y and not top.crossed


top.crossed := true

minima = max[1]
maxima = min[1]
loc = time[1]

for i = 1 to (bar.index - top.x) - 1


minima := math.min(min[i], minima)
maxima := minima == min[i] ? max[i] : maxima
loc := minima == min[i] ? time[i] : loc
bullish_ob.unshift(ob.new(maxima, minima, loc))

if bullish_ob.size() > 100//obbBullLast


bullish_ob.pop()

if bullish_ob.size() > 0
for i = bullish_ob.size() - 1 to 0
element = bullish_ob.get(i)

if not element.breaker
if math.min(bar.close, bar.open) < element.btm
element.breaker := true
element.break_loc := time
else
if bar.close > element.top
bullish_ob.remove(i)

var bearish_ob = array.new<ob>(0)

if bar.close < btm.y and not btm.crossed


btm.crossed := true

minima = min[1]
maxima = max[1]
loc = time[1]

for i = 1 to (bar.index - btm.x) - 1


maxima := math.max(max[i], maxima)
minima := maxima == max[i] ? min[i] : minima
loc := maxima == max[i] ? time[i] : loc

bearish_ob.unshift(ob.new(maxima, minima, loc))

if bearish_ob.size() > 100//obbBearLast


bearish_ob.pop()

if bearish_ob.size() > 0
for i = bearish_ob.size() - 1 to 0
element = bearish_ob.get(i)

if not element.breaker
if math.max(bar.close, bar.open) > element.top
element.breaker := true
element.break_loc := time
else
if bar.close < element.btm
bearish_ob.remove(i)

if bxOBB.size() > 0
for i = 0 to bxOBB.size() - 1
box.delete(bxOBB.shift())

if lnOBB.size() > 0
for i = 0 to lnOBB.size() - 1
line.delete(lnOBB.shift())

if barstate.islast
if obbBullLast > 0 and bullish_ob.size() > 0
for i = 0 to math.min(obbBullLast - 1, bullish_ob.size() - 1)
get_ob = bullish_ob.get(i)
get_ob.renderBlocks(obbBullColor, obbBullBreakColor)

if obbBearLast > 0 and bearish_ob.size() > 0


for i = 0 to math.min(obbBearLast - 1, bearish_ob.size() - 1)
get_ob = bearish_ob.get(i)
get_ob.renderBlocks(obbBearColor, obbBearBreakColor)

//-----------------------------------------------------------------------------{
//CONSTANTS
//-----------------------------------------------------------------------------{
color TRANSP_CSS = #ffffff00

//Tooltips
string MODE_TOOLTIP = 'Allows to display historical Structure or only the
recent ones'
string STYLE_TOOLTIP = 'Indicator color theme'
string COLOR_CANDLES_TOOLTIP = 'Display additional candles with a color reflecting
the current trend detected by structure'
string SHOW_INTERNAL = 'Display internal market structure'
string CONFLUENCE_FILTER = 'Filter non significant internal structure
breakouts'
string SHOW_SWING = 'Display swing market Structure'
string SHOW_SWING_POINTS = 'Display swing point as labels on the chart'
string SHOW_SWHL_POINTS = 'Highlight most recent strong and weak high/low
points on the chart'
string HIGHLIGHT_MIT_OB = 'Highlight mitigated orderblocks with other color'
string INTERNAL_OB = 'Display internal order blocks on the chart\n\
nNumber of internal order blocks to display on the chart'
string SWING_OB = 'Display swing order blocks on the chart\n\nNumber
of internal swing blocks to display on the chart'
string FILTER_OB = 'Method used to filter out volatile order blocks \n\
nIt is recommended to use the cumulative mean range method when a low amount of
data is available'
string SHOW_EQHL = 'Display equal highs and equal lows on the chart'
string EQHL_BARS = 'Number of bars used to confirm equal highs and
equal lows'
string EQHL_THRESHOLD = 'Sensitivity threshold in a range (0, 1) used for
the detection of equal highs & lows\n\nLower values will return fewer but more
pertinent results'
string SHOW_FVG = 'Display fair values gaps on the chart'
string AUTO_FVG = 'Filter out non significant fair value gaps'
string FVG_TF = 'Fair value gaps timeframe'
string EXTEND_FVG = 'Determine how many bars to extend the Fair Value
Gap boxes on chart'
string PED_ZONES = 'Display premium, discount, and equilibrium zones on
chart'

//-----------------------------------------------------------------------------{
//Settings
//-----------------------------------------------------------------------------{
//General
//----------------------------------------{
mode = input.string('Historical'
, options = ['Historical', 'Present']
, group = 'Smart Money Concepts'
, tooltip = MODE_TOOLTIP)

style = input.string('Colored'
, options = ['Colored', 'Monochrome']
, group = 'Smart Money Concepts'
, tooltip = STYLE_TOOLTIP)

show_trend = input(false, 'Color Candles'


, group = 'Smart Money Concepts'
, tooltip = COLOR_CANDLES_TOOLTIP)

//----------------------------------------}
//Internal Structure
//----------------------------------------{
show_internals = input(true, 'Show Internal Structure'
, group = 'Real Time Internal Structure'
, tooltip = SHOW_INTERNAL)

show_ibull = input.string('All', 'Bullish Structure'


, options = ['All', 'BOS', 'CHoCH']
, inline = 'ibull'
, group = 'Real Time Internal Structure')

swing_ibull_css = input(#089981, ''


, inline = 'ibull'
, group = 'Real Time Internal Structure')

//Bear Structure
show_ibear = input.string('All', 'Bearish Structure'
, options = ['All', 'BOS', 'CHoCH']
, inline = 'ibear'
, group = 'Real Time Internal Structure')

swing_ibear_css = input(#f23645, ''


, inline = 'ibear'
, group = 'Real Time Internal Structure')

ifilter_confluence = input(false, 'Confluence Filter'


, group = 'Real Time Internal Structure'
, tooltip = CONFLUENCE_FILTER)

//----------------------------------------}
//Swing Structure
//----------------------------------------{
show_Structure = input(true, 'Show Swing Structure'
, group = 'Real Time Swing Structure'
, tooltip = SHOW_SWING)

//Bull Structure
show_bull = input.string('All', 'Bullish Structure'
, options = ['All', 'BOS', 'CHoCH']
, inline = 'bull'
, group = 'Real Time Swing Structure')

swing_bull_css = input(#089981, ''


, inline = 'bull'
, group = 'Real Time Swing Structure')

//Bear Structure
show_bear = input.string('All', 'Bearish Structure'
, options = ['All', 'BOS', 'CHoCH']
, inline = 'bear'
, group = 'Real Time Swing Structure')

swing_bear_css = input(#f23645, ''


, inline = 'bear'
, group = 'Real Time Swing Structure')

//Swings
show_swings = input(false, 'Show Swings Points'
, inline = 'swings'
, group = 'Real Time Swing Structure'
, tooltip = SHOW_SWING_POINTS)

length = input.int(50, ''


, minval = 10
, inline = 'swings'
, group = 'Real Time Swing Structure')

show_hl_swings = input(true, 'Show Strong/Weak High/Low'


, group = 'Real Time Swing Structure'
, tooltip = SHOW_SWHL_POINTS)

//----------------------------------------}
//Order Blocks
//----------------------------------------{
show_iob = input(true, 'Internal Order Blocks'
, inline = 'iob'
, group = 'Order Blocks'
, tooltip = INTERNAL_OB)

iob_showlast = input.int(5, ''


, minval = 1
, inline = 'iob'
, group = 'Order Blocks')

show_ob = input(false, 'Swing Order Blocks'


, inline = 'ob'
, group = 'Order Blocks'
, tooltip = SWING_OB)

ob_showlast = input.int(5, ''


, minval = 1
, inline = 'ob'
, group = 'Order Blocks')

ob_filter = input.string('Atr', 'Order Block Filter'


, options = ['Atr', 'Cumulative Mean Range']
, group = 'Order Blocks'
, tooltip = FILTER_OB)

ob_highlight_mit = input(true, 'Highlight Mitigated Order blocks'


, inline = 'ob'
, group = 'Order Blocks'
, tooltip = HIGHLIGHT_MIT_OB)

ibull_ob_css = input.color(color.new(#3179f5, 80), 'Internal Bullish OB'


, inline = 'inull_ob_css'
, group = 'Order Blocks')

ibullm_ob_css = input.color(color.new(#636363, 80), ''


, inline = 'inull_ob_css'
, group = 'Order Blocks'
, tooltip = 'Unmitigated and Mitigated colors')

ibear_ob_css = input.color(color.new(#f77c80, 80), 'Internal Bearish OB'


, inline = 'ibear_ob_css'
, group = 'Order Blocks')

ibearm_ob_css = input.color(color.new(#636363, 80), ''


, inline = 'ibear_ob_css'
, group = 'Order Blocks'
, tooltip = 'Unmitigated and Mitigated colors')

bull_ob_css = input.color(color.new(#1848cc, 80), 'Bullish OB'


, inline = 'bull_ob_css'
, group = 'Order Blocks')

bullm_ob_css = input.color(color.new(#636363, 80), ''


, group = 'Order Blocks'
, inline = 'bull_ob_css'
, tooltip = 'Unmitigated and Mitigated colors')

bear_ob_css = input.color(color.new(#b22833, 80), 'Bearish OB'


, group = 'Order Blocks'
, inline = 'bear_ob_css')

bearm_ob_css = input.color(color.new(#636363, 80), ''


, group = 'Order Blocks'
, inline = 'bear_ob_css'
, tooltip = 'Unmitigated and Mitigated colors')

//----------------------------------------}
//EQH/EQL
//----------------------------------------{
show_eq = input(true, 'Equal High/Low'
, group = 'EQH/EQL'
, tooltip = SHOW_EQHL)

eq_len = input.int(3, 'Bars Confirmation'


, minval = 1
, group = 'EQH/EQL'
, tooltip = EQHL_BARS)

eq_threshold = input.float(0.1, 'Threshold'


, minval = 0
, maxval = 0.5
, step = 0.1
, group = 'EQH/EQL'
, tooltip = EQHL_THRESHOLD)

//----------------------------------------}
//Fair Value Gaps
//----------------------------------------{
show_fvg = input(false, 'Fair Value Gaps'
, group = 'Fair Value Gaps'
, tooltip = SHOW_FVG)

fvg_auto = input(true, "Auto Threshold"


, group = 'Fair Value Gaps'
, tooltip = AUTO_FVG)

fvg_tf = input.timeframe('', "Timeframe"


, group = 'Fair Value Gaps'
, tooltip = FVG_TF)

bull_fvg_css = input.color(color.new(#00ff68, 70), 'Bullish FVG'


, group = 'Fair Value Gaps')

bear_fvg_css = input.color(color.new(#ff0008, 70), 'Bearish FVG'


, group = 'Fair Value Gaps')

fvg_extend = input.int(1, "Extend FVG"


, minval = 0
, group = 'Fair Value Gaps'
, tooltip = EXTEND_FVG)

//----------------------------------------}
//Previous day/week high/low
//----------------------------------------{
//Daily
show_pdhl = input(false, 'Daily'
, inline = 'daily'
, group = 'Highs & Lows MTF')

pdhl_style = input.string('⎯⎯⎯', ''


, options = ['⎯⎯⎯', '----', '····']
, inline = 'daily'
, group = 'Highs & Lows MTF')

pdhl_css = input(#2157f3, ''


, inline = 'daily'
, group = 'Highs & Lows MTF')

//Weekly
show_pwhl = input(false, 'Weekly'
, inline = 'weekly'
, group = 'Highs & Lows MTF')

pwhl_style = input.string('⎯⎯⎯', ''


, options = ['⎯⎯⎯', '----', '····']
, inline = 'weekly'
, group = 'Highs & Lows MTF')

pwhl_css = input(#2157f3, ''


, inline = 'weekly'
, group = 'Highs & Lows MTF')

//Monthly
show_pmhl = input(false, 'Monthly'
, inline = 'monthly'
, group = 'Highs & Lows MTF')

pmhl_style = input.string('⎯⎯⎯', ''


, options = ['⎯⎯⎯', '----', '····']
, inline = 'monthly'
, group = 'Highs & Lows MTF')

pmhl_css = input(#2157f3, ''


, inline = 'monthly'
, group = 'Highs & Lows MTF')

//----------------------------------------}
//Premium/Discount zones
//----------------------------------------{
show_sd = input(false, 'Premium/Discount Zones'
, group = 'Premium & Discount Zones'
, tooltip = PED_ZONES)

premium_css = input.color(#f23645, 'Premium Zone'


, group = 'Premium & Discount Zones')

eq_css = input.color(#b2b5be, 'Equilibrium Zone'


, group = 'Premium & Discount Zones')

discount_css = input.color(#089981, 'Discount Zone'


, group = 'Premium & Discount Zones')

//-----------------------------------------------------------------------------}
//Functions
//-----------------------------------------------------------------------------{
n = bar_index

atr1 = ta.atr(200)
cmean_range = ta.cum(high - low) / n

//HL Output function


hl() => [high, low]

//Get ohlc values function


get_ohlc()=> [close[1], open[1], high, low, high[2], low[2]]

//Display Structure function


display_Structure(x, y, txt, css, dashed, down, lbl_size)=>
structure_line = line.new(x, y, n, y
, color = css
, style = dashed ? line.style_dashed : line.style_solid)

structure_lbl = label.new(int(math.avg(x, n)), y, txt


, color = TRANSP_CSS
, textcolor = css
, style = down ? label.style_label_down : label.style_label_up
, size = lbl_size)

if mode == 'Present'
line.delete(structure_line[1])
label.delete(structure_lbl[1])

//Swings detection/measurements
swings(len)=>
var os = 0

upper = ta.highest(len)
lower = ta.lowest(len)

os := high[len] > upper ? 0 : low[len] < lower ? 1 : os[1]

top = os == 0 and os[1] != 0 ? high[len] : 0


btm = os == 1 and os[1] != 1 ? low[len] : 0

[top, btm]

//Order block coordinates function


ob_coord(use_max, loc, target_top, target_btm, target_left, target_right,
target_type, target_mit)=>
min = 99999999.
max = 0.
idx = 1

ob_threshold = ob_filter == 'Atr' ? atr1 : cmean_range

//Search for highest/lowest high within the structure interval and get range
if use_max
for i = 1 to (n - loc)-1
if (high[i] - low[i]) < ob_threshold[i] * 2
max := math.max(high[i], max)
min := max == high[i] ? low[i] : min
idx := max == high[i] ? i : idx
else
for i = 1 to (n - loc)-1
if (high[i] - low[i]) < ob_threshold[i] * 2
min := math.min(low[i], min)
max := min == low[i] ? high[i] : max
idx := min == low[i] ? i : idx

array.unshift(target_top, max)
array.unshift(target_btm, min)
array.unshift(target_left, time[idx])
array.unshift(target_right, time[idx])
array.unshift(target_type, use_max ? -1 : 1)
array.unshift(target_mit, 0)

//Set order blocks


display_ob(boxes, target_top, target_btm, target_left, target_right, target_type,
target_mit, show_last, swing, size)=>
for i = 0 to math.min(show_last-1, size-1)
get_box = array.get(boxes, i)

box.set_lefttop(get_box, array.get(target_left, i), array.get(target_top,


i))
box.set_rightbottom(get_box, array.get(target_right, i),
array.get(target_btm, i))
box.set_extend(get_box, array.get(target_mit, i) > 0 ? extend.none :
extend.right)

color css = na

if swing
if style == 'Monochrome'
css := array.get(target_type, i) == 1 ? color.new(#b2b5be, 80) :
color.new(#5d606b, 80)
border_css = array.get(target_type, i) == 1 ? #b2b5be : #5d606b
box.set_border_color(get_box, border_css)
else
if array.get(target_mit, i) > 0
css := array.get(target_type, i) == 1 ? bullm_ob_css :
bearm_ob_css
else
css := array.get(target_type, i) == 1 ? bull_ob_css :
bear_ob_css

box.set_border_color(get_box, css)
box.set_bgcolor(get_box, css)

else
if style == 'Monochrome'
css := array.get(target_type, i) == 1 ? color.new(#b2b5be, 80) :
color.new(#5d606b, 80)
else
if array.get(target_mit, i) > 0
css := array.get(target_type, i) == 1 ? ibullm_ob_css :
ibearm_ob_css
else
css := array.get(target_type, i) == 1 ? ibull_ob_css :
ibear_ob_css

box.set_border_color(get_box, css)
box.set_bgcolor(get_box, css)

//Line Style function


get_line_style(style) =>
out = switch style
'⎯⎯⎯' => line.style_solid
'----' => line.style_dashed
'····' => line.style_dotted

//Set line/labels function for previous high/lows


phl(h, l, tf, css)=>
var line high_line = line.new(na,na,na,na
, xloc = xloc.bar_time
, color = css
, style = get_line_style(pdhl_style))

var label high_lbl = label.new(na,na


, xloc = xloc.bar_time
, text = str.format('P{0}H', tf)
, color = TRANSP_CSS
, textcolor = css
, size = size.small
, style = label.style_label_left)

var line low_line = line.new(na,na,na,na


, xloc = xloc.bar_time
, color = css
, style = get_line_style(pdhl_style))

var label low_lbl = label.new(na,na


, xloc = xloc.bar_time
, text = str.format('P{0}L', tf)
, color = TRANSP_CSS
, textcolor = css
, size = size.small
, style = label.style_label_left)

hy = ta.valuewhen(h != h[1], h, 1)
hx = ta.valuewhen(h == high, time, 1)
ly = ta.valuewhen(l != l[1], l, 1)
lx = ta.valuewhen(l == low, time, 1)

if barstate.islast
ext = time + (time - time[1])*20

//High
line.set_xy1(high_line, hx, hy)
line.set_xy2(high_line, ext, hy)

label.set_xy(high_lbl, ext, hy)

//Low
line.set_xy1(low_line, lx, ly)
line.set_xy2(low_line, ext, ly)

label.set_xy(low_lbl, ext, ly)

//-----------------------------------------------------------------------------}
//Global variables
//-----------------------------------------------------------------------------{
var trend = 0, var itrend = 0

var top_y = 0., var top_x = 0


var btm_y = 0., var btm_x = 0

var itop_y = 0., var itop_x = 0


var ibtm_y = 0., var ibtm_x = 0

var trail_up = high, var trail_dn = low


var trail_up_x = 0, var trail_dn_x = 0

var top_cross = true, var btm_cross = true


var itop_cross = true, var ibtm_cross = true

var txt_top = '', var txt_btm = ''

//Alerts
bull_choch_alert = false
bull_bos_alert = false

bear_choch_alert = false
bear_bos_alert = false

bull_ichoch_alert = false
bull_ibos_alert = false

bear_ichoch_alert = false
bear_ibos_alert = false

bull_iob_mit = false
bear_iob_mit = false

bull_ob_mit = false
bear_ob_mit = false

bull_iob_break = false
bear_iob_break = false
bull_ob_break = false
bear_ob_break = false

eqh_alert = false
eql_alert = false

//Structure colors
var bull_css = style == 'Monochrome' ? #b2b5be
: swing_bull_css

var bear_css = style == 'Monochrome' ? #b2b5be


: swing_bear_css

var ibull_css = style == 'Monochrome' ? #b2b5be


: swing_ibull_css

var ibear_css = style == 'Monochrome' ? #b2b5be


: swing_ibear_css

//Swings
[top1, btm1] = swings(length)

[itop, ibtm] = swings(5)

//-----------------------------------------------------------------------------}
//Pivot High
//-----------------------------------------------------------------------------{
var line extend_top = na

var label extend_top_lbl = label.new(na, na


, color = TRANSP_CSS
, textcolor = bear_css
, style = label.style_label_down
, size = size.tiny)

if top1
top_cross := true
txt_top := top1 > top_y ? 'HH' : 'LH'

if show_swings
top_lbl = label.new(n-length, top1, txt_top
, color = TRANSP_CSS
, textcolor = bear_css
, style = label.style_label_down
, size = size.small)

if mode == 'Present'
label.delete(top_lbl[1])

//Extend recent top1 to last bar


line.delete(extend_top[1])
extend_top := line.new(n-length, top1, n, top1
, color = bear_css)

top_y := top1
top_x := n - length

trail_up := top1
trail_up_x := n - length

if itop
itop_cross := true

itop_y := itop
itop_x := n - 5

//Trailing maximum
trail_up := math.max(high, trail_up)
trail_up_x := trail_up == high ? n : trail_up_x

//Set top extension label/line


if barstate.islast and show_hl_swings
line.set_xy1(extend_top, trail_up_x, trail_up)
line.set_xy2(extend_top, n + 20, trail_up)

label.set_x(extend_top_lbl, n + 20)
label.set_y(extend_top_lbl, trail_up)
label.set_text(extend_top_lbl, trend < 0 ? 'Strong High' : 'Weak High')

//-----------------------------------------------------------------------------}
//Pivot Low
//-----------------------------------------------------------------------------{
var line extend_btm = na

var label extend_btm_lbl = label.new(na, na


, color = TRANSP_CSS
, textcolor = bull_css
, style = label.style_label_up
, size = size.tiny)

if btm1
btm_cross := true
txt_btm := btm1 < btm_y ? 'LL' : 'HL'

if show_swings
btm_lbl = label.new(n - length, btm1, txt_btm
, color = TRANSP_CSS
, textcolor = bull_css
, style = label.style_label_up
, size = size.small)

if mode == 'Present'
label.delete(btm_lbl[1])

//Extend recent btm to last bar


line.delete(extend_btm[1])
extend_btm := line.new(n - length, btm1, n, btm1
, color = bull_css)

btm_y := btm1
btm_x := n-length

trail_dn := btm1
trail_dn_x := n-length

if ibtm
ibtm_cross := true
ibtm_y := ibtm
ibtm_x := n - 5

//Trailing minimum
trail_dn := math.min(low, trail_dn)
trail_dn_x := trail_dn == low ? n : trail_dn_x

//Set btm extension label/line


if barstate.islast and show_hl_swings
line.set_xy1(extend_btm, trail_dn_x, trail_dn)
line.set_xy2(extend_btm, n + 20, trail_dn)

label.set_x(extend_btm_lbl, n + 20)
label.set_y(extend_btm_lbl, trail_dn)
label.set_text(extend_btm_lbl, trend > 0 ? 'Strong Low' : 'Weak Low')

//-----------------------------------------------------------------------------}
//Order Blocks Arrays
//-----------------------------------------------------------------------------{
var iob_top = array.new_float(0)
var iob_btm = array.new_float(0)
var iob_left = array.new_int(0)
var iob_right = array.new_int(0)
var iob_type = array.new_int(0)
var iob_mit = array.new_int(0)

var ob_top = array.new_float(0)


var ob_btm = array.new_float(0)
var ob_left = array.new_int(0)
var ob_right = array.new_int(0)
var ob_type = array.new_int(0)
var ob_mit = array.new_int(0)

//-----------------------------------------------------------------------------}
//Pivot High BOS/CHoCH
//-----------------------------------------------------------------------------{
//Filtering
var bull_concordant = true

if ifilter_confluence
bull_concordant := high - math.max(close, open) > math.min(close, open - low)

//Detect internal bullish Structure


if ta.crossover(close, itop_y) and itop_cross and top_y != itop_y and
bull_concordant
bool choch = na

if itrend < 0
choch := true
bull_ichoch_alert := true
else
bull_ibos_alert := true

txt = choch ? 'CHoCH' : 'BOS'

if show_internals
if show_ibull == 'All' or (show_ibull == 'BOS' and not choch) or
(show_ibull == 'CHoCH' and choch)
display_Structure(itop_x, itop_y, txt, ibull_css, true, true,
size.tiny)

itop_cross := false
itrend := 1

//Internal Order Block


if show_iob
ob_coord(false, itop_x, iob_top, iob_btm, iob_left, iob_right, iob_type,
iob_mit)

//Detect bullish Structure


if ta.crossover(close, top_y) and top_cross
bool choch = na

if trend < 0
choch := true
bull_choch_alert := true
else
bull_bos_alert := true

txt = choch ? 'CHoCH' : 'BOS'

if show_Structure
if show_bull == 'All' or (show_bull == 'BOS' and not choch) or (show_bull
== 'CHoCH' and choch)
display_Structure(top_x, top_y, txt, bull_css, false, true, size.small)

//Order Block
if show_ob
ob_coord(false, top_x, ob_top, ob_btm, ob_left, ob_right, ob_type, ob_mit)

top_cross := false
trend := 1

//-----------------------------------------------------------------------------}
//Pivot Low BOS/CHoCH
//-----------------------------------------------------------------------------{
var bear_concordant = true

if ifilter_confluence
bear_concordant := high - math.max(close, open) < math.min(close, open - low)

//Detect internal bearish Structure


if ta.crossunder(close, ibtm_y) and ibtm_cross and btm_y != ibtm_y and
bear_concordant
bool choch = false

if itrend > 0
choch := true
bear_ichoch_alert := true
else
bear_ibos_alert := true

txt = choch ? 'CHoCH' : 'BOS'

if show_internals
if show_ibear == 'All' or (show_ibear == 'BOS' and not choch) or
(show_ibear == 'CHoCH' and choch)
display_Structure(ibtm_x, ibtm_y, txt, ibear_css, true, false,
size.tiny)

ibtm_cross := false
itrend := -1

//Internal Order Block


if show_iob
ob_coord(true, ibtm_x, iob_top, iob_btm, iob_left, iob_right, iob_type,
iob_mit)

//Detect bearish Structure


if ta.crossunder(close, btm_y) and btm_cross
bool choch = na

if trend > 0
choch := true
bear_choch_alert := true
else
bear_bos_alert := true

txt = choch ? 'CHoCH' : 'BOS'

if show_Structure
if show_bear == 'All' or (show_bear == 'BOS' and not choch) or (show_bear
== 'CHoCH' and choch)
display_Structure(btm_x, btm_y, txt, bear_css, false, false,
size.small)

//Order Block
if show_ob
ob_coord(true, btm_x, ob_top, ob_btm, ob_left, ob_right, ob_type, ob_mit)

btm_cross := false
trend := -1

//-----------------------------------------------------------------------------}
//Order Blocks
//-----------------------------------------------------------------------------{
//Set order blocks
var iob_boxes = array.new_box(0)
var ob_boxes = array.new_box(0)

//Delete internal order blocks box coordinates if top/bottom is broken


for element in iob_type
index = array.indexof(iob_type, element)

// Mark internal orderbox as mitigated if price tapped inside the orderblock


if ob_highlight_mit
if element == 1 and low[1] > array.get(iob_top, index) and low <=
array.get(iob_top, index)
array.set(iob_mit, index, array.get(iob_mit, index) + 1)
array.set(iob_right, index, time)
bull_iob_mit := true
else if element == -1 and high[1] < array.get(iob_btm, index) and high >=
array.get(iob_btm, index)
array.set(iob_mit, index, array.get(iob_mit, index) + 1)
array.set(iob_right, index, time)
bear_iob_mit := true
// box.new()

if close < array.get(iob_btm, index) and element == 1


array.remove(iob_top, index)
array.remove(iob_btm, index)
array.remove(iob_left, index)
array.remove(iob_right, index)
array.remove(iob_type, index)
array.remove(iob_mit, index)
bull_iob_break := true

else if close > array.get(iob_top, index) and element == -1


array.remove(iob_top, index)
array.remove(iob_btm, index)
array.remove(iob_left, index)
array.remove(iob_right, index)
array.remove(iob_type, index)
array.remove(iob_mit, index)
bear_iob_break := true

//Delete internal order blocks box coordinates if top/bottom is broken


for element in ob_type
index = array.indexof(ob_type, element)

if ob_highlight_mit
if element == 1 and low[1] > array.get(ob_top, index) and low <=
array.get(ob_top, index)
array.set(ob_mit, index, array.get(ob_mit, index) + 1)
array.set(ob_right, index, time)
bull_ob_mit := true
else if element == -1 and high[1] < array.get(ob_btm, index) and high >=
array.get(ob_btm, index)
array.set(ob_mit, index, array.get(ob_mit, index) + 1)
array.set(ob_right, index, time)

bear_ob_mit := true

if close < array.get(ob_btm, index) and element == 1


array.remove(ob_top, index)
array.remove(ob_btm, index)
array.remove(ob_left, index)
array.remove(ob_right, index)
array.remove(ob_type, index)
array.remove(ob_mit, index)
bull_ob_break := true

else if close > array.get(ob_top, index) and element == -1


array.remove(ob_top, index)
array.remove(ob_btm, index)
array.remove(ob_left, index)
array.remove(ob_right, index)
array.remove(ob_type, index)
array.remove(ob_mit, index)
bear_ob_break := true

iob_size = array.size(iob_type)
ob_size = array.size(ob_type)
if barstate.isfirst
if show_iob
for i = 0 to iob_showlast-1
array.push(iob_boxes, box.new(na,na,na,na, xloc = xloc.bar_time))
if show_ob
for i = 0 to ob_showlast-1
array.push(ob_boxes, box.new(na,na,na,na, xloc = xloc.bar_time))

if iob_size > 0
if barstate.islast
display_ob(iob_boxes, iob_top, iob_btm, iob_left, iob_right, iob_type,
iob_mit, iob_showlast, false, iob_size)

if ob_size > 0
if barstate.islast
display_ob(ob_boxes, ob_top, ob_btm, ob_left, ob_right, ob_type, ob_mit,
ob_showlast, true, ob_size)

//-----------------------------------------------------------------------------}
//EQH/EQL
//-----------------------------------------------------------------------------{
var eq_prev_top = 0.
var eq_top_x = 0

var eq_prev_btm = 0.
var eq_btm_x = 0

if show_eq
eq_top = ta.pivothigh(eq_len, eq_len)
eq_btm = ta.pivotlow(eq_len, eq_len)

if eq_top
max = math.max(eq_top, eq_prev_top)
min = math.min(eq_top, eq_prev_top)

if max < min + atr1 * eq_threshold


eqh_line = line.new(eq_top_x, eq_prev_top, n-eq_len, eq_top
, color = bear_css
, style = line.style_dotted)

eqh_lbl = label.new(int(math.avg(n-eq_len, eq_top_x)), eq_top, 'EQH'


, color = #00000000
, textcolor = bear_css
, style = label.style_label_down
, size = size.tiny)

if mode == 'Present'
line.delete(eqh_line[1])
label.delete(eqh_lbl[1])

eqh_alert := true

eq_prev_top := eq_top
eq_top_x := n-eq_len

if eq_btm
max = math.max(eq_btm, eq_prev_btm)
min = math.min(eq_btm, eq_prev_btm)
if min > max - atr1 * eq_threshold
eql_line = line.new(eq_btm_x, eq_prev_btm, n-eq_len, eq_btm
, color = bull_css
, style = line.style_dotted)

eql_lbl = label.new(int(math.avg(n-eq_len, eq_btm_x)), eq_btm, 'EQL'


, color = #00000000
, textcolor = bull_css
, style = label.style_label_up
, size = size.tiny)

eql_alert := true

if mode == 'Present'
line.delete(eql_line[1])
label.delete(eql_lbl[1])

eq_prev_btm := eq_btm
eq_btm_x := n-eq_len

//-----------------------------------------------------------------------------}
//Fair Value Gaps
//-----------------------------------------------------------------------------{
var bullish_fvg_max = array.new_box(0)
var bullish_fvg_min = array.new_box(0)

var bearish_fvg_max = array.new_box(0)


var bearish_fvg_min = array.new_box(0)

float bullish_fvg_avg = na
float bearish_fvg_avg = na

bullish_fvg_cnd = false
bearish_fvg_cnd = false

[src_c1, src_o1, src_h, src_l, src_h2, src_l2] =


request.security(syminfo.tickerid, fvg_tf, get_ohlc())

if show_fvg
delta_per = (src_c1 - src_o1) / src_o1 * 100

change_tf = timeframe.change(fvg_tf)

threshold = fvg_auto ? ta.cum(math.abs(change_tf ? delta_per : 0)) / n * 2


: 0

//FVG conditions
bullish_fvg_cnd := src_l > src_h2
and src_c1 > src_h2
and delta_per > threshold
and change_tf

bearish_fvg_cnd := src_h < src_l2


and src_c1 < src_l2
and -delta_per > threshold
and change_tf

//FVG Areas
if bullish_fvg_cnd
array.unshift(bullish_fvg_max, box.new(n-1, src_l, n + fvg_extend,
math.avg(src_l, src_h2)
, border_color = bull_fvg_css
, bgcolor = bull_fvg_css))

array.unshift(bullish_fvg_min, box.new(n-1, math.avg(src_l, src_h2), n +


fvg_extend, src_h2
, border_color = bull_fvg_css
, bgcolor = bull_fvg_css))

if bearish_fvg_cnd
array.unshift(bearish_fvg_max, box.new(n-1, src_h, n + fvg_extend,
math.avg(src_h, src_l2)
, border_color = bear_fvg_css
, bgcolor = bear_fvg_css))

array.unshift(bearish_fvg_min, box.new(n-1, math.avg(src_h, src_l2), n +


fvg_extend, src_l2
, border_color = bear_fvg_css
, bgcolor = bear_fvg_css))

for bx in bullish_fvg_min
if low < box.get_bottom(bx)
box.delete(bx)
box.delete(array.get(bullish_fvg_max, array.indexof(bullish_fvg_min,
bx)))

for bx in bearish_fvg_max
if high > box.get_top(bx)
box.delete(bx)
box.delete(array.get(bearish_fvg_min, array.indexof(bearish_fvg_max,
bx)))

//-----------------------------------------------------------------------------}
//Previous day/week high/lows
//-----------------------------------------------------------------------------{
//Daily high/low
[pdh, pdl] = request.security(syminfo.tickerid, 'D', hl()
, lookahead = barmerge.lookahead_on)

//Weekly high/low
[pwh, pwl] = request.security(syminfo.tickerid, 'W', hl()
, lookahead = barmerge.lookahead_on)

//Monthly high/low
[pmh, pml] = request.security(syminfo.tickerid, 'M', hl()
, lookahead = barmerge.lookahead_on)

//Display Daily
if show_pdhl
phl(pdh, pdl, 'D', pdhl_css)

//Display Weekly
if show_pwhl
phl(pwh, pwl, 'W', pwhl_css)

//Display Monthly
if show_pmhl
phl(pmh, pml, 'M', pmhl_css)
//-----------------------------------------------------------------------------}
//Premium/Discount/Equilibrium zones
//-----------------------------------------------------------------------------{
var premium = box.new(na, na, na, na
, bgcolor = color.new(premium_css, 80)
, border_color = na)

var premium_lbl = label.new(na, na


, text = 'Premium'
, color = TRANSP_CSS
, textcolor = premium_css
, style = label.style_label_down
, size = size.small)

var eq = box.new(na, na, na, na


, bgcolor = color.rgb(120, 123, 134, 80)
, border_color = na)

var eq_lbl = label.new(na, na


, text = 'Equilibrium'
, color = TRANSP_CSS
, textcolor = eq_css
, style = label.style_label_left
, size = size.small)

var discount = box.new(na, na, na, na


, bgcolor = color.new(discount_css, 80)
, border_color = na)

var discount_lbl = label.new(na, na


, text = 'Discount'
, color = TRANSP_CSS
, textcolor = discount_css
, style = label.style_label_up
, size = size.small)

//Show Premium/Discount Areas


if barstate.islast and show_sd
avg = math.avg(trail_up, trail_dn)

box.set_lefttop(premium, math.max(top_x, btm_x), trail_up)


box.set_rightbottom(premium, n, .95 * trail_up + .05 * trail_dn)

label.set_xy(premium_lbl, int(math.avg(math.max(top_x, btm_x), n)), trail_up)

box.set_lefttop(eq, math.max(top_x, btm_x), .525 * trail_up + .475*trail_dn)


box.set_rightbottom(eq, n, .525 * trail_dn + .475 * trail_up)

label.set_xy(eq_lbl, n, avg)

box.set_lefttop(discount, math.max(top_x, btm_x), .95 * trail_dn + .05 *


trail_up)
box.set_rightbottom(discount, n, trail_dn)
label.set_xy(discount_lbl, int(math.avg(math.max(top_x, btm_x), n)), trail_dn)

//-----------------------------------------------------------------------------}
//Trend
//-----------------------------------------------------------------------------{
var color trend_css = na

if show_trend
if style == 'Colored'
trend_css := itrend == 1 ? bull_css : bear_css
else if style == 'Monochrome'
trend_css := itrend == 1 ? #b2b5be : #5d606b

plotcandle(open, high, low, close


, color = trend_css
, wickcolor = trend_css
, bordercolor = trend_css
, editable = false)

//-----------------------------------------------------------------------------}
//Alerts
//-----------------------------------------------------------------------------{
//Internal Structure
alertcondition(bull_ibos_alert, 'Internal Bullish BOS', 'Internal Bullish BOS
formed')
alertcondition(bull_ichoch_alert, 'Internal Bullish CHoCH', 'Internal Bullish CHoCH
formed')

alertcondition(bear_ibos_alert, 'Internal Bearish BOS', 'Internal Bearish BOS


formed')
alertcondition(bear_ichoch_alert, 'Internal Bearish CHoCH', 'Internal Bearish CHoCH
formed')

//Swing Structure
alertcondition(bull_bos_alert, 'Bullish BOS', 'Internal Bullish BOS formed')
alertcondition(bull_choch_alert, 'Bullish CHoCH', 'Internal Bullish CHoCH formed')

alertcondition(bear_bos_alert, 'Bearish BOS', 'Bearish BOS formed')


alertcondition(bear_choch_alert, 'Bearish CHoCH', 'Bearish CHoCH formed')

//order Blocks
alertcondition(bull_iob_break, 'Bullish Internal OB Breakout', 'Price broke bullish
iternal OB')
alertcondition(bear_iob_break, 'Bearish Internal OB Breakout', 'Price broke bearish
iternal OB')

alertcondition(bull_ob_break, 'Bullish OB Breakout', 'Price broke bullish OB')


alertcondition(bear_ob_break, 'bearish OB Breakout', 'Price broke bearish OB')

alertcondition(bull_iob_mit, 'Bullish Internal OB Mitigated', 'Bullish internal OB


mitigated')
alertcondition(bear_iob_mit, 'Bearish Internal OB Mitigated', 'Bearish internal OB
mitigated')

alertcondition(bull_ob_mit, 'Bullish OB Mitigated', 'Bullish OB mitigated')


alertcondition(bear_ob_mit, 'Bearish OB Mitigated', 'Bearish OB mitigated')

//EQH/EQL
alertcondition(eqh_alert, 'Equal Highs', 'Equal highs detected')
alertcondition(eql_alert, 'Equal Lows', 'Equal lows detected')

//FVG
alertcondition(bullish_fvg_cnd, 'Bullish FVG', 'Bullish FVG formed')
alertcondition(bearish_fvg_cnd, 'Bearish FVG', 'Bearish FVG formed')
//-----------------------------------------------------------------------------}

//------------------------------------------------------------------------------
// ICT UNICORN MODEL Settings
//-----------------------------------------------------------------------------{
len = input.int ( 10 , 'Swings'
, group='Unicorn')

iBull = input.bool ( true , 'Bull' ,


inline = 'bl', group='Unicorn')
colBl = input.color ( #089981 , '' ,
inline = 'bl', group='Unicorn')

iBear = input.bool ( true , 'Bear' ,


inline = 'br', group='Unicorn')
colBr = input.color ( #f23645 , '' ,
inline = 'br', group='Unicorn')

combine = input.bool ( false , 'Combine'


, tooltip= 'Bull and Bear pattern can be present at the same
time' , group='Unicorn')

//Targets
risk = input.float ( 1 ,
'Risk/Reward' , step = .1, inline = 'r' , group='Targets')
reward = input.float ( 1 ,
':' , step = .1, inline = 'r' , group='Targets')
rr = reward / risk

trail = input.bool ( false , 'Trailing Stop' ,


inline = 'ts', group='Targets')
lenS = input.int ( 5 , '', minval =3, maxval=10,
inline = 'ts', group='Targets')

showTargets = input(true, 'Target Areas' ,


inline='target_css', group='Targets')
colRisk = input.color(color.new(#787b86, 80), '' ,
inline='target_css', group='Targets')
colReward = input.color(color.new(#5b9cf6, 80), '' ,
inline='target_css', group='Targets')

//-----------------------------------------------------------------------------}
//UDT's
//-----------------------------------------------------------------------------{
type piv
int b
float p
bool br

type ZZ1
int [] d
int [] x
float [] y

type unicorn
box box
box fvg
box Risk
box Reward

line lT
line lB
line SL
line linSL

label labC

bool active
bool isTaR
bool isTsL
bool trig

float swing
float TaR
float TsL

//-----------------------------------------------------------------------------}
//Variables
//-----------------------------------------------------------------------------{
var x = 0
var y = 0.
var z = 0.

var ZZ1 aZZ1 =


ZZ1.new(
array.new < int >(50, 0),
array.new < int >(50, 0),
array.new < float >(50, na)
)

var patL = array.new< line >(3, line.new(na, na, na, na))

var aUniBl = array.new<unicorn>(2, unicorn.new(


box.new (na, 0, 0, na)
, box.new (na, 0, 0, na)
, box.new (na, 0, 0, na)
, box.new (na, 0, 0, na)
, line.new(na, 0, 0, na)
, line.new(na, 0, 0, na)
, line.new(na, 0, 0, na)
, line.new(na, 0, 0, na)
, label.new (na, na)
, false, false, false, false
, na , na , na
)
)
var aUniBr = array.new<unicorn>(2, unicorn.new(
box.new (na, 0, 0, na)
, box.new (na, 0, 0, na)
, box.new (na, 0, 0, na)
, box.new (na, 0, 0, na)
, line.new(na, 0, 0, na)
, line.new(na, 0, 0, na)
, line.new(na, 0, 0, na)
, line.new(na, 0, 0, na)
, label.new (na, na)
, false, false, false, false
, na , na , na
)
)

piv[] swingH = na
piv[] swingL = na
float mnPiv = na
float mxPiv = 0

//-----------------------------------------------------------------------------}
//Methods
//-----------------------------------------------------------------------------{
method in_out(ZZ1 aZZ1, int d, int Cx, float Cy, int Dx, float Dy) =>
aZZ1.d.unshift(d), aZZ1.x.unshift(Dx), aZZ1.y.unshift(Dy), aZZ1.d.pop(),
aZZ1.x.pop(), aZZ1.y.pop()

method n(float p) => bool out = not na(p)

method remove(unicorn uni) =>


uni.active := false
uni.swing := na
uni.TaR := na
uni.fvg .delete()
uni.linSL.delete()
uni.lT .delete()
uni.lB .delete()
uni.SL .delete()
uni.labC .delete()
uni.box.set_bgcolor(color.new(na, na))

//-----------------------------------------------------------------------------}
//Execution
//-----------------------------------------------------------------------------{
n1 = bar_index
atr2 = ta.atr(14)
cFg = chart.fg_color

lenL = 1
ph = ta.pivothigh(len, lenL)
pl = ta.pivotlow (len, lenL)

phTsL = ta.pivothigh(lenS, lenS)


plTsL = ta.pivotlow (lenS, lenS)

highest = ta.highest(5)
lowest = ta.lowest (5)

firstBl = aUniBl.first()
firstBr = aUniBr.first()

secndBl = aUniBl.get (1)


secndBr = aUniBr.get (1)

bool chS_bl = ta.change(firstBl.swing) != 0


bool chS_br = ta.change(firstBr.swing) != 0
//Creating ZZ
if ph.n()
if ph > mxPiv
mxPiv := ph
if swingH.size() > 0
for i = swingH.size() -1 to 0
get = swingH.get(i)
if ph >= get.p
swingH.remove(i)

swingH.unshift(piv.new(n1 -1, ph))

dr_ = aZZ1.d.get (0)


Cx_ = aZZ1.x.get (0)
Cy_ = aZZ1.y.get (0)
Dx_ = n1 -lenL
Dy_ = high[lenL]

if dr_ < 1 // if previous point was a pl, add, and change direction ( 1)
aZZ1.in_out( 1, Cx_, Cy_, Dx_, Dy_)
else
if dr_ == 1 and ph > Cy_
aZZ1.x.set(0, Dx_), aZZ1.y.set(0, Dy_)

if pl.n()
if pl < mnPiv
mnPiv := pl
if swingL.size() > 0
for i = swingL.size() -1 to 0
get = swingL.get(i)
if pl <= get.p
swingL.remove(i)

swingL.unshift(piv.new(n1 -1, pl))

dr_ = aZZ1.d.get (0)


Cx_ = aZZ1.x.get (0)
Cy_ = aZZ1.y.get (0)
Dx_ = n1 -lenL
Dy_ = low[lenL]

if dr_ > -1 // if previous point was a ph, add, and change direction (-1)
aZZ1.in_out(-1, Cx_, Cy_, Dx_, Dy_)
else
if dr_ == -1 and pl < Cy_
aZZ1.x.set(0, Dx_), aZZ1.y.set(0, Dy_)

Ax = aZZ1.x.get (3)
Ay = aZZ1.y.get (3)
Bx = aZZ1.x.get (2)
By = aZZ1.y.get (2)
Cx = aZZ1.x.get (1)
Cy = aZZ1.y.get (1)
Dx = aZZ1.x.get (0)
Dy = aZZ1.y.get (0)
dir1 = aZZ1.d.get (0)
//Unicorn Pattern
if firstBl.active
if combine or (not combine and (not firstBl.active[1] or chS_bl))
if not secndBl.trig
secndBl.remove()

if not firstBl.trig and


close < firstBl.fvg.get_bottom()
firstBl.remove()

if firstBr.active
if combine or (not combine and (not firstBr.active[1] or chS_br))
if not secndBr.trig
secndBr.remove()

if not firstBr.trig and


close > firstBr.fvg.get_top()
firstBr.remove()

if n1 -lenL == Dx

if dir1 < 1 and iBear


and close[lenL] < By and Cy > Ay
and Dx - Cx > (len > 1 ? 1 : 0 )
and Cx - Bx > (len > 1 ? 1 : 0 )
and Bx - Ax > (len > 1 ? 1 : 0 )

// BRB
switch
close[n1 - Bx +0] < open[n1 - Bx +0] => x := Bx -0, y := high[n1 - Bx
+0], z := low[n1 - Bx +0]
close[n1 - Bx +1] < open[n1 - Bx +1] => x := Bx -1, y := high[n1 - Bx
+1], z := low[n1 - Bx +1]
close[n1 - Bx +2] < open[n1 - Bx +2] => x := Bx -2, y := high[n1 - Bx
+2], z := low[n1 - Bx +2]
close[n1 - Bx +3] < open[n1 - Bx +3] => x := Bx -3, y := high[n1 - Bx
+3], z := low[n1 - Bx +3]
close[n1 - Bx +4] < open[n1 - Bx +4] => x := Bx -4, y := high[n1 - Bx
+4], z := low[n1 - Bx +4]

// FVG
for i = 0 to n1 - Cx
fvgT = low[i+2]
fvgB = high[i]
if fvgB < fvgT
and ((fvgT < y and fvgT > z) or (fvgB < y and fvgB > z))
and fvgT - fvgB > atr2 * 0.05 // FVG large enough
if y != firstBr.box.get_top()
aUniBr.unshift(unicorn.new(
box = box.new( x , y , n1 -i-2 , z
, border_color = color.new( cFg , 100)
, bgcolor = color.new( cFg , 97))
, fvg = box.new(n1 -i-2, low[i+2], n1-1, high[i]
, border_color = color.new( na , na )
, bgcolor = color.new( colBr , 75))
, active = true , swing = Cy
, isTaR = false, TaR = na
, lT = line.new(x, y, n1-1, y
, color=color.new(cFg, 50)
, style=line.style_dashed)
, lB = line.new(x, z, n1-1, z
, color=color.new(cFg, 50)
, style=line.style_dashed)
, SL = line.new(Cx, Cy, Cx, Cy
, color=color.new(cFg, 65)
, style=line.style_dotted)
, trig=false
)
)

if not combine

if not firstBl.trig
firstBl.remove()

firstBl.active := false
firstBl.TaR := na
firstBl.TsL := na
firstBl.swing := na

break

if dir1 > -1 and iBull


and close[lenL] > By and Cy < Ay
and Dx - Cx > (len > 1 ? 1 : 0 )
and Cx - Bx > (len > 1 ? 1 : 0 )
and Bx - Ax > (len > 1 ? 1 : 0 )

// BRB
switch
close[n1 - Bx +0] > open[n1 - Bx +0] => x := Bx -0, y := high[n1 - Bx
+0], z := low[n1 - Bx +0]
close[n1 - Bx +1] > open[n1 - Bx +1] => x := Bx -1, y := high[n1 - Bx
+1], z := low[n1 - Bx +1]
close[n1 - Bx +2] > open[n1 - Bx +2] => x := Bx -2, y := high[n1 - Bx
+2], z := low[n1 - Bx +2]
close[n1 - Bx +3] > open[n1 - Bx +3] => x := Bx -3, y := high[n1 - Bx
+3], z := low[n1 - Bx +3]
close[n1 - Bx +4] > open[n1 - Bx +4] => x := Bx -4, y := high[n1 - Bx
+4], z := low[n1 - Bx +4]

// FVG
for i = 0 to n1 - Cx
fvgB = high[i+2]
fvgT = low [i]
if fvgB < fvgT
and ((fvgT < y and fvgT > z) or (fvgB < y and fvgB > z))
and fvgT - fvgB > atr2 * 0.05 // FVG large enough
if y != firstBl.box.get_top()
aUniBl.unshift(unicorn.new(
box = box.new( x , y , n1-i-2 , z
, border_color = color.new( cFg , 100)
, bgcolor = color.new( cFg , 97))
, fvg = box.new(n1 -i-2, low[i], n1-1, high[i+2]
, border_color = color.new( na , na )
, bgcolor = color.new( colBl , 75))
, active = true , swing = Cy
, isTaR = false, TaR = na
, lT = line.new(x, y, n1-1, y
, color=color.new(cFg, 50)
, style=line.style_dashed)
, lB = line.new(x, z, n1-1, z
, color=color.new(cFg, 50)
, style=line.style_dashed)
, SL = line.new(Cx, Cy, Cx, Cy
, color=color.new(cFg, 65)
, style=line.style_dotted)
, trig = false
)
)

if not combine

if not firstBr.trig
firstBr.remove()

firstBr.active := false
firstBr.TaR := na
firstBr.TsL := na
firstBr.swing := na

break

if firstBr.active

firstBr.Risk .set_right(n1 +1)


firstBr.Reward.set_right(n1 +1)

rgt = firstBr.fvg.get_right()
top = firstBr.lT .get_y2 ()
btm = firstBr.lB .get_y2 ()

isStopBr = high > firstBr.swing


if isStopBr
if showTargets
firstBr.linSL :=
line.new(
rgt, firstBr.swing
, n1, firstBr.swing
, color
= color.new(cFg, 50))

firstBr.active := false
firstBr.TaR := na
firstBr.TsL := na
firstBr.swing := na

if not firstBr.trig
firstBr.fvg.set_right(n1-1)

if firstBr.isTaR
if low < firstBr.TaR
if showTargets
line.new(
rgt, firstBr.TaR
, n1, firstBr.TaR
, color
= color.new(cFg, 50))

firstBr.isTaR := false
firstBr.active := false
firstBr.TaR := na
firstBr.TsL := na

if trail

switch
close[1] > firstBr.TsL[1] => firstBr.TsL := na
close > firstBr.TsL => firstBr.isTsL := false

if phTsL.n()
firstBr.TsL := math.min(firstBr.TsL, phTsL)
else
trigger =
close < btm
and open > btm and open < top
and math.max(close[1], open[1]) > btm
and math.min(close[1], open[1]) < top

if trigger
label.new(n1, high, text='●'
, color=color.new(na, na), textcolor=colBr
, style=label.style_label_center
, size=size.tiny
)

firstBr.trig := true
firstBr.isTaR := true

firstBr.SL .set_x2 (n1)


firstBr.lT .set_x2 (n1)
firstBr.lB .set_x2 (n1)
firstBr.fvg.set_right(n1)

diff = (firstBr.swing - btm) * rr


firstBr.TaR := btm - diff
firstBr.TsL := firstBr.swing

if showTargets
firstBr.Risk := box.new(
chart.point.from_index(n1 , firstBr.swing)
, chart.point.from_index(n1 +1, btm )
, border_color=color.new(na , na )
, bgcolor =colRisk
)
firstBr.Reward := box.new(
chart.point.from_index(n1 , btm )
, chart.point.from_index(n1 +1, btm - diff)
, border_color=color.new(na , na )
, bgcolor =colReward
)

if firstBl.active

firstBl.Risk .set_right(n1 +1)


firstBl.Reward.set_right(n1 +1)

top = firstBl.lT .get_y2 ()


btm = firstBl.lB .get_y2 ()
rgt = firstBl.fvg.get_right()

isStopBl = low < firstBl.swing


if isStopBl
if showTargets
firstBl.linSL :=
line.new(
rgt, firstBl.swing
, n1, firstBl.swing
, color
= color.new(cFg, 50))

firstBl.active := false
firstBl.TaR := na
firstBl.TsL := na
firstBl.swing := na

if not firstBl.trig
firstBl.fvg.set_right(n1-1)

if firstBl.isTaR
if high > firstBl.TaR
if showTargets
line.new(
rgt, firstBl.TaR
, n1, firstBl.TaR
, color
= color.new(cFg, 50))

firstBl.isTaR := false
firstBl.active := false
firstBl.TaR := na
firstBl.TsL := na

if trail
switch
close[1] < firstBl.TsL[1] => firstBl.TsL := na
close < firstBl.TsL => firstBl.isTsL := false

if plTsL.n()
firstBl.TsL := math.max(firstBl.TsL, plTsL)
else
trigger =
close > top
and open < top and open > btm
and math.min(close[1], open[1]) < top
and math.max(close[1], open[1]) > btm

if trigger
label.new(n1, low, text='●'
, color=color.new(na, na), textcolor=colBl
, style=label.style_label_center
, size=size.tiny
)
firstBl.trig := true
firstBl.isTaR := true

firstBl.SL .set_x2 (n1)


firstBl.lT .set_x2 (n1)
firstBl.lB .set_x2 (n1)
firstBl.fvg.set_right(n1)

diff = (top - firstBl.swing) * rr


firstBl.TaR := top + diff
firstBl.TsL := firstBl.swing

if showTargets
firstBl.Risk := box.new(
chart.point.from_index(n1 , firstBl.swing)
, chart.point.from_index(n1 +1, top )
, border_color=color.new(na , na )
, bgcolor =colRisk
)
firstBl.Reward := box.new(
chart.point.from_index(n1 , top )
, chart.point.from_index(n1 +1, top + diff)
, border_color=color.new(na , na )
, bgcolor =colReward
)

//-----------------------------------------------------------------------------}
//Plot
//-----------------------------------------------------------------------------{
plot(trail and (firstBl.TsL >= firstBl.TsL[1] or na(firstBl.TsL[1])) ?
firstBl.TsL : na, color = colBl, style=plot.style_linebr)
plot(trail and (firstBr.TsL <= firstBr.TsL[1] or na(firstBr.TsL[1])) ?
firstBr.TsL : na, color = colBr, style=plot.style_linebr)

//-----------------------------------------------------------------------------//--
---------------------------------------------------------------------------}
// Initialize trade variables
var float entryPrice = na
var float exitPrice = na
var float profitLoss = na
var bool inTrade = false
var string tradeSignal = ""

// Input parameters
RSI_Period = input.int(14, title='RSI Length', minval=1)
SF = input.int(5, title='RSI Smoothing', minval=1, maxval=100) // Number input for
RSI Smoothing
QQE = input.float(4.238, title='Fast QQE Factor')
ThreshHold = input.float(10, title="Thresh-hold")
RsiMaThreshold = input.float(50, title="RsiMa Threshold") // Customizable threshold
for RsiMa

// Source input
srcInput = input.string("close", title="Source for Calculations", options=["close",
"open", "high", "low"])
src = switch srcInput
"open" => open
"high" => high
"low" => low
=> close // Default is close

// MA type selection
maType = input.string("EMA", title="Moving Average Type", options=["SMA", "EMA",
"DEMA", "TEMA", "WMA", "VWMA", "HMA", "RMA", "Combined VWMA"])

// Invisible value line parameters


lookBackPeriod = input.int(20, title="Lookback Period for Invisible Line")
invisibleValueLine = src - ta.sma(src, lookBackPeriod)

// Plot color options


showColoring = input.bool(true, title="Enable Coloring")

// Define MA function
ma(type, src, len) =>
switch type
"SMA" => ta.sma(src, len)
"EMA" => ta.ema(src, len)
"DEMA" =>
e = ta.ema(src, len)
2 * e - ta.ema(e, len)
"TEMA" =>
e = ta.ema(src, len)
3 * (e - ta.ema(e, len)) + ta.ema(ta.ema(e, len), len)
"WMA" => ta.wma(src, len)
"VWMA" => ta.vwma(src, len)
"HMA" =>
wma1 = ta.wma(src, len)
wma2 = ta.wma(src, len / 2)
2 * wma2 - wma1
"RMA" => ta.rma(src, len)
"Combined VWMA" =>
sma = ta.sma(src, len)
ema = ta.ema(src, len)
wma = ta.wma(src, len)
hma = 2 * ta.wma(src, len / 2) - ta.wma(src, len)
rma = ta.rma(src, len)

// Calculate total weight based on how many MAs are selected


totalWeight = 0.0
weights = array.new_float(5, 0.0) // Initialize an array to store
weights

// Assign weights based on contributions


array.set(weights, 0, 0.2) // SMA
array.set(weights, 1, 0.2) // EMA
array.set(weights, 2, 0.2) // WMA
array.set(weights, 3, 0.2) // HMA
array.set(weights, 4, 0.2) // RMA

// Sum weights
for i = 0 to array.size(weights) - 1
totalWeight := totalWeight + array.get(weights, i)

// Calculate combined VWMA


combinedVWMA = (sma * array.get(weights, 0) + ema * array.get(weights,
1) + wma * array.get(weights, 2) + hma * array.get(weights, 3) + rma *
array.get(weights, 4)) / totalWeight
combinedVWMA // Return the combined VWMA

// Calculate QQE
Wilders_Period = RSI_Period * 2 - 1
Rsi = ta.rsi(src, RSI_Period)
RsiMa = ma(maType, Rsi, SF) // Use selected MA type here
AtrRsi = math.abs(RsiMa[1] - RsiMa)
MaAtrRsi = ma(maType, AtrRsi, Wilders_Period) // Use selected MA type here
dar = ma(maType, MaAtrRsi, Wilders_Period) * QQE // Use selected MA type here

// Initialize longband and shortband


var float longband = na
var float shortband = na

// Initialize trend variable

DeltaFastAtrRsi = dar
RSIndex = RsiMa
newshortband = RSIndex + DeltaFastAtrRsi
newlongband = RSIndex - DeltaFastAtrRsi

// Calculate longband and shortband with updated logic


longband := na(longband[1]) ? newlongband : (RSIndex[1] > longband[1] and RSIndex >
longband[1]) ? math.max(longband[1], newlongband) : longband[1]
shortband := na(shortband[1]) ? newshortband : (RSIndex[1] < shortband[1] and
RSIndex < shortband[1]) ? math.min(shortband[1], newshortband) : shortband[1]

// Calculate cross values


cross_1 = ta.cross(longband[1], RSIndex)
cross_to_shortband = ta.cross(RSIndex, shortband[1])

// Assign values to trend


trend := na(trend[1]) ? na : (cross_to_shortband ? 1 : (cross_1 ? -1 : trend[1]))

FastAtrRsiTL = trend == 1 ? longband : shortband

// Define buy/sell conditions using invisible value line


buyCondition = ta.cross(RsiMa, longband) and trend == -1 and invisibleValueLine > 0
sellCondition = ta.cross(shortband, RSIndex) and trend == 1 and invisibleValueLine
< 0

// Track trades and calculate profit/loss


if (buyCondition and not inTrade)
entryPrice := close
inTrade := true
tradeSignal := "BUY"
exitPrice := na
profitLoss := na

if (sellCondition and inTrade)


exitPrice := close
profitLoss := exitPrice - entryPrice
inTrade := false
tradeSignal := "SELL"
// Trend Color Logic
trendStrength = RsiMa - RsiMa[1]
color trendColor = na

// Define color conditions


if (trendStrength > 0 and trendStrength[1] > 0)
trendColor := #56ff5c // Rising (ordinary green)
else if (trendStrength > 0)
trendColor := #00ff15 // Spontaneous rising (fluorescent green)
else if (trendStrength < 0 and trendStrength[1] < 0)
trendColor := #ff2a2a // Falling (ordinary red)
else if (trendStrength < 0)
trendColor := color.rgb(255, 0, 0) // Spontaneous falling (fluorescent red)
else
trendColor := color.new(color.gray, 0) // Neutral (gray)

// Plot the continuous trend strength line below the bars


plot(trendStrength, color=trendColor, title="Continuous Trend Strength",
linewidth=2, style=plot.style_line)

// Plot buy/sell signals


plotshape(series=buyCondition ? close : na, location=location.belowbar,
color=color.fuchsia, style=shape.triangleup, size=size.small, title="Buy Signal")
plotshape(series=sellCondition ? close : na, location=location.abovebar,
color=color.red, style=shape.triangledown, size=size.small, title="Sell Signal")

// Create a small chart for trade results


var table tradeTable = table.new(position.bottom_right, 1, 3, border_width=1)

// Update table with trade details


if (not na(entryPrice) and not inTrade)
table.cell(tradeTable, 0, 0, text="Buy Price: " + str.tostring(entryPrice),
bgcolor=color.green, text_color=color.white)
table.cell(tradeTable, 0, 1, text="Sell Price: " + str.tostring(exitPrice),
bgcolor=color.red, text_color=color.white)
table.cell(tradeTable, 0, 2, text="Profit/Loss: " + str.tostring(profitLoss),
bgcolor=profitLoss >= 0 ? color.green : color.red, text_color=color.white)

// Bar Color Logic


bgc = RsiMa - RsiMaThreshold > ThreshHold ? color.rgb(0, 255, 8) : RsiMa -
RsiMaThreshold < 0 - ThreshHold ? #ff0000 : color.rgb(54, 51, 47)
barcolor(bgc)

// Plot Invisible Value Line for Debugging


plot(invisibleValueLine, color=color.new(color.blue, 100), title="Invisible Value
Line") // Adjust transparency to make it invisible

amplitude = input.int(title="Amplitude", defval=2)


channelDeviation = input.float(title="Channel Deviation", defval=2)
showArrows = input.bool(title="Show Arrows", defval=true)
showChannels = input.bool(title="Show Channels", defval=true)

var int trenda = 0


var int nextTrend = 0
var float maxLowPrice = na
var float minHighPrice = na

var float up = na
var float down = na
float atrHigh = na
float atrLow = na
float arrowUp = na
float arrowDown = na
atr2a = ta.atr(100) / 2
dev = channelDeviation * atr2a

// Calculate highest and lowest prices over the specified amplitude


highPrice = ta.highest(high, amplitude)
lowPrice = ta.lowest(low, amplitude)
highma = ta.sma(high, amplitude)
lowma = ta.sma(low, amplitude)

if nextTrend == 1
maxLowPrice := na(maxLowPrice) ? lowPrice : math.max(lowPrice, maxLowPrice)
previousLow = na(low[1]) ? low : low[1] // Get previous low safely
if highma < maxLowPrice and close < previousLow
trenda := 1
nextTrend := 0
minHighPrice := highPrice
else
minHighPrice := na(minHighPrice) ? highPrice : math.min(highPrice,
minHighPrice)

previousHigh = na(high[1]) ? high : high[1] // Get previous high safely


if lowma > minHighPrice and close > previousHigh
trenda := 0
nextTrend := 1
maxLowPrice := lowPrice

if trenda == 0
if not na(trenda[1]) and trenda[1] != 0
up := na(down[1]) ? down : down[1]
arrowUp := up - atr2a
else
up := na(up[1]) ? maxLowPrice : math.max(maxLowPrice, up[1])
atrHigh := up + dev
atrLow := up - dev
else
if not na(trenda[1]) and trenda[1] != 1
down := na(up[1]) ? up : up[1]
arrowDown := down + atr2a
else
down := na(down[1]) ? minHighPrice : math.min(minHighPrice, down[1])
atrHigh := down + dev
atrLow := down - dev

ht = trenda == 0 ? up : down

var color buyColor = color.new(color.green, 0)


var color sellColor = color.new(color.red, 0)

htColor = trenda == 0 ? buyColor : sellColor


htPlot = plot(ht, title="HalfTrend", linewidth=2, color=htColor)

// Input parameters for Super Trend


superTrendFactor = input.float(3.0, title="Super Trend Factor")
superTrendLength = input.int(10, title="Super Trend Length")

// Calculate Super Trend


[superTrend, direction] = ta.supertrend(superTrendFactor, superTrendLength)

// Define color based on direction and trend


var color trendColor1 = na
trendColor1 := direction == 1 ? color.green : direction == -1 ? color.red : na

// Plot Super Trend with different colors for rising and falling
plot(superTrend, color=direction == 1 ? color.red : color.green, linewidth=2,
title="Super Trend")

// Background color for trend direction


bgcolor(direction == 1 ? color.new(color.red, 90) : na, title="Bullish Trend
Background")
bgcolor(direction == -1 ? color.new(color.green, 90) : na, title="Bearish Trend
Background")

// Optional: Labels to indicate trend direction


if direction == 1
label.new(bar_index, na, text="Bullish", style=label.style_label_up,
color=color.green, textcolor=color.white)
if direction == -1
label.new(bar_index, na, text="Bearish", style=label.style_label_down,
color=color.red, textcolor=color.white)

You might also like