Author Message:
The Hyperbolic Tangent is designed for technical analysis, particularly in markets with assets that have lower prices or price ratios. This indicator leverages the Hyperbolic Tangent Moving Average (HTMA), a custom moving average calculated using the hyperbolic tangent function, to smooth price data and reduce the impact of short-term volatility.
Include 3 studies to select from (Supertrend, Volatility Stop and Median Kijun-Sen).
CODE:
CSS:
#//Indicator for TOS
#// © InvestorUnknown | TRW: @Andrej S.
#Indicator("Hyperbolic Tangent SuperTrend [InvestorUnknown]", "Hyperbolic Tangent SuperTrend"
#indicator("Hyperbolic Tangent Volatility Stop [InvestorUnknown]", "Hyperbolic Tangent Volatility Stop"
#indicator("Hyperbolic Tangent Median Kijun-Sen [InvestorUnknown]", "Median Kijun-Sen", overlay=true)
# Converted by Sam4Cok@Samer800 - 11/2024
input colorBars = yes; # "Color Bars?"
input HyperbolicTangentType = {Default "SuperTrend", "Volatility Stop", "Median Kijun-Sen"};
input repaint = yes; #(true, "Allow Intra-day Updating"
input source = {"open", "high", "low", "close", "oc2", "hl2",Default "occ3", "hlc3", "ohlc4", "hlcc4"};
input htmaLength = 6; #, "HTMA Length"
input HyperbolicTangentMultiplier = 0.2; #, "Hyperbolic Tangent Multiplier"
input plotHtmaLine = no; #(false, "Plot HTMA?",
input atrLength = 8; #, "ATR Length"
input atrMultiplier = 2.0; #, "ATR Multiplier"
input kijunSenLength = 16; #, "KIjun Sen Length"
input MedianLength = 32; #, "Median Length"
def na = Double.NaN;
def last = isNaN(close);
#-- Color
DefineGlobalColor("up", CreateColor(4, 208, 19));
DefineGlobalColor("dn", CreateColor(227, 34, 34));
#-- Function
Script pine_supertrend {
input src = close;
input calc_price = close;
input atrPeriod = 8;
input factor = 2;
def tr = if IsNaN(high[1]) then high - low else TrueRange(high, close, low);
def atr = WildersAverage(tr, atrPeriod);
def upBand = src + factor * atr;
def loBand = src - factor * atr;
def lowerBand;
def upperBand;
def prevLowerBand = CompoundValue(1, lowerBand[1], 0);
def prevUpperBand = CompoundValue(1, upperBand[1], 0);
lowerBand = if loBand > prevLowerBand or calc_price[1] < prevLowerBand then loBand else prevLowerBand;
upperBand = if upBand < prevUpperBand or calc_price[1] > prevUpperBand then upBand else prevUpperBand;
def _direction;
def superTrend;
def prevSuperTrend = superTrend[1];
if IsNaN(atr[1]) {
_direction = 1;
} else if prevSuperTrend == prevUpperBand {
_direction = if calc_price > upperBand then -1 else 1;
} else {
_direction = if calc_price < lowerBand then 1 else -1;
}
superTrend = if _direction == -1 then lowerBand else upperBand;
plot st = if IsNaN(superTrend) then Double.NaN else superTrend;
plot dir = if IsNaN(_direction) then Double.NaN else _direction;
}
Script pine_volStop {
input src = close;
input atrlen = 8;
input atrfactor = 2;
def tr = TrueRange(high, close, low);
def atr = atr(Length = atrlen) * atrfactor;
def atrM = if atr then atr else tr;
def max; def min; def uptrend; def stop;
def pMax = CompoundValue(1, max[1], src);
def pMin = CompoundValue(1, min[1], src);
def pUptrend = CompoundValue(1, uptrend[1], yes);
def pStop = CompoundValue(1, stop[1], src);
def max1 = max(pMax, src);
def min1 = min(pMin, src);
def stop1 = if pUptrend then max(pStop, max1 - atrM) else min(pStop, min1 + atrM);
uptrend = src - stop1 >= 0.0;
if uptrend != pUptrend {
max = src;
min = src;
stop = if uptrend then max - atrM else min + atrM;
} else {
max = max1;
min = min1;
stop = stop1;
}
plot stp = stop;
plot trend = uptrend;
}
Script kijun_sen {
input len = 16;
input source = close;
def ll = lowest(source,len);
def hh = highest(source,len);
def kijun_sen = (ll + hh) / 2;
plot out = kijun_sen;
}
Script htma {
input src = close;
input len = 6;
input mul = 0.2;
def x = (src - Average(src, len)) * mul;
def e_x = Exp(x);
def e_neg_x = Exp(-x);
def tanH = (e_x - e_neg_x) / (e_x + e_neg_x);
def tanh_src = tanH * StDev(src, len) + Average(src, len);
def htma = Average(tanh_src, len);
plot out = htma;
}
#// - - - - - CALCULATIONS - - - - - //{
def src;
Switch (source) {
Case "open" : src = open;
Case "high" : src = high;
Case "low" : src = low;
Case "close" : src = close;
Case "oc2" : src = (open + close) / 2;
Case "hl2" : src = (high + low) / 2;
Case "hlc3" : src = (high + low + close) / 3;
Case "ohlc4" : src = (open + high + low + close) / 4;
Case "hlcc4" : src = (high + low + close + close) / 4;
Default : src = (open + close + close) / 3;
}
def htma = htma(src, htmaLength, HyperbolicTangentMultiplier);
def med = median(htma, MedianLength);
def ht;
Switch (HyperbolicTangentType) {
Case "Median Kijun-Sen" :
ht = kijun_sen(kijunSenLength, med);
Case "Volatility Stop" :
ht = pine_volStop(htma, atrLength, atrMultiplier);
Default :
ht = pine_supertrend(htma, src, atrLength, atrMultiplier);
}
def col = ht > src;
def maxx = max(open, close);
def minn = min(open, close);
#// Overlay
plot htmaLine = if plotHtmaLine and !last then if repaint then htma else htma[1] else na; # title="HTMA"
plot upTrend = if !col then ht else na; # "Up Trend"
plot dnTrend = if !col then na else ht; # "Down Trend"
htmaLine.SetDefaultColor(Color.WHITE);
upTrend.SetDefaultColor(GlobalColor("up"));
dnTrend.SetDefaultColor(GlobalColor("dn"));
AddCloud(dnTrend, maxx, Color.DARK_RED);
AddCloud(minn, upTrend, Color.DARK_GREEN);
#-- Signals
def sig = if ht > src then -1 else 1;
plot sigUp = if (if repaint then sig else sig[1]) Crosses Above 0 then ht else na;
plot sigDn = if (if repaint then sig else sig[1]) Crosses Below 0 then ht else na;
sigUp.SetLineWeight(2);
sigDn.SetLineWeight(2);
sigUp.SetDefaultColor(GlobalColor("up"));
sigDn.SetDefaultColor(GlobalColor("dn"));
sigUp.SetPaintingStrategy(PaintingStrategy.SQUARES);
sigDn.SetPaintingStrategy(PaintingStrategy.SQUARES);
#-- Bar Color
AssignPriceColor(if !colorBars then Color.CURRENT else
if !repaint then if col[1] then Color.RED else Color.GREEN else
if col then Color.RED else Color.GREEN);
#-- END of CODE