Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 18

//@version=4

study("Regression Channel [DW]", overlay=true, max_bars_back=5000)

//This is an experimental study which calculates a linear regression channel


over a specified period or interval using custom moving average types for its
calculations.

//linear regression is a linear approach to modeling the relationship between


a dependent variable and one or more independent variables.
//In linear regression, the relationships are modeled using linear predictor
functions whose unknown model parameters are estimated from the data.

//The regression channel in this study is modeled using the least squares
approach with four base average types to choose from:
// -> Arnaud Legoux Moving Average (ALMA)
// -> Exponential Moving Average (EMA)
// -> Simple Moving Average (SMA)
// -> Volume Weighted Moving Average (VWMA)
//When using VWMA, if no volume is present, the calculation will
automatically switch to tick volume, making it compatible with any
cryptocurrency, stock, currency pair, or index you want to analyze.

//There are two window types for calculation in this script as well:
// -> Continuous, which generates a regression model over a fixed number of
bars continuously.
// -> Interval, which generates a regression model that only moves its
starting point when a new interval starts. The number of bars for calculation
cumulatively increases until the end of the interval.

//The channel is generated by calculating standard deviation multiplied by


the channel width coefficient, adding it to and subtracting it from the
regression line, then dividing it into quartiles.

//To observe the path of the regression, I've included a tracer line, which
follows the current point of the regression line. This is also referred to as
a Least Squares Moving Average (LSMA).

//For added predictive capability, there is an option to extend the channel


lines into the future.

//A custom bar color scheme based on channel direction and price proximity to
the current regression value is included.

//I don't necessarily recommend using this tool as a standalone, but rather
as a supplement to your analysis systems.
//Regression analysis is far from an exact science. However, with the right
combination of tools and strategies in place, it can greatly enhance your
analysis and trading.
//---------------------------------------------------------------------------
-----------------------------------------------------------------------------
---------
//Updates:
// -> Script structure has been reorganized.
// -> Corrected NaN filter values in initial states.
// -> Added Rolling Moving Average and Linear Weighted Moving Average to the
list of available base averages.
// -> Added style customization for the channel lines. Because TV doesn't
have built-in style inputs for line objects, you'll find these settings in
the "Inputs" section. For each channel line, you can now adjust:
// - If the line is drawn - selected via the specified toggle switch
// - Width of the line - can be any integer greater than zero
// - Style of the line - available styles are solid, dotted, and dashed
// - Color of the line - uses my RGB color editor, which has 216 colors to
choose from via the specified R, G, and B inputs

//---------------------------------------------------------------------------
-----------------------------------------------------------------------------
---------
//Functions
//---------------------------------------------------------------------------
-----------------------------------------------------------------------------
---------

//Interval Renewal Function


newbar(T)=>
t = time(T)
newbar = (na(t[1]) and not na(t)) or (nz(t[1], t) < t) ? 1 : 0
newbar

//ALMA Function
ALMA(y, t)=>
m = (0.85*(t - 1))
s = t/6
wt = 0.0
wtsum = 0.0
cumwt = 0.0
for i = 0 to (t - 1)
wt := exp(-pow((i - m), 2)/(2*pow(s, 2)))
wtsum := wtsum + wt*nz(y[t - 1 - i], y)
cumwt := cumwt + wt
ALMA = wtsum/cumwt
ALMA

//EMA Function
EMA(y, t)=>
EMA = y
EMA := na(EMA[1]) ? y : (y - nz(EMA[1]))*(2/(t + 1)) + nz(EMA[1])
EMA
//SMA Function
SMA(y, t)=>
num_sum = 0.0
for i = 0 to (t - 1)
num_sum := num_sum + nz(y[i], y)
SMA = num_sum/t
SMA

//SMMA Function
RMA(y, t)=>
RMA = 0.0
RMA := na(RMA[1]) ? SMA(y, t) : (nz(RMA[1])*(t - 1) + y)/t
RMA

//LWMA Function
LWMA(y, t)=>
num_sum = 0.0
den_sum = 0.0
for i = 0 to (t - 1)
num_sum := num_sum + (t - i)*nz(y[i], y)
den_sum := den_sum + (t - i)
LWMA = num_sum/den_sum
LWMA

//VWMA Function With Tick Volume Substitution For NaN Values


VWMA(y, t)=>
tick = syminfo.mintick
rng = high - low
var tickrng = tick
tickrng := abs(rng) < tick ? tickrng : rng
tickvol = abs(tickrng)/tick
vol = na(volume) ? tickvol : volume
vp = y*vol
vpsum = 0.0
vsum = 0.0
for i = 0 to (t - 1)
vpsum := vpsum + nz(vp[i], vp)
vsum := vsum + nz(vol[i], vol)
VWMA = vpsum/vsum
VWMA

//Filter Selector Function


filt(y, t, f_type)=>
(f_type=="ALMA" ? ALMA(y, t) :
f_type=="EMA" ? EMA(y, t) :
f_type=="SMA" ? SMA(y, t) :
f_type=="RMA" ? RMA(y, t) :
f_type=="LWMA" ? LWMA(y, t) :
VWMA(y, t))

//Filtered Standard Deviation Function


st_dev(y, t, filt_type, ndev) =>
sqrt(filt(pow(y - filt(y, t, filt_type), 2), t, filt_type))*ndev

//Correlation Coefficient Function


corr(x, y, t, f_type)=>
x_dev = round(t/2)
y_dev = y - filt(y, t, f_type)
xy_sum = 0.0
x2_sum = 0.0
y2_sum = 0.0
for i = 0 to (t - 1)
xy_sum := xy_sum + x_dev*nz(y_dev[i], y_dev)
x2_sum := x2_sum + pow(x_dev, 2)
y2_sum := y2_sum + pow(nz(y_dev[i], y_dev), 2)
den = sqrt(x2_sum*y2_sum)
corr = den==0 ? 0 : xy_sum/den
corr

//Linear Regression Y Coordinate Function


lin_reg_filt(y, t, f_type, m)=>
x = bar_index
r = corr(x, y, t, f_type)
sy = st_dev(y, t, f_type, m)
sx = round(t/2)
y_mean = filt(y, t, f_type)
x_mean = nz(bar_index[sx], 0)
b = t==1 ? 0 : r*(sy/sx)
a = y_mean - b*x_mean
Y1 = a + b*nz(x[t - 1], x)
Y2 = a + b*x
[Y1, Y2]

//Line Drawing Function


draw_line(Y1, Y2, t, col, ls, lw, extend)=>
int X1 = nz(bar_index[t - 1], 0)
int X2 = bar_index
var line Line = na
if bar_index != nz(bar_index[1], 0)
line.delete(Line)
Line := line.new(x1=X1, y1=Y1, x2=X2, y2=Y2, xloc=xloc.bar_index,
extend=extend, color=col, style=ls=="Solid" ? line.style_solid : ls=="Dotted"
? line.style_dotted : line.style_dashed, width=lw)

//Color Selector Function


rgb_color(r, g, b)=>
int trans = 0
color rgb_color = #000000
if r=="0"
if g=="0"
rgb_color := b=="51" ? color.new(#000033, trans) : b=="102" ?
color.new(#000066, trans) : b=="153" ? color.new(#000099, trans) : b=="204" ?
color.new(#0000cc, trans) : b=="255" ? color.new(#0000ff, trans) :
color.new(#000000, trans)
if g=="51"
rgb_color := b=="51" ? color.new(#003333, trans) : b=="102" ?
color.new(#003366, trans) : b=="153" ? color.new(#003399, trans) : b=="204" ?
color.new(#0033cc, trans) : b=="255" ? color.new(#0033ff, trans) :
color.new(#003300, trans)
if g=="102"
rgb_color := b=="51" ? color.new(#006633, trans) : b=="102" ?
color.new(#006666, trans) : b=="153" ? color.new(#006699, trans) : b=="204" ?
color.new(#0066cc, trans) : b=="255" ? color.new(#0066ff, trans) :
color.new(#006600, trans)
if g=="153"
rgb_color := b=="51" ? color.new(#009933, trans) : b=="102" ?
color.new(#009966, trans) : b=="153" ? color.new(#009999, trans) : b=="204" ?
color.new(#0099cc, trans) : b=="255" ? color.new(#0099ff, trans) :
color.new(#009900, trans)
if g=="204"
rgb_color := b=="51" ? color.new(#00cc33, trans) : b=="102" ?
color.new(#00cc66, trans) : b=="153" ? color.new(#00cc99, trans) : b=="204" ?
color.new(#00cccc, trans) : b=="255" ? color.new(#00ccff, trans) :
color.new(#00cc00, trans)
if g=="255"
rgb_color := b=="51" ? color.new(#00ff33, trans) : b=="102" ?
color.new(#00ff66, trans) : b=="153" ? color.new(#00ff99, trans) : b=="204" ?
color.new(#00ffcc, trans) : b=="255" ? color.new(#00ffff, trans) :
color.new(#00ff00, trans)
if r=="51"
if g=="0"
rgb_color := b=="51" ? color.new(#330033, trans) : b=="102" ?
color.new(#330066, trans) : b=="153" ? color.new(#330099, trans) : b=="204" ?
color.new(#3300cc, trans) : b=="255" ? color.new(#3300ff, trans) :
color.new(#330000, trans)
if g=="51"
rgb_color := b=="51" ? color.new(#333333, trans) : b=="102" ?
color.new(#333366, trans) : b=="153" ? color.new(#333399, trans) : b=="204" ?
color.new(#3333cc, trans) : b=="255" ? color.new(#3333ff, trans) :
color.new(#333300, trans)
if g=="102"
rgb_color := b=="51" ? color.new(#336633, trans) : b=="102" ?
color.new(#336666, trans) : b=="153" ? color.new(#336699, trans) : b=="204" ?
color.new(#3366cc, trans) : b=="255" ? color.new(#3366ff, trans) :
color.new(#336600, trans)
if g=="153"
rgb_color := b=="51" ? color.new(#339933, trans) : b=="102" ?
color.new(#339966, trans) : b=="153" ? color.new(#339999, trans) : b=="204" ?
color.new(#3399cc, trans) : b=="255" ? color.new(#3399ff, trans) :
color.new(#339900, trans)
if g=="204"
rgb_color := b=="51" ? color.new(#33cc33, trans) : b=="102" ?
color.new(#33cc66, trans) : b=="153" ? color.new(#33cc99, trans) : b=="204" ?
color.new(#33cccc, trans) : b=="255" ? color.new(#33ccff, trans) :
color.new(#33cc00, trans)
if g=="255"
rgb_color := b=="51" ? color.new(#33ff33, trans) : b=="102" ?
color.new(#33ff66, trans) : b=="153" ? color.new(#33ff99, trans) : b=="204" ?
color.new(#33ffcc, trans) : b=="255" ? color.new(#33ffff, trans) :
color.new(#33ff00, trans)
if r=="102"
if g=="0"
rgb_color := b=="51" ? color.new(#660033, trans) : b=="102" ?
color.new(#660066, trans) : b=="153" ? color.new(#660099, trans) : b=="204" ?
color.new(#6600cc, trans) : b=="255" ? color.new(#6600ff, trans) :
color.new(#660000, trans)
if g=="51"
rgb_color := b=="51" ? color.new(#663333, trans) : b=="102" ?
color.new(#663366, trans) : b=="153" ? color.new(#663399, trans) : b=="204" ?
color.new(#6633cc, trans) : b=="255" ? color.new(#6633ff, trans) :
color.new(#663300, trans)
if g=="102"
rgb_color := b=="51" ? color.new(#666633, trans) : b=="102" ?
color.new(#666666, trans) : b=="153" ? color.new(#666699, trans) : b=="204" ?
color.new(#6666cc, trans) : b=="255" ? color.new(#6666ff, trans) :
color.new(#666600, trans)
if g=="153"
rgb_color := b=="51" ? color.new(#669933, trans) : b=="102" ?
color.new(#669966, trans) : b=="153" ? color.new(#669999, trans) : b=="204" ?
color.new(#6699cc, trans) : b=="255" ? color.new(#6699ff, trans) :
color.new(#669900, trans)
if g=="204"
rgb_color := b=="51" ? color.new(#66cc33, trans) : b=="102" ?
color.new(#66cc66, trans) : b=="153" ? color.new(#66cc99, trans) : b=="204" ?
color.new(#66cccc, trans) : b=="255" ? color.new(#66ccff, trans) :
color.new(#66cc00, trans)
if g=="255"
rgb_color := b=="51" ? color.new(#66ff33, trans) : b=="102" ?
color.new(#66ff66, trans) : b=="153" ? color.new(#66ff99, trans) : b=="204" ?
color.new(#66ffcc, trans) : b=="255" ? color.new(#66ffff, trans) :
color.new(#66ff00, trans)
if r=="153"
if g=="0"
rgb_color := b=="51" ? color.new(#990033, trans) : b=="102" ?
color.new(#990066, trans) : b=="153" ? color.new(#990099, trans) : b=="204" ?
color.new(#9900cc, trans) : b=="255" ? color.new(#9900ff, trans) :
color.new(#990000, trans)
if g=="51"
rgb_color := b=="51" ? color.new(#993333, trans) : b=="102" ?
color.new(#993366, trans) : b=="153" ? color.new(#993399, trans) : b=="204" ?
color.new(#9933cc, trans) : b=="255" ? color.new(#9933ff, trans) :
color.new(#993300, trans)
if g=="102"
rgb_color := b=="51" ? color.new(#996633, trans) : b=="102" ?
color.new(#996666, trans) : b=="153" ? color.new(#996699, trans) : b=="204" ?
color.new(#9966cc, trans) : b=="255" ? color.new(#9966ff, trans) :
color.new(#996600, trans)
if g=="153"
rgb_color := b=="51" ? color.new(#999933, trans) : b=="102" ?
color.new(#999966, trans) : b=="153" ? color.new(#999999, trans) : b=="204" ?
color.new(#9999cc, trans) : b=="255" ? color.new(#9999ff, trans) :
color.new(#999900, trans)
if g=="204"
rgb_color := b=="51" ? color.new(#99cc33, trans) : b=="102" ?
color.new(#99cc66, trans) : b=="153" ? color.new(#99cc99, trans) : b=="204" ?
color.new(#99cccc, trans) : b=="255" ? color.new(#99ccff, trans) :
color.new(#99cc00, trans)
if g=="255"
rgb_color := b=="51" ? color.new(#99ff33, trans) : b=="102" ?
color.new(#99ff66, trans) : b=="153" ? color.new(#99ff99, trans) : b=="204" ?
color.new(#99ffcc, trans) : b=="255" ? color.new(#99ffff, trans) :
color.new(#99ff00, trans)
if r=="204"
if g=="0"
rgb_color := b=="51" ? color.new(#cc0033, trans) : b=="102" ?
color.new(#cc0066, trans) : b=="153" ? color.new(#cc0099, trans) : b=="204" ?
color.new(#cc00cc, trans) : b=="255" ? color.new(#cc00ff, trans) :
color.new(#cc0000, trans)
if g=="51"
rgb_color := b=="51" ? color.new(#cc3333, trans) : b=="102" ?
color.new(#cc3366, trans) : b=="153" ? color.new(#cc3399, trans) : b=="204" ?
color.new(#cc33cc, trans) : b=="255" ? color.new(#cc33ff, trans) :
color.new(#cc3300, trans)
if g=="102"
rgb_color := b=="51" ? color.new(#cc6633, trans) : b=="102" ?
color.new(#cc6666, trans) : b=="153" ? color.new(#cc6699, trans) : b=="204" ?
color.new(#cc66cc, trans) : b=="255" ? color.new(#cc66ff, trans) :
color.new(#cc6600, trans)
if g=="153"
rgb_color := b=="51" ? color.new(#cc9933, trans) : b=="102" ?
color.new(#cc9966, trans) : b=="153" ? color.new(#cc9999, trans) : b=="204" ?
color.new(#cc99cc, trans) : b=="255" ? color.new(#cc99ff, trans) :
color.new(#cc9900, trans)
if g=="204"
rgb_color := b=="51" ? color.new(#cccc33, trans) : b=="102" ?
color.new(#cccc66, trans) : b=="153" ? color.new(#cccc99, trans) : b=="204" ?
color.new(#cccccc, trans) : b=="255" ? color.new(#ccccff, trans) :
color.new(#cccc00, trans)
if g=="255"
rgb_color := b=="51" ? color.new(#ccff33, trans) : b=="102" ?
color.new(#ccff66, trans) : b=="153" ? color.new(#ccff99, trans) : b=="204" ?
color.new(#ccffcc, trans) : b=="255" ? color.new(#ccffff, trans) :
color.new(#ccff00, trans)
if r=="255"
if g=="0"
rgb_color := b=="51" ? color.new(#ff0033, trans) : b=="102" ?
color.new(#ff0066, trans) : b=="153" ? color.new(#ff0099, trans) : b=="204" ?
color.new(#ff00cc, trans) : b=="255" ? color.new(#ff00ff, trans) :
color.new(#ff0000, trans)
if g=="51"
rgb_color := b=="51" ? color.new(#ff3333, trans) : b=="102" ?
color.new(#ff3366, trans) : b=="153" ? color.new(#ff3399, trans) : b=="204" ?
color.new(#ff33cc, trans) : b=="255" ? color.new(#ff33ff, trans) :
color.new(#ff3300, trans)
if g=="102"
rgb_color := b=="51" ? color.new(#ff6633, trans) : b=="102" ?
color.new(#ff6666, trans) : b=="153" ? color.new(#ff6699, trans) : b=="204" ?
color.new(#ff66cc, trans) : b=="255" ? color.new(#ff66ff, trans) :
color.new(#ff6600, trans)
if g=="153"
rgb_color := b=="51" ? color.new(#ff9933, trans) : b=="102" ?
color.new(#ff9966, trans) : b=="153" ? color.new(#ff9999, trans) : b=="204" ?
color.new(#ff99cc, trans) : b=="255" ? color.new(#ff99ff, trans) :
color.new(#ff9900, trans)
if g=="204"
rgb_color := b=="51" ? color.new(#ffcc33, trans) : b=="102" ?
color.new(#ffcc66, trans) : b=="153" ? color.new(#ffcc99, trans) : b=="204" ?
color.new(#ffcccc, trans) : b=="255" ? color.new(#ffccff, trans) :
color.new(#ffcc00, trans)
if g=="255"
rgb_color := b=="51" ? color.new(#ffff33, trans) : b=="102" ?
color.new(#ffff66, trans) : b=="153" ? color.new(#ffff99, trans) : b=="204" ?
color.new(#ffffcc, trans) : b=="255" ? color.new(#ffffff, trans) :
color.new(#ffff00, trans)
rgb_color

//---------------------------------------------------------------------------
-----------------------------------------------------------------------------
---------
//Inputs
//---------------------------------------------------------------------------
-----------------------------------------------------------------------------
---------

//Source
src = input(defval=close, title="Source")

//Filter Type
filt_type = input(defval="SMA", options=["ALMA", "EMA", "SMA", "RMA", "LWMA",
"VWMA"], title="Base Average Type")

//Window Type
w_type = input(defval="Continuous", options=["Continuous", "Interval"],
title="Window Type")
//Sampling Period
len = input(defval=200, minval=2, title="Sampling Length (for Continuous
Window Type)")

//Interval Size
res = input(defval="D", title="Interval Size (For Interval Window Type)")

//Channel Width Coefficient


ndev = input(defval=1.0, minval=0, title="Channel Width Coefficient")

//Extended Lines Toggle Switch


extend_lines = input(defval=false, title="Extend Lines") ? extend.right :
extend.none

//Regression Line Toggle


show_reg_line = input(defval=true, title="Show Regression Line
═══════════════════════════════")

//Regression Line Width


reg_lw = input(defval=4, minval=1, title="Regression Line Width")

//Regression Line Style


reg_ls = input(defval="Solid", options=["Solid", "Dotted", "Dashed"],
title="Regression Line Style")

//Regression Line Positive Color Inputs


pos_line_R = input(defval="0", options=["0", "51", "102", "153", "204",
"255"], title="Regression Line Positive Color R Input")
pos_line_G = input(defval="255", options=["0", "51", "102", "153", "204",
"255"], title="Regression Line Positive Color G Input")
pos_line_B = input(defval="0", options=["0", "51", "102", "153", "204",
"255"], title="Regression Line Positive Color B Input")

//Regression Line Negative Color Inputs


neg_line_R = input(defval="255", options=["0", "51", "102", "153", "204",
"255"], title="Regression Line Negative Color R Input")
neg_line_G = input(defval="0", options=["0", "51", "102", "153", "204",
"255"], title="Regression Line Negative Color G Input")
neg_line_B = input(defval="0", options=["0", "51", "102", "153", "204",
"255"], title="Regression Line Negative Color B Input")

//Channel High Line Toggle


show_hi_line = input(defval=true, title="Show Channel High Line
═══════════════════════════════")

//Channel High Line Width


hi_lw = input(defval=2, minval=1, title="Channel High Line Width")

//Channel High Line Style


hi_ls = input(defval="Solid", options=["Solid", "Dotted", "Dashed"],
title="Channel High Line Style")
//Channel High Line Color Inputs
hi_line_R = input(defval="0", options=["0", "51", "102", "153", "204",
"255"], title="Channel High Line Color R Input")
hi_line_G = input(defval="255", options=["0", "51", "102", "153", "204",
"255"], title="Channel High Line Color G Input")
hi_line_B = input(defval="0", options=["0", "51", "102", "153", "204",
"255"], title="Channel High Line Color B Input")

//Channel Q3 Line Toggle


show_q3_line = input(defval=true, title="Show Channel Q3 Line
═══════════════════════════════")

//Channel Q3 Line Width


q3_lw = input(defval=2, minval=1, title="Channel Q3 Line Width")

//Channel Q2 Line Style


q3_ls = input(defval="Dashed", options=["Solid", "Dotted", "Dashed"],
title="Channel Q3 Line Style")

//Channel Q3 Line Color Inputs


q3_line_R = input(defval="0", options=["0", "51", "102", "153", "204",
"255"], title="Channel Q3 Line Color R Input")
q3_line_G = input(defval="204", options=["0", "51", "102", "153", "204",
"255"], title="Channel Q3 Line Color G Input")
q3_line_B = input(defval="0", options=["0", "51", "102", "153", "204",
"255"], title="Channel Q3 Line Color B Input")

show_q1_line = input(defval=true, title="Show Channel Q1 Line


═══════════════════════════════")

//Channel Q1 Line Width


q1_lw = input(defval=2, minval=1, title="Channel Q1 Line Width")

//Channel Q1 Line Style


q1_ls = input(defval="Dashed", options=["Solid", "Dotted", "Dashed"],
title="Channel Q1 Line Style")

//Channel Q1 Line Color Inputs


q1_line_R = input(defval="204", options=["0", "51", "102", "153", "204",
"255"], title="Channel Q1 Line Color R Input")
q1_line_G = input(defval="0", options=["0", "51", "102", "153", "204",
"255"], title="Channel Q1 Line Color G Input")
q1_line_B = input(defval="0", options=["0", "51", "102", "153", "204",
"255"], title="Channel Q1 Line Color B Input")

//Channel Low Line Toggle


show_lo_line = input(defval=true, title="Show Channel Low Line
═══════════════════════════════")

//Channel Low Line Width


lo_lw = input(defval=2, minval=1, title="Channel Low Line Width")

//Channel Low Line Style


lo_ls = input(defval="Solid", options=["Solid", "Dotted", "Dashed"],
title="Channel Low Line Style")

//Channel Low Line Color Inputs


lo_line_R = input(defval="255", options=["0", "51", "102", "153", "204",
"255"], title="Channel Low Line Color R Input")
lo_line_G = input(defval="0", options=["0", "51", "102", "153", "204",
"255"], title="Channel Low Line Color G Input")
lo_line_B = input(defval="0", options=["0", "51", "102", "153", "204",
"255"], title="Channel Low Line Color B Input")

//---------------------------------------------------------------------------
-----------------------------------------------------------------------------
---------
//Definitions
//---------------------------------------------------------------------------
-----------------------------------------------------------------------------
---------

//Interval Renewal Condition


newint = newbar(res) ? 1 : 0

//Interval Bars
var int inter_bars = 1
inter_bars := newint ? 1 : inter_bars + 1

//Sampling Period Selection


int per = w_type=="Interval" ? inter_bars : int(len)

//Standard Deviation
s_dev = st_dev(src, per, filt_type, ndev)

//Linear Regression Y Values


[y_1, y_2] = lin_reg_filt(src, per, filt_type, ndev)

//Colors
pos_color = rgb_color(pos_line_R, pos_line_G, pos_line_B)
neg_color = rgb_color(neg_line_R, neg_line_G, neg_line_B)
hi_color = rgb_color(hi_line_R, hi_line_G, hi_line_B)
q3_color = rgb_color(q3_line_R, q3_line_G, q3_line_B)
q1_color = rgb_color(q1_line_R, q1_line_G, q1_line_B)
lo_color = rgb_color(lo_line_R, lo_line_G, lo_line_B)
reg_color = y_2 > y_1 ? pos_color : y_2 < y_1 ? neg_color :
color.new(#cccccc, 0)
bar_color = (src > y_2) and (y_2 <= y_1) ? #008b00 :
(src > y_2) and (y_2 > y_1) ? #00ff00 :
(src < y_2) and (y_2 >= y_1) ? #8b0000 :
(src < y_2) and (y_2 < y_1) ? #ff0000 : #cccccc
//---------------------------------------------------------------------------
-----------------------------------------------------------------------------
---------
//Outputs
//---------------------------------------------------------------------------
-----------------------------------------------------------------------------
---------

//Regression Line Tracer


plot(y_2, color=#ffffff, linewidth=1, title="Regression Line Current Value")

//Regression Line
if show_reg_line
draw_line(y_1, y_2, per, reg_color, reg_ls, reg_lw, extend_lines)

//Channel High Line


if show_hi_line
draw_line(y_1 + s_dev, y_2 + s_dev, per, hi_color, hi_ls, hi_lw,
extend_lines)

//Channel Q3 Line
if show_q3_line
draw_line(y_1 + s_dev/2, y_2 + s_dev/2, per, q3_color, q3_ls, q3_lw,
extend_lines)

//Channel Q1 Line
if show_q1_line
draw_line(y_1 - s_dev/2, y_2 - s_dev/2, per, q1_color, q1_ls, q1_lw,
extend_lines)

//Channel Low Line


if show_lo_line
draw_line(y_1 - s_dev, y_2 - s_dev, per, lo_color, lo_ls, lo_lw,
extend_lines)

//Bar Color
barcolor(bar_color)

startyear = input(defval = 2020, title = "Start Year")


startmonth = input(defval = 1, title = "Start Month")
startday = input(defval = 1, title = "Start day")
prd = input(defval = 20, title="Pivot Period", minval = 10, maxval = 50)
PPnum = input(defval = 3, title="Number of Pivot Points to check", minval =
2, maxval = 6)
utcol = input(defval = color.lime, title = "Colors", inline = "tcol")
dtcol = input(defval = color.red, title = "", inline = "tcol")

float ph = pivothigh(prd, prd)


float pl = pivotlow(prd, prd)

var tval = array.new_float(PPnum)


var tpos = array.new_int(PPnum)
var bval = array.new_float(PPnum)
var bpos = array.new_int(PPnum)

add_to_array(apointer1, apointer2, val)=>


array.unshift(apointer1, val)
array.unshift(apointer2, bar_index)
array.pop(apointer1)
array.pop(apointer2)

if ph
add_to_array(tval, tpos, ph)

if pl
add_to_array(bval, bpos, pl)

// line definitions
maxline = 3
var bln = array.new_line(maxline, na)
var tln = array.new_line(maxline, na)

// loop for pivot points to check if there is possible trend line


countlinelo = 0
countlinehi = 0

starttime = timestamp(startyear, startmonth, startday, 0, 0, 0)

if time >= starttime


for x = 0 to maxline - 1
line.delete(array.get(bln, x))
line.delete(array.get(tln, x))
for p1 = 0 to PPnum - 2
uv1 = 0.0
uv2 = 0.0
up1 = 0
up2 = 0
if countlinelo <= maxline
for p2 = PPnum - 1 to p1 + 1
val1 = array.get(bval, p1)
val2 = array.get(bval, p2)
pos1 = array.get(bpos, p1)
pos2 = array.get(bpos, p2)
if val1 > val2
diff = (val1 - val2) / (pos1 - pos2)
hline = val2 + diff
lloc = bar_index
lval = low
valid = true
for x = pos2 + 1 - prd to bar_index
if close[bar_index - x] < hline
valid := false
break
lloc := x
lval := hline
hline := hline + diff

if valid
uv1 := hline - diff
uv2 := val2
up1 := lloc
up2 := pos2
break

dv1 = 0.0
dv2 = 0.0
dp1 = 0
dp2 = 0
if countlinehi <= maxline
for p2 = PPnum - 1 to p1 + 1
val1 = array.get(tval, p1)
val2 = array.get(tval, p2)
pos1 = array.get(tpos, p1)
pos2 = array.get(tpos, p2)
if val1 < val2
diff = (val2 - val1) / float(pos1 - pos2)
hline = val2 - diff
lloc = bar_index
lval = high
valid = true
for x = pos2 + 1 - prd to bar_index
if close[bar_index - x] > hline
valid := false
break
lloc := x
lval := hline
hline := hline - diff

if valid
dv1 := hline + diff
dv2 := val2
dp1 := lloc
dp2 := pos2
break

// if there is continues uptrend line then draw it


if up1 != 0 and up2 != 0 and countlinelo < maxline
countlinelo += 1
array.set(bln, countlinelo - 1, line.new(up2 - prd, uv2, up1,
uv1, color = utcol))

// if there is continues downtrend line then draw it


if dp1 != 0 and dp2 != 0 and countlinehi < maxline
countlinehi += 1
array.set(tln, countlinehi - 1, line.new(dp2 - prd, dv2, dp1,
dv1, color = dtcol))

overlay_main = input(false, title="Plot on price (rather than on indicator)")


osc = input(ohlc4, title="Indicator", type=input.source)
lbR = input(title="Pivot Lookback Right", defval=5)
lbL = input(title="Pivot Lookback Left", defval=5)
rangeUpper = input(title="Max of Lookback Range", defval=60)
rangeLower = input(title="Min of Lookback Range", defval=5)
plotBull = input(title="Plot Bullish", defval=true)
plotHiddenBull = input(title="Plot Hidden Bullish", defval=false)
plotBear = input(title="Plot Bearish", defval=true)
plotHiddenBear = input(title="Plot Hidden Bearish", defval=false)
delay_plot_til_closed = input(title="Delay plot until candle is closed (don't
repaint)", defval=false)
bearColor = color.red
bullColor = color.green
hiddenBullColor = color.new(color.green, 80)
hiddenBearColor = color.new(color.red, 80)
textColor = color.white
noneColor = color.new(color.white, 100)

repaint = (not(delay_plot_til_closed) or barstate.ishistory or


barstate.isconfirmed)

plFound = na(pivotlow(osc, lbL, lbR)) ? false : true


phFound = na(pivothigh(osc, lbL, lbR)) ? false : true
_inRange(cond) =>
bars = barssince(cond == true)
rangeLower <= bars and bars <= rangeUpper

//---------------------------------------------------------------------------
---
// Regular Bullish
// Osc: Higher Low
oscHL = osc[lbR] > valuewhen(plFound, osc[lbR], 1) and _inRange(plFound[1])

// Price: Lower Low

priceLL = low[lbR] < valuewhen(plFound, low[lbR], 1)


bullCond = plotBull and priceLL and oscHL and plFound and repaint

plot(
plFound ? overlay_main ? low[lbR] : osc[lbR] : na,
offset=-lbR,
title="Regular Bullish",
linewidth=2,
color=(bullCond ? bullColor : noneColor),
transp=0
)

plotshape(
bullCond ? overlay_main ? low[lbR] : osc[lbR] : na,
offset=-lbR,
title="Regular Bullish Label",
text=" Bull ",
style=shape.labelup,
location=location.absolute,
color=bullColor,
textcolor=textColor,
transp=0
)

//---------------------------------------------------------------------------
---
// Hidden Bullish
// Osc: Lower Low

oscLL = osc[lbR] < valuewhen(plFound, osc[lbR], 1) and _inRange(plFound[1])

// Price: Higher Low

priceHL = low[lbR] > valuewhen(plFound, low[lbR], 1)


hiddenBullCond = plotHiddenBull and priceHL and oscLL and plFound and repaint

plot(
plFound ? overlay_main ? low[lbR] : osc[lbR] : na,
offset=-lbR,
title="Hidden Bullish",
linewidth=2,
color=(hiddenBullCond ? hiddenBullColor : noneColor),
transp=0
)

plotshape(
hiddenBullCond ? overlay_main ? low[lbR] : osc[lbR] : na,
offset=-lbR,
title="Hidden Bullish Label",
text=" H Bull ",
style=shape.labelup,
location=location.absolute,
color=bullColor,
textcolor=textColor,
transp=0
)

//---------------------------------------------------------------------------
---
// Regular Bearish
// Osc: Lower High

oscLH = osc[lbR] < valuewhen(phFound, osc[lbR], 1) and _inRange(phFound[1])

// Price: Higher High

priceHH = high[lbR] > valuewhen(phFound, high[lbR], 1)

bearCond = plotBear and priceHH and oscLH and phFound and repaint

plot(
phFound ? overlay_main ? high[lbR] : osc[lbR] : na,
offset=-lbR,
title="Regular Bearish",
linewidth=2,
color=(bearCond ? bearColor : noneColor),
transp=0
)

plotshape(
bearCond ? overlay_main ? high[lbR] : osc[lbR] : na,
offset=-lbR,
title="Regular Bearish Label",
text=" Bear ",
style=shape.labeldown,
location=location.absolute,
color=bearColor,
textcolor=textColor,
transp=0
)

//---------------------------------------------------------------------------
---
// Hidden Bearish
// Osc: Higher High

oscHH = osc[lbR] > valuewhen(phFound, osc[lbR], 1) and _inRange(phFound[1])


// Price: Lower High

priceLH = high[lbR] < valuewhen(phFound, high[lbR], 1)

hiddenBearCond = plotHiddenBear and priceLH and oscHH and phFound and repaint

plot(
phFound ? overlay_main ? high[lbR] : osc[lbR] : na,
offset=-lbR,
title="Hidden Bearish",
linewidth=2,
color=(hiddenBearCond ? hiddenBearColor : noneColor),
transp=0
)

plotshape(
hiddenBearCond ? overlay_main ? high[lbR] : osc[lbR] : na,
offset=-lbR,
title="Hidden Bearish Label",
text=" H Bear ",
style=shape.labeldown,
location=location.absolute,
color=bearColor,
textcolor=textColor,
transp=0
)

You might also like