Best Indicator
Best Indicator
t = time("1440", session.regular)
var int startTime =time
int ncandles =0
if barstate.isfirst
startTime := timenow - period_time*86400000
bar_offset:= ta.barssince(is_first_inRange)
is_first = na(t[1]) and not na(t) or t[1] < t
is_first_inRange:=is_first and t>startTime
high_price=0.0
low_price=0.0
price_level=0.0
if is_first_inRange or barstate.islast
last_time:= t[1]
ncandles := bar_offset
current_low_price=0.0
for i = 1 to (ncandles)
current_low_price:=low[i]
if current_low_price < low_price or low_price==0.0
low_price:=current_low_price
current_high_price=0.0
for i = 1 to (ncandles)
current_high_price:=high[i]
if current_high_price >high_price or high_price==0.0
high_price:=current_high_price
diff := (high_price-low_price)/resolution
for j = 0 to (resolution)
array.set(range_prices, (j), (low_price + (diff * (j+1))))
for i = 0 to (ncandles)
int w_candle = 0
array.fill(partial_vol, 0.0)
for j = 0 to (resolution - 1)
float j_total_vol = array.get(total_vol, j)
float j_partial_vol = array.get(partial_vol, j)
float sum_partial_total=0.0
if w_candle > 0
sum_partial_total := j_total_vol + j_partial_vol/w_candle
else
sum_partial_total := j_total_vol
array.set(total_vol, j, sum_partial_total)
maxV := array.max(total_vol)
maxV_index := array.indexof(total_vol, maxV)
if is_first_inRange
price_level:=diff*maxV_index+low_price
if high_price - price_level > price_level - low_price
margin:=high_price - price_level
ys:=price_level - margin
else
margin:=price_level - low_price
ys:=price_level + margin
if ys > high_price
array.shift(is_support)
array.push(is_support, false)
else
array.shift(is_support)
array.push(is_support, true)
array.shift(all_ys)
array.push(all_ys, ys)
array.shift(ys_time)
array.push(ys_time, t)
// if barstate.islast
// for i=0 to (show_from - 1)
// ys := array.get(all_ys, i)
// time_back = array.get(ys_time, i)
// if array.get(is_support, i)
// if show_support_line
// line.new(x1=int(time_back), y1=ys, x2=time + 86400000,
y2=ys, color=sup_color ,xloc= xloc.bar_time, extend = extend.none, width=2,
style=line.style_dashed)
// else
// if show_res_line
// line.new(x1=int(time_back), y1=ys, x2=time + 86400000,
y2=ys, color=res_color ,xloc= xloc.bar_time, extend = extend.none, width=2,
style=line.style_dashed)
// if show_labels
// label.new(int(time + 86400000), ys, text ="From days: " +
str.tostring(show_from - i), xloc=xloc.bar_time)
dif_time=0.0
if is_first_inRange or barstate.islast
last_time:= int(t[1])
dif_time:= (time-last_time)
if dif_time/86400000 > 1.5
dif_time:=(dif_time)/9
else
dif_time:=(dif_time)/3
diff_t=0
x1=0.0
norm_vol=0.0
proportion=resolution/bar_count
for i = 0 to (resolution - 1)
y=array.get(range_prices,i)
current_vol= array.get(total_vol,i)
norm_vol :=current_vol/maxV
x1 :=dif_time*norm_vol
diff_t := last_time + int(x1)
if (i % int(proportion) == 0 or int(proportion) == 0) and
show_volume_bars
line.new(x1=t[1], y1=y, x2=diff_t, y2=y,
color=volume_bars_color ,xloc= xloc.bar_time, extend = extend.none, width=2)
if show_L_line
line.new(x1=t[1], y1=low_price, x2=time, y2=low_price,xloc=
xloc.bar_time, color=high_low_color)
if show_vpoc_line
line.new(x1=t[1], y1=diff*maxV_index+low_price, x2=time,
y2=diff*maxV_index+low_price, color=vpoc_color, width=2,xloc= xloc.bar_time)
if show_H_line
line.new(x1=t[1], y1=high_price, x2=time, y2=high_price,xloc=
xloc.bar_time, color=high_low_color)
///////////////////////////////////////////////////////////////////////////////////
/////
is_new_bar(t) =>
ta.change(time(t)) != 0
round_to_nearest(v, x) =>
math.round(v / x) * x
var a = array.new_float(0)
a_min = 0.0
a_min := nz(a_min[1], round_to_nearest(low, tick_size))
a_max = 0.0
a_max := nz(a_max[1], round_to_nearest(high, tick_size))
d_switch = is_new_bar(dtf)
if d_switch
a_min := low
a_max := high
array.clear(a)
// Array bounds
a_min := math.min(a_min, round_to_nearest(low, tick_size))
a_max := math.max(a_max, round_to_nearest(high, tick_size))
a_size = array.size(a)
// POC
poc_index = -1
poc_prev = -1.0
sum_vol = 0.0
for i = 0 to a_size - 1 by 1
poc_current = array.get(a, i)
sum_vol += poc_current
if array.size(uppocs) > 0
for i = 0 to array.size(uppocs) - 1 by 1
myuppoc = array.get(uppocs, i)
if myuppoc > low
line.delete(array.get(uplines, i))
if array.size(downpocs) > 0
for i = 0 to array.size(downpocs) - 1 by 1
mydownpoc = array.get(downpocs, i)
if mydownpoc < high
line.delete(array.get(downlines, i))
///////////////////
//Key Levels
///////////////////////////////////////////////////
displayStyle = input.string(defval='Standard', title='Display Style',
options=['Standard', 'Right Anchored'], inline='Display')
mergebool = input.bool(defval=true, title='Merge Levels?', inline='Display')
distanceright = input.int(defval=30, title='Distance', minval=5, maxval=500,
inline='Dist')
radistance = input.int(defval=250, title='Anchor Distance', minval=5, maxval=500,
inline='Dist')
labelsize = input.string(defval='Medium', title='Text Size', options=['Small',
'Medium', 'Large'])
linesize = input.string(defval='Small', title='Line Width', options=['Small',
'Medium', 'Large'], inline='Line')
linestyle = input.string(defval='Solid', title='Line Style', options=['Solid',
'Dashed', 'Dotted'], inline='Line')
if globalcoloring == true
DailyColor := GlobalColor
MondayColor := GlobalColor
WeeklyColor := GlobalColor
MonthlyColor := GlobalColor
YearlyColor := GlobalColor
IntraColor := GlobalColor
IntraColor
if weekly_time != weekly_time[1]
untested_monday := false
untested_monday
linewidthint = 1
if linesize == 'Small'
linewidthint := 1
linewidthint
if linesize == 'Medium'
linewidthint := 2
linewidthint
if linesize == 'Large'
linewidthint := 3
linewidthint
fontsize = size.small
if labelsize == 'Small'
fontsize := size.small
fontsize
if labelsize == 'Medium'
fontsize := size.normal
fontsize
if labelsize == 'Large'
fontsize := size.large
fontsize
linestyles = line.style_solid
if linestyle == 'Dashed'
linestyles := line.style_dashed
linestyles
if linestyle == 'Dotted'
linestyles := line.style_dotted
linestyles
get_limit_right(bars) =>
timenow + (time - time[1]) * bars
//////////////////////////////////////////////////////////////////////////////////
if can_draw_intra
intra_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
if displayStyle == 'Right Anchored'
intra_time := get_limit_right(radistance)
intra_time
line.set_x1(intra_line, intra_time)
line.set_x2(intra_line, intra_limit_right)
line.set_y1(intra_line, intra_open)
line.set_y2(intra_line, intra_open)
label.set_x(intra_label, intra_limit_right)
label.set_y(intra_label, intra_open)
label.set_text(intra_label, iotext)
if mergebool
f_LevelMerge(pricearray, labelarray, intra_open, intra_label,
IntraColor)
//////////////////////////////////////////////////////////////////////////////////
//HIGH HIGH HIGH HIGH HIGH HIGH HIGH HIGH HIGH HIGH HIGH HIGH HIGH HIGH HIGH HIGH
if can_draw_intrah
intrah_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
if displayStyle == 'Right Anchored'
intrah_time := get_limit_right(radistance)
intrah_time
line.set_x1(intrah_line, intrah_time)
line.set_x2(intrah_line, intrah_limit_right)
line.set_y1(intrah_line, intrah_open)
line.set_y2(intrah_line, intrah_open)
label.set_x(intrah_label, intrah_limit_right)
label.set_y(intrah_label, intrah_open)
label.set_text(intrah_label, pihtext)
if mergebool
f_LevelMerge(pricearray, labelarray, intrah_open, intrah_label,
IntraColor)
//////////////////////////////////////////////////////////////////////////////////
//LOW LOW LOW LOW LOW LOW LOW LOW LOW LOW LOW LOW LOW LOW LOW LOW
if can_draw_intral
intral_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
if displayStyle == 'Right Anchored'
intral_time := get_limit_right(radistance)
intral_time
line.set_x1(intral_line, intral_time)
line.set_x2(intral_line, intral_limit_right)
line.set_y1(intral_line, intral_open)
line.set_y2(intral_line, intral_open)
label.set_x(intral_label, intral_limit_right)
label.set_y(intral_label, intral_open)
label.set_text(intral_label, piltext)
if mergebool
f_LevelMerge(pricearray, labelarray, intral_open, intral_label,
IntraColor)
///////////////////////////////////////////////////////////////////////////////
if can_draw_intram
intram_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
intram_time = intrah_time
intram_open = (intral_open + intrah_open) / 2
if displayStyle == 'Right Anchored'
intram_time := get_limit_right(radistance)
intram_time
var intram_line = line.new(x1=intram_time, x2=intram_limit_right,
y1=intram_open, y2=intram_open, color=IntraColor, width=DEFAULT_LINE_WIDTH,
xloc=xloc.bar_time, style=linestyles)
var intram_label = label.new(x=intram_limit_right, y=intram_open,
text=pimtext, style=DEFAULT_LABEL_STYLE, textcolor=IntraColor,
size=DEFAULT_LABEL_SIZE, xloc=xloc.bar_time)
line.set_x1(intram_line, intram_time)
line.set_x2(intram_line, intram_limit_right)
line.set_y1(intram_line, intram_open)
line.set_y2(intram_line, intram_open)
label.set_x(intram_label, intram_limit_right)
label.set_y(intram_label, intram_open)
label.set_text(intram_label, pimtext)
if mergebool
f_LevelMerge(pricearray, labelarray, intram_open, intram_label,
IntraColor)
////////////////////////////////////////// MONDAY
if is_monday_enabled
monday_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
if displayStyle == 'Right Anchored'
monday_time := get_limit_right(radistance)
monday_time
line.set_x1(monday_line, monday_time)
line.set_x2(monday_line, monday_limit_right)
line.set_y1(monday_line, monday_high)
line.set_y2(monday_line, monday_high)
label.set_x(monday_label, monday_limit_right)
label.set_y(monday_label, monday_high)
label.set_text(monday_label, pmonhtext)
if mergebool
f_LevelMerge(pricearray, labelarray, monday_high, monday_label,
MondayColor)
if is_monday_enabled
monday_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
if displayStyle == 'Right Anchored'
monday_time := get_limit_right(radistance)
monday_time
line.set_x1(monday_low_line, monday_time)
line.set_x2(monday_low_line, monday_limit_right)
line.set_y1(monday_low_line, monday_low)
line.set_y2(monday_low_line, monday_low)
label.set_x(monday_low_label, monday_limit_right)
label.set_y(monday_low_label, monday_low)
label.set_text(monday_low_label, pmonltext)
if mergebool
f_LevelMerge(pricearray, labelarray, monday_low, monday_low_label,
MondayColor)
if is_monday_mid
mondaym_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
line.set_x1(daily_line, daily_time)
line.set_x2(daily_line, daily_limit_right)
line.set_y1(daily_line, daily_open)
line.set_y2(daily_line, daily_open)
label.set_x(daily_label, daily_limit_right)
label.set_y(daily_label, daily_open)
label.set_text(daily_label, dotext)
if mergebool
f_LevelMerge(pricearray, labelarray, daily_open, daily_label,
DailyColor)
//////////////////////////////////////////////////////////////////////////////////
//////////////////DAILY HIGH DAILY HIGH DAILY HIGH DAILY HIGH DAILY HIGH DAILY HIGH
DAILY HIGH
if is_dailyrange_enabled
dailyh_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
if displayStyle == 'Right Anchored'
dailyh_time := get_limit_right(radistance)
dailyh_time
// draw tails before lines for better visual
line.set_x1(dailyh_line, dailyh_time)
line.set_x2(dailyh_line, dailyh_limit_right)
line.set_y1(dailyh_line, dailyh_open)
line.set_y2(dailyh_line, dailyh_open)
label.set_x(dailyh_label, dailyh_limit_right)
label.set_y(dailyh_label, dailyh_open)
label.set_text(dailyh_label, pdhtext)
if mergebool
f_LevelMerge(pricearray, labelarray, dailyh_open, dailyh_label,
DailyColor)
//////////////////////////////////////////////////////////////////////////////////
//////////////////DAILY LOW DAILY LOW DAILY LOW DAILY LOW DAILY LOW DAILY LOW DAILY
LOW DAILY LOW
if is_dailyrange_enabled
dailyl_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
if displayStyle == 'Right Anchored'
dailyl_time := get_limit_right(radistance)
dailyl_time
line.set_x1(dailyl_line, dailyl_time)
line.set_x2(dailyl_line, dailyl_limit_right)
line.set_y1(dailyl_line, dailyl_open)
line.set_y2(dailyl_line, dailyl_open)
label.set_x(dailyl_label, dailyl_limit_right)
label.set_y(dailyl_label, dailyl_open)
label.set_text(dailyl_label, pdltext)
if mergebool
f_LevelMerge(pricearray, labelarray, dailyl_open, dailyl_label,
DailyColor)
////////////////////////////////////////////////////////////////////////////////
Daily MID
if is_dailym_enabled
dailym_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
dailym_time = dailyh_time
dailym_open = (dailyl_open + dailyh_open) / 2
if displayStyle == 'Right Anchored'
dailym_time := get_limit_right(radistance)
dailym_time
var dailym_line = line.new(x1=dailym_time, x2=dailym_limit_right,
y1=dailym_open, y2=dailym_open, color=DailyColor, width=DEFAULT_LINE_WIDTH,
xloc=xloc.bar_time, style=linestyles)
var dailym_label = label.new(x=dailym_limit_right, y=dailym_open,
text=pdmtext, style=DEFAULT_LABEL_STYLE, textcolor=DailyColor,
size=DEFAULT_LABEL_SIZE, xloc=xloc.bar_time)
line.set_x1(dailym_line, dailym_time)
line.set_x2(dailym_line, dailym_limit_right)
line.set_y1(dailym_line, dailym_open)
line.set_y2(dailym_line, dailym_open)
label.set_x(dailym_label, dailym_limit_right)
label.set_y(dailym_label, dailym_open)
label.set_text(dailym_label, pdmtext)
if mergebool
f_LevelMerge(pricearray, labelarray, dailym_open, dailym_label,
DailyColor)
//////////////////////////////////////////////////////////////////////////////////
if is_weekly_enabled
weekly_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
cweekly_time = weekly_time
if displayStyle == 'Right Anchored'
cweekly_time := get_limit_right(radistance)
cweekly_time
line.set_x1(weekly_line, cweekly_time)
line.set_x2(weekly_line, weekly_limit_right)
line.set_y1(weekly_line, weekly_open)
line.set_y2(weekly_line, weekly_open)
label.set_x(weekly_label, weekly_limit_right)
label.set_y(weekly_label, weekly_open)
label.set_text(weekly_label, wotext)
if mergebool
f_LevelMerge(pricearray, labelarray, weekly_open, weekly_label,
WeeklyColor)
// the weekly open can be the daily open too (monday)
// only the weekly will be draw, in these case we update its label
// if is_weekly_open and can_show_daily
// label.set_text(weekly_label, "DO / WO ")
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
WEEKLY HIGH WEEKLY HIGH WEEKLY HIGH
if is_weeklyrange_enabled
weeklyh_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
if displayStyle == 'Right Anchored'
weeklyh_time := get_limit_right(radistance)
weeklyh_time
line.set_x1(weeklyh_line, weeklyh_time)
line.set_x2(weeklyh_line, weeklyh_limit_right)
line.set_y1(weeklyh_line, weeklyh_open)
line.set_y2(weeklyh_line, weeklyh_open)
label.set_x(weeklyh_label, weeklyh_limit_right)
label.set_y(weeklyh_label, weeklyh_open)
label.set_text(weeklyh_label, pwhtext)
if mergebool
f_LevelMerge(pricearray, labelarray, weeklyh_open, weeklyh_label,
WeeklyColor)
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
WEEKLY LOW WEEKLY LOW WEEKLY LOW
if is_weeklyrange_enabled
weeklyl_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
if displayStyle == 'Right Anchored'
weeklyl_time := get_limit_right(radistance)
weeklyl_time
line.set_x1(weeklyl_line, weeklyl_time)
line.set_x2(weeklyl_line, weeklyl_limit_right)
line.set_y1(weeklyl_line, weeklyl_open)
line.set_y2(weeklyl_line, weeklyl_open)
label.set_x(weeklyl_label, weeklyl_limit_right)
label.set_y(weeklyl_label, weeklyl_open)
label.set_text(weeklyl_label, pwltext)
if mergebool
f_LevelMerge(pricearray, labelarray, weeklyl_open, weeklyl_label,
WeeklyColor)
//////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Weekly MID
if is_weekly_mid
weeklym_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
weeklym_time = weeklyh_time
weeklym_open = (weeklyl_open + weeklyh_open) / 2
if displayStyle == 'Right Anchored'
weeklym_time := get_limit_right(radistance)
weeklym_time
line.set_x1(monthlyl_line, monthlyl_time)
line.set_x2(monthlyl_line, monthlyl_limit_right)
line.set_y1(monthlyl_line, monthlyl_open)
line.set_y2(monthlyl_line, monthlyl_open)
label.set_x(monthlyl_label, monthlyl_limit_right)
label.set_y(monthlyl_label, monthlyl_open)
label.set_text(monthlyl_label, pmltext)
if mergebool
f_LevelMerge(pricearray, labelarray, monthlyl_open, monthlyl_label,
MonthlyColor)
// the weekly open can be the daily open too (monday)
// only the weekly will be draw, in these case we update its label
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
MONTHLY HIGH HIGH HIGH
if is_monthlyrange_enabled
monthlyh_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
if displayStyle == 'Right Anchored'
monthlyh_time := get_limit_right(radistance)
monthlyh_time
line.set_x1(monthlyh_line, monthlyl_time)
line.set_x2(monthlyh_line, monthlyh_limit_right)
line.set_y1(monthlyh_line, monthlyh_open)
line.set_y2(monthlyh_line, monthlyh_open)
label.set_x(monthlyh_label, monthlyh_limit_right)
label.set_y(monthlyh_label, monthlyh_open)
label.set_text(monthlyh_label, pmhtext)
if mergebool
f_LevelMerge(pricearray, labelarray, monthlyh_open, monthlyh_label,
MonthlyColor)
// the weekly open can be the daily open too (monday)
// only the weekly will be draw, in these case we update its label
////////////////////////////////////////////////////////////////////////////////
MONTHLY MID
if is_monthly_mid
monthlym_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
monthlym_time = monthlyh_time
monthlym_open = (monthlyl_open + monthlyh_open) / 2
if displayStyle == 'Right Anchored'
monthlym_time := get_limit_right(radistance)
monthlym_time
var monthlym_line = line.new(x1=monthlym_time, x2=monthlym_limit_right,
y1=monthlym_open, y2=monthlym_open, color=MonthlyColor, width=DEFAULT_LINE_WIDTH,
xloc=xloc.bar_time, style=linestyles)
var monthlym_label = label.new(x=monthlym_limit_right, y=monthlym_open,
text=pmmtext, style=DEFAULT_LABEL_STYLE, textcolor=MonthlyColor,
size=DEFAULT_LABEL_SIZE, xloc=xloc.bar_time)
line.set_x1(monthlym_line, monthlym_time)
line.set_x2(monthlym_line, monthlym_limit_right)
line.set_y1(monthlym_line, monthlym_open)
line.set_y2(monthlym_line, monthlym_open)
label.set_x(monthlym_label, monthlym_limit_right)
label.set_y(monthlym_label, monthlym_open)
label.set_text(monthlym_label, pmmtext)
if mergebool
f_LevelMerge(pricearray, labelarray, monthlym_open, monthlym_label,
MonthlyColor)
//////////////////////////////////////////////////////////////////////////////////
if is_monthly_enabled
monthly_limit_right = get_limit_right(DEFAULT_EXTEND_RIGHT)
if displayStyle == 'Right Anchored'
monthly_time := get_limit_right(radistance)
monthly_time
line.set_x1(monthlyLine, monthly_time)
line.set_x2(monthlyLine, monthly_limit_right)
line.set_y1(monthlyLine, monthly_open)
line.set_y2(monthlyLine, monthly_open)
label.set_x(monthlyLabel, monthly_limit_right)
label.set_y(monthlyLabel, monthly_open)
label.set_text(monthlyLabel, motext)
if mergebool
f_LevelMerge(pricearray, labelarray, monthly_open, monthlyLabel,
MonthlyColor)
/////////////////////////////////////////////////////////////////////////////
// the monthly open can be the weekly open (monday 1st) and/or daily open
too
// only the monthly will be draw, in these case we update its label
// if is_monthly_open
// if can_show_daily
// label.set_text(monthlyLabel, "DO / MO ")
// if is_weekly_open
// if can_show_weekly
// label.set_text(monthlyLabel, "WO / MO ")
// if can_show_daily and can_show_weekly
// label.set_text(monthlyLabel, "DO / WO / MO ")
// the start of the line is drew from the first week of the month
// if the first day of the weekly candle (monday) is the 2nd of the month
// we fix the start of the line position on the Prev weekly candle
if timeframe.isweekly and dayofweek(monthly_time) != dayofweek.monday
line.set_x1(monthlyLine, monthly_time - (weekly_time - weekly_time[1]))
//////////////////////////////////////////////////////////////////////////////////
//Smart Money Concept
//-----------------------------------------------------------------------------{
//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 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'
//-----------------------------------------------------------------------------{
//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(true, '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)
//Bear Structure
show_ibear = input.string('All', 'Bearish Structure'
, options = ['All', 'BOS', 'CHoCH']
, inline = 'ibear'
, group = 'Real Time Internal Structure')
//----------------------------------------}
//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')
//Bear Structure
show_bear = input.string('All', 'Bearish Structure'
, options = ['All', 'BOS', 'CHoCH']
, 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)
// //----------------------------------------}
// //EQH/EQL
// //----------------------------------------{
// show_eq = input(true, 'Equal High/Low'
// , group = 'EQH/EQL'
// , tooltip = SHOW_EQHL)
//----------------------------------------}
//Fair Value Gaps
//----------------------------------------{
show_fvg = input(true, 'Fair Value Gaps'
, group = 'Fair Value Gaps'
, tooltip = SHOW_FVG)
//-----------------------------------------------------------------------------}
//Functions
//-----------------------------------------------------------------------------{
n = bar_index
atr = ta.atr(200)
cmean_range = ta.cum(high - low) / n
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)
[top, btm]
//Line Style function
get_line_style(style) =>
out = switch style
'⎯⎯⎯' => line.style_solid
'----' => line.style_dashed
'····' => line.style_dotted
//-----------------------------------------------------------------------------}
//Global variables
//-----------------------------------------------------------------------------{
var trend = 0, var itrend = 0
//Structure colors
var bull_css = style == 'Monochrome' ? #b2b5be
: swing_bull_css
//Labels size
var internal_structure_lbl_size = internal_structure_size == 'Tiny'
? size.tiny
: internal_structure_size == 'Small'
? size.small
: size.normal
//-----------------------------------------------------------------------------}
//Pivot High
//-----------------------------------------------------------------------------{
var line extend_top = na
if top
top_cross := true
txt_top := top > top_y ? 'HH' : 'LH'
if show_swings
top_lbl = label.new(n-length, top, txt_top
, color = TRANSP_CSS
, textcolor = bear_css
, style = label.style_label_down
, size = swing_structure_lbl_size)
if mode == 'Present'
label.delete(top_lbl[1])
top_y := top
top_x := n - length
trail_up := top
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
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
if btm
btm_cross := true
txt_btm := btm < btm_y ? 'LL' : 'HL'
if show_swings
btm_lbl = label.new(n - length, btm, txt_btm
, color = TRANSP_CSS
, textcolor = bull_css
, style = label.style_label_up
, size = swing_structure_lbl_size)
if mode == 'Present'
label.delete(btm_lbl[1])
btm_y := btm
btm_x := n-length
trail_dn := btm
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
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')
//-----------------------------------------------------------------------------}
//Pivot High BOS/CHoCH
//-----------------------------------------------------------------------------{
//Filtering
var bull_concordant = true
if ifilter_confluence
bull_concordant := high - math.max(close, open) > math.min(close, open - low)
if itrend < 0
choch := true
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,
internal_structure_lbl_size)
itop_cross := false
itrend := 1
if trend < 0
choch := true
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,
swing_structure_lbl_size)
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)
if itrend > 0
choch := 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,
internal_structure_lbl_size)
ibtm_cross := false
itrend := -1
if trend > 0
choch := true
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,
swing_structure_lbl_size)
btm_cross := false
trend := -1
// //-----------------------------------------------------------------------------}
// //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 mode == 'Present'
// line.delete(eqh_line[1])
// label.delete(eqh_lbl[1])
// 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 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)
float bullish_fvg_avg = na
float bearish_fvg_avg = na
bullish_fvg_cnd = false
bearish_fvg_cnd = false
if show_fvg
delta_per = (src_c1 - src_o1) / src_o1 * 100
change_tf = timeframe.change(fvg_tf)
//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))
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))
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)))
//-----------------------------------------------------------------------------}
//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