Author message:
The LOWESS (Locally Weighted Scatterplot Smoothing) [ChartPrime] indicator is an advanced technical analysis tool that combines LOWESS smoothing with a Modified Adaptive Gaussian Moving Average. This indicator provides traders with a sophisticated method for trend analysis, pivot point identification, and breakout detection.
Read more: https://www.tradingview.com/script/...ly-Weighted-Scatterplot-Smoothing-ChartPrime/
CODE:
CSS:
#// Indicator for TOS
#// © ChartPrime
#indicator("LOWESS (Locally Weighted Scatterplot Smoothing) [ChartPrime]", "Lowess & GaussianMA [ChartPrime]"
# Converted by Sam4Cok@Samer800 - 08/2024
input source = close;
input GaussianLength = 30; # "LOWESS (Locally Weighted Scatterplot Smoothing)"
input lowessLength = 10;
input showPivotsLines = yes;
input pivotsLength = 5; # "Pivots"
input showCountBreaks = no; # "Count Breaks"
input showGaussianScatterplot = no; # "Gaussian Scatterplot")
def na = Double.NaN;
def last = isNaN(close);
def leftBars = Max(pivotsLength, 2);
#-- Functions
script rising{
input src = close;
input len = 20;
def rising = fold i = 0 to len with p=1 while p do
GetValue(src, i) >= GetValue(src, i + 1);
plot out = rising;
}
script falling{
input src = close;
input len = 20;
def falling = fold i = 0 to len with p=1 while p do
GetValue(src, i) <= GetValue(src, i + 1);
plot out = falling;
}
script Pivot {
input series = close;
input leftBars = 10;
input rightBars = 10;
input isHigh = yes;
def na = Double.NaN;
def HH = series == Highest(series, leftBars + 1);
def LL = series == Lowest(series, leftBars + 1);
def pivotRange = (leftBars + rightBars + 1);
def leftEdgeValue = if series[pivotRange] == 0 then na else series[pivotRange];
def pvtCond = !IsNaN(series) and !IsNaN(leftEdgeValue);
def barIndexH = if pvtCond then
fold i = 1 to rightBars + 1 with p=1 while p do
series > GetValue(series, - i) else na;
def barIndexL = if pvtCond then
fold j = 1 to rightBars + 1 with q=1 while q do
series < GetValue(series, - j) else na;
def PivotPoint;
if isHigh {
PivotPoint = if HH and barIndexH then series else na;
} else {
PivotPoint = if LL and barIndexL then series else na;
}
plot pvt = PivotPoint;
}
script lowess {
input src = close;
input length = 10;
def sum_w = fold i = 0 to length-1 with p do
p + Power(1 - Power(i / length, 3), 3);
def sum_wx = fold i1 = 0 to length-1 with p1 do
p1 + i1 * Power(1 - Power(i1 / length, 3), 3);
def sum_wy = fold i2 = 0 to length-1 with p2 do
p2 + src[i2] * Power(1 - Power(i2 / length, 3), 3);
def a = sum_wy / sum_w;
def b = sum_wx / sum_w;
def lowess = a + b * (length - 1) / 2000;
plot out = lowess;
}
#//@function Calculates Modified Adaptive Gaussian Moving Average
script GaussianMA {
input src = close;
input length = 30;
def nATR = ATR(Length = length);
def stdv = StDev(src, length);
def sigma = (nATR + stdv) / 2; #// Volatility adaption
def sigmaM = sigma * 2;
def hh = Highest(src, length);
def ll = Lowest(src, length);
def sumOfWeights = fold j = 0 to length with q do
q + Exp(-Power(((j - length) / sigmaM), 2) / 2);
def gma1 = fold i = 0 to length with p do
p + (Exp(-Power(((i - length) / sigmaM), 2) / 2)) *
(Max(hh[i], hh) + Min(ll[i], ll));
def gma = (gma1 / sumOfWeights) / 2;
plot out = gma;
}
#// Calculate pivot high and low
def rightBars = leftBars - 2;
def ph = pivot(high[-rightBars], leftBars, rightBars, yes);
def pl = pivot(low[-rightBars], leftBars, rightBars, no);
# // Gaussian MA plot
def gma = GaussianMA(source, GaussianLength);
def smoothed = lowess(gma, lowessLength);
def smoothed1 = smoothed[2];
#// Determine color for smoothed line based on its direction
def gmaCol = Random() * 255;
def raisUp = rising(smoothed, 2);
def fallDn = falling(smoothed,2);
def smoothedCol = if raisUp then 1 else
if fallDn then -1 else smoothedCol[1];
def crossUp = smoothedCol>0 and (smoothedCol!=smoothedCol[1]);
def crossDn = smoothedCol<0 and (smoothedCol!=smoothedCol[1]);
#// 𝙑𝙄𝙎𝙐𝘼𝙇𝙄𝙕𝘼𝙏𝙄𝙊𝙉
plot dirUp1 = if crossUp then smoothed else na;
plot dirDn1 = if crossDn then smoothed else na;
plot dirUp = if crossUp then smoothed else na;
plot dirDn = if crossDn then smoothed else na;
plot GaussianMovAvg = if showGaussianScatterplot then gma else na; # "Gaussian Moving Average"
plot smoothedMovAvg = if yes then smoothed else na; # "Gaussian Moving Average"
GaussianMovAvg.AssignValueColor(CreateColor(gmaCol, gmaCol, gmaCol));
GaussianMovAvg.SetPaintingStrategy(PaintingStrategy.POINTS);
smoothedMovAvg.SetLineWeight(2);
smoothedMovAvg.AssignValueColor(if smoothedCol>0 then Color.CYAN else
if smoothedCol<0 then Color.MAGENTA else Color.DARK_GRAY);
dirUp.SetLineWeight(3);
dirDn.SetLineWeight(3);
dirUp1.SetPaintingStrategy(PaintingStrategy.SQUARES);
dirDn1.SetPaintingStrategy(PaintingStrategy.SQUARES);
dirUp1.SetDefaultColor(Color.DARK_GREEN);
dirDn1.SetDefaultColor(Color.PLUM);
dirUp.SetPaintingStrategy(PaintingStrategy.SQUARES);
dirDn.SetPaintingStrategy(PaintingStrategy.SQUARES);
dirUp.SetDefaultColor(Color.CYAN);
dirDn.SetDefaultColor(Color.MAGENTA);
# Draw Line
#// Draw lines and labels for pivot highs
def condH = !isNaN(ph[rightBars]) and smoothedCol[-rightBars] > 0;
def lbl_h;
def line_h;
def crossedUp;
def cnt_Up;
if condH and !crossedUp[1] {
line_h = high;
lbl_h = high;
crossedUp = no;
cnt_Up = 0;
} else if (close > line_h[1]) or cnt_Up[1] >= 300 {
line_h = na;
lbl_h = no;
crossedUp = yes;
cnt_Up = 0;
} else {
line_h = if line_h[1] then line_h[1] else close;
lbl_h = no;
crossedUp = no;
cnt_Up = cnt_Up[1] + 1;
}
#// Draw lines and labels for pivot lows
def condL = !isNaN(pl[rightBars]) and smoothedCol[-rightBars] < 0;
def lbl_l;
def line_l;
def crossedDn;
def cnt_Dn;
if condL and !crossedDn[1]{
line_l = low;
lbl_l = low;
crossedDn = no;
cnt_Dn = 0;
} else if (close < line_l[1]) or cnt_Dn[1] >= 300 {
line_l = na;
lbl_l = no;
crossedDn = yes;
cnt_Dn = 0;
} else {
line_l = if line_l[1] then line_l[1] else close;
lbl_l = no;
crossedDn = no;
cnt_Dn = cnt_Dn[1] + 1;
}
plot pvtLineUp = if showPivotsLines and !last and line_h then line_h else na;
plot pvtLineDn = if showPivotsLines and !last and line_l then line_l else na;
plot pointUp = if lbl_h then lbl_h else na;
plot pointDn = if lbl_l then lbl_l else na;
pointUp.SetPaintingStrategy(PaintingStrategy.POINTS);
pointUp.SetDefaultColor(Color.CYAN);
pvtLineUp.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
pvtLineUp.SetDefaultColor(Color.CYAN);
pointDn.SetPaintingStrategy(PaintingStrategy.POINTS);
pointDn.SetDefaultColor(Color.MAGENTA);
pvtLineDn.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
pvtLineDn.SetDefaultColor(Color.MAGENTA);
#// Counts
def count_Up; def count_Dn;
if crossedUp {
count_dn = 0;
count_up = count_up[1] + 1;
} else if crossedDn {
count_dn = count_dn[1] + 1;
count_up = 0;
} else {
count_dn = count_dn[1];
count_up = count_up[1];
}
plot cntUp = if showCountBreaks and crossedUp then count_up else na;
plot cntDn = if showCountBreaks and crossedDn then count_dn else na;
cntUp.SetPaintingStrategy(PaintingStrategy.VALUES_ABOVE);
cntDn.SetPaintingStrategy(PaintingStrategy.VALUES_Below);
cntUp.SetDefaultColor(Color.CYAN);
cntDn.SetDefaultColor(Color.MAGENTA);
#-- END of CODE