Untitled

mail@pastecode.io avatar
unknown
plain_text
10 days ago
57 kB
50
Indexable
Never
//@version=5
VERSION                   = 'v6_1_23'// 2023.10.13
strategy(
  'ALGOX',
  shorttitle              = 'ALGOX ' + VERSION,
  overlay                 = true,
  explicit_plot_zorder    = true,
  pyramiding              = 0,
  default_qty_type        = strategy.percent_of_equity,
  default_qty_value       = 10,
  calc_on_every_tick      = false,
  process_orders_on_close = true)


// Project #827
// Actual version: @gu5tavo71 for Riccardo (@rikyfx for PineScripters Jobs)
// This script reuses open source code from another authors:
// @PineCoders, Built-in Library, and Community Scripts
// Disclaimer: I am not a financial advisor.
//             For purpose educate only. Use at your own risk.




G_SCRIPT01   = '■ ' + 'SAIYAN OCC'
//#region ———— <↓↓↓ G_SCRIPT01 ↓↓↓> {


// === INPUTS ===
res                       = input.timeframe('15',  'TIMEFRAME', group ="NON REPAINT")
useRes                    = input(true,            'Use Alternate Signals')
intRes                    = input(8,               'Multiplier for Alernate Signals')
basisType                 = input.string('ALMA',   'MA Type: ', options=['TEMA', 'HullMA', 'ALMA'])
basisLen                  = input.int(2,           'MA Period', minval=1)
offsetSigma               = input.int(5,           'Offset for LSMA / Sigma for ALMA', minval=0)
offsetALMA                = input.float(0.85,      '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


//FUNCTIONS


//      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)




//
//END FUNCTIONS
//  




//
//CALCULATIONS
//
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)


// if barstate.islast
    // label.new(x = bar_index + 10, y = close[1], text = str.tostring( array.size(current_supply_poi) ))
//     label.new(x = bar_index + 20, y = close[1], text = str.tostring( box.get_bottom( array.get(current_supply_box, 0))))
//     label.new(x = bar_index + 30, y = close[1], text = str.tostring( box.get_bottom( array.get(current_supply_box, 1))))
//     label.new(x = bar_index + 40, y = close[1], text = str.tostring( box.get_bottom( array.get(current_supply_box, 2))))
//     label.new(x = bar_index + 50, y = close[1], text = str.tostring( box.get_bottom( array.get(current_supply_box, 3))))
//     label.new(x = bar_index + 60, y = close[1], text = str.tostring( box.get_bottom( array.get(current_supply_box, 4))))


// Get user input


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






// // Functions
// supertrend(_src, factor, atrLen) =>
    // atr = ta.atr(atrLen)
    // upperBand = _src + factor * atr
    // lowerBand = _src - factor * atr
    // prevLowerBand = nz(lowerBand[1])
    // prevUpperBand = nz(upperBand[1])
    // lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
    // upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
    // int direction = na
    // float superTrend = na
    // prevSuperTrend = superTrend[1]
    // if na(atr[1])
        // direction := 1
    // else if prevSuperTrend == prevUpperBand
        // direction := close > upperBand ? -1 : 1
    // else
        // direction := close < lowerBand ? 1 : -1
    // superTrend := direction == -1 ? lowerBand : upperBand
    // [superTrend, direction]
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]




// // Get Components
// ocAvg       = math.avg(open, close)
// sma1        = ta.sma(close, 5)
// sma2        = ta.sma(close, 6)
// sma3        = ta.sma(close, 7)
// sma4        = ta.sma(close, 8)
// sma5        = ta.sma(close, 9)
// sma6        = ta.sma(close, 10)
// sma7        = ta.sma(close, 11)
// sma8        = ta.sma(close, 12)
// sma9        = ta.sma(close, 13)
// sma10       = ta.sma(close, 14)
// sma11       = ta.sma(close, 15)
// sma12       = ta.sma(close, 16)
// sma13       = ta.sma(close, 17)
// sma14       = ta.sma(close, 18)
// sma15       = ta.sma(close, 19)
// sma16       = ta.sma(close, 20)
// psar        = ta.sar(0.02, 0.02, 0.2)
[_, 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)


// // Colors
// green       = #00d9ff, green2   = #00d9ff
// red         = #ff0090, red2     = #ff0090


// // Plots
// k1 = plot(ta.ema(upperKC1, 50), "k1", na,             editable = false)
// k2 = plot(ta.ema(upperKC2, 50), "k2", na,             editable = false)
// k3 = plot(ta.ema(upperKC3, 50), "k3", na,             editable = false)
// k4 = plot(ta.ema(upperKC4, 50), "k4", na,             editable = false)
// k5 = plot(ta.ema(lowerKC4, 50), "k5", na,             editable = false)
// k6 = plot(ta.ema(lowerKC3, 50), "k6", na,             editable = false)
// k7 = plot(ta.ema(lowerKC2, 50), "k7", na,             editable = false)
// k8 = plot(ta.ema(lowerKC1, 50), "k8", na,             editable = false)
// fill(k1, k2, channelBal ? color.new(red2,   40) : na, editable = false)
// fill(k2, k3, channelBal ? color.new(red2,   65) : na, editable = false)
// fill(k3, k4, channelBal ? color.new(red2,   90) : na, editable = false)
// fill(k5, k6, channelBal ? color.new(green2, 90) : na, editable = false)
// fill(k6, k7, channelBal ? color.new(green2, 65) : na, editable = false)
// fill(k7, k8, channelBal ? color.new(green2, 40) : na, editable = false)


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.


// // Constants colours that include fully non-transparent option.
// green100   = #008000FF
// lime100    = #00FF00FF
// red100     = #FF0000FF
// blue100    = #0000FFFF
// aqua100    = #00FFFFFF
// darkred100 = #8B0000FF
// gray100    = #808080FF


/////////////////////////////////////////////
// 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 ph or 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 = (ph[x] ? high[x + rb] : low[x + rb]) + cwidth
                dnl = (ph[x] ? 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 ph[x] and countpp < 21
                        array.set(sr_levels, countpp, high[x + rb])
                    if 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 ph or 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 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 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_
// TF1Bull   = securityNoRep1(syminfo.tickerid, "1"   , emaBull)
// TF3Bull   = securityNoRep1(syminfo.tickerid, "3"   , emaBull)
// TF5Bull   = securityNoRep1(syminfo.tickerid, "5"   , emaBull)
// TF15Bull  = securityNoRep1(syminfo.tickerid, "15"  , emaBull)
// TF30Bull  = securityNoRep1(syminfo.tickerid, "30"  , emaBull)
// TF60Bull  = securityNoRep1(syminfo.tickerid, "60"  , emaBull)
// TF120Bull = securityNoRep1(syminfo.tickerid, "120" , emaBull)
// TF240Bull = securityNoRep1(syminfo.tickerid, "240" , emaBull)
// TF480Bull = securityNoRep1(syminfo.tickerid, "480" , emaBull)
// TFDBull   = securityNoRep1(syminfo.tickerid, "1440", emaBull)
// [wt1, wt2] = wavetrend(close, 5, 10)
// [wtDivBear1, wtDivBull1] = f_findDivs(wt2, 15, -40)
// [wtDivBear2, wtDivBull2] = f_findDivs(wt2, 45, -65)
// wtDivBull = wtDivBull1 or wtDivBull2
// wtDivBear = wtDivBear1 or wtDivBear2
////////////////////////////////////////////////////////
// === 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)
//
// // === ALERT conditions
// xlong     = ta.crossover(closeSeriesAlt, openSeriesAlt)
// xshort    = ta.crossunder(closeSeriesAlt, openSeriesAlt)
// // longCond  = xlong  // alternative: longCond[1]? false : (xlong or xlong[1]) and close>closeSeriesAlt and close>=open
// // shortCond = xshort  // alternative: shortCond[1]? false : (xshort or xshort[1]) and close<closeSeriesAlt and close<=open
// // // === /ALERT conditions.
// buy       = ta.crossover(closeSeriesAlt, openSeriesAlt)
// sell      = ta.crossunder(closeSeriesAlt, openSeriesAlt)


// plotshape(buy,  title = "Buy",  text = 'Buy',  style = shape.labelup,   location = location.belowbar, color= #00DBFF, textcolor = #FFFFFF, transp = 0, size = size.tiny)
// plotshape(sell, title = "Sell", text = 'Sell', style = shape.labeldown, location = location.abovebar, color= #E91E63, textcolor = #FFFFFF, transp = 0, size = size.tiny)


// plotcandle(
  // open, high, low, close,
  // title     = 'plotcandle',
  // color     = close > open ? color.rgb(120, 9, 139) : color.rgb(69, 155, 225),
  // wickcolor = close > open ? color.rgb(120, 9, 139) : color.rgb(69, 155, 225))




// // === STRATEGY ===
// // stop loss
// slPoints = input.int(defval=0, title = 'Initial Stop Loss Points (zero to disable)', minval=0)
// tpPoints = input.int(defval=0, title = 'Initial Target Profit Points (zero for disable)', minval=0)
// // Include bar limiting algorithm
// ebar     = input.int(defval=4000, title = 'Number of Bars for Back Testing', minval=0)
// dummy    = input    (false, title = '- SET to ZERO for Daily or Longer Timeframes')
// //
// // Calculate how many mars since last bar
// tdays    = (timenow - time) / 60000.0  // number of minutes since last bar
// tdays   := timeframe.ismonthly ? tdays / 1440.0 / 5.0 / 4.3 / timeframe.multiplier :
           // timeframe.isweekly  ? tdays / 1440.0 / 5.0 / timeframe.multiplier       :
           // timeframe.isdaily   ? tdays / 1440.0 / timeframe.multiplier             :
           // tdays / timeframe.multiplier  // number of bars since last bar
// //
// //set up exit parameters
// TP = tpPoints > 0 ? tpPoints : na
// SL = slPoints > 0 ? slPoints : na


// // === /STRATEGY ===
// ////////////////////////////////////////////////////////////////////////////////
// // to automate put this in trendinview message:     {{strategy.order.alert_message}}
// i_alert_txt_entry_long  = input.text_area(defval = "", title = "Long Entry Message",  group = "Alerts")
// i_alert_txt_entry_short = input.text_area(defval = "", title = "Short Entry Message", group = "Alerts")


// // Entries and Exits with TP/SL
// if buy
    // //strategy.close("Short" , alert_message = i_alert_txt_exit_short)
    // strategy.entry("Long" , strategy.long , alert_message = i_alert_txt_entry_long)
    // alert(message = "Long position")


// if sell
    // //strategy.close("Long" , alert_message = i_alert_txt_exit_long)
    // strategy.entry("Short" , strategy.short, alert_message = i_alert_txt_entry_short)
    // alert(message = "SHort position")




//#endregion }
// ——————————— <↑↑↑ G_SCRIPT01 ↑↑↑>


//<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      (1,         'Level TP1'                     , group = G_RISK,
     tooltip =                   T_LVL)
i_lxQtyTP1   = input.float      (50,        'Qty   TP1'                     , group = G_RISK,
     tooltip =                   T_QTY)
i_lxLvlTP2   = input.float      (1.5,       'Level TP2'                     , group = G_RISK,
     tooltip =                   T_LVL)
i_lxQtyTP2   = input.float      (30,        'Qty   TP2'                     , group = G_RISK,
     tooltip =                   T_QTY)
i_lxLvlTP3   = input.float      (2,         'Level TP3'                     , group = G_RISK,
     tooltip =                   T_LVL)
i_lxQtyTP3   = input.float      (20,        '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)))


//#endregion }
// ——————————— <↑↑↑ G_SCRIPT02 ↑↑↑>


//#region ———— <↓↓↓ G_SCRIPT03 ↓↓↓> {
c_barCol = close > open ? color.rgb(120, 9, 139) : color.rgb(69, 155, 225)
barcolor(
  i_barColOn ? c_barCol : na)


// ——————————— <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 ↑↑↑>
Leave a Comment