Creator Message:
The biggest problem with supertrends is that there are a lot of false signals, which when the trend is uncertain give a lot of losses
My task in creating this script was to minimize the number of false sinhals.
Smart supertrend is both dependent on ATR, price movmment as well as ADX , CLOUD
It works in such a way that when the cloud and adx recognize that the trend is bullish , the strategy instead of opening the shorts, closes the longs waiting for a more certain situation.
The settings are default I didn't focus too much on optimization just on the brain indicator itself
The indicator can also be used for altcoins as well as major coins on different time frames
CODE:
CSS:
#/ This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
#// © wielkieef
#study("Smart SuperTrend", overlay = true)
# Converted by Sam4Cok@samer800 - 01/2023
#//INPUTS
input BarColor = no;
input CloudLines = yes;
input src = hl2;
input ppPeriod = 2; # "PP period"
input atrFactor = 3; # "ATR Factor"
input atrPeriod = 10; # "ATR Period"
input CloudLength = 12; # "Cloud Length"
input ADX_options = {default CLASSIC, MASANAKAMURA}; # "ADX OPTION"
input adxLenght = 14;# "ADX Lenght"
input adxThreshold = 20;# "ADX Treshold"
input closeBars = 2; # Closed bars that have to exceed the ST value before the trend reversal is confirmed
#//INDICATORS
def na = Double.NaN;
def bar = BarNumber();
def h = high;
def l = low;
def c = close;
def adxOps = if ADX_options == ADX_options.CLASSIC then 1 else
if ADX_options == ADX_options.MASANAKAMURA then 0 else adxOps[1];
script nz {
input data = close;
input repl = 0;
def ret_val = if data == 0 then repl else data;
plot return = ret_val;
}
script fixnan {
input source = close;
def fix = if !IsNaN(source) then source else fix[1];
plot result = fix;
}
script FindPivots {
input dat = close; # default data or study being evaluated
input HL = 0; # default high or low pivot designation, -1 low, +1 high
input lbL = 5; # default Pivot Lookback Left
input lbR = 1; # default Pivot Lookback Right
##############
def _nan; # used for non-number returns
def _BN; # the current barnumber
def _VStop; # confirms that the lookforward period continues the pivot trend
def _V; # the Value at the actual pivot point
##############
_BN = BarNumber();
_nan = Double.NaN;
_VStop = if !IsNaN(dat) and lbR > 0 and lbL > 0 then
fold a = 1 to lbR + 1 with b=1 while b do
if HL > 0 then dat > GetValue(dat, -a) else dat < GetValue(dat, -a) else _nan;
if (HL > 0) {
_V = if _BN > lbL and dat == Highest(dat, lbL + 1) and _VStop
then dat else _nan;
} else {
_V = if _BN > lbL and dat == Lowest(dat, lbL + 1) and _VStop
then dat else _nan;
}
plot result = if !IsNaN(_V) and _VStop then _V else _nan;
}
#calcADX(_len) =>
script calcADX {
input _len = 10;
def na = Double.NaN;
def tr = TrueRange(high, close, low);
def up = (high - high[1]);
def down = -(low - low[1]);
def plusDM = if IsNaN(up) then na else (if up > down and up > 0 then up else 0);
def minusDM = if IsNaN(down) then na else (if down > up and down > 0 then down else 0);
def truerange = WildersAverage(tr, _len);
def _plus = fixnan(100 * WildersAverage(plusDM, _len) / truerange);
def _minus = fixnan(100 * WildersAverage(minusDM, _len) / truerange);
def sum = _plus + _minus;
def _adx = 100 * WildersAverage(AbsValue(_plus - _minus) / (if sum == 0 then 1 else sum), _len);
plot plus = _plus;
plot minus = _minus;
plot adx = _adx;
}
#calcADX_Masanakamura(_len) =>
script calcADX_Masanakamura {
input _len = 10;
def SmoothedTrueRange;
def SmoothedDirectionalMovementPlus;
def SmoothedDirectionalMovementMinus;
def tr = TrueRange(high, close, low);
def DirectionalMovementPlus = if (high - high[1]) > (low[1] - low) then Max((high - high[1]), 0) else 0;
def DirectionalMovementMinus = if (low[1] - low) > (high - high[1]) then Max((low[1] - low), 0) else 0;
SmoothedTrueRange = nz(SmoothedTrueRange[1]) - (nz(SmoothedTrueRange[1]) / _len) + tr;
SmoothedDirectionalMovementPlus = nz(SmoothedDirectionalMovementPlus[1]) - (nz(SmoothedDirectionalMovementPlus[1])
/ _len) + DirectionalMovementPlus;
SmoothedDirectionalMovementMinus = nz(SmoothedDirectionalMovementMinus[1]) - (nz(SmoothedDirectionalMovementMinus[1])
/ _len) + DirectionalMovementMinus;
def DP = SmoothedDirectionalMovementPlus / SmoothedTrueRange * 100;
def DM = SmoothedDirectionalMovementMinus / SmoothedTrueRange * 100;
def DX = AbsValue(DP - DM) / (DP + DM) * 100;
def AX = SimpleMovingAvg(DX, _len);
plot DIP = DP;
plot DIM = DM;
plot ADX = AX;
}
#computeAlpha(src, fastLimit, slowLimit) =>
script computeAlpha {
input src = close;
input fastLimit = 0.5;
input slowLimit = 0.05;
def PI = 2 * ASin(1);
def Period;
def detrender;
def smooth;
def I2;
def Q2;
def phase;
def mesaPeriodMult = 0.075 * nz(Period[2], Period[1]) + 0.54;
# // Calc
smooth = (4 * src + 3 * nz(src[1], src) + 2 * nz(src[2], src) + nz(src[3], src)) / 10;
detrender = (0.0962 * smooth + 0.5769 * nz(smooth[2], smooth) - 0.5769 * nz(smooth[4], smooth) -
0.0962 * nz(smooth[6], smooth)) * (0.075 * nz(Period[1]) + 0.54);
# // Compute InPhase and Quadrature components
def I1 = nz(detrender[3], detrender);
def Q1 = (0.0962 * detrender + 0.5769 * nz(detrender[2], detrender) - 0.5769 * nz(detrender[4], detrender) -
0.0962 * nz(detrender[6], detrender)) * (.075 * nz(Period[1], detrender) + 0.54);
# // Advance the phase of I1 and Q1 by 90 degrees
def jI = (.0962 * I1 + .5769 * nz(I1[2], I1) - .5769 * nz(I1[4], I1) - .0962 * nz(I1[6], I1)) * (.075 * nz(Period[1]) + 0.54);
def jQ = (.0962 * Q1 + .5769 * nz(Q1[2], Q1) - .5769 * nz(Q1[4], Q1) - .0962 * nz(Q1[6], Q1)) * (.075 * nz(Period[1]) + 0.54);
# // Phasor addition for 3 bar averaging
def I22 = I1 - jQ;
def Q22 = Q1 + jI;
# // Smooth the I and Q components before applying the discriminator
I2 = if IsNaN(I2[1]) then I22 else 0.2 * I2[1] + 0.8 * nz(I2[2], I2[1]);
Q2 = if IsNaN(Q2[1]) then Q22 else 0.2 * Q2[1] + 0.8 * nz(Q2[2], Q2[1]);
# // Homodyne Discriminator
def Re1 = I2 * nz(I2[1], I2) + Q2 * nz(Q2[1], Q2);
def Im1 = I2 * nz(Q2[1], Q2) - Q2 * nz(I2[1], I2);
def Re = if IsNaN(Re[1]) then Re1 else 0.2 * Re[1] + 0.8 * nz(Re[2], Re[1]);
def Im = if IsNaN(Im[1]) then Im1 else 0.2 * Im[1] + 0.8 * nz(Im[2], Im[1]);
#def mesaPeriod1;
if Re != 0 and Im != 0 {
Period = 2 * PI / ATan(Im / Re);
} else {
if Period[1] <= 1.5 * nz(Period[2], Period[1]) {
Period = Period[1];
} else {
if Period[1] >= 0.67 * nz(Period[2], Period[1]) {
Period = Period[1];
} else
if Max(Period[1], 6) < 50 {
Period = Max(Period[1], 6);
} else {
Period = 0.2 * Period[1] + 0.8 * nz(Period[2], Period[1]);
;
}
}
}
phase = if I1 != 0 then (180 / PI) * ATan(Q1 / I1) else phase[1];
def deltaPhase = nz(phase[1]) - phase;
def alpha1 = fastLimit / If(deltaPhase < 1, 1, deltaPhase);
def alpha = If(alpha1 < slowLimit, slowLimit, alpha1);
plot MAMA = alpha;
plot FAMA = alpha / 2;
}
def er = AbsValue(src - nz(src[CloudLength], src[1])) / Sum(AbsValue(src - src[1]), CloudLength);
def a = computeAlpha(src, er, er * 0.1).MAMA;
def b = computeAlpha(src, er, er * 0.1).FAMA;
def mama;
def fama;
def kama;
mama = a * src + (1 - a) * nz(mama[1], ExpAverage(src, CloudLength)[1]);
fama = b * mama + (1 - b) * nz(fama[1], ExpAverage(src, CloudLength)[1]);
def alpha = Power((er * (b - a)) + a, 2);
kama = alpha * src + (1 - alpha) * nz(kama[1]);
def L_cloud = kama > kama[1];
def S_cloud = kama < kama[1];
def n_cloud = kama == kama[1];
def CLOUD_COLOR = if L_cloud then 1 else if S_cloud then -1 else 0;
def mama_p = if n_cloud then na else mama;
def fama_p = if n_cloud then na else fama;
AddCloud(mama_p, fama_p, CreateColor(41, 98, 255), CreateColor(156, 39, 176), CloudLines);
#---//PRICE POSITION
def ph = if bar > ppPeriod then findpivots(h, 1, ppPeriod, ppPeriod) else Highest(h, ppPeriod);
def pl = if bar > ppPeriod then findpivots(l, -1, ppPeriod, ppPeriod) else Lowest(l, ppPeriod);
def lastpp = if !IsNaN(ph) then ph else if !IsNaN(pl) then pl else na;
#// calculate the Center line using pivot points
def center;
if (lastpp) {
if IsNaN(center[1]) {
center = lastpp;
} else {
center = (center[1] * 2 + lastpp) / 3;
}
} else {
center = center[1];
}
def nATR = ATR(LENGTH = atrPeriod);
def Up = center - (atrFactor * nATR);
def Dn = center + (atrFactor * nATR);
def TUp;
def TDown;
def Trend;
TUp = if close[1] > TUp[1] then Max(Up, TUp[1]) else Up;
TDown = if close[1] < TDown[1] then Min(Dn, TDown[1]) else Dn;
Trend = if close > TDown[1] then 1 else if close < TUp[1] then -1 else nz(Trend[1], 1);
def Trailingsl = if Trend == 1 then TUp else TDown;
#def Trailingsl = if trend == 1 then lastUp else lastDn;
#---ADX
def DIPlusC = calcADX(adxLenght).plus;
def DIMinusC = calcADX(adxLenght).Minus;
def ADXC = calcADX(adxLenght).ADX;
def DIPlusM = calcADX_Masanakamura(adxLenght).DIP;
def DIMinusM = calcADX_Masanakamura(adxLenght).DIM;
def ADXM = calcADX_Masanakamura(adxLenght).ADX;
def DIPlus = if adxOps then DIPlusC else DIPlusM;
def DIMinus = if adxOps then DIMinusC else DIMinusM;
def ADX = if adxOps then ADXC else ADXM;
def L_adx = DIPlus > DIMinus and ADX > adxThreshold;
def S_adx = DIPlus < DIMinus and ADX > adxThreshold;
#------
def bsignal = Trend == 1 and Trend[1] == -1;
def ssignal = Trend == -1 and Trend[1] == 1;
def first_long = if bsignal and !S_cloud then Trailingsl else na;
def first_short = if ssignal and !L_cloud then Trailingsl else na;
def second_long = L_cloud and L_adx and Trend == 1;
def second_short = S_cloud and S_adx and Trend == -1;
def Long = second_long or first_long;
def Short = second_short or first_short;
def long_short;
def long_last = Long and (nz(long_short[1]) == 0 or nz(long_short[1]) == -1);
def short_last = Short and (nz(long_short[1]) == 0 or nz(long_short[1]) == 1);
long_short = if long_last then 1 else if short_last then -1 else long_short[1];
def last_long_cond = Long and long_last;
def last_short_cond = Short and short_last;
def Long_plot = if bsignal and !S_cloud then Trailingsl else na or if last_long_cond then Trailingsl else na;
def Short_plot = if ssignal and !L_cloud then Trailingsl else na or if last_short_cond then Trailingsl else na;
def Long_stop = if ssignal and L_cloud then Trailingsl else na;
def Short_stop = if bsignal and S_cloud then Trailingsl else na;
#// ----Plots-
plot SmartSTup = if Trend == 1 then Trailingsl else na;#, color = CLOUD_COLOR , linewidth = 1, title = "PP line")
SmartSTup.SetDefaultColor(Color.GREEN);
plot SmartSTdn = if Trend == 1 then na else Trailingsl;#, color = CLOUD_COLOR , linewidth = 1, title = "PP line")
SmartSTdn.SetDefaultColor(Color.RED);
AddChartBubble(Long_plot, low, "Long", Color.GREEN, no);
AddChartBubble(Short_plot, high, "Short", Color.RED, yes);
plot LongExit = Long_stop;
LongExit.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_DOWN);
LongExit.SetDefaultColor(Color.CYAN);
LongExit.SetLineWeight(3);
plot ShortExit = Short_stop;
ShortExit.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_UP);
ShortExit.SetDefaultColor(Color.MAGENTA);
ShortExit.SetLineWeight(3);
#-------barcolor
AssignPriceColor(if !BarColor then Color.CURRENT else
if CLOUD_COLOR > 0 then Color.GREEN else if CLOUD_COLOR<0 then Color.RED else Color.GRAY);
#--- END CODE
Last edited by a moderator: