//CONSTANTS & STRINGS & INPUTS
//---------------------------------------------------------------------------------------------------------------
------{
BULLISH_LEG =1
BEARISH_LEG =0
BULLISH = +1
BEARISH = -1
GREEN = #089981
RED = #F23645
BLUE = #2157f3
GRAY = #878b94
MONO_BULLISH = #b2b5be
MONO_BEARISH = #5d606b
HISTORICAL = 'Historical'
PRESENT = 'Present'
COLORED = 'Colored'
MONOCHROME = 'Monochrome'
ALL = 'All'
BOS = 'BOS'
CHOCH = 'CHoCH'
TINY = [Link]
SMALL = [Link]
NORMAL = [Link]
ATR = 'Atr'
RANGE = 'Cumulative Mean Range'
CLOSE = 'Close'
HIGHLOW = 'High/Low'
SOLID = '⎯⎯⎯'
DASHED = '----'
DOTTED = '····'
SMART_GROUP = 'Smart Money Concepts'
INTERNAL_GROUP = 'Real Time Internal Structure'
SWING_GROUP = 'Real Time Swing Structure'
BLOCKS_GROUP = 'Order Blocks'
EQUAL_GROUP = 'EQH/EQL'
GAPS_GROUP = 'Fair Value Gaps'
LEVELS_GROUP = 'Highs & Lows MTF'
ZONES_GROUP = 'Premium & Discount Zones'
modeTooltip = 'Allows to display historical Structure or only the
recent ones'
styleTooltip = 'Indicator color theme'
showTrendTooltip = 'Display additional candles with a color reflecting
the current trend detected by structure'
showInternalsTooltip = 'Display internal market structure'
internalFilterConfluenceTooltip = 'Filter non significant internal structure
breakouts'
showStructureTooltip = 'Display swing market Structure'
showSwingsTooltip = 'Display swing point as labels on the chart'
showHighLowSwingsTooltip = 'Highlight most recent strong and weak
high/low points on the chart'
showInternalOrderBlocksTooltip = 'Display internal order blocks on the chart\n\
nNumber of internal order blocks to display on the chart'
showSwingOrderBlocksTooltip = 'Display swing order blocks on the chart\n\
nNumber of internal swing blocks to display on the chart'
orderBlockFilterTooltip = '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'
orderBlockMitigationTooltip = 'Select what values to use for order block
mitigation'
showEqualHighsLowsTooltip = 'Display equal highs and equal lows on the
chart'
equalHighsLowsLengthTooltip = 'Number of bars used to confirm equal highs
and equal lows'
equalHighsLowsThresholdTooltip = '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'
showFairValueGapsTooltip = 'Display fair values gaps on the chart'
fairValueGapsThresholdTooltip = 'Filter out non significant fair value gaps'
fairValueGapsTimeframeTooltip = 'Fair value gaps timeframe'
fairValueGapsExtendTooltip = 'Determine how many bars to extend the Fair
Value Gap boxes on chart'
showPremiumDiscountZonesTooltip = 'Display premium, discount, and
equilibrium zones on chart'
modeInput = [Link]( HISTORICAL, 'Mode', group
= SMART_GROUP, tooltip = modeTooltip, options = [HISTORICAL, PRESENT])
styleInput = [Link]( COLORED, 'Style', group =
SMART_GROUP, tooltip = styleTooltip,options = [COLORED, MONOCHROME])
showTrendInput = input( false, 'Color Candles', group =
SMART_GROUP, tooltip = showTrendTooltip)
showInternalsInput = input( true, 'Show Internal Structure',
group = INTERNAL_GROUP, tooltip = showInternalsTooltip)
showInternalBullInput = [Link]( ALL, 'Bullish Structure',
group = INTERNAL_GROUP, inline = 'ibull', options = [ALL,BOS,CHOCH])
internalBullColorInput = input( GREEN, '', group =
INTERNAL_GROUP, inline = 'ibull')
showInternalBearInput = [Link]( ALL, 'Bearish Structure' ,
group = INTERNAL_GROUP, inline = 'ibear', options = [ALL,BOS,CHOCH])
internalBearColorInput = input( RED, '', group =
INTERNAL_GROUP, inline = 'ibear')
internalFilterConfluenceInput = input( false, 'Confluence Filter',
group = INTERNAL_GROUP, tooltip = internalFilterConfluenceTooltip)
internalStructureSize = [Link]( TINY, 'Internal Label Size',
group = INTERNAL_GROUP, options = [TINY,SMALL,NORMAL])
showStructureInput = input( true, 'Show Swing Structure',
group = SWING_GROUP, tooltip = showStructureTooltip)
showSwingBullInput = [Link]( ALL, 'Bullish Structure',
group = SWING_GROUP, inline = 'bull', options = [ALL,BOS,CHOCH])
swingBullColorInput = input( GREEN, '', group =
SWING_GROUP, inline = 'bull')
showSwingBearInput = [Link]( ALL, 'Bearish Structure',
group = SWING_GROUP, inline = 'bear', options = [ALL,BOS,CHOCH])
swingBearColorInput = input( RED, '', group =
SWING_GROUP, inline = 'bear')
swingStructureSize = [Link]( SMALL, 'Swing Label Size',
group = SWING_GROUP, options = [TINY,SMALL,NORMAL])
showSwingsInput = input( false, 'Show Swings Points',
group = SWING_GROUP, tooltip = showSwingsTooltip,inline = 'swings')
swingsLengthInput = [Link]( 50, '', group =
SWING_GROUP, minval = 10, inline = 'swings')
showHighLowSwingsInput = input( true, 'Show Strong/Weak
High/Low',group = SWING_GROUP, tooltip = showHighLowSwingsTooltip)
showInternalOrderBlocksInput = input( true, 'Internal Order Blocks' ,
group = BLOCKS_GROUP, tooltip = showInternalOrderBlocksTooltip, inline =
'iob')
internalOrderBlocksSizeInput = [Link]( 5, '', group =
BLOCKS_GROUP, minval = 1, maxval = 20, inline = 'iob')
showSwingOrderBlocksInput = input( false, 'Swing Order Blocks',
group = BLOCKS_GROUP, tooltip = showSwingOrderBlocksTooltip, inline =
'ob')
swingOrderBlocksSizeInput = [Link]( 5, '', group =
BLOCKS_GROUP, minval = 1, maxval = 20, inline = 'ob')
orderBlockFilterInput = [Link]( 'Atr', 'Order Block Filter', group
= BLOCKS_GROUP, tooltip = orderBlockFilterTooltip, options = [ATR,
RANGE])
orderBlockMitigationInput = [Link]( HIGHLOW, 'Order Block
Mitigation', group = BLOCKS_GROUP, tooltip = orderBlockMitigationTooltip,
options = [CLOSE,HIGHLOW])
internalBullishOrderBlockColor = [Link]([Link](#3179f5, 80), 'Internal
Bullish OB', group = BLOCKS_GROUP)
internalBearishOrderBlockColor = [Link]([Link](#f77c80, 80), 'Internal
Bearish OB', group = BLOCKS_GROUP)
swingBullishOrderBlockColor = [Link]([Link](#1848cc, 80), 'Bullish
OB', group = BLOCKS_GROUP)
swingBearishOrderBlockColor = [Link]([Link](#b22833, 80), 'Bearish
OB', group = BLOCKS_GROUP)
showEqualHighsLowsInput = input( true, 'Equal High/Low',
group = EQUAL_GROUP, tooltip = showEqualHighsLowsTooltip)
equalHighsLowsLengthInput = [Link]( 3, 'Bars Confirmation',
group = EQUAL_GROUP, tooltip = equalHighsLowsLengthTooltip, minval =
1)
equalHighsLowsThresholdInput = [Link]( 0.1, 'Threshold',
group = EQUAL_GROUP, tooltip = equalHighsLowsThresholdTooltip, minval =
0, maxval = 0.5, step = 0.1)
equalHighsLowsSizeInput = [Link]( TINY, 'Label Size',
group = EQUAL_GROUP, options = [TINY,SMALL,NORMAL])
showFairValueGapsInput = input( false, 'Fair Value Gaps',
group = GAPS_GROUP, tooltip = showFairValueGapsTooltip)
fairValueGapsThresholdInput = input( true, 'Auto Threshold',
group = GAPS_GROUP, tooltip = fairValueGapsThresholdTooltip)
fairValueGapsTimeframeInput = [Link]('', 'Timeframe',
group = GAPS_GROUP, tooltip = fairValueGapsTimeframeTooltip)
fairValueGapsBullColorInput = [Link]([Link](#00ff68, 70), 'Bullish
FVG' , group = GAPS_GROUP)
fairValueGapsBearColorInput = [Link]([Link](#ff0008, 70), 'Bearish
FVG' , group = GAPS_GROUP)
fairValueGapsExtendInput = [Link]( 1, 'Extend FVG',
group = GAPS_GROUP, tooltip = fairValueGapsExtendTooltip, minval = 0)
showDailyLevelsInput = input( false, 'Daily', group =
LEVELS_GROUP, inline = 'daily')
dailyLevelsStyleInput = [Link]( SOLID, '', group =
LEVELS_GROUP, inline = 'daily', options = [SOLID,DASHED,DOTTED])
dailyLevelsColorInput = input( BLUE, '', group =
LEVELS_GROUP, inline = 'daily')
showWeeklyLevelsInput = input( false, 'Weekly', group =
LEVELS_GROUP, inline = 'weekly')
weeklyLevelsStyleInput = [Link]( SOLID, '', group =
LEVELS_GROUP, inline = 'weekly', options = [SOLID,DASHED,DOTTED])
weeklyLevelsColorInput = input( BLUE, '', group =
LEVELS_GROUP, inline = 'weekly')
showMonthlyLevelsInput = input( false, 'Monthly', group =
LEVELS_GROUP, inline = 'monthly')
monthlyLevelsStyleInput = [Link]( SOLID, '', group =
LEVELS_GROUP, inline = 'monthly', options = [SOLID,DASHED,DOTTED])
monthlyLevelsColorInput = input( BLUE, '', group =
LEVELS_GROUP, inline = 'monthly')
showPremiumDiscountZonesInput = input( false, 'Premium/Discount
Zones', group = ZONES_GROUP , tooltip = showPremiumDiscountZonesTooltip)
premiumZoneColorInput = [Link]( RED, 'Premium Zone',
group = ZONES_GROUP)
equilibriumZoneColorInput = [Link]( GRAY, 'Equilibrium Zone',
group = ZONES_GROUP)
discountZoneColorInput = [Link]( GREEN, 'Discount Zone',
group = ZONES_GROUP)
//---------------------------------------------------------------------------------------------------------------
------}
//DATA STRUCTURES & VARIABLES
//---------------------------------------------------------------------------------------------------------------
------{
// @type UDT representing alerts as bool fields
// @field internalBullishBOS internal structure custom alert
// @field internalBearishBOS internal structure custom alert
// @field internalBullishCHoCH internal structure custom alert
// @field internalBearishCHoCH internal structure custom alert
// @field swingBullishBOS swing structure custom alert
// @field swingBearishBOS swing structure custom alert
// @field swingBullishCHoCH swing structure custom alert
// @field swingBearishCHoCH swing structure custom alert
// @field internalBullishOrderBlock internal order block custom alert
// @field internalBearishOrderBlock internal order block custom alert
// @field swingBullishOrderBlock swing order block custom alert
// @field swingBearishOrderBlock swing order block custom alert
// @field equalHighs equal high low custom alert
// @field equalLows equal high low custom alert
// @field bullishFairValueGap fair value gap custom alert
// @field bearishFairValueGap fair value gap custom alert
type alerts
bool internalBullishBOS = false
bool internalBearishBOS = false
bool internalBullishCHoCH = false
bool internalBearishCHoCH = false
bool swingBullishBOS = false
bool swingBearishBOS = false
bool swingBullishCHoCH = false
bool swingBearishCHoCH = false
bool internalBullishOrderBlock = false
bool internalBearishOrderBlock = false
bool swingBullishOrderBlock = false
bool swingBearishOrderBlock = false
bool equalHighs = false
bool equalLows = false
bool bullishFairValueGap = false
bool bearishFairValueGap = false
// @type UDT representing last swing extremes (top & bottom)
// @field top last top swing price
// @field bottom last bottom swing price
// @field barTime last swing bar time
// @field barIndex last swing bar index
// @field lastTopTime last top swing time
// @field lastBottomTime last bottom swing time
type trailingExtremes
float top
float bottom
int barTime
int barIndex
int lastTopTime
int lastBottomTime
// @type UDT representing Fair Value Gaps
// @field top top price
// @field bottom bottom price
// @field bias bias (BULLISH or BEARISH)
// @field topBox top box
// @field bottomBox bottom box
type fairValueGap
float top
float bottom
int bias
box topBox
box bottomBox
// @type UDT representing trend bias
// @field bias BULLISH or BEARISH
type trend
int bias
// @type UDT representing Equal Highs Lows display
// @field l_ine displayed line
// @field l_abel displayed label
type equalDisplay
line l_ine = na
label l_abel = na
// @type UDT representing a pivot point (swing point)
// @field currentLevel current price level
// @field lastLevel last price level
// @field crossed true if price level is crossed
// @field barTime bar time
// @field barIndex bar index
type pivot
float currentLevel
float lastLevel
bool crossed
int barTime = time
int barIndex = bar_index
// @type UDT representing an order block
// @field barHigh bar high
// @field barLow bar low
// @field barTime bar time
// @field bias BULLISH or BEARISH
type orderBlock
float barHigh
float barLow
int barTime
int bias
// @variable current swing pivot high
var pivot swingHigh = [Link](na,na,false)
// @variable current swing pivot low
var pivot swingLow = [Link](na,na,false)
// @variable current internal pivot high
var pivot internalHigh = [Link](na,na,false)
// @variable current internal pivot low
var pivot internalLow = [Link](na,na,false)
// @variable current equal high pivot
var pivot equalHigh = [Link](na,na,false)
// @variable current equal low pivot
var pivot equalLow = [Link](na,na,false)
// @variable swing trend bias
var trend swingTrend = [Link](0)
// @variable internal trend bias
var trend internalTrend = [Link](0)
// @variable equal high display
var equalDisplay equalHighDisplay = [Link]()
// @variable equal low display
var equalDisplay equalLowDisplay = [Link]()
// @variable storage for fairValueGap UDTs
var array<fairValueGap> fairValueGaps = [Link]<fairValueGap>()
// @variable storage for parsed highs
var array<float> parsedHighs = [Link]<float>()
// @variable storage for parsed lows
var array<float> parsedLows = [Link]<float>()
// @variable storage for raw highs
var array<float> highs = [Link]<float>()
// @variable storage for raw lows
var array<float> lows = [Link]<float>()
// @variable storage for bar time values
var array<int> times = [Link]<int>()
// @variable last trailing swing high and low
var trailingExtremes trailing = [Link]()
// @variable storage for orderBlock UDTs (swing order
blocks)
var array<orderBlock> swingOrderBlocks = [Link]<orderBlock>()
// @variable storage for orderBlock UDTs (internal order
blocks)
var array<orderBlock> internalOrderBlocks = [Link]<orderBlock>()
// @variable storage for swing order blocks boxes
var array<box> swingOrderBlocksBoxes = [Link]<box>()
// @variable storage for internal order blocks boxes
var array<box> internalOrderBlocksBoxes = [Link]<box>()
// @variable color for swing bullish structures
var swingBullishColor = styleInput == MONOCHROME ?
MONO_BULLISH : swingBullColorInput
// @variable color for swing bearish structures
var swingBearishColor = styleInput == MONOCHROME ?
MONO_BEARISH : swingBearColorInput
// @variable color for bullish fair value gaps
var fairValueGapBullishColor = styleInput == MONOCHROME ?
[Link](MONO_BULLISH,70) : fairValueGapsBullColorInput
// @variable color for bearish fair value gaps
var fairValueGapBearishColor = styleInput == MONOCHROME ?
[Link](MONO_BEARISH,70) : fairValueGapsBearColorInput
// @variable color for premium zone
var premiumZoneColor = styleInput == MONOCHROME ?
MONO_BEARISH : premiumZoneColorInput
// @variable color for discount zone
var discountZoneColor = styleInput == MONOCHROME ?
MONO_BULLISH : discountZoneColorInput
// @variable bar index on current script iteration
varip int currentBarIndex = bar_index
// @variable bar index on last script iteration
varip int lastBarIndex = bar_index
// @variable alerts in current bar
alerts currentAlerts = [Link]()
// @variable time at start of chart
var initialTime = time
// we create the needed boxes for displaying order blocks at the first execution
if [Link]
if showSwingOrderBlocksInput
for index = 1 to swingOrderBlocksSizeInput
[Link]([Link](na,na,na,na,xloc =
xloc.bar_time,extend = [Link]))
if showInternalOrderBlocksInput
for index = 1 to internalOrderBlocksSizeInput
[Link]([Link](na,na,na,na,xloc =
xloc.bar_time,extend = [Link]))
// @variable source to use in bearish order blocks mitigation
bearishOrderBlockMitigationSource = orderBlockMitigationInput == CLOSE ?
close : high
// @variable source to use in bullish order blocks mitigation
bullishOrderBlockMitigationSource = orderBlockMitigationInput == CLOSE ?
close : low
// @variable default volatility measure
atrMeasure = [Link](200)
// @variable parsed volatility measure by user settings
volatilityMeasure = orderBlockFilterInput == ATR ? atrMeasure :
[Link]([Link])/bar_index
// @variable true if current bar is a high volatility bar
highVolatilityBar = (high - low) >= (2 * volatilityMeasure)
// @variable parsed high
parsedHigh = highVolatilityBar ? low : high
// @variable parsed low
parsedLow = highVolatilityBar ? high : low
// we store current values into the arrays at each bar
[Link](parsedHigh)
[Link](parsedLow)
[Link](high)
[Link](low)
[Link](time)
//---------------------------------------------------------------------------------------------------------------
------}
//USER-DEFINED FUNCTIONS
//---------------------------------------------------------------------------------------------------------------
------{
// @function Get the value of the current leg, it can be 0 (bearish) or 1
(bullish)
// @returns int
leg(int size) =>
var leg =0
newLegHigh = high[size] > [Link]( size)
newLegLow = low[size] < [Link]( size)
if newLegHigh
leg := BEARISH_LEG
else if newLegLow
leg := BULLISH_LEG
leg
// @function Identify whether the current value is the start of a new leg
(swing)
// @param leg (int) Current leg value
// @returns bool
startOfNewLeg(int leg) => [Link](leg) != 0
// @function Identify whether the current level is the start of a new
bearish leg (swing)
// @param leg (int) Current leg value
// @returns bool
startOfBearishLeg(int leg) => [Link](leg) == -1
// @function Identify whether the current level is the start of a new
bullish leg (swing)
// @param leg (int) Current leg value
// @returns bool
startOfBullishLeg(int leg) => [Link](leg) == +1
// @function create a new label
// @param labelTime bar time coordinate
// @param labelPrice price coordinate
// @param tag text to display
// @param labelColor text color
// @param labelStyle label style
// @returns label ID
drawLabel(int labelTime, float labelPrice, string tag, color labelColor, string
labelStyle) =>
var label l_abel = na
if modeInput == PRESENT
l_abel.delete()
l_abel :=
[Link]([Link](labelTime,na,labelPrice),tag,xloc.bar_time,color=color(
na),textcolor=labelColor,style = labelStyle,size = [Link])
// @function create a new line and label representing an EQH or EQL
// @param p_ivot starting pivot
// @param level price level of current pivot
// @param size how many bars ago was the current pivot detected
// @param equalHigh true for EQH, false for EQL
// @returns label ID
drawEqualHighLow(pivot p_ivot, float level, int size, bool equalHigh) =>
equalDisplay e_qualDisplay = equalHigh ? equalHighDisplay :
equalLowDisplay
string tag = 'EQL'
color equalColor = swingBullishColor
string labelStyle = label.style_label_up
if equalHigh
tag := 'EQH'
equalColor := swingBearishColor
labelStyle := label.style_label_down
if modeInput == PRESENT
[Link]( e_qualDisplay.l_ine)
[Link]( e_qualDisplay.l_abel)
e_qualDisplay.l_ine :=
[Link]([Link](p_ivot.barTime,na,p_ivot.currentLevel),
[Link](time[size],na,level), xloc = xloc.bar_time, color = equalColor,
style = line.style_dotted)
labelPosition = [Link](0.5*(p_ivot.barIndex + bar_index - size))
e_qualDisplay.l_abel := [Link]([Link](na,labelPosition,level),
tag, xloc.bar_index, color = color(na), textcolor = equalColor, style = labelStyle,
size = equalHighsLowsSizeInput)
// @function store current structure and trailing swing points, and also
display swing points and equal highs/lows
// @param size (int) structure size
// @param equalHighLow (bool) true for displaying current highs/lows
// @param internal (bool) true for getting internal structures
// @returns label ID
getCurrentStructure(int size,bool equalHighLow = false, bool internal = false)
=>
currentLeg = leg(size)
newPivot = startOfNewLeg(currentLeg)
pivotLow = startOfBullishLeg(currentLeg)
pivotHigh = startOfBearishLeg(currentLeg)
if newPivot
if pivotLow
pivot p_ivot = equalHighLow ? equalLow : internal ? internalLow :
swingLow
if equalHighLow and [Link](p_ivot.currentLevel - low[size]) <
equalHighsLowsThresholdInput * atrMeasure
drawEqualHighLow(p_ivot, low[size], size, false)
[Link] := true
p_ivot.lastLevel := p_ivot.currentLevel
p_ivot.currentLevel := low[size]
p_ivot.crossed := false
p_ivot.barTime := time[size]
p_ivot.barIndex := bar_index[size]
if not equalHighLow and not internal
[Link] := p_ivot.currentLevel
[Link] := p_ivot.barTime
[Link] := p_ivot.barIndex
[Link] := p_ivot.barTime
if showSwingsInput and not internal and not equalHighLow
drawLabel(time[size], p_ivot.currentLevel, p_ivot.currentLevel <
p_ivot.lastLevel ? 'LL' : 'HL', swingBullishColor, label.style_label_up)
else
pivot p_ivot = equalHighLow ? equalHigh : internal ? internalHigh :
swingHigh
if equalHighLow and [Link](p_ivot.currentLevel - high[size]) <
equalHighsLowsThresholdInput * atrMeasure
drawEqualHighLow(p_ivot,high[size],size,true)
[Link] := true
p_ivot.lastLevel := p_ivot.currentLevel
p_ivot.currentLevel := high[size]
p_ivot.crossed := false
p_ivot.barTime := time[size]
p_ivot.barIndex := bar_index[size]
if not equalHighLow and not internal
[Link] := p_ivot.currentLevel
[Link] := p_ivot.barTime
[Link] := p_ivot.barIndex
[Link] := p_ivot.barTime
if showSwingsInput and not internal and not equalHighLow
drawLabel(time[size], p_ivot.currentLevel, p_ivot.currentLevel >
p_ivot.lastLevel ? 'HH' : 'LH', swingBearishColor, label.style_label_down)
// @function draw line and label representing a structure
// @param p_ivot base pivot point
// @param tag test to display
// @param structureColor base color
// @param lineStyle line style
// @param labelStyle label style
// @param labelSize text size
// @returns label ID
drawStructure(pivot p_ivot, string tag, color structureColor, string lineStyle,
string labelStyle, string labelSize) =>
var line l_ine = [Link](na,na,na,na,xloc = xloc.bar_time)
var label l_abel = [Link](na,na)
if modeInput == PRESENT
l_ine.delete()
l_abel.delete()
l_ine := [Link]([Link](p_ivot.barTime,na,p_ivot.currentLevel),
[Link](time,na,p_ivot.currentLevel), xloc.bar_time,
color=structureColor, style=lineStyle)
l_abel :=
[Link]([Link](na,[Link](0.5*(p_ivot.barIndex+bar_index)),p_ivo
[Link]), tag, xloc.bar_index, color=color(na), textcolor=structureColor,
style=labelStyle, size = labelSize)
// @function delete order blocks
// @param internal true for internal order blocks
// @returns orderBlock ID
deleteOrderBlocks(bool internal = false) =>
array<orderBlock> orderBlocks = internal ? internalOrderBlocks :
swingOrderBlocks
for [index,eachOrderBlock] in orderBlocks
bool crossedOderBlock = false
if bearishOrderBlockMitigationSource > [Link] and
[Link] == BEARISH
crossedOderBlock := true
if internal
[Link] := true
else
[Link] := true
else if bullishOrderBlockMitigationSource < [Link] and
[Link] == BULLISH
crossedOderBlock := true
if internal
[Link] := true
else
[Link] := true
if crossedOderBlock
[Link](index)
// @function fetch and store order blocks
// @param p_ivot base pivot point
// @param internal true for internal order blocks
// @param bias BULLISH or BEARISH
// @returns void
storeOrdeBlock(pivot p_ivot,bool internal = false,int bias) =>
if (not internal and showSwingOrderBlocksInput) or (internal and
showInternalOrderBlocksInput)
array<float> a_rray = na
int parsedIndex = na
if bias == BEARISH
a_rray := [Link](p_ivot.barIndex,bar_index)
parsedIndex := p_ivot.barIndex + a_rray.indexof(a_rray.max())
else
a_rray := [Link](p_ivot.barIndex,bar_index)
parsedIndex := p_ivot.barIndex + a_rray.indexof(a_rray.min())
orderBlock o_rderBlock =
[Link]([Link](parsedIndex), [Link](parsedIndex),
[Link](parsedIndex),bias)
array<orderBlock> orderBlocks = internal ? internalOrderBlocks :
swingOrderBlocks
if [Link]() >= 100
[Link]()
[Link](o_rderBlock)
// @function draw order blocks as boxes
// @param internal true for internal order blocks
// @returns void
drawOrderBlocks(bool internal = false) =>
array<orderBlock> orderBlocks = internal ? internalOrderBlocks :
swingOrderBlocks
orderBlocksSize = [Link]()
if orderBlocksSize > 0
maxOrderBlocks = internal ? internalOrderBlocksSizeInput :
swingOrderBlocksSizeInput
array<orderBlock> parsedOrdeBlocks = [Link](0,
[Link](maxOrderBlocks,orderBlocksSize))
array<box> b_oxes = internal ? internalOrderBlocksBoxes :
swingOrderBlocksBoxes
for [index,eachOrderBlock] in parsedOrdeBlocks
orderBlockColor = styleInput == MONOCHROME ? ([Link]
== BEARISH ? [Link](MONO_BEARISH,80) : [Link](MONO_BULLISH,80)) :
internal ? ([Link] == BEARISH ? internalBearishOrderBlockColor :
internalBullishOrderBlockColor) : ([Link] == BEARISH ?
swingBearishOrderBlockColor : swingBullishOrderBlockColor)
box b_ox = b_oxes.get(index)
b_ox.set_top_left_point(
[Link]([Link],na,[Link]))
b_ox.set_bottom_right_point([Link](last_bar_time,na,[Link]
rLow))
b_ox.set_border_color( internal ? na : orderBlockColor)
b_ox.set_bgcolor( orderBlockColor)
// @function detect and draw structures, also detect and store order
blocks
// @param internal true for internal structures or order blocks
// @returns void
displayStructure(bool internal = false) =>
var bullishBar = true
var bearishBar = true
if internalFilterConfluenceInput
bullishBar := high - [Link](close, open) > [Link](close, open - low)
bearishBar := high - [Link](close, open) < [Link](close, open - low)
pivot p_ivot = internal ? internalHigh : swingHigh
trend t_rend = internal ? internalTrend : swingTrend
lineStyle = internal ? line.style_dashed : line.style_solid
labelSize = internal ? internalStructureSize : swingStructureSize
extraCondition = internal ? [Link] !=
[Link] and bullishBar : true
bullishColor = styleInput == MONOCHROME ? MONO_BULLISH : internal ?
internalBullColorInput : swingBullColorInput
if [Link](close,p_ivot.currentLevel) and not p_ivot.crossed and
extraCondition
string tag = t_rend.bias == BEARISH ? CHOCH : BOS
if internal
[Link] := tag == CHOCH
[Link] := tag == BOS
else
[Link] := tag == CHOCH
[Link] := tag == BOS
p_ivot.crossed := true
t_rend.bias := BULLISH
displayCondition = internal ? showInternalsInput and (showInternalBullInput
== ALL or (showInternalBullInput == BOS and tag != CHOCH) or
(showInternalBullInput == CHOCH and tag == CHOCH)) : showStructureInput
and (showSwingBullInput == ALL or (showSwingBullInput == BOS and tag !=
CHOCH) or (showSwingBullInput == CHOCH and tag == CHOCH))
if displayCondition
drawStructure(p_ivot,tag,bullishColor,lineStyle,label.style_label_down,labelSize)
if (internal and showInternalOrderBlocksInput) or (not internal and
showSwingOrderBlocksInput)
storeOrdeBlock(p_ivot,internal,BULLISH)
p_ivot := internal ? internalLow : swingLow
extraCondition := internal ? [Link] !=
[Link] and bearishBar : true
bearishColor = styleInput == MONOCHROME ? MONO_BEARISH : internal ?
internalBearColorInput : swingBearColorInput
if [Link](close,p_ivot.currentLevel) and not p_ivot.crossed and
extraCondition
string tag = t_rend.bias == BULLISH ? CHOCH : BOS
if internal
[Link] := tag == CHOCH
[Link] := tag == BOS
else
[Link] := tag == CHOCH
[Link] := tag == BOS
p_ivot.crossed := true
t_rend.bias := BEARISH
displayCondition = internal ? showInternalsInput and
(showInternalBearInput == ALL or (showInternalBearInput == BOS and tag !=
CHOCH) or (showInternalBearInput == CHOCH and tag == CHOCH)) :
showStructureInput and (showSwingBearInput == ALL or (showSwingBearInput
== BOS and tag != CHOCH) or (showSwingBearInput == CHOCH and tag ==
CHOCH))
if displayCondition
drawStructure(p_ivot,tag,bearishColor,lineStyle,label.style_label_up,labelSize)
if (internal and showInternalOrderBlocksInput) or (not internal and
showSwingOrderBlocksInput)
storeOrdeBlock(p_ivot,internal,BEARISH)
// @function draw one fair value gap box (each fair value gap has two
boxes)
// @param leftTime left time coordinate
// @param rightTime right time coordinate
// @param topPrice top price level
// @param bottomPrice bottom price level
// @param boxColor box color
// @returns box ID
fairValueGapBox(leftTime,rightTime,topPrice,bottomPrice,boxColor) =>
[Link]([Link](leftTime,na,topPrice),[Link](rightTime +
fairValueGapsExtendInput * (time-time[1]),na,bottomPrice), xloc=xloc.bar_time,
border_color = boxColor, bgcolor = boxColor)
// @function delete fair value gaps
// @returns fairValueGap ID
deleteFairValueGaps() =>
for [index,eachFairValueGap] in fairValueGaps
if (low < [Link] and [Link] ==
BULLISH) or (high > [Link] and [Link] ==
BEARISH)
[Link]()
[Link]()
[Link](index)
// @function draw fair value gaps
// @returns fairValueGap ID
drawFairValueGaps() =>
[lastClose, lastOpen, lastTime, currentHigh, currentLow, currentTime,
last2High, last2Low] = [Link]([Link],
fairValueGapsTimeframeInput, [close[1], open[1], time[1], high[0], low[0],
time[0], high[2], low[2]],lookahead = barmerge.lookahead_on)
barDeltaPercent = (lastClose - lastOpen) / (lastOpen * 100)
newTimeframe = [Link](fairValueGapsTimeframeInput)
threshold = fairValueGapsThresholdInput ?
[Link]([Link](newTimeframe ? barDeltaPercent : 0)) / bar_index * 2 : 0
bullishFairValueGap = currentLow > last2High and lastClose > last2High and
barDeltaPercent > threshold and newTimeframe
bearishFairValueGap = currentHigh < last2Low and lastClose < last2Low and -
barDeltaPercent > threshold and newTimeframe
if bullishFairValueGap
[Link] := true
[Link]([Link](currentLow,last2High,BULLISH,fairValue
GapBox(lastTime,currentTime,currentLow,[Link](currentLow,last2High),fairVa
lueGapBullishColor),fairValueGapBox(lastTime,currentTime,[Link](currentLow
,last2High),last2High,fairValueGapBullishColor)))
if bearishFairValueGap
[Link] := true
[Link]([Link](currentHigh,last2Low,BEARISH,fairValue
GapBox(lastTime,currentTime,currentHigh,[Link](currentHigh,last2Low),fairV
alueGapBearishColor),fairValueGapBox(lastTime,currentTime,[Link](currentHi
gh,last2Low),last2Low,fairValueGapBearishColor)))
// @function get line style from string
// @param style line style
// @returns string
getStyle(string style) =>
switch style
SOLID => line.style_solid
DASHED => line.style_dashed
DOTTED => line.style_dotted
// @function draw MultiTimeFrame levels
// @param timeframe base timeframe
// @param sameTimeframe true if chart timeframe is same as base timeframe
// @param style line style
// @param levelColor line and text color
// @returns void
drawLevels(string timeframe, bool sameTimeframe, string style, color
levelColor) =>
[topLevel, bottomLevel, leftTime, rightTime] =
[Link]([Link], timeframe, [high[1], low[1], time[1],
time],lookahead = barmerge.lookahead_on)
float parsedTop = sameTimeframe ? high : topLevel
float parsedBottom = sameTimeframe ? low : bottomLevel
int parsedLeftTime = sameTimeframe ? time : leftTime
int parsedRightTime = sameTimeframe ? time : rightTime
int parsedTopTime = time
int parsedBottomTime = time
if not sameTimeframe
int leftIndex = times.binary_search_rightmost(parsedLeftTime)
int rightIndex = times.binary_search_rightmost(parsedRightTime)
array<int> timeArray = [Link](leftIndex,rightIndex)
array<float> topArray = [Link](leftIndex,rightIndex)
array<float> bottomArray = [Link](leftIndex,rightIndex)
parsedTopTime := [Link]() > 0 ?
[Link]([Link]([Link]())) : initialTime
parsedBottomTime := [Link]() > 0 ?
[Link]([Link]([Link]())) : initialTime
var line topLine = [Link](na, na, na, na, xloc = xloc.bar_time, color =
levelColor, style = getStyle(style))
var line bottomLine = [Link](na, na, na, na, xloc = xloc.bar_time, color =
levelColor, style = getStyle(style))
var label topLabel = [Link](na, na, xloc = xloc.bar_time, text =
[Link]('P{0}H',timeframe), color=color(na), textcolor = levelColor, size =
[Link], style = label.style_label_left)
var label bottomLabel = [Link](na, na, xloc = xloc.bar_time, text =
[Link]('P{0}L',timeframe), color=color(na), textcolor = levelColor, size =
[Link], style = label.style_label_left)
topLine.set_first_point( [Link](parsedTopTime,na,parsedTop))
topLine.set_second_point( [Link](last_bar_time + 20 * (time-
time[1]),na,parsedTop))
topLabel.set_point( [Link](last_bar_time + 20 * (time-
time[1]),na,parsedTop))
bottomLine.set_first_point( [Link](parsedBottomTime,na,parsedBottom)
)
bottomLine.set_second_point([Link](last_bar_time + 20 * (time-
time[1]),na,parsedBottom))
bottomLabel.set_point( [Link](last_bar_time + 20 * (time-
time[1]),na,parsedBottom))
// @function true if chart timeframe is higher than provided timeframe
// @param timeframe timeframe to check
// @returns bool
higherTimeframe(string timeframe) => timeframe.in_seconds() >
timeframe.in_seconds(timeframe)
// @function update trailing swing points
// @returns int
updateTrailingExtremes() =>
[Link] := [Link](high,[Link])
[Link] := [Link] == high ? time : [Link]
[Link] := [Link](low,[Link])
[Link] := [Link] == low ? time :
[Link]
// @function draw trailing swing points
// @returns void
drawHighLowSwings() =>
var line topLine = [Link](na, na, na, na, color = swingBearishColor, xloc
= xloc.bar_time)
var line bottomLine = [Link](na, na, na, na, color = swingBullishColor,
xloc = xloc.bar_time)
var label topLabel = [Link](na, na, color=color(na), textcolor =
swingBearishColor, xloc = xloc.bar_time, style = label.style_label_down, size =
[Link])
var label bottomLabel = [Link](na, na, color=color(na), textcolor =
swingBullishColor, xloc = xloc.bar_time, style = label.style_label_up, size =
[Link])
rightTimeBar = last_bar_time + 20 * (time - time[1])
topLine.set_first_point( [Link]([Link], na, [Link]))
topLine.set_second_point( [Link](rightTimeBar, na, [Link]))
topLabel.set_point( [Link](rightTimeBar, na, [Link]))
topLabel.set_text( [Link] == BEARISH ? 'Strong High' : 'Weak
High')
bottomLine.set_first_point( [Link]([Link], na,
[Link]))
bottomLine.set_second_point([Link](rightTimeBar, na,
[Link]))
bottomLabel.set_point( [Link](rightTimeBar, na, [Link]))
bottomLabel.set_text( [Link] == BULLISH ? 'Strong Low' : 'Weak
Low')
// @function draw a zone with a label and a box
// @param labelLevel price level for label
// @param labelIndex bar index for label
// @param top top price level for box
// @param bottom bottom price level for box
// @param tag text to display
// @param zoneColor base color
// @param style label style
// @returns void
drawZone(float labelLevel, int labelIndex, float top, float bottom, string tag,
color zoneColor, string style) =>
var label l_abel = [Link](na,na,text = tag, color=color(na),textcolor =
zoneColor, style = style, size = [Link])
var box b_ox = [Link](na,na,na,na,bgcolor =
[Link](zoneColor,80),border_color = color(na), xloc = xloc.bar_time)
b_ox.set_top_left_point( [Link]([Link],na,top))
b_ox.set_bottom_right_point([Link](last_bar_time,na,bottom))
l_abel.set_point( [Link](na,labelIndex,labelLevel))
// @function draw premium/discount zones
// @returns void
drawPremiumDiscountZones() =>
drawZone([Link], [Link](0.5*([Link] + last_bar_index)),
[Link], 0.95*[Link] + 0.05*[Link], 'Premium',
premiumZoneColor, label.style_label_down)
equilibriumLevel = [Link]([Link], [Link])
drawZone(equilibriumLevel, last_bar_index, 0.525*[Link] +
0.475*[Link], 0.525*[Link] + 0.475*[Link], 'Equilibrium',
equilibriumZoneColorInput, label.style_label_left)
drawZone([Link], [Link](0.5*([Link] +
last_bar_index)), 0.95*[Link] + 0.05*[Link], [Link],
'Discount', discountZoneColor, label.style_label_up)
//---------------------------------------------------------------------------------------------------------------
------}
//MUTABLE VARIABLES & EXECUTION
//---------------------------------------------------------------------------------------------------------------
------{
parsedOpen = showTrendInput ? open : na
candleColor = [Link] == BULLISH ? swingBullishColor :
swingBearishColor
plotcandle(parsedOpen,high,low,close,color = candleColor, wickcolor =
candleColor, bordercolor = candleColor)
if showHighLowSwingsInput or showPremiumDiscountZonesInput
updateTrailingExtremes()
if showHighLowSwingsInput
drawHighLowSwings()
if showPremiumDiscountZonesInput
drawPremiumDiscountZones()
if showFairValueGapsInput
deleteFairValueGaps()
getCurrentStructure(swingsLengthInput,false)
getCurrentStructure(5,false,true)
if showEqualHighsLowsInput
getCurrentStructure(equalHighsLowsLengthInput,true)
if showInternalsInput or showInternalOrderBlocksInput or showTrendInput
displayStructure(true)
if showStructureInput or showSwingOrderBlocksInput or
showHighLowSwingsInput
displayStructure()
if showInternalOrderBlocksInput
deleteOrderBlocks(true)
if showSwingOrderBlocksInput
deleteOrderBlocks()
if showFairValueGapsInput
drawFairValueGaps()
if [Link] or [Link]
if showInternalOrderBlocksInput
drawOrderBlocks(true)
if showSwingOrderBlocksInput
drawOrderBlocks()
lastBarIndex := currentBarIndex
currentBarIndex := bar_index
newBar = currentBarIndex != lastBarIndex
if [Link] or ([Link] and newBar)
if showDailyLevelsInput and not higherTimeframe('D')
drawLevels('D',[Link],dailyLevelsStyleInput,dailyLevelsColorInput)
if showWeeklyLevelsInput and not higherTimeframe('W')
drawLevels('W',[Link],weeklyLevelsStyleInput,weeklyLevelsColorInp
ut)
if showMonthlyLevelsInput and not higherTimeframe('M')
drawLevels('M',[Link],monthlyLevelsStyleInput,monthlyLevelsColo
rInput)
//---------------------------------------------------------------------------------------------------------------
------}
//ALERTS
//---------------------------------------------------------------------------------------------------------------
------{
alertcondition([Link], 'Internal Bullish BOS',
'Internal Bullish BOS formed')
alertcondition([Link], 'Internal Bullish CHoCH',
'Internal Bullish CHoCH formed')
alertcondition([Link], 'Internal Bearish BOS',
'Internal Bearish BOS formed')
alertcondition([Link], 'Internal Bearish CHoCH',
'Internal Bearish CHoCH formed')
alertcondition([Link], 'Bullish BOS',
'Internal Bullish BOS formed')
alertcondition([Link], 'Bullish CHoCH',
'Internal Bullish CHoCH formed')
alertcondition([Link], 'Bearish BOS',
'Bearish BOS formed')
alertcondition([Link], 'Bearish CHoCH',
'Bearish CHoCH formed')
alertcondition([Link], 'Bullish Internal OB
Breakout', 'Price broke bullish internal OB')
alertcondition([Link], 'Bearish Internal OB
Breakout', 'Price broke bearish internal OB')
alertcondition([Link], 'Bullish Swing OB
Breakout', 'Price broke bullish swing OB')
alertcondition([Link], 'Bearish Swing OB
Breakout', 'Price broke bearish swing OB')
alertcondition([Link], 'Equal Highs', 'Equal
highs detected')
alertcondition([Link], 'Equal Lows', 'Equal
lows detected')
alertcondition([Link], 'Bullish FVG',
'Bullish FVG formed')
alertcondition([Link], 'Bearish FVG',
'Bearish FVG formed')
//---------------------------------------------------------------------------------------------------------------
------}