0% found this document useful (1 vote)
1K views31 pages

Strategy ALGOX by Leo

Strategy ALGOX by Leo

Uploaded by

amrik51072
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 (1 vote)
1K views31 pages

Strategy ALGOX by Leo

Strategy ALGOX by Leo

Uploaded by

amrik51072
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/ 31

//@version=5

strategy('Strategy ALGOX by Leo', overlay = true, explicit_plot_zorder = true,


pyramiding = 0, default_qty_type = strategy.percent_of_equity, initial_capital =
1000, default_qty_value = 1, calc_on_every_tick = false, process_orders_on_close =
true)

G_SCRIPT01 = '■ ' + 'SAIYAN OCC'


//#region ———— <↓↓↓ G_SCRIPT01 ↓↓↓> {

// === INPUTS ===


res = input.timeframe('15', 'TIMEFRAME', group ="NON
REPAINT")
useRes = input(true, 'Use Alternate Signals')
intRes = input(10, 'Multiplier for Alernate
Signals')
basisType = input.string('ALMA', 'MA Type: ', options=['TEMA',
'HullMA', 'ALMA'])
basisLen = input.int(50, 'MA Period', minval=1)
offsetSigma = input.int(5, 'Offset for LSMA / Sigma for
ALMA', minval=0)
offsetALMA = input.float(2, 'Offset for ALMA', minval=0,
step=0.01)
scolor = input(false, 'Show coloured Bars to indicate
Trend?')
delayOffset = input.int(0, 'Delay Open/Close MA', minval=0,
step=1,
tooltip = 'Forces Non-Repainting')
tradeType = input.string('BOTH', 'What trades should be taken :
',
options = ['LONG', 'SHORT', 'BOTH', 'NONE'])
//=== /INPUTS ===
h = input(false, 'Signals for Heikin Ashi
Candles')
//INDICATOR SETTINGS
swing_length = input.int(10, 'Swing High/Low Length', group =
'Settings', minval = 1, maxval = 50)
history_of_demand_to_keep = input.int(20, 'History To Keep', minval = 5,
maxval = 50)
box_width = input.float(2.5, 'Supply/Demand Box Width', group
= 'Settings', minval = 1, maxval = 10, step = 0.5)

//INDICATOR VISUAL SETTINGS


show_zigzag = input.bool(false, 'Show Zig Zag', group = 'Visual
Settings', inline = '1')
show_price_action_labels = input.bool(false, 'Show Price Action Labels',
group = 'Visual Settings', inline = '2')

supply_color = input.color(#00000000, 'Supply', group = 'Visual


Settings', inline = '3')
supply_outline_color = input.color(#00000000, 'Outline', group = 'Visual
Settings', inline = '3')

demand_color = input.color(#00000000, 'Demand', group = 'Visual


Settings', inline = '4')
demand_outline_color = input.color(#00000000, 'Outline', group = 'Visual
Settings', inline = '4')
bos_label_color = input.color(#00000000, 'BOS Label', group = 'Visual
Settings', inline = '5')
poi_label_color = input.color(#00000000, 'POI Label', group = 'Visual
Settings', inline = '7')
poi_border_color = input.color(#00000000, 'POI border', group = 'Visual
Settings', inline = '7')
swing_type_color = input.color(#00000000, 'Price Action Label', group =
'Visual Settings', inline = '8')
zigzag_color = input.color(#00000000, 'Zig Zag', group = 'Visual
Settings', inline = '9')

//END SETTINGS

// FUNCTION TO ADD NEW AND REMOVE LAST IN ARRAY


f_array_add_pop(array, new_value_to_add) =>
array.unshift(array, new_value_to_add)
array.pop(array)

// FUNCTION SWING H & L LABELS


f_sh_sl_labels(array, swing_type) =>

var string label_text = na


if swing_type == 1
if array.get(array, 0) >= array.get(array, 1)
label_text := 'HH'
else
label_text := 'LH'
label.new(
bar_index - swing_length,
array.get(array,0),
text = label_text,
style = label.style_label_down,
textcolor = swing_type_color,
color = swing_type_color,
size = size.tiny)

else if swing_type == -1
if array.get(array, 0) >= array.get(array, 1)
label_text := 'HL'
else
label_text := 'LL'
label.new(
bar_index - swing_length,
array.get(array,0),
text = label_text,
style = label.style_label_up,
textcolor = swing_type_color,
color = swing_type_color,
size = size.tiny)

// FUNCTION MAKE SURE SUPPLY ISNT OVERLAPPING


f_check_overlapping(new_poi, box_array, atrValue) =>

atr_threshold = atrValue * 2
okay_to_draw = true

for i = 0 to array.size(box_array) - 1
top = box.get_top(array.get(box_array, i))
bottom = box.get_bottom(array.get(box_array, i))
poi = (top + bottom) / 2

upper_boundary = poi + atr_threshold


lower_boundary = poi - atr_threshold

if new_poi >= lower_boundary and new_poi <= upper_boundary


okay_to_draw := false
break
else
okay_to_draw := true
okay_to_draw

// FUNCTION TO DRAW SUPPLY OR DEMAND ZONE


f_supply_demand(value_array, bn_array, box_array, label_array, box_type, atrValue)
=>
atr_buffer = atrValue * (box_width / 10)
box_left = array.get(bn_array, 0)
box_right = bar_index
var float box_top = 0.00
var float box_bottom = 0.00
var float poi = 0.00
if box_type == 1
box_top := array.get(value_array, 0)
box_bottom := box_top - atr_buffer
poi := (box_top + box_bottom) / 2
else if box_type == -1
box_bottom := array.get(value_array, 0)
box_top := box_bottom + atr_buffer
poi := (box_top + box_bottom) / 2
okay_to_draw = f_check_overlapping(poi, box_array, atrValue)
// okay_to_draw = true
//delete oldest box, and then create a new box and add it to the array
if box_type == 1 and okay_to_draw
box.delete( array.get(box_array, array.size(box_array) - 1) )
f_array_add_pop(box_array, box.new( left = box_left, top = box_top, right =
box_right, bottom = box_bottom, border_color = supply_outline_color,
bgcolor = supply_color, extend = extend.right, text = 'SUPPLY',
text_halign = text.align_center, text_valign = text.align_center, text_color =
poi_label_color, text_size = size.small, xloc = xloc.bar_index))

box.delete( array.get(label_array, array.size(label_array) - 1) )


f_array_add_pop(label_array, box.new( left = box_left, top = poi, right =
box_right, bottom = poi, border_color = poi_border_color,
bgcolor = poi_border_color, extend = extend.right, text = 'POI',
text_halign = text.align_left, text_valign = text.align_center, text_color =
poi_label_color, text_size = size.small, xloc = xloc.bar_index))
else if box_type == -1 and okay_to_draw
box.delete( array.get(box_array, array.size(box_array) - 1) )
f_array_add_pop(box_array, box.new( left = box_left, top = box_top, right =
box_right, bottom = box_bottom, border_color = demand_outline_color,
bgcolor = demand_color, extend = extend.right, text = 'DEMAND',
text_halign = text.align_center, text_valign = text.align_center, text_color =
poi_label_color, text_size = size.small, xloc = xloc.bar_index))

box.delete( array.get(label_array, array.size(label_array) - 1) )


f_array_add_pop(label_array, box.new( left = box_left, top = poi, right =
box_right, bottom = poi, border_color = poi_border_color,
bgcolor = poi_border_color, extend = extend.right, text = 'POI',
text_halign = text.align_left, text_valign = text.align_center, text_color =
poi_label_color, text_size = size.small, xloc = xloc.bar_index))

// FUNCTION TO CHANGE SUPPLY/DEMAND TO A BOS IF BROKEN


f_sd_to_bos(box_array, bos_array, label_array, zone_type) =>

if zone_type == 1
for i = 0 to array.size(box_array) - 1
level_to_break = box.get_top(array.get(box_array,i))
// if ta.crossover(close, level_to_break)
if close >= level_to_break
copied_box = box.copy(array.get(box_array,i))
f_array_add_pop(bos_array, copied_box)
mid = (box.get_top(array.get(box_array,i)) +
box.get_bottom(array.get(box_array,i))) / 2
box.set_top(array.get(bos_array,0), mid)
box.set_bottom(array.get(bos_array,0), mid)
box.set_extend( array.get(bos_array,0), extend.none)
box.set_right( array.get(bos_array,0), bar_index)
box.set_text( array.get(bos_array,0), 'BOS' )
box.set_text_color( array.get(bos_array,0), bos_label_color)
box.set_text_size( array.get(bos_array,0), size.small)
box.set_text_halign( array.get(bos_array,0), text.align_center)
box.set_text_valign( array.get(bos_array,0), text.align_center)
box.delete(array.get(box_array, i))
box.delete(array.get(label_array, i))

if zone_type == -1
for i = 0 to array.size(box_array) - 1
level_to_break = box.get_bottom(array.get(box_array,i))
// if ta.crossunder(close, level_to_break)
if close <= level_to_break
copied_box = box.copy(array.get(box_array,i))
f_array_add_pop(bos_array, copied_box)
mid = (box.get_top(array.get(box_array,i)) +
box.get_bottom(array.get(box_array,i))) / 2
box.set_top(array.get(bos_array,0), mid)
box.set_bottom(array.get(bos_array,0), mid)
box.set_extend( array.get(bos_array,0), extend.none)
box.set_right( array.get(bos_array,0), bar_index)
box.set_text( array.get(bos_array,0), 'BOS' )
box.set_text_color( array.get(bos_array,0), bos_label_color)
box.set_text_size( array.get(bos_array,0), size.small)
box.set_text_halign( array.get(bos_array,0), text.align_center)
box.set_text_valign( array.get(bos_array,0), text.align_center)
box.delete(array.get(box_array, i))
box.delete(array.get(label_array, i))

// FUNCTION MANAGE CURRENT BOXES BY CHANGING ENDPOINT


f_extend_box_endpoint(box_array) =>

for i = 0 to array.size(box_array) - 1
box.set_right(array.get(box_array, i), bar_index + 100)

//
stratRes = timeframe.ismonthly ? str.tostring(timeframe.multiplier * intRes,
'###M') :
timeframe.isweekly ? str.tostring(timeframe.multiplier * intRes,
'###W') :
timeframe.isdaily ? str.tostring(timeframe.multiplier * intRes,
'###D') :
timeframe.isintraday ? str.tostring(timeframe.multiplier * intRes,
'####') :
'60'
src = h ? request.security(ticker.heikinashi(syminfo.tickerid),
timeframe.period, close, lookahead = barmerge.lookahead_off) : close

// CALCULATE ATR
atrValue = ta.atr(50)

// CALCULATE SWING HIGHS & SWING LOWS


swing_high = ta.pivothigh(high, swing_length, swing_length)
swing_low = ta.pivotlow(low, swing_length, swing_length)

// ARRAYS FOR SWING H/L & BN


var swing_high_values = array.new_float(5,0.00)
var swing_low_values = array.new_float(5,0.00)

var swing_high_bns = array.new_int(5,0)


var swing_low_bns = array.new_int(5,0)

// ARRAYS FOR SUPPLY / DEMAND


var current_supply_box = array.new_box(history_of_demand_to_keep, na)
var current_demand_box = array.new_box(history_of_demand_to_keep, na)

// ARRAYS FOR SUPPLY / DEMAND POI LABELS


var current_supply_poi = array.new_box(history_of_demand_to_keep, na)
var current_demand_poi = array.new_box(history_of_demand_to_keep, na)

// ARRAYS FOR BOS


var supply_bos = array.new_box(5, na)
var demand_bos = array.new_box(5, na)

//END CALCULATIONS

// NEW SWING HIGH


if not na(swing_high)

//MANAGE SWING HIGH VALUES


f_array_add_pop(swing_high_values, swing_high)
f_array_add_pop(swing_high_bns, bar_index[swing_length])
if show_price_action_labels
f_sh_sl_labels(swing_high_values, 1)

f_supply_demand(swing_high_values, swing_high_bns, current_supply_box,


current_supply_poi, 1, atrValue)

// NEW SWING LOW


else if not na(swing_low)

//MANAGE SWING LOW VALUES


f_array_add_pop(swing_low_values, swing_low)
f_array_add_pop(swing_low_bns, bar_index[swing_length])
if show_price_action_labels
f_sh_sl_labels(swing_low_values, -1)

f_supply_demand(swing_low_values, swing_low_bns, current_demand_box,


current_demand_poi, -1, atrValue)
f_sd_to_bos(current_supply_box, supply_bos, current_supply_poi, 1)
f_sd_to_bos(current_demand_box, demand_bos, current_demand_poi, -1)

f_extend_box_endpoint(current_supply_box)
f_extend_box_endpoint(current_demand_box)

channelBal = input.bool(false, "Channel Balance", group = "CHART")

lr_slope(_src, _len) =>


x = 0.0, y = 0.0, x2 = 0.0, xy = 0.0
for i = 0 to _len - 1
val = _src[i]
per = i + 1
x += per
y += val
x2 += per * per
xy += val * per
_slp = (_len * xy - x * y) / (_len * x2 - x * x)
_avg = y / _len
_int = _avg - _slp * x / _len + _slp
[_slp, _avg, _int]
lr_dev(_src, _len, _slp, _avg, _int) =>
upDev = 0.0, dnDev = 0.0
val = _int
for j = 0 to _len - 1
price = high[j] - val
if price > upDev
upDev := price
price := val - low[j]
if price > dnDev
dnDev := price
price := _src[j]
val += _slp
[upDev, dnDev]

//
[_, upperKC1, lowerKC1] = ta.kc(close, 80, 10.5)
[_, upperKC2, lowerKC2] = ta.kc(close, 80, 9.5)
[_, upperKC3, lowerKC3] = ta.kc(close, 80, 8)
[_, upperKC4, lowerKC4] = ta.kc(close, 80, 3)

barsL = 10
barsR = 10
pivotHigh = fixnan(ta.pivothigh(barsL, barsR)[1])
pivotLow = fixnan(ta.pivotlow(barsL, barsR)[1])
source = close, period = 150
[s, a, i] = lr_slope(source, period)
[upDev, dnDev] = lr_dev(source, period, s, a, i)

y1 = low - (ta.atr(30) * 2), y1B = low - ta.atr(30)


y2 = high + (ta.atr(30) * 2), y2B = high + ta.atr(30)
x1 = bar_index - period + 1, _y1 = i + s * (period - 1), x2 = bar_index, _y2 = i

//Functions
//Line Style function
get_line_style(style) =>
out = switch style
'???' => line.style_solid
'----' => line.style_dashed
' ' => line.style_dotted

//Function to get order block coordinates


get_coordinates(condition, top, btm, ob_val)=>
var ob_top = array.new_float(0)
var ob_btm = array.new_float(0)
var ob_avg = array.new_float(0)
var ob_left = array.new_int(0)

float ob = na

//Append coordinates to arrays


if condition
avg = math.avg(top, btm)

array.unshift(ob_top, top)
array.unshift(ob_btm, btm)
array.unshift(ob_avg, avg)

ob := ob_val

[ob_top, ob_btm, ob_avg, ob_left, ob]

//Function to remove mitigated order blocks from coordinate arrays


remove_mitigated(ob_top, ob_btm, ob_left, ob_avg, target, bull)=>
mitigated = false
target_array = bull ? ob_btm : ob_top

for element in target_array


idx = array.indexof(target_array, element)

if (bull ? target < element : target > element)


mitigated := true

array.remove(ob_top, idx)
array.remove(ob_btm, idx)
array.remove(ob_avg, idx)
array.remove(ob_left, idx)

mitigated

//Function to set order blocks


set_order_blocks(ob_top, ob_btm, ob_left, ob_avg, ext_last, bg_css, border_css,
lvl_css)=>
var ob_box = array.new_box(0)
var ob_lvl = array.new_line(0)

//Global elements
var os = 0
var target_bull = 0.
var target_bear = 0.

// Create non-repainting security function


rp_security(_symbol, _res, _src) =>
request.security(_symbol, _res, _src[barstate.isrealtime ? 1 : 0])

htfHigh = rp_security(syminfo.tickerid, res, high)


htfLow = rp_security(syminfo.tickerid, res, low)
// Main Indicator
// Functions
smoothrng(x, t, m) =>
wper = t * 2 - 1
avrng = ta.ema(math.abs(x - x[1]), t)
smoothrng = ta.ema(avrng, wper) * m
rngfilt(x, r) =>
rngfilt = x
rngfilt := x > nz(rngfilt[1]) ? x - r < nz(rngfilt[1]) ? nz(rngfilt[1]) : x - r
: x + r > nz(rngfilt[1]) ? nz(rngfilt[1]) : x + r
percWidth(len, perc) => (ta.highest(len) - ta.lowest(len)) * perc / 100
securityNoRep(sym, res, src) => request.security(sym, res, src, barmerge.gaps_off,
barmerge.lookahead_on)
swingPoints(prd) =>
pivHi = ta.pivothigh(prd, prd)
pivLo = ta.pivotlow (prd, prd)
last_pivHi = ta.valuewhen(pivHi, pivHi, 1)
last_pivLo = ta.valuewhen(pivLo, pivLo, 1)
hh = pivHi and pivHi > last_pivHi ? pivHi : na
lh = pivHi and pivHi < last_pivHi ? pivHi : na
hl = pivLo and pivLo > last_pivLo ? pivLo : na
ll = pivLo and pivLo < last_pivLo ? pivLo : na
[hh, lh, hl, ll]
f_chartTfInMinutes() =>
float _resInMinutes = timeframe.multiplier * (
timeframe.isseconds ? 1 :
timeframe.isminutes ? 1. :
timeframe.isdaily ? 60. * 24 :
timeframe.isweekly ? 60. * 24 * 7 :
timeframe.ismonthly ? 60. * 24 * 30.4375 : na)
f_kc(src, len, sensitivity) =>
basis = ta.sma(src, len)
span = ta.atr(len)
[basis + span * sensitivity, basis - span * sensitivity]
wavetrend(src, chlLen, avgLen) =>
esa = ta.ema(src, chlLen)
d = ta.ema(math.abs(src - esa), chlLen)
ci = (src - esa) / (0.015 * d)
wt1 = ta.ema(ci, avgLen)
wt2 = ta.sma(wt1, 3)
[wt1, wt2]
f_top_fractal(_src) => _src[4] < _src[2] and _src[3] < _src[2] and _src[2] >
_src[1] and _src[2] > _src[0]
f_bot_fractal(_src) => _src[4] > _src[2] and _src[3] > _src[2] and _src[2] <
_src[1] and _src[2] < _src[0]
top_fractal = f_top_fractal(src)
bot_fractal = f_bot_fractal(src)
f_fractalize (_src) => top_fractal ? 1 : bot_fractal ? -1 : 0
f_findDivs(src, topLimit, botLimit) =>
fractalTop = f_fractalize(src) > 0 and src[2] >= topLimit ? src[2] : na
fractalBot = f_fractalize(src) < 0 and src[2] <= botLimit ? src[2] : na
highPrev = ta.valuewhen(fractalTop, src[2], 0)[2]
highPrice = ta.valuewhen(fractalTop, high[2], 0)[2]
lowPrev = ta.valuewhen(fractalBot, src[2], 0)[2]
lowPrice = ta.valuewhen(fractalBot, low[2], 0)[2]
bearSignal = fractalTop and high[1] > highPrice and src[1] < highPrev
bullSignal = fractalBot and low[1] < lowPrice and src[1] > lowPrev
[bearSignal, bullSignal]
// Get user input
enableSR = input(false , "SR On/Off", group="SR")
colorSup = input(#00000000 , "Support Color", group="SR")
colorRes = input(#00000000 , "Resistance Color", group="SR")
strengthSR = input.int(2 , "S/R Strength", 1, group="SR")
lineStyle = input.string("Dotted", "Line Style", ["Solid", "Dotted", "Dashed"],
group="SR")
lineWidth = input.int(2 , "S/R Line Width", 1, group="SR")
useZones = input(true , "Zones On/Off", group="SR")
useHLZones = input(true , "High Low Zones On/Off", group="SR")
zoneWidth = input.int(2 , "Zone Width %", 0,
tooltip = "it's calculated using % of the distance between highest/lowest in
last 300 bars", group="SR")
expandSR = input(true , "Expand SR")
// Get components
rb = 10
prd = 284
ChannelW = 10
label_loc = 55
style = lineStyle == "Solid" ? line.style_solid :
lineStyle == "Dotted" ? line.style_dotted : line.style_dashed
ph = ta.pivothigh(rb, rb)
pl = ta.pivotlow (rb, rb)
sr_levels = array.new_float(21, na)
prdhighest = ta.highest(prd)
prdlowest = ta.lowest(prd)
cwidth = percWidth(prd, ChannelW)
zonePerc = percWidth(300, zoneWidth)
aas = array.new_bool(41, true)
u1 = 0.0, u1 := nz(u1[1])
d1 = 0.0, d1 := nz(d1[1])
highestph = 0.0, highestph := highestph[1]
lowestpl = 0.0, lowestpl := lowestpl[1]

var sr_levs = array.new_float(21, na)


label hlabel = na, label.delete(hlabel[1])
label llabel = na, label.delete(llabel[1])
var sr_lines = array.new_line(21, na)
var sr_linesH = array.new_line(21, na)
var sr_linesL = array.new_line(21, na)
var sr_linesF = array.new_linefill(21, na)
var sr_labels = array.new_label(21, na)
if (not na(ph) or not na(pl))
for x = 0 to array.size(sr_levels) - 1
array.set(sr_levels, x, na)
highestph := prdlowest
lowestpl := prdhighest
countpp = 0
for x = 0 to prd
if na(close[x])
break
if not na(ph[x]) or not na(pl[x])
highestph := math.max(highestph, nz(ph[x], prdlowest), nz(pl[x],
prdlowest))
lowestpl := math.min(lowestpl, nz(ph[x], prdhighest), nz(pl[x],
prdhighest))
countpp += 1
if countpp > 40
break
if array.get(aas, countpp)
upl = (not na(ph[x]) and (ph[x] != 0) ? high[x + rb] : low[x + rb])
+ cwidth
dnl = (not na(ph[x]) and (ph[x] != 0) ? high[x + rb] : low[x + rb])
- cwidth
u1 := countpp == 1 ? upl : u1
d1 := countpp == 1 ? dnl : d1
tmp = array.new_bool(41, true)
cnt = 0
tpoint = 0
for xx = 0 to prd
if na(close[xx])
break
if not na(ph[xx]) or not na(pl[xx])
chg = false
cnt += 1
if cnt > 40
break
if array.get(aas, cnt)
if not na(ph[xx])
if high[xx + rb] <= upl and high[xx + rb] >= dnl
tpoint += 1
chg := true
if not na(pl[xx])
if low[xx + rb] <= upl and low[xx + rb] >= dnl
tpoint += 1
chg := true
if chg and cnt < 41
array.set(tmp, cnt, false)
if tpoint >= strengthSR
for g = 0 to 40 by 1
if not array.get(tmp, g)
array.set(aas, g, false)
if (not na(ph[x]) and countpp < 21)
array.set(sr_levels, countpp, high[x + rb])
if (not na(pl[x]) and countpp < 21)
array.set(sr_levels, countpp, low[x + rb])
// Plot
var line highest_ = na, line.delete(highest_)
var line lowest_ = na, line.delete(lowest_)
var line highest_fill1 = na, line.delete(highest_fill1)
var line highest_fill2 = na, line.delete(highest_fill2)
var line lowest_fill1 = na, line.delete(lowest_fill1)
var line lowest_fill2 = na, line.delete(lowest_fill2)
hi_col = close >= highestph ? colorSup : colorRes
lo_col = close >= lowestpl ? colorSup : colorRes
if enableSR
highest_ := line.new(bar_index - 311, highestph, bar_index, highestph,
xloc.bar_index, expandSR ? extend.both : extend.right, hi_col, style, lineWidth)
lowest_ := line.new(bar_index - 311, lowestpl , bar_index, lowestpl ,
xloc.bar_index, expandSR ? extend.both : extend.right, lo_col, style, lineWidth)
if useHLZones
highest_fill1 := line.new(bar_index - 311, highestph + zonePerc, bar_index,
highestph + zonePerc, xloc.bar_index, expandSR ? extend.both : extend.right, na)
highest_fill2 := line.new(bar_index - 311, highestph - zonePerc, bar_index,
highestph - zonePerc, xloc.bar_index, expandSR ? extend.both : extend.right, na)
lowest_fill1 := line.new(bar_index - 311, lowestpl + zonePerc , bar_index,
lowestpl + zonePerc , xloc.bar_index, expandSR ? extend.both : extend.right, na)
lowest_fill2 := line.new(bar_index - 311, lowestpl - zonePerc , bar_index,
lowestpl - zonePerc , xloc.bar_index, expandSR ? extend.both : extend.right, na)
linefill.new(highest_fill1, highest_fill2, hi_col)
linefill.new(lowest_fill1 , lowest_fill2 , lo_col)
if (not na(ph) or not na(pl))
for x = 0 to array.size(sr_lines) - 1
array.set(sr_levs, x, array.get(sr_levels, x))
for x = 0 to array.size(sr_lines) - 1
line.delete(array.get(sr_lines, x))
line.delete(array.get(sr_linesH, x))
line.delete(array.get(sr_linesL, x))
linefill.delete(array.get(sr_linesF, x))
if (not na(array.get(sr_levs, x)) and enableSR)
line_col = close >= array.get(sr_levs, x) ? colorSup : colorRes
array.set(sr_lines, x, line.new(bar_index - 355, array.get(sr_levs, x),
bar_index, array.get(sr_levs, x), xloc.bar_index, expandSR ? extend.both :
extend.right, line_col, style, lineWidth))
if useZones
array.set(sr_linesH, x, line.new(bar_index - 355, array.get(sr_levs, x)
+ zonePerc, bar_index, array.get(sr_levs, x) + zonePerc, xloc.bar_index, expandSR ?
extend.both : extend.right, na))
array.set(sr_linesL, x, line.new(bar_index - 355, array.get(sr_levs, x)
- zonePerc, bar_index, array.get(sr_levs, x) - zonePerc, xloc.bar_index, expandSR ?
extend.both : extend.right, na))
array.set(sr_linesF, x, linefill.new(array.get(sr_linesH, x),
array.get(sr_linesL, x), line_col))
for x = 0 to array.size(sr_labels) - 1
label.delete(array.get(sr_labels, x))
if (not na(array.get(sr_levs, x)) and enableSR)
lab_loc = close >= array.get(sr_levs, x) ? label.style_label_up :
label.style_label_down
lab_col = close >= array.get(sr_levs, x) ? colorSup : colorRes
array.set(sr_labels, x, label.new(bar_index + label_loc, array.get(sr_levs,
x), str.tostring(math.round_to_mintick(array.get(sr_levs, x))), color=lab_col ,
textcolor=#000000, style=lab_loc))
hlabel := enableSR ? label.new(bar_index + label_loc +
math.round(math.sign(label_loc)) * 20, highestph, "High Level : " +
str.tostring(highestph), color=hi_col, textcolor=#000000,
style=label.style_label_down) : na
llabel := enableSR ? label.new(bar_index + label_loc +
math.round(math.sign(label_loc)) * 20, lowestpl , "Low Level : " +
str.tostring(lowestpl) , color=lo_col, textcolor=#000000,
style=label.style_label_up ) : na

// Get components
rsi = ta.rsi(close, 28)
//rsiOb = rsi > 78 and rsi > ta.ema(rsi, 10)
//rsiOs = rsi < 27 and rsi < ta.ema(rsi, 10)
rsiOb = rsi > 65 and rsi > ta.ema(rsi, 10)
rsiOs = rsi < 35 and rsi < ta.ema(rsi, 10)
dHigh = securityNoRep(syminfo.tickerid, "D", high [1])
dLow = securityNoRep(syminfo.tickerid, "D", low [1])
dClose = securityNoRep(syminfo.tickerid, "D", close[1])
ema = ta.ema(close, 144)
emaBull = close > ema
equal_tf(res) => str.tonumber(res) == f_chartTfInMinutes() and not
timeframe.isseconds
higher_tf(res) => str.tonumber(res) > f_chartTfInMinutes() or timeframe.isseconds
too_small_tf(res) => (timeframe.isweekly and res=="1") or (timeframe.ismonthly and
str.tonumber(res) < 10)
securityNoRep1(sym, res, src) =>
bool bull_ = na
bull_ := equal_tf(res) ? src : bull_
bull_ := higher_tf(res) ? request.security(sym, res, src, barmerge.gaps_off,
barmerge.lookahead_on) : bull_
bull_array = request.security_lower_tf(syminfo.tickerid, higher_tf(res) ?
str.tostring(f_chartTfInMinutes()) + (timeframe.isseconds ? "S" : "") :
too_small_tf(res) ? (timeframe.isweekly ? "3" : "10") : res, src)
if array.size(bull_array) > 1 and not equal_tf(res) and not higher_tf(res)
bull_ := array.pop(bull_array)
array.clear(bull_array)
bull_

// === BASE FUNCTIONS ===


// Returns MA input selection variant, default to SMA if blank or typo.
variant(type, src, len, offSig, offALMA) =>
v1 = ta.sma(src, len) // Simple
v2 = ta.ema(src, len) // Exponential
v3 = 2 * v2 - ta.ema(v2, len) // Double Exponential
v4 = 3 * (v2 - ta.ema(v2, len)) + ta.ema(ta.ema(v2, len), len) // Triple
Exponential
v5 = ta.wma(src, len) // Weighted
v6 = ta.vwma(src, len) // Volume Weighted
v7 = 0.0
sma_1 = ta.sma(src, len) // Smoothed
v7 := na(v7[1]) ? sma_1 : (v7[1] * (len - 1) + src) / len
v8 = ta.wma(2 * ta.wma(src, len / 2) - ta.wma(src, len),
math.round(math.sqrt(len))) // Hull
v9 = ta.linreg(src, len, offSig) // Least Squares
v10 = ta.alma(src, len, offALMA, offSig) // Arnaud Legoux
v11 = ta.sma(v1, len) // Triangular (extreme smooth)
// SuperSmoother filter
// 2013 John F. Ehlers
a1 = math.exp(-1.414 * 3.14159 / len)
b1 = 2 * a1 * math.cos(1.414 * 3.14159 / len)
c2 = b1
c3 = -a1 * a1
c1 = 1 - c2 - c3
v12 = 0.0
v12 := c1 * (src + nz(src[1])) / 2 + c2 * nz(v12[1]) + c3 * nz(v12[2])
type == 'EMA' ? v2 : type == 'DEMA' ? v3 : type == 'TEMA' ? v4 : type ==
'WMA' ? v5 : type == 'VWMA' ? v6 : type == 'SMMA' ? v7 : type == 'HullMA' ? v8 :
type == 'LSMA' ? v9 : type == 'ALMA' ? v10 : type == 'TMA' ? v11 : type == 'SSMA' ?
v12 : v1

// security wrapper for repeat calls


reso(exp, use, res) =>
security_1 = request.security(syminfo.tickerid, res, exp, gaps =
barmerge.gaps_off, lookahead = barmerge.lookahead_on)
use ? security_1 : exp

// === /BASE FUNCTIONS ===


// === SERIES SETUP ===
closeSeries = variant(basisType, close[delayOffset], basisLen, offsetSigma,
offsetALMA)
openSeries = variant(basisType, open[delayOffset], basisLen, offsetSigma,
offsetALMA)
// === /SERIES ===

// Get Alternate resolution Series if selected.


closeSeriesAlt = reso(closeSeries, useRes, stratRes)
openSeriesAlt = reso(openSeries, useRes, stratRes)

//<triggers>
lxTrigger = false
sxTrigger = false
leTrigger = ta.crossover (closeSeriesAlt, openSeriesAlt)
seTrigger = ta.crossunder(closeSeriesAlt, openSeriesAlt)

G_RISK = '■ ' + 'Risk Management'


//#region ———— <↓↓↓ G_RISK ↓↓↓> {

// ——————————— <constant_declarations>
//Tooltip
T_LVL = '(%) Exit Level'
T_QTY = '(%) Adjust trade exit volume'
T_MSG = 'Paste JSON message for your bot'
//Webhook Message
O_LEMSG = 'Long Entry'
O_LXMSGSL = 'Long SL'
O_LXMSGTP1 = 'Long TP1'
O_LXMSGTP2 = 'Long TP2'
O_LXMSGTP3 = 'Long TP3'
O_LXMSG = 'Long Exit'
O_SEMSG = 'Short Entry'
O_SXMSGSL = 'Short SL'
O_SXMSGA = 'Short TP1'
O_SXMSGB = 'Short TP2'
O_SXMSGC = 'Short TP3'
O_SXMSGX = 'Short Exit'

// ——————————— <input> | | |
Line length guide |
i_lxLvlTP1 = input.float (0.2, 'Level TP1' ,
group = G_RISK,
tooltip = T_LVL)
i_lxQtyTP1 = input.float (80.0, 'Qty TP1' ,
group = G_RISK,
tooltip = T_QTY)
i_lxLvlTP2 = input.float (0.5, 'Level TP2' , group
= G_RISK,
tooltip = T_LVL)
i_lxQtyTP2 = input.float (10.0, 'Qty TP2' ,
group = G_RISK,
tooltip = T_QTY)
i_lxLvlTP3 = input.float (7.0, 'Level TP3' ,
group = G_RISK,
tooltip = T_LVL)
i_lxQtyTP3 = input.float (2, 'Qty TP3' , group
= G_RISK,
tooltip = T_QTY)
i_lxLvlSL = input.float (0.5, 'Stop Loss' , group
= G_RISK,
tooltip = T_LVL)
i_sxLvlTP1 = i_lxLvlTP1
i_sxQtyTP1 = i_lxQtyTP1
i_sxLvlTP2 = i_lxLvlTP2
i_sxQtyTP2 = i_lxQtyTP2
i_sxLvlTP3 = i_lxLvlTP3
i_sxQtyTP3 = i_lxQtyTP3
i_sxLvlSL = i_lxLvlSL

G_MSG = '■ ' + 'Webhook Message'


i_leMsg = input.string (O_LEMSG ,'Long Entry' , group
= G_MSG, tooltip = T_MSG)
i_lxMsgSL = input.string (O_LXMSGSL ,'Long SL' , group
= G_MSG, tooltip = T_MSG)
i_lxMsgTP1 = input.string (O_LXMSGTP1,'Long TP1' , group
= G_MSG, tooltip = T_MSG)
i_lxMsgTP2 = input.string (O_LXMSGTP2,'Long TP2' , group
= G_MSG, tooltip = T_MSG)
i_lxMsgTP3 = input.string (O_LXMSGTP3,'Long TP3' , group
= G_MSG, tooltip = T_MSG)
i_lxMsg = input.string (O_LXMSG ,'Long Exit' , group
= G_MSG, tooltip = T_MSG)
i_seMsg = input.string (O_SEMSG ,'Short Entry' , group
= G_MSG, tooltip = T_MSG)
i_sxMsgSL = input.string (O_SXMSGSL ,'Short SL' , group
= G_MSG, tooltip = T_MSG)
i_sxMsgTP1 = input.string (O_SXMSGA ,'Short TP1' , group
= G_MSG, tooltip = T_MSG)
i_sxMsgTP2 = input.string (O_SXMSGB ,'Short TP2' , group
= G_MSG, tooltip = T_MSG)
i_sxMsgTP3 = input.string (O_SXMSGC ,'Short TP3' , group
= G_MSG, tooltip = T_MSG)
i_sxMsg = input.string (O_SXMSGX ,'Short Exit' , group
= G_MSG, tooltip = T_MSG)
i_src = close

G_DISPLAY = 'Display'
//<display>
i_alertOn = input.bool (true, 'Alert Labels On/Off' , group
= G_DISPLAY)
i_barColOn = input.bool (true, 'Bar Color On/Off' , group
= G_DISPLAY)

// ——————————— <function_declarations>
// @function Calculate the Take Profit line, and the crossover or crossunder
f_tp(_condition, _conditionValue, _leTrigger, _seTrigger, _src, _lxLvlTP,
_sxLvlTP)=>
var float _tpLine = 0.0
_topLvl = _src + (_src * (_lxLvlTP / 100))
_botLvl = _src - (_src * (_sxLvlTP / 100))
_tpLine := _condition[1] != _conditionValue and _leTrigger ? _topLvl :
_condition[1] != -_conditionValue and _seTrigger ? _botLvl :
nz(_tpLine[1])
[_tpLine]

// @function Similar to "ta.crossover" or "ta.crossunder"


f_cross(_scr1, _scr2, _over)=>
_cross = _over ? _scr1 > _scr2 and _scr1[1] < _scr2[1] :
_scr1 < _scr2 and _scr1[1] > _scr2[1]

// ——————————— <calculations>
//<set initial values>
var float condition = 0.0
var float slLine = 0.0
var float entryLine = 0.0
//<entry & exit orders>
entryLine := leTrigger and condition[1] <= 0.0 ? close :
seTrigger and condition[1] >= 0.0 ? close : nz(entryLine[1])
//<SL>
slTopLvl = i_src + (i_src * (i_lxLvlSL / 100))
slBotLvl = i_src - (i_src * (i_sxLvlSL / 100))
slLine := condition[1] <= 0.0 and leTrigger ? slBotLvl :
condition[1] >= 0.0 and seTrigger ? slTopLvl : nz(slLine[1])
slLong = f_cross(low, slLine, false)
slShort = f_cross(high, slLine, true )
//<TP1, TP2 & TP3>
[tp3Line] = f_tp(condition, 1.2,leTrigger, seTrigger, i_src, i_lxLvlTP3,
i_sxLvlTP3)
[tp2Line] = f_tp(condition, 1.1,leTrigger, seTrigger, i_src, i_lxLvlTP2,
i_sxLvlTP2)
[tp1Line] = f_tp(condition, 1.0,leTrigger, seTrigger, i_src, i_lxLvlTP1,
i_sxLvlTP1)
tp3Long = f_cross(high, tp3Line, true )
tp3Short = f_cross(low, tp3Line, false)
tp2Long = f_cross(high, tp2Line, true )
tp2Short = f_cross(low, tp2Line, false)
tp1Long = f_cross(high, tp1Line, true )
tp1Short = f_cross(low, tp1Line, false)

switch
leTrigger and condition[1] <= 0.0 => condition := 1.0
seTrigger and condition[1] >= 0.0 => condition := -1.0
tp3Long and condition[1] == 1.2 => condition := 1.3
tp3Short and condition[1] == -1.2 => condition := -1.3
tp2Long and condition[1] == 1.1 => condition := 1.2
tp2Short and condition[1] == -1.1 => condition := -1.2
tp1Long and condition[1] == 1.0 => condition := 1.1
tp1Short and condition[1] == -1.0 => condition := -1.1
slLong and condition[1] >= 1.0 => condition := 0.0
slShort and condition[1] <= -1.0 => condition := 0.0
lxTrigger and condition[1] >= 1.0 => condition := 0.0
sxTrigger and condition[1] <= -1.0 => condition := 0.0

longE = leTrigger and condition[1] <= 0.0 and condition == 1.0


shortE = seTrigger and condition[1] >= 0.0 and condition == -1.0
longX = lxTrigger and condition[1] >= 1.0 and condition == 0.0
shortX = sxTrigger and condition[1] <= -1.0 and condition == 0.0
longSL = slLong and condition[1] >= 1.0 and condition == 0.0
shortSL = slShort and condition[1] <= -1.0 and condition == 0.0
longTP3 = tp3Long and condition[1] == 1.2 and condition == 1.3
shortTP3 = tp3Short and condition[1] == -1.2 and condition == -1.3
longTP2 = tp2Long and condition[1] == 1.1 and condition == 1.2
shortTP2 = tp2Short and condition[1] == -1.1 and condition == -1.2
longTP1 = tp1Long and condition[1] == 1.0 and condition == 1.1
shortTP1 = tp1Short and condition[1] == -1.0 and condition == -1.1

// ——————————— <strategy_calls> {
//<long orders>
if strategy.position_size <= 0 and longE and barstate.isconfirmed
strategy.entry(
'Long',
strategy.long,
alert_message = i_leMsg,
comment = 'LE')
if strategy.position_size > 0 and condition == 1.0
strategy.exit(
id = 'LXTP1',
from_entry = 'Long',
qty_percent = i_lxQtyTP1,
limit = tp1Line,
stop = slLine,
comment_profit = 'LXTP1',
comment_loss = 'SL',
alert_profit = i_lxMsgTP1,
alert_loss = i_lxMsgSL)
if strategy.position_size > 0 and condition == 1.1
strategy.exit(
id = 'LXTP2',
from_entry = 'Long',
qty_percent = i_lxQtyTP2,
limit = tp2Line,
stop = slLine,
comment_profit = 'LXTP2',
comment_loss = 'SL',
alert_profit = i_lxMsgTP2,
alert_loss = i_lxMsgSL)
if strategy.position_size > 0 and condition == 1.2
strategy.exit(
id = 'LXTP3',
from_entry = 'Long',
qty_percent = i_lxQtyTP3,
limit = tp3Line,
stop = slLine,
comment_profit = 'LXTP3',
comment_loss = 'SL',
alert_profit = i_lxMsgTP3,
alert_loss = i_lxMsgSL)
if longX
strategy.close(
'Long',
alert_message = i_lxMsg,
comment = 'LX')
//<short orders>
if strategy.position_size >= 0 and shortE and barstate.isconfirmed
strategy.entry(
'Short',
strategy.short,
alert_message = i_leMsg,
comment = 'SE')
if strategy.position_size < 0 and condition == -1.0
strategy.exit(
id = 'SXTP1',
from_entry = 'Short',
qty_percent = i_sxQtyTP1,
limit = tp1Line,
stop = slLine,
comment_profit = 'SXTP1',
comment_loss = 'SL',
alert_profit = i_sxMsgTP1,
alert_loss = i_sxMsgSL)
if strategy.position_size < 0 and condition == -1.1
strategy.exit(
id = 'SXTP2',
from_entry = 'Short',
qty_percent = i_sxQtyTP2,
limit = tp2Line,
stop = slLine,
comment_profit = 'SXTP2',
comment_loss = 'SL',
alert_profit = i_sxMsgTP2,
alert_loss = i_sxMsgSL)
if strategy.position_size < 0 and condition == -1.2
strategy.exit(
id = 'SXTP3',
from_entry = 'Short',
qty_percent = i_sxQtyTP3,
limit = tp3Line,
stop = slLine,
comment_profit = 'SXTP3',
comment_loss = 'SL',
alert_profit = i_sxMsgTP3,
alert_loss = i_sxMsgSL)
if shortX
strategy.close(
'Short',
alert_message = i_sxMsg,
comment = 'SX')

// ——————————— <visuals>
c_tp = leTrigger or seTrigger ? na :
condition == 0.0 ? na : color.green
c_entry = leTrigger or seTrigger ? na :
condition == 0.0 ? na : color.blue
c_sl = leTrigger or seTrigger ? na :
condition == 0.0 ? na : color.red
p_tp1Line = plot (
condition == 1.0 or
condition == -1.0 ? tp1Line : na,
title = "TP Line 1",
color = c_tp,
linewidth = 1,
style = plot.style_linebr)
p_tp2Line = plot (
condition == 1.0 or
condition == -1.0 or
condition == 1.1 or
condition == -1.1 ? tp2Line : na,
title = "TP Line 2",
color = c_tp,
linewidth = 1,
style = plot.style_linebr)
p_tp3Line = plot (
condition == 1.0 or
condition == -1.0 or
condition == 1.1 or
condition == -1.1 or
condition == 1.2 or
condition == -1.2 ? tp3Line : na,
title = "TP Line 3",
color = c_tp,
linewidth = 1,
style = plot.style_linebr)
p_entryLine = plot (
condition >= 1.0 or
condition <= -1.0 ? entryLine : na,
title = "Entry Line",
color = c_entry,
linewidth = 1,
style = plot.style_linebr)
p_slLine = plot (
condition == 1.0 or
condition == -1.0 or
condition == 1.1 or
condition == -1.1 or
condition == 1.2 or
condition == -1.2 ? slLine : na,
title = "SL Line",
color = c_sl,
linewidth = 1,
style = plot.style_linebr)
fill(
p_tp3Line, p_entryLine,
color = leTrigger or seTrigger ? na :color.new(color.green, 90))
fill(
p_entryLine, p_slLine,
color = leTrigger or seTrigger ? na :color.new(color.red, 90))

//<alerts labels>
plotshape(
i_alertOn and longE,
title = 'Long',
text = 'Long',
textcolor = color.white,
color = color.green,
style = shape.labelup,
size = size.tiny,
location = location.belowbar)
plotshape(
i_alertOn and shortE,
title = 'Short',
text = 'Short',
textcolor = color.white,
color = color.red,
style = shape.labeldown,
size = size.tiny,
location = location.abovebar)
plotshape(
i_alertOn and (longX or shortX) ? close : na,
title = 'Close',
text = 'Close',
textcolor = color.white,
color = color.gray,
style = shape.labelup,
size = size.tiny,
location = location.absolute)
l_tp = i_alertOn and (longTP1 or shortTP1) ? close : na
plotshape(
l_tp,
title = "TP1 Cross",
text = "TP1",
textcolor = color.white,
color = color.olive,
style = shape.labelup,
size = size.tiny,
location = location.absolute)
plotshape(
i_alertOn and (longTP2 or shortTP2) ? close : na,
title = "TP2 Cross",
text = "TP2",
textcolor = color.white,
color = color.olive,
style = shape.labelup,
size = size.tiny,
location = location.absolute)
plotshape(
i_alertOn and (longTP3 or shortTP3) ? close : na,
title = "TP3 Cross",
text = "TP3",
textcolor = color.white,
color = color.olive,
style = shape.labelup,
size = size.tiny,
location = location.absolute)
plotshape(
i_alertOn and (longSL or shortSL) ? close : na,
title = "SL Cross",
text = "SL",
textcolor = color.white,
color = color.maroon,
style = shape.labelup,
size = size.tiny,
location = location.absolute)

//<debug>
plot(
na,
title = "─── <debug> ───",
editable = false,
display = display.data_window)
plot(
condition,
title = "condition",
editable = false,
display = display.data_window)
plot(
strategy.position_size * 100,
title = ".position_size",
editable = false,
display = display.data_window)
//#endregion }
// ——————————— <↑↑↑ G_RISK ↑↑↑>

//#region ———— <↓↓↓ G_SCRIPT02 ↓↓↓> {


// @function Queues a new element in an array and de-queues its first
element.
f_qDq(_array, _val) =>
array.push(_array, _val)
_return = array.shift(_array)
_return
var line[] a_slLine = array.new_line(1)
var line[] a_entryLine = array.new_line(1)
var line[] a_tp3Line = array.new_line(1)
var line[] a_tp2Line = array.new_line(1)
var line[] a_tp1Line = array.new_line(1)
var label[] a_slLabel = array.new_label(1)
var label[] a_tp3label = array.new_label(1)
var label[] a_tp2label = array.new_label(1)
var label[] a_tp1label = array.new_label(1)
var label[] a_entryLabel = array.new_label(1)

newEntry = longE or shortE


entryIndex = 1
entryIndex := newEntry ? bar_index : nz(entryIndex[1])
lasTrade = bar_index >= entryIndex
l_right = 10

line.delete(
f_qDq(a_slLine,
line.new(
entryIndex,
slLine,
last_bar_index + l_right,
slLine,
style = line.style_solid,
color = c_sl)))
line.delete(
f_qDq(a_entryLine,
line.new(
entryIndex,
entryLine,
last_bar_index + l_right,
entryLine,
style = line.style_solid,
color = color.blue)))
line.delete(
f_qDq(a_tp3Line,
line.new(
entryIndex,
tp3Line,
last_bar_index + l_right,
tp3Line,
style = line.style_solid,
color = c_tp)))
line.delete(
f_qDq(a_tp2Line,
line.new(
entryIndex,
tp2Line,
last_bar_index + l_right,
tp2Line,
style = line.style_solid,
color = c_tp)))
line.delete(
f_qDq(a_tp1Line,
line.new(
entryIndex,
tp1Line,
last_bar_index + l_right,
tp1Line,
style = line.style_solid,
color = c_tp)))

label.delete(
f_qDq(a_slLabel,
label.new(
last_bar_index + l_right,
slLine,
'SL: ' + str.tostring(slLine, '##.###'),
style = label.style_label_left,
textcolor = color.white,
color = c_sl)))
label.delete(
f_qDq(a_entryLabel,
label.new(
last_bar_index + l_right,
entryLine,
'Entry: ' + str.tostring(entryLine, '##.###'),
style = label.style_label_left,
textcolor = color.white,
color = color.blue)))
label.delete(
f_qDq(a_tp3label,
label.new(
last_bar_index + l_right,
tp3Line,
'TP3: ' + str.tostring(tp3Line, '##.###'),
style = label.style_label_left,
textcolor = color.white,
color = c_tp)))
label.delete(
f_qDq(a_tp2label,
label.new(
last_bar_index + l_right,
tp2Line,
'TP2: ' + str.tostring(tp2Line, '##.###'),
style = label.style_label_left,
textcolor = color.white,
color = c_tp)))
label.delete(
f_qDq(a_tp1label,
label.new(
last_bar_index + l_right,
tp1Line,
'TP1: ' + str.tostring(tp1Line, '##.###'),
style = label.style_label_left,
textcolor = color.white,
color = c_tp)))

// ——————————— <alerts>
//<any_alert_function_call>
if longE or shortE or longX or shortX
alert(message = 'Any Alert', freq = alert.freq_once_per_bar_close)
if longE
alert(message = 'Long Entry', freq = alert.freq_once_per_bar_close)
if shortE
alert(message = 'Short Entry', freq = alert.freq_once_per_bar_close)
if longX
alert(message = 'Long Exit', freq = alert.freq_once_per_bar_close)
if shortX
alert(message = 'Short Exit', freq = alert.freq_once_per_bar_close)
//#endregion }
// ——————————— <↑↑↑ G_SCRIPT03 ↑↑↑>

////////////////////////////////////////
//indicator("Percentage of Target by Leo", overlay=false, precision = 0,
max_labels_count = 500,max_lines_count=500)

string t1 = "Process Noise 1: This is the primary noise factor for the Kalman
filter process. A higher value increases the filter’s responsiveness to price
changes, but may result in less smooth output. Adjust this based on market
volatility and the desired balance between smoothness and responsiveness."
string t2 = "Process Noise 2: This is the secondary noise factor for the Kalman
filter process. It works in conjunction with Process Noise 1. Increasing this value
also makes the filter more responsive but may introduce more noise. Fine-tune this
alongside Process Noise 1 for optimal filtering."
string t3 = "Measurement Noise: This value defines the amount of noise in the price
data, impacting how much the filter trusts the current price series. Higher values
will make the filter rely more on past data, reducing responsiveness. Use this to
control the trade-off between smoothness and responsiveness in trending or noisy
markets."
string t4 = "Osc Smoothness: Controls the level of smoothing applied to the trend
strength oscillator. Higher values result in a smoother oscillator but may cause
delays. Lower values make the oscillator more reactive to trend changes, which can
be useful for capturing quick reversals or volatility."
string t5 = "Kalman Filter Model: Choose between standard, volume-adjusted, and
Parkinson-adjusted Kalman filter models. Volume-adjusted uses trading volume to
adapt noise, while Parkinson-adjusted considers price range volatility. Each model
impacts how the Kalman filter adjusts to market conditions."
string t6 = "Sigma Lookback: Defines the number of bars used to calculate the
standard deviation for confidence bands in the Kalman filter. Higher values use
more historical data, which can stabilize the filter in trending markets. Lower
values make it more responsive to recent changes."
string t7 = "Trend Lookback: Sets the period over which the trend strength is
calculated. Shorter periods make the indicator more sensitive to recent trends,
while longer periods smooth the trend, emphasizing longer-term movement."
string t8 = "Strength Smoothness: Defines the level of smoothing applied to the
calculated trend strength. Higher values create a more gradual trend strength
curve, suitable for identifying persistent trends. Lower values make it more
responsive, highlighting shorter-term fluctuations."

enum kf_model
standard = "Standard"
volume_adjusted = "Volume adjusted"
parkinson_adjusted = "Parkinson adjusted"

process_noise_1 = 0.01//input.float(0.01, "Process Noise 1", minval=0.0,


maxval=10000, step=0.01, tooltip=t1, group='General settings')
process_noise_2 = 0.01//input.float(0.01, "Process Noise 2", minval=0.0,
maxval=10000, step=0.01, tooltip=t2, group='General settings')
measurement_noise = input.float(500.0, "Measurement Noise", minval=0.0,
maxval=10000, step=2.0, tooltip=t3, group='General settings')
R1 = input.int(10, title="Osc Smoothness", minval=2, tooltip=t4,
group='General settings')
src1 = close//input.source(close, "Input Source", tooltip='Primary
input to filter', group='General settings')
selected_kf_model = input.enum(kf_model.standard, "Kalman Filter Model",
tooltip=t5, group='Kalman Model Settings')
N = 500//input.int(500, "Sigma Lookback", minval=2, step=1,
tooltip=t6, group='Additional Settings')
N2 = input.int(10, "Trend Lookback", minval=2, step=1, tooltip=t7,
group='Trend Settings')
R2 = input.int(10, title="Strength Smoothness", minval=2,
tooltip=t8, group='Trend Settings')
pos_col = input.color(color.lime, title="Trend", inline="style",
group='Style Settings')
neu_col = input.color(color.blue, title="", inline="style", group='Style
Settings')
neg_col = input.color(color.red, title="", inline="style", group='Style
Settings')
ob_col = input.color(color.green, title="OBOS", inline="style1",
group='Style Settings')
os_col = input.color(color.red, title="", inline="style1", group='Style
Settings')
bg_col = input.color(color.rgb(87, 130, 194, 90), title="BG",
inline="style2", group='Style Settings')

var float filtered_src = na


var float trend_strength = na
var Y_diff = array.new<float>()
var osc_buffer = array.new<float>()

var F = matrix.new<float>(2, 2, 0.0)


F.set(0, 0, 1.0)
F.set(0, 1, 1.0)
F.set(1, 0, 1.0)

var P = matrix.new<float>(2, 2, 0.0)


matrix.set(P, 0, 0, 1.0)
matrix.set(P, 1, 1, 1.0)

var Q = matrix.new<float>(2, 2, 0.0)


matrix.set(Q, 0, 0, process_noise_1)
matrix.set(Q, 0, 1, process_noise_1 * process_noise_2)
matrix.set(Q, 1, 0, process_noise_2 * process_noise_1)
matrix.set(Q, 1, 1, process_noise_2)

var R = matrix.new<float>(1, 1, measurement_noise)


var H = matrix.new<float>(1, 2, 0.0)
matrix.set(H, 0, 0, 1.0)

var I = matrix.new<float>(2, 2, 0.0)


matrix.set(I, 0, 0, 1.0)
matrix.set(I, 1, 1, 1.0)

var X = array.from(0.0, 0.0)


if barstate.isfirst
X := array.from(src1, src1)

if barstate.isconfirmed
x1 = matrix.get(F, 0, 0) * array.get(X, 0) + matrix.get(F, 0, 1) * array.get(X,
1)
x2 = matrix.get(F, 1, 1) * array.get(X, 1)
X := array.from(x1, x2)
P := F.mult(P.mult(F.transpose())).sum(Q)

array.push(Y_diff, src1 - array.get(X, 0))

R_adjusted = R.copy()
if selected_kf_model != kf_model.standard and bar_index > 2
if selected_kf_model == kf_model.volume_adjusted
matrix.set(R_adjusted, 0, 0, matrix.get(R, 0, 0) * volume[1] /
math.min(volume[1], volume))
else if selected_kf_model == kf_model.parkinson_adjusted
current_range = high - low
previous_range = high[1] - low[1]
range_ratio = current_range / math.max(previous_range, syminfo.mintick)
parkinson_scaled = 1 + range_ratio
matrix.set(R_adjusted, 0, 0, matrix.get(R, 0, 0) * parkinson_scaled)

S = H.mult(P.mult(H.transpose())).sum(R_adjusted)
K = P.mult(H.transpose().mult(S.inv()))
innovation = src1 - array.get(H.mult(X), 0)
diff = K.mult(innovation)
X := array.from(array.get(X, 0) + matrix.get(diff, 0, 0), array.get(X, 1) +
matrix.get(diff, 1, 0))
P := I.sum(K.mult(H).mult(-1)).mult(P)

estimate = array.get(X, 0)
oscillator = array.get(X, 1)
filtered_src := estimate

array.push(osc_buffer, oscillator)

if array.size(Y_diff) >= N
array.shift(Y_diff)

if array.size(osc_buffer) >= N2
A = osc_buffer.abs().max()
trend_strength := ta.wma((oscillator / A * 100 ),R2)
array.shift(osc_buffer)

var int num_segments = 10


segment_width = 100 / num_segments
filled_segments = math.floor(math.abs(trend_strength) / segment_width)
osc_color = neu_col

if not na(trend_strength)
for i = 0 to num_segments - 1
if i < filled_segments
osc_color := color.new(trend_strength > 0 ? pos_col : neg_col, 80 - i *
10)
else
break

//oscPlot = plot(ta.wma(trend_strength,R1), color=osc_color, linewidth=3,


title="Kalman Trend Strength Oscillator")
//kalmanPlot= plot(filtered_src, color=osc_color, linewidth = 2, title="Adaptive
Kalman Filter", force_overlay = false)
//UpperBand = hline(70, title="70")
//midline = hline(0, title="0")
//LowerBand = hline(-70, title="-70")

//fill(UpperBand, LowerBand, color=bg_col, title="Background Fill")


//midLinePlot = plot(0, color = na, editable = false, display = display.none)
//fill(oscPlot, midLinePlot, 80, 30, top_color = color.new(ob_col, 0), bottom_color
= color.new(ob_col, 100), title = "Upper Gradient Fill")
//fill(oscPlot, midLinePlot, -30, -80, top_color = color.new(os_col, 100),
bottom_color = color.new(os_col, 0), title = "Lower Gradient Fill")

if barstate.islast
trend_strength_current = math.round(trend_strength)
var table trend_table = table.new(position.bottom_center, num_segments + 1, 1,
border_color=chart.fg_color, border_width=1, frame_color=chart.fg_color,
frame_width=1)
for i = 0 to num_segments - 1
table_segment_color = i < filled_segments ? color.new(trend_strength > 0 ?
pos_col : neg_col, 70 - i * 10) : color.new(chart.fg_color, 100)
table.cell(trend_table, i, 0, "", bgcolor=table_segment_color, width=1,
height=2)
table.cell(trend_table, num_segments, 0, str.tostring(trend_strength_current) +
" %", text_color=chart.fg_color, bgcolor=na)

int len = input.int(20, "Length", minval = 5)


string mode = input.string("AVG", "Type", ["AVG", "MEADIAN", "MODE"])
float distance = input.float(1, step = 0.1)
bool show_retest = input.bool(false, "Retest Signals")
color up = input.color(color.rgb(40, 218, 150), group = "Color")
color dn = input.color(color.rgb(218, 105, 40), group = "Color")

gaussian_filter(src1, length, sigma) =>


var float[] weights = array.new_float(100)
float total = 0.0
float pi = math.pi

for i = 0 to length - 1
float weight = math.exp(-0.5 * math.pow((i - length / 2) / sigma, 2.0)) /
math.sqrt(sigma * 2.0 * pi)
weights.set(i, weight)
total := total + weight

for i = 0 to length - 1
weights.set(i, weights.get(i) / total)

float sum = 0.0


for i = 0 to length - 1
sum := sum + src1[i] * weights.get(i)
sum

multi_trend(src1, period) =>


array<float> g_value = array.new<float>()
float volatility = ta.sma(high - low, 100)

var float lower_band = 0.0


var float upper_band = 0.0
var float trend_line = 0.0
var bool trend = na

for step = 0 to 20 by 1
float gaussian_filter = gaussian_filter(src1, (period + step), 10)
g_value.push(gaussian_filter)

float coeff = 0.05


float score = 0.0

for i = 0 to g_value.size() - 1
float g_f = g_value.get(i)
if g_f > g_value.first()
score += coeff

color color = score > 0.5


? color.from_gradient(score, 0.5, 1, na, dn)
: color.from_gradient(score, 0, 0.5, up, na)

float value = switch mode


"AVG" => g_value.avg()
"MEADIAN" => g_value.median()
"MODE" => g_value.mode()

lower_band := value - volatility * distance


upper_band := value + volatility * distance

if ta.crossover(close, upper_band)
trend := true
if ta.crossunder(close, lower_band)
trend := false

trend_line :=
trend ? lower_band
: not trend ? upper_band : na

[score, value, color, trend_line, trend]

[score, avg, color, trend_line, trend] = multi_trend(close, len)

//p2 = plot(avg, color = color, linewidth=1,force_overlay=false)

//p1 = plot(ta.change(trend) ? na : trend_line,


// color = close > trend_line ? up : dn,
// linewidth = 2,
// style = plot.style_linebr,force_overlay=false)

//plot(trend_line, color = close > trend_line ? up : dn, linewidth=1, style =


plot.style_linebr,force_overlay=false)
if ta.crossunder(close, trend_line)
label.new(bar_index, trend_line, score < 0.5 ? "▼+" : "▼",
color = dn,
textcolor = chart.bg_color,
style = label.style_label_lower_right,
size = score < 0.5 ? size.small : size.tiny,force_overlay=true)

if ta.crossover(close, trend_line)
label.new(bar_index, trend_line, score > 0.5 ? "▲+" : "▲",
color = up,
textcolor = chart.bg_color,
style = label.style_label_upper_right,
size = score > 0.5 ? size.small : size.tiny,force_overlay=true)

color trend_color = trend ? color.new(up, 80) : color.new(dn, 80)

//fill(p1, p2, trend_line, avg, trend_color, na)


//fill(p1, p2, trend_line, avg, trend_color, na)

if show_retest
if ta.crossunder(high, avg) and not trend
label.new(bar_index[1], high[1], "▼",
color = color(na),
style = label.style_label_down,
textcolor = chart.fg_color,
size = size.small,force_overlay=true)

if ta.crossover(close, avg) and trend


label.new(bar_index[1], low[1], "▲",
color = color(na),
style = label.style_label_up,
textcolor = chart.fg_color,
size = size.small,force_overlay=true)

float score_up = (score - 1) * -1


float score_dn = 1 - score_up

if barstate.islast
table trend_strength_up = table.new(position.bottom_center, 100,
100,force_overlay=true)
table trend_strength_dn = table.new(position.top_center, 100,
100,force_overlay=true)

for i = 0 to score_up * 20
trend_strength_up.cell(0 + i, 0, bgcolor = color.new(up, 100 - i * 5), text
= i == 0 ? "|" : "", text_color = color.gray)

if i == score_up * 20
trend_strength_up.cell(0 + i, 0,
text = str.tostring(score_up * 100,
format.percent) + " ▲",
text_color = chart.fg_color,
height = 2)

for i = 0 to score_dn * 20
trend_strength_dn.cell(0 + i, 0, bgcolor = color.new(dn, 100 - i * 5), text
= i == 0 ? "|" : "", text_color = color.gray)

if i == score_dn * 20
trend_strength_dn.cell(0 + i, 0,
text = str.tostring(score_dn * 100,
format.percent) + " ▼",
text_color = chart.fg_color,
height = 2)

length = input.int(10, "Trend Length")


target = input.int(0, "Set Targets")

var bool trend1 = na


float trend_value = na
color up_color = #06b690
color dn_color = #b62c06

series float atr_value = ta.sma(ta.atr(200), 200) * 0.8


series float sma_high = ta.sma(high, length) + atr_value
series float sma_low = ta.sma(low, length) - atr_value
color plot_color = color.new(chart.fg_color, 50)

type TrendTargets
line[] lines
label[] labels

var TrendTargets targets_up = TrendTargets.new(array.new_line(),


array.new_label())
var TrendTargets targets_down = TrendTargets.new(array.new_line(),
array.new_label())

if ta.crossover(close, sma_high) and barstate.isconfirmed


trend1 := true
if ta.crossunder(close, sma_low) and barstate.isconfirmed
trend1 := false

trend_value := switch
trend1 => sma_low
not trend1 => sma_high

trend_color1 = trend1 ? up_color : not trend1 ? dn_color : na

bool signal_up = ta.change(trend1) and not trend1[1]


bool signal_down = ta.change(trend1) and trend1[1]

method draw_targets(TrendTargets targets, bool signal1, bool signal2, bool


direction)=>
float base = direction ? sma_low : sma_high
float atr_multiplier = atr_value * (direction ? 1 : -1)

// Reset counters for up and down targets


var int count_up = 0
var int count_down = 0

if trend1
count_down := 0
count_up += 1
if not trend1
count_down += 1
count_up := 0

int count = direction ? count_up : count_down

if signal1
float target_len1 = atr_multiplier * (5+target)
float target_len2 = atr_multiplier * (10+target*2)
float target_len3 = atr_multiplier * (15+target*3)

for line_i in targets.lines


int i = targets.lines.indexof(line_i)
label.delete(targets.labels.get(i))
line.delete(line_i)

array.clear(targets.lines)
array.clear(targets.labels)

line stop_loss_line = line.new(bar_index, base, bar_index + 20,


base,force_overlay=true)
line entry_line = line.new(bar_index, close, bar_index + 20,
close,force_overlay=true)
line target1_line = line.new(bar_index, close + target_len1, bar_index +
20, close + target_len1,force_overlay=true)
line target2_line = line.new(bar_index, close + target_len2, bar_index +
20, close + target_len2,force_overlay=true)
line target3_line = line.new(bar_index, close + target_len3, bar_index +
20, close + target_len3,force_overlay=true)
linefill.new(stop_loss_line, entry_line, color.new(dn_color, 95))
linefill.new(entry_line, target3_line, color.new(up_color, 95))
label stop_loss_label = label.new(bar_index + 20, base,
str.tostring(math.round(base, 2)),force_overlay=true)
label entry_label = label.new(bar_index + 20, close,
str.tostring(math.round(close, 2)),force_overlay=true)
label target1_label = label.new(bar_index + 20, close + target_len1, "1 -
" + str.tostring(math.round(close + target_len1, 2)),force_overlay=true)
label target2_label = label.new(bar_index + 20, close + target_len2, "2 -
" + str.tostring(math.round(close + target_len2, 2)),force_overlay=true)
label target3_label = label.new(bar_index + 20, close + target_len3, "3 -
" + str.tostring(math.round(close + target_len3, 2)),force_overlay=true)
targets.lines.push(stop_loss_line)
targets.lines.push(entry_line)
targets.lines.push(target1_line)
targets.lines.push(target2_line)
targets.lines.push(target3_line)
targets.labels.push(stop_loss_label)
targets.labels.push(entry_label)
targets.labels.push(target1_label)
targets.labels.push(target2_label)
targets.labels.push(target3_label)

for lbl in targets.labels


int idx = targets.labels.indexof(lbl)
line line_ref = targets.lines.get(idx)
lbl.set_style(label.style_label_left)
lbl.set_color(#b2b5be7f)
lbl.set_textcolor(color.gray)
line_ref.set_color(chart.fg_color)

if signal2
for line_i in targets.lines
int i = targets.lines.indexof(line_i)
label.delete(targets.labels.get(i))
line.delete(line_i)

array.clear(targets.lines)
array.clear(targets.labels)

for line_i in targets.lines


int idx = targets.lines.indexof(line_i)
label lbl_ref = targets.labels.get(idx)
label first_label = targets.labels.first()
line entry_line = targets.lines.get(1)
label entry_label = targets.labels.get(1)

if high >= line.get_y2(line_i) and low <= line.get_y2(line_i) and count > 1
lbl_ref.set_style(label.style_label_left)
lbl_ref.set_color(#b2b5be7f)
lbl_ref.set_text(" ✔ ")
lbl_ref.set_textcolor(#16ac09)
line_i.set_style(line.style_dashed)
line_i.set_color(plot_color)

if high >= line.get_y2(targets.lines.first()) and low <=


line.get_y2(targets.lines.first()) and count > 1
first_label.set_text(" ✖ ")

if direction ? trend : not trend


first_label.set_textcolor(#db1e1e)
line_i.set_x2(bar_index + 20)
targets.lines.first().set_color(#db1e1e)

label.set_x(targets.labels.get(idx), bar_index + 20)

entry_line.set_style(line.style_solid)
entry_line.set_color(up_color)
entry_label.set_text("◉ " +
str.tostring(math.round(line.get_y2(entry_line), 2)))
entry_label.set_textcolor(#1d80dd)

targets_down.draw_targets(signal_down, signal_up, false)


targets_up.draw_targets(signal_up, signal_down, true)
plotcandle(open, high, low, close,
title = 'Title',
color = trend_color1,
wickcolor = trend_color1,
bordercolor = trend_color1)

//p10 = plot(trend ? trend_value : na, style = plot.style_linebr, color =


plot_color,force_overlay=true)
//p20 = plot(not trend ? trend_value : na, style = plot.style_linebr, color =
plot_color,force_overlay=true)
//p0 = plot(hl2, display = display.none, editable = false,force_overlay=true)
//fill(p10, p0, trend_value, hl2, color.new(chart.fg_color, 90), na)
//fill(p20, p0, trend_value, hl2, color.new(chart.fg_color, 90), na)

float sigUp = signal_up ? low - atr_value*2 : na


float sigDn = signal_down ? high + atr_value*2 : na

plotshape(sigUp, "", shape.triangleup, location.absolute, up_color, size =


size.tiny,force_overlay=true)
plotshape(sigUp, "", shape.triangleup, location.absolute, color.new(up_color,
80), size = size.small,force_overlay=true)

plotshape(sigDn, "", shape.triangledown, location.absolute, dn_color, size =


size.tiny,force_overlay=true)
plotshape(sigDn, "", shape.triangledown, location.absolute, color.new(dn_color,
80), size = size.small,force_overlay=true)

You might also like