Scrip Smart Money Concept
Scrip Smart Money Concept
//@version=5
indicator('Smart Money Concepts [LuxAlgo]', 'LuxAlgo - Smart Money
Concepts', overlay = true, max_labels_count = 500, max_lines_count =
500, max_boxes_count = 500)
//--------------------------------------------------------------------
-------------------------------------------------}
//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 = size.tiny
SMALL = size.small
NORMAL = size.normal
ATR = 'Atr'
RANGE = 'Cumulative Mean Range'
CLOSE = 'Close'
HIGHLOW = 'High/Low'
SOLID = '⎯⎯⎯'
DASHED = '----'
DOTTED = '····'
//--------------------------------------------------------------------
-------------------------------------------------}
//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
// we create the needed boxes for displaying order blocks at the first
execution
if barstate.isfirst
if showSwingOrderBlocksInput
for index = 1 to swingOrderBlocksSizeInput
swingOrderBlocksBoxes.push(box.new(na,na,na,na,xloc =
xloc.bar_time,extend = extend.right))
if showInternalOrderBlocksInput
for index = 1 to internalOrderBlocksSizeInput
internalOrderBlocksBoxes.push(box.new(na,na,na,na,xloc =
xloc.bar_time,extend = extend.right))
//--------------------------------------------------------------------
-------------------------------------------------}
//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] > ta.highest( size)
newLegLow = low[size] < ta.lowest( size)
if newLegHigh
leg := BEARISH_LEG
else if newLegLow
leg := BULLISH_LEG
leg
if modeInput == PRESENT
l_abel.delete()
l_abel :=
label.new(chart.point.new(labelTime,na,labelPrice),tag,xloc.bar_time,c
olor=color(na),textcolor=labelColor,style = labelStyle,size =
size.small)
if equalHigh
tag := 'EQH'
equalColor := swingBearishColor
labelStyle := label.style_label_down
if modeInput == PRESENT
line.delete( e_qualDisplay.l_ine)
label.delete( e_qualDisplay.l_abel)
e_qualDisplay.l_ine :=
line.new(chart.point.new(p_ivot.barTime,na,p_ivot.currentLevel),
chart.point.new(time[size],na,level), xloc = xloc.bar_time, color =
equalColor, style = line.style_dotted)
labelPosition = math.round(0.5*(p_ivot.barIndex +
bar_index - size))
e_qualDisplay.l_abel :=
label.new(chart.point.new(na,labelPosition,level), tag,
xloc.bar_index, color = color(na), textcolor = equalColor, style =
labelStyle, size = equalHighsLowsSizeInput)
if newPivot
if pivotLow
pivot p_ivot = equalHighLow ? equalLow : internal ?
internalLow : swingLow
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]
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 modeInput == PRESENT
l_ine.delete()
l_abel.delete()
l_ine :=
line.new(chart.point.new(p_ivot.barTime,na,p_ivot.currentLevel),
chart.point.new(time,na,p_ivot.currentLevel), xloc.bar_time,
color=structureColor, style=lineStyle)
l_abel :=
label.new(chart.point.new(na,math.round(0.5*(p_ivot.barIndex+bar_index
)),p_ivot.currentLevel), tag, xloc.bar_index, color=color(na),
textcolor=structureColor, style=labelStyle, size = labelSize)
array<float> a_rray = na
int parsedIndex = na
if bias == BEARISH
a_rray :=
parsedHighs.slice(p_ivot.barIndex,bar_index)
parsedIndex := p_ivot.barIndex +
a_rray.indexof(a_rray.max())
else
a_rray := parsedLows.slice(p_ivot.barIndex,bar_index)
parsedIndex := p_ivot.barIndex +
a_rray.indexof(a_rray.min())
orderBlock o_rderBlock =
orderBlock.new(parsedHighs.get(parsedIndex),
parsedLows.get(parsedIndex), times.get(parsedIndex),bias)
array<orderBlock> orderBlocks = internal ?
internalOrderBlocks : swingOrderBlocks
if orderBlocksSize > 0
maxOrderBlocks = internal ?
internalOrderBlocksSizeInput : swingOrderBlocksSizeInput
array<orderBlock> parsedOrdeBlocks = orderBlocks.slice(0,
math.min(maxOrderBlocks,orderBlocksSize))
array<box> b_oxes = internal ?
internalOrderBlocksBoxes : swingOrderBlocksBoxes
b_ox.set_bottom_right_point(chart.point.new(last_bar_time,na,eachOrder
Block.barLow))
b_ox.set_border_color( internal ? na :
orderBlockColor)
b_ox.set_bgcolor( orderBlockColor)
if internalFilterConfluenceInput
bullishBar := high - math.max(close, open) > math.min(close,
open - low)
bearishBar := high - math.max(close, open) < math.min(close,
open - low)
if internal
currentAlerts.internalBullishCHoCH := tag == CHOCH
currentAlerts.internalBullishBOS := tag == BOS
else
currentAlerts.swingBullishCHoCH := tag == CHOCH
currentAlerts.swingBullishBOS := tag == BOS
p_ivot.crossed := true
t_rend.bias := BULLISH
if displayCondition
drawStructure(p_ivot,tag,bullishColor,lineStyle,label.style_label_down
,labelSize)
if internal
currentAlerts.internalBearishCHoCH := tag == CHOCH
currentAlerts.internalBearishBOS := tag == BOS
else
currentAlerts.swingBearishCHoCH := tag == CHOCH
currentAlerts.swingBearishBOS := tag == BOS
p_ivot.crossed := true
t_rend.bias := BEARISH
if displayCondition
drawStructure(p_ivot,tag,bearishColor,lineStyle,label.style_label_up,l
abelSize)
// @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) =>
box.new(chart.point.new(leftTime,na,topPrice),chart.point.new(rightTim
e + fairValueGapsExtendInput * (time-time[1]),na,bottomPrice),
xloc=xloc.bar_time, border_color = boxColor, bgcolor = boxColor)
if bullishFairValueGap
currentAlerts.bullishFairValueGap := true
fairValueGaps.unshift(fairValueGap.new(currentLow,last2High,BULLISH,fa
irValueGapBox(lastTime,currentTime,currentLow,math.avg(currentLow,last
2High),fairValueGapBullishColor),fairValueGapBox(lastTime,currentTime,
math.avg(currentLow,last2High),last2High,fairValueGapBullishColor)))
if bearishFairValueGap
currentAlerts.bearishFairValueGap := true
fairValueGaps.unshift(fairValueGap.new(currentHigh,last2Low,BEARISH,fa
irValueGapBox(lastTime,currentTime,currentHigh,math.avg(currentHigh,la
st2Low),fairValueGapBearishColor),fairValueGapBox(lastTime,currentTime
,math.avg(currentHigh,last2Low),last2Low,fairValueGapBearishColor)))
if not sameTimeframe
int leftIndex =
times.binary_search_rightmost(parsedLeftTime)
int rightIndex =
times.binary_search_rightmost(parsedRightTime)
array<int> timeArray =
times.slice(leftIndex,rightIndex)
array<float> topArray =
highs.slice(leftIndex,rightIndex)
array<float> bottomArray = lows.slice(leftIndex,rightIndex)
topLine.set_first_point(
chart.point.new(parsedTopTime,na,parsedTop))
topLine.set_second_point( chart.point.new(last_bar_time + 20 *
(time-time[1]),na,parsedTop))
topLabel.set_point( chart.point.new(last_bar_time + 20 *
(time-time[1]),na,parsedTop))
bottomLine.set_first_point(
chart.point.new(parsedBottomTime,na,parsedBottom))
bottomLine.set_second_point(chart.point.new(last_bar_time + 20 *
(time-time[1]),na,parsedBottom))
bottomLabel.set_point( chart.point.new(last_bar_time + 20 *
(time-time[1]),na,parsedBottom))
topLine.set_first_point( chart.point.new(trailing.lastTopTime,
na, trailing.top))
topLine.set_second_point( chart.point.new(rightTimeBar, na,
trailing.top))
topLabel.set_point( chart.point.new(rightTimeBar, na,
trailing.top))
topLabel.set_text( swingTrend.bias == BEARISH ? 'Strong
High' : 'Weak High')
bottomLine.set_first_point(
chart.point.new(trailing.lastBottomTime, na, trailing.bottom))
bottomLine.set_second_point(chart.point.new(rightTimeBar, na,
trailing.bottom))
bottomLabel.set_point( chart.point.new(rightTimeBar, na,
trailing.bottom))
bottomLabel.set_text( swingTrend.bias == BULLISH ? 'Strong
Low' : 'Weak Low')
b_ox.set_top_left_point(
chart.point.new(trailing.barTime,na,top))
b_ox.set_bottom_right_point(chart.point.new(last_bar_time,na,bottom))
l_abel.set_point(
chart.point.new(na,labelIndex,labelLevel))
drawZone(trailing.bottom, math.round(0.5*(trailing.barIndex +
last_bar_index)), 0.95*trailing.bottom + 0.05*trailing.top,
trailing.bottom, 'Discount', discountZoneColor, label.style_label_up)
//--------------------------------------------------------------------
-------------------------------------------------}
//MUTABLE VARIABLES & EXECUTION
//--------------------------------------------------------------------
-------------------------------------------------{
parsedOpen = showTrendInput ? open : na
candleColor = internalTrend.bias == 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 barstate.islastconfirmedhistory or barstate.islast
if showInternalOrderBlocksInput
drawOrderBlocks(true)
if showSwingOrderBlocksInput
drawOrderBlocks()
lastBarIndex := currentBarIndex
currentBarIndex := bar_index
newBar = currentBarIndex != lastBarIndex
drawLevels('D',timeframe.isdaily,dailyLevelsStyleInput,dailyLevelsColo
rInput)
drawLevels('W',timeframe.isweekly,weeklyLevelsStyleInput,weeklyLevelsC
olorInput)
drawLevels('M',timeframe.ismonthly,monthlyLevelsStyleInput,monthlyLeve
lsColorInput)
//--------------------------------------------------------------------
-------------------------------------------------}
//ALERTS
//--------------------------------------------------------------------
-------------------------------------------------{
alertcondition(currentAlerts.internalBullishBOS, 'Internal
Bullish BOS', 'Internal Bullish BOS formed')
alertcondition(currentAlerts.internalBullishCHoCH, 'Internal
Bullish CHoCH', 'Internal Bullish CHoCH formed')
alertcondition(currentAlerts.internalBearishBOS, 'Internal
Bearish BOS', 'Internal Bearish BOS formed')
alertcondition(currentAlerts.internalBearishCHoCH, 'Internal
Bearish CHoCH', 'Internal Bearish CHoCH formed')
alertcondition(currentAlerts.internalBullishOrderBlock, 'Bullish
Internal OB Breakout', 'Price broke bullish internal OB')
alertcondition(currentAlerts.internalBearishOrderBlock, 'Bearish
Internal OB Breakout', 'Price broke bearish internal OB')
alertcondition(currentAlerts.swingBullishOrderBlock, 'Bullish Swing
OB Breakout', 'Price broke bullish swing OB')
alertcondition(currentAlerts.swingBearishOrderBlock, 'Bearish Swing
OB Breakout', 'Price broke bearish swing OB')
alertcondition(currentAlerts.equalHighs, 'Equal Highs',
'Equal highs detected')
alertcondition(currentAlerts.equalLows, 'Equal Lows',
'Equal lows detected')
//--------------------------------------------------------------------
-------------------------------------------------}