Support Resistance Channels
"Support Resistance Channels" by LonesomeTheBlue, MPL-2.0. Ported to FloScript by FloSignals; modifications under MPL-2.0. Original: Support Resistance Channels (v6.0), read 2026-10-12T16:08:45.477Z; source language v6.
Licence: Mozilla Public License 2.0 (MPL-2.0) — full text. The source is published with it, modifications included, under the same licence.
Support Resistance Channels by LonesomeTheBlue, ported from Pine v6. Overlay indicator with 2 plots, 4 marker series, alerts and 17 inputs.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © LonesomeTheBlue
// ------------------------------------------------------------------------------------------------
// Original author: LonesomeTheBlue
// Original title: Support Resistance Channels
// Licence: MPL-2.0 (the header above is the original notice, kept verbatim)
// Pine version: 6
// Fetched: 2026-10-12
// Ported to FloScript by FloSignals; modifications under MPL-2.0.
// Converter: @flosignals/floscript 0.1.0, strict mode, score 100/100
// ------------------------------------------------------------------------------------------------
//@floscript=1
//@version=6
indicator('Support Resistance Channels', 'SRchannel', overlay=true, max_bars_back=501)
prd = input.int(defval=10, title='Pivot Period', minval=4, maxval=30, group='Settings 🔨', tooltip='Used while calculating Pivot Points, checks left&right bars')
ppsrc = input.string(defval='High/Low', title='Source', options=['High/Low', 'Close/Open'], group='Settings 🔨', tooltip='Source for Pivot Points')
ChannelW = input.int(defval=5, title='Maximum Channel Width %', minval=1, maxval=8, group='Settings 🔨', tooltip='Calculated using Highest/Lowest levels in 300 bars')
minstrength = input.int(defval=1, title='Minimum Strength', minval=1, group='Settings 🔨', tooltip='Channel must contain at least 2 Pivot Points')
maxnumsr = input.int(defval=6, title='Maximum Number of S/R', minval=1, maxval=10, group='Settings 🔨', tooltip='Maximum number of Support/Resistance Channels to Show') - 1
loopback = input.int(defval=290, title='Loopback Period', minval=100, maxval=400, group='Settings 🔨', tooltip='While calculating S/R levels it checks Pivots in Loopback Period')
res_col = input.color(defval=color.new(color.red, 75), title='Resistance Color', group='Colors 🟡🟢🟣')
sup_col = input.color(defval=color.new(color.lime, 75), title='Support Color', group='Colors 🟡🟢🟣')
inch_col = input.color(defval=color.new(color.gray, 75), title='Color When Price in Channel', group='Colors 🟡🟢🟣')
showpp = input.bool(defval=false, title='Show Pivot Points', group='Extras ⏶⏷')
showsrbroken = input.bool(defval=false, title='Show Broken Support/Resistance', group='Extras ⏶⏷')
showthema1en = input.bool(defval=false, title='MA 1', inline='ma1')
showthema1len = input.int(defval=50, title='', inline='ma1')
showthema1type = input.string(defval='SMA', title='', options=['SMA', 'EMA'], inline='ma1')
showthema2en = input.bool(defval=false, title='MA 2', inline='ma2')
showthema2len = input.int(defval=200, title='', inline='ma2')
showthema2type = input.string(defval='SMA', title='', options=['SMA', 'EMA'], inline='ma2')
ma1 = showthema1en ? (showthema1type == 'SMA' ? ta.sma(close, showthema1len) : ta.ema(close, showthema1len)) : na
ma2 = showthema2en ? (showthema2type == 'SMA' ? ta.sma(close, showthema2len) : ta.ema(close, showthema2len)) : na
plot(ma1, color=not na(ma1) ? color.blue : na)
plot(ma2, color=not na(ma2) ? color.red : na)
// get Pivot High/low
float src1 = ppsrc == 'High/Low' ? high : math.max(close, open)
float src2 = ppsrc == 'High/Low' ? low : math.min(close, open)
float ph = ta.pivothigh(src1, prd, prd)
float pl = ta.pivotlow(src2, prd, prd)
// draw Pivot points
plotshape(bool(ph) and showpp, text='H', style=shape.labeldown, color=na, textcolor=color.new(color.red, 0), location=location.abovebar, offset=-prd)
plotshape(bool(pl) and showpp, text='L', style=shape.labelup, color=na, textcolor=color.new(color.lime, 0), location=location.belowbar, offset=-prd)
//calculate maximum S/R channel width
prdhighest = ta.highest(300)
prdlowest = ta.lowest(300)
cwidth = (prdhighest - prdlowest) * ChannelW / 100
// get/keep Pivot levels
var pivotvals = array.new_float(0)
var pivotlocs = array.new_float(0)
if bool(ph) or bool(pl)
array.unshift(pivotvals, bool(ph) ? ph : pl)
array.unshift(pivotlocs, bar_index)
for x = array.size(pivotvals) - 1 to 0 by 1
if bar_index - array.get(pivotlocs, x) > loopback // remove old pivot points
array.pop(pivotvals)
array.pop(pivotlocs)
continue
break
//find/create SR channel of a pivot point
get_sr_vals(ind) =>
float lo = array.get(pivotvals, ind)
float hi = lo
int numpp = 0
for y = 0 to array.size(pivotvals) - 1 by 1
float cpp = array.get(pivotvals, y)
float wdth = cpp <= hi ? hi - cpp : cpp - lo
if wdth <= cwidth // fits the max channel width?
if cpp <= hi
lo := math.min(lo, cpp)
lo
else
hi := math.max(hi, cpp)
hi
numpp := numpp + 20 // each pivot point added as 20
numpp
[hi, lo, numpp]
// keep old SR channels and calculate/sort new channels if we met new pivot point
var suportresistance = array.new_float(20, 0) // min/max levels
changeit(x, y) =>
tmp = array.get(suportresistance, y * 2)
array.set(suportresistance, y * 2, array.get(suportresistance, x * 2))
array.set(suportresistance, x * 2, tmp)
tmp := array.get(suportresistance, y * 2 + 1)
array.set(suportresistance, y * 2 + 1, array.get(suportresistance, x * 2 + 1))
array.set(suportresistance, x * 2 + 1, tmp)
if bool(ph) or bool(pl)
supres = array.new_float(0) // number of pivot, strength, min/max levels
stren = array.new_float(10, 0)
// get levels and strengs
for x = 0 to array.size(pivotvals) - 1 by 1
[hi, lo, strength] = get_sr_vals(x)
array.push(supres, strength)
array.push(supres, hi)
array.push(supres, lo)
// add each HL to strengh
for x = 0 to array.size(pivotvals) - 1 by 1
h = array.get(supres, x * 3 + 1)
l = array.get(supres, x * 3 + 2)
s = 0
for y = 0 to loopback by 1
if high[y] <= h and high[y] >= l or low[y] <= h and low[y] >= l
s := s + 1
s
array.set(supres, x * 3, array.get(supres, x * 3) + s)
//reset SR levels
array.fill(suportresistance, 0)
// get strongest SRs
src = 0
for x = 0 to array.size(pivotvals) - 1 by 1
stv = -1. // value
stl = -1 // location
for y = 0 to array.size(pivotvals) - 1 by 1
if array.get(supres, y * 3) > stv and array.get(supres, y * 3) >= minstrength * 20
stv := array.get(supres, y * 3)
stl := y
stl
if stl >= 0
//get sr level
hh = array.get(supres, stl * 3 + 1)
ll = array.get(supres, stl * 3 + 2)
array.set(suportresistance, src * 2, hh)
array.set(suportresistance, src * 2 + 1, ll)
array.set(stren, src, array.get(supres, stl * 3))
// make included pivot points' strength zero
for y = 0 to array.size(pivotvals) - 1 by 1
if array.get(supres, y * 3 + 1) <= hh and array.get(supres, y * 3 + 1) >= ll or array.get(supres, y * 3 + 2) <= hh and array.get(supres, y * 3 + 2) >= ll
array.set(supres, y * 3, -1)
src := src + 1
if src >= 10
break
for x = 0 to 8 by 1
for y = x + 1 to 9 by 1
if array.get(stren, y) > array.get(stren, x)
tmp = array.get(stren, y)
array.set(stren, y, array.get(stren, x))
changeit(x, y)
get_level(ind) =>
float ret = na
if ind < array.size(suportresistance)
if array.get(suportresistance, ind) != 0
ret := array.get(suportresistance, ind)
ret
ret
get_color(ind) =>
color ret = na
if ind < array.size(suportresistance)
if array.get(suportresistance, ind) != 0
ret := array.get(suportresistance, ind) > close and array.get(suportresistance, ind + 1) > close ? res_col : array.get(suportresistance, ind) < close and array.get(suportresistance, ind + 1) < close ? sup_col : inch_col
ret
ret
var srchannels = array.new_box(10)
for x = 0 to math.min(9, maxnumsr) by 1
box.delete(array.get(srchannels, x))
srcol = get_color(x * 2)
if not na(srcol)
array.set(srchannels, x, box.new(left=bar_index, top=get_level(x * 2), right=bar_index + 1, bottom=get_level(x * 2 + 1), border_color=srcol, border_width=1, extend=extend.both, bgcolor=srcol))
resistancebroken = false
supportbroken = false
// check if it's not in a channel
not_in_a_channel = true
for x = 0 to math.min(9, maxnumsr) by 1
if close <= array.get(suportresistance, x * 2) and close >= array.get(suportresistance, x * 2 + 1)
not_in_a_channel := false
not_in_a_channel
// if price is not in a channel then check broken ones
if not_in_a_channel
for x = 0 to math.min(9, maxnumsr) by 1
if close[1] <= array.get(suportresistance, x * 2) and close > array.get(suportresistance, x * 2)
resistancebroken := true
resistancebroken
if close[1] >= array.get(suportresistance, x * 2 + 1) and close < array.get(suportresistance, x * 2 + 1)
supportbroken := true
supportbroken
alertcondition(resistancebroken, title='Resistance Broken', message='Resistance Broken')
alertcondition(supportbroken, title='Support Broken', message='Support Broken')
plotshape(showsrbroken and resistancebroken, style=shape.triangleup, location=location.belowbar, color=color.new(color.lime, 0), size=size.tiny)
plotshape(showsrbroken and supportbroken, style=shape.triangledown, location=location.abovebar, color=color.new(color.red, 0), size=size.tiny)
This file is under the Mozilla Public License 2.0; it is a port of the original by LonesomeTheBlue, with the original licence header kept and the changes made for FloScript noted in the file.
- v2
Library refresh 2026-10-14
- v1
Library refresh 2026-10-12
Disclaimer. Scripts are written and published by members, or ported by FloSignals from open-source originals, and are their authors' own work and opinion. FloSignals does not review them for correctness and nothing in a script is financial advice or a recommendation to buy or sell anything — read the Risk Disclaimer. Posting here is under the Community Rules; a script that is not the poster's to post can be reported as the Copyright & Takedowns page says.

Comments (0)
No comments yet. Members can leave one.