// Indicator link :
// https://www.tradingview.com/script/EXMF52oC-Price-Action-Channel-Master-by-JustUncleL/#:~:text=This%20indicator%20combines%20a%20number,based%20on%20various%20boundary%20criteria.
//@version=3
//
study("Price Action Channel Master by JustUncleL", shorttitle="PACMASTER", overlay=true)
//
// By: JustUncleL
// Date: 21-Jul-2017
//
//
// Description:
// This indicator combines a number of PAC types into one indicator and will
// replace some of my previously PAC scripts (some were not published).
// It draws a Moving Average (MA) channel based on various boundary criteria.
// Even though the MA choices are not limited to SMA and EMA, these would be
// the your first choices with most PAC requirements, feel free to experiment though.
// Optional 2nd channel can be displayed.
// Optional Bar colouring around the 1st channel.
//
// Options Available:
// ------------------
// 1) Select between different types of moving averages for the base (centre) MA line
// choices are :
// - SMA = Simple Moving Average (default)
// - EMA = Exponential Moving Average.
// - WMA = Weighted Moving Average
// - VWMA = Volume Weighted Moving Average
// - SMMA = Smoothed Simple Moving Average.
// - DEMA = Double Exponential Moving Average
// - TEMA = Triple Exponential Moving Average.
// - LAGMA = Laguerre Moving Average
// - HullMA = Hull Moving Average
// - SSMA = Ehlers Super Smoother Moving average
// - SWMA = Symmetrically Weighted MA with fixed length 4, wgts:[1/6,2/6,2/6,1,6]
// - ZEMA = Near Zero Lag Exponential Moving Average.
// - TMA = Triangular (smoothed) Simple Moving Average.
//
// 2) Select Channel Boundary Criteria:
// - HILO = Channel boundaries based on High and Low MAs (default).
// - ATR = Channel boundaries are Multiplier * ATR distance from base line
// - PIP = Channel boundaries are Multiplier * PIPs distance from base line
// - STDEV = Channel boundaries are Multiplier * StdDev(price) distance from base line
// (this is the same as Bollinger bands if SMA is the base MA)
// - KC = Channel boundaries are Multiplier * StdDev(True Range) distance from base line
// (this is the same as KC channel if SMA is the base MA)
//
// 3) Option to display coloured Candles around the Ribbon, the coulouring uses
// the Default candle 3-tone colour scheme:
// - Lime = candle closed above Ribbon.
// - Red = candle closed below Ribbon.
// - Gray = Candle Closed inside Ribbon.
// the Grab candles 6-tone colour scheme:
// - Lime = Bull candle closed above Ribbon.
// - Green = Bear candle closed above Ribbon.
// - Red = Bull candle closed below Ribbon.
// - DarkRed = Bear candle closed below Ribbon.
// - Aqua = Bull candle closed inside Ribbon.
// - Blue = Bear candle closed inside Ribbon.
//
// Modifications:
//
// 12-Dec-2017 : Updated imputs to use selectable options.
// Added implied GPL copyright notice.
// Added SWMA and Laguerre types to moving average options.
//
// 22-Jul-2017 : Requested good idea - Added optional second PAC channel
//
// 21-Jul-2017 : Corrected Error with KC lower boundary
// Corrected release date of script.
//
// 21-Jul-2017 : Original Version.
//
//
// -----------------------------------------------------------------------------
// Copyright 2017 JustUncleL
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// The GNU General Public License can be found here
// .
//
// -----------------------------------------------------------------------------
//
// Main Channel MA - type, source, length
ma_type = input(defval="EMA", title="CHNL 1 MA Type: ", options=["SMA", "EMA", "WMA", "VWMA", "SMMA", "DEMA", "TEMA", "LAGMA","SWMA","HullMA", "ZEMA", "TMA", "SSMA"])
ma_len = input(defval=20, title="CHNL 1 MA - Length", minval=1)
gamma = input(defval=0.77, title="CHNL 1 MA - Gamma for LAGMA (Laguerre)")
ma_src = input(close, title="CHNL 1 MA - Source")
//
pac_type = input(defval="HILO", title="CHNL 1 PAC Type: ", options=["HILO", "ATR", "PIP", "KC", "STDEV"])
mult_factor_ = input(defval=1.0, title="CHNL 1 Muliplier: ATR Ratio, #PIPs or #Deviations", minval=0,step=0.1, type=float)
mult_factor = pac_type=="PIP" and mult_factor_<1? 1 : mult_factor_
//
sBars = input(false, title="Colour Bars to PAC ( Only based on 1st channel )")
uGrabClr = input(false, title="Use Grab Candle (6-tone) Colouring, instead of default (3-tone)")
//
show_2nd = input(false, title="Enable Display of Second Channel")
//
// Optional Second Channel MA - type, source, length
ma_type2 = input(defval="EMA", title="CHNL 2 MA Type: ", options=["SMA", "EMA", "WMA", "VWMA", "SMMA", "DEMA", "TEMA", "LAGMA","SWMA","HullMA", "ZEMA", "TMA", "SSMA"])
ma_len2 = input(defval=100, title="CHNL 2 MA - Length", minval=1)
gamma2 = input(defval=0.33, title="CHNL 2 MA - Gamma for LAGMA (Laguerre)")
ma_src2 = input(close, title="CHNL 2 MA - Source")
//
pac_type2 = input(defval="HILO", title="CHNL 2 PAC Type: ", options=["HILO", "ATR", "PIP", "KC", "STDEV"])
mult_factor_2 = input(defval=1.0, title="CHNL 2 Muliplier: ATR Ratio, #PIPs or #Deviations", minval=0,step=0.1, type=float)
mult_factor2 = pac_type2=="PIP" and mult_factor_2<1? 1 : mult_factor_2
//
// - /INPUTS
// Constants colours that include fully non-transparent option.
green100 = #008000FF
lime100 = #00FF00FF
red100 = #FF0000FF
blue100 = #0000FFFF
aqua100 = #00FFFFFF
darkred100 = #8B0000FF
gray100 = #808080FF
pip=syminfo.mintick * 10
// - FUNCTIONS
// - variant(type, src, len)
// Returns MA input selection variant, default to SMA if blank or typo.
// SuperSmoother filter
// © 2013 John F. Ehlers
variant_supersmoother(src,len) =>
a1 = exp(-1.414*3.14159 / len)
b1 = 2*a1*cos(1.414*3.14159 / len)
c2 = b1
c3 = (-a1)*a1
c1 = 1 - c2 - c3
v9 = 0.0
v9 := c1*(src + nz(src[1])) / 2 + c2*nz(v9[1]) + c3*nz(v9[2])
v9
variant_smoothed(src,len) =>
v5 = 0.0
v5 := na(v5[1]) ? sma(src, len) : (v5[1] * (len - 1) + src) / len
v5
variant_zerolagema(src,len) =>
ema1 = ema(src, len)
ema2 = ema(ema1, len)
v10 = ema1+(ema1-ema2)
v10
variant_doubleema(src,len) =>
v2 = ema(src, len)
v6 = 2 * v2 - ema(v2, len)
v6
variant_tripleema(src,len) =>
v2 = ema(src, len)
v7 = 3 * (v2 - ema(v2, len)) + ema(ema(v2, len), len) // Triple Exponential
v7
//calc Laguerre
variant_lag(p,g) => // Laguerre MA
L0 = 0.0
L1 = 0.0
L2 = 0.0
L3 = 0.0
L0 := (1 - g)*p+g*nz(L0[1])
L1 := -g*L0+nz(L0[1])+g*nz(L1[1])
L2 := -g*L1+nz(L1[1])+g*nz(L2[1])
L3 := -g*L2+nz(L2[1])+g*nz(L3[1])
f = (L0 + 2*L1 + 2*L2 + L3)/6
f
// return variant, defaults to SMA
variant(type, src, len, g) =>
type=="EMA" ? ema(src,len) :
type=="WMA" ? wma(src,len):
type=="VWMA" ? vwma(src,len) :
type=="SMMA" ? variant_smoothed(src,len) :
type=="DEMA" ? variant_doubleema(src,len):
type=="TEMA" ? variant_tripleema(src,len):
type=="LAGMA" ? variant_lag(src,g) :
type=="HullMA"? wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len))) :
type=="SSMA" ? variant_supersmoother(src,len) :
type=="SWMA" ? swma(src) :
type=="ZEMA" ? variant_zerolagema(src,len) :
type=="TMA" ? sma(sma(src,len),len) : sma(src,len)
// - /variant
// - channel
// Function to get PAC Channel Boundaries
//
atrUpper(C,M,L) =>
ATR = atr(L)
x=C+M*ATR
x
atrLower(C,M,L) =>
ATR = atr(L)
x=C-M*ATR
x
pipUpper(C,M,L) =>
x=C+M*pip
x
pipLower(C,M,L) =>
x=C-M*pip
x
stdUpper(S,C,M,L) =>
y= stdev(S,L)
x=C+M*y
x
stdLower(S,C,M,L) =>
y = stdev(S,L)
x=C-M*y
x
hiloUpper(T,C,M,L,g) =>
y=variant(T,high,L,g)
y
hiloLower(T,C,M,L,g) =>
y=variant(T,low,L,g)
y
kcUpper(T,C,M,L,g) =>
y = variant(T, tr, L,g)
x = C + y * M
x
kcLower(T,C,M,L,g) =>
y = variant(T, tr, L,g)
x = C - y * M
x
channel(type, T, S, C, M, L,g) =>
Upr = type=="ATR"? atrUpper(C,M,L) : type=="STDEV"? stdUpper(S,C,M,L) : type=="PIP"? pipUpper(C,M,L) : type=="KC"? kcUpper(T,C,M,L,g) : hiloUpper(T,C,M,L,g)
Lwr = type=="ATR"? atrLower(C,M,L) : type=="STDEV"? stdLower(S,C,M,L) : type=="PIP"? pipLower(C,M,L) : type=="KC"? kcLower(T,C,M,L,g) : hiloLower(T,C,M,L,g)
[Upr,Lwr]
// - /channel
// === /FUNCTIONS ===
// -- Main Channel
pacC = variant(ma_type, ma_src, ma_len, gamma)
[pacU,pacL] = channel(pac_type, ma_type, ma_src, pacC, mult_factor, ma_len,gamma)
//
plot(pacC, color=red, linewidth=2, title="PAC Center",transp=20)
L = plot(pacL, color=blue, linewidth=1, title="PAC Lower",transp=20)
U = plot(pacU, color=blue, linewidth=1, title="PAC Upper",transp=20)
fill(L,U, color=blue, transp=95)
// Colour bars according to the close position relative to the MA selected
// Or Grab candle colour code bars according to the close position relative to the MA selected
grabcol = uGrabClr? close>=open? close>pacL and close>pacU? lime100 : closepacL and close>pacU? green100 : closepacL and close>pacU ? lime100 : close