//@version=5 VERSION = ' V6_1_24' strategy('ALGOX V6_1_24', shorttitle = '🚀〄 ALGO EXTREMEP Profit Crypto 〄🚀'+ VERSION, 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) //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //$ $ //$ Gratitude is appreciated! $ //$ You may donate via: $ //$ $ //$ Crypto-multi-currency wallet $ //$ https://tinyurl.com/4f9dr9nw $ //$ $ //$ - BTC: 1EpDN7pg1WqURcK7te5kQtgx3H17wuHiV7 $ //$ $ //$ - LTC: MJyEtVt7EFmA18Bo1vjRMbguivHnVbbWvp $ //$ $ //$ - Tether TRC20 (USDT): TWQdh36osEJ3mDrG7kGEHgSVHQSgSR61ZY $ //$ $ //$ Donate as much as you see fit. $ //$ Do it if you find the stuff useful! $ //$ 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(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) // lxTrigger = false sxTrigger = false leTrigger = ta.crossover (closeSeriesAlt, openSeriesAlt) seTrigger = ta.crossunder(closeSeriesAlt, openSeriesAlt) G_RISK = '■ ' + 'Risk Management' //#region ———— <↓↓↓ G_RISK ↓↓↓> { // ——————————— //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' // ——————————— | | | 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' // 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 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] // ——————————— // var float condition = 0.0 var float slLine = 0.0 var float entryLine = 0.0 // entryLine := leTrigger and condition[1] <= 0.0 ? close : seTrigger and condition[1] >= 0.0 ? close : nz(entryLine[1]) // 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 ) // [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 // ——————————— { // 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') // 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') // ——————————— 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)) // 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) // plot( na, title = "─── ───", 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))) // ——————————— // 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 ↑↑↑>