#//@version=4
#// Original Hilbert by everget :
#https://www.tradingview.com/script/aaWzn9bK-Ehlers-MESA-Adaptive-Moving-Averages-MAMA-FAMA/
#study("MAMA FAMA KAMA", overlay=true)
# Converted by Sam4Cok@Samer800 - 11/2022
# Update - Added MTF and alerts by Sam4Cok@Samer800 - 11/2022
declare upper;
input BarColor = yes;
input Length = 20;
input src = hl2;
input useChartTime = yes;
input Aggregation = AggregationPeriod.FIFTEEN_MIN;
input PlotKamaLine = yes;
input MamaFamaCloud = yes;
input ShowCloudLines = no;
input alerts = yes;
input sound = {default "NoSound", "Ding", "Bell", "Chimes", "Ring"};
def na = Double.NaN;
def mtfHigh = high(Period=Aggregation);
def mtfLow = low(Period=Aggregation);
def mtfhl2 = (mtfHigh + mtfLow) / 2;
def Source;
if useChartTime {
Source = src;
} else {
Source = mtfhl2;
}
script nz {
input data = close;
input repl = 0;
def ret_val = if data == 0 then repl else data;
plot return = ret_val;
}
#calc_kama(src, len) =>
script kama {
input src = close;
input len = 20;
input fastLimit = 0.5;
input slowLimit = 0.05;
def dist = AbsValue(src - src[1]);
def signal = AbsValue(src - src[len]);
def noise = Sum(dist, len);
def effr = If(noise != 0, signal / noise, 1);
def sc = Power(effr * (fastLimit - slowLimit) + slowLimit, 2);
def kama = nz(kama[1], src) + sc * (src - nz(kama[1], src));
plot result = kama;
}
#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 Source = if(useChartTime, src, mtfhl2);
def mom = Source - nz(Source[Length], Source[1]);
def volatility = Sum(AbsValue(Source - Source[1]), Length);
def fastLimit = If(volatility != 0, AbsValue(mom) / volatility, 2 / (Length + 1));
def slowLimit = fastLimit * 0.1;
def a = computeAlpha(Source, fastLimit, slowLimit).MAMA;
def b = computeAlpha(Source, fastLimit, slowLimit).FAMA;
def mama;
def fama;
mama = a * Source + (1 - a) * nz(mama[1], ExpAverage(Source, Length)[1]);
fama = b * mama + (1 - b) * nz(fama[1], ExpAverage(Source, Length)[1]);
def ShowLins = If(ShowCloudLines and !MamaFamaCloud, no, yes);
plot mama_p = mama; # "MAMA"
mama_p.AssignValueColor(if mama >= fama then CreateColor(41, 98, 255) else CreateColor(156, 39, 176));
mama_p.SetHiding(ShowLins);
plot fama_p = fama; # "FAMA"
fama_p.AssignValueColor(if mama >= fama then CreateColor(41, 98, 255) else CreateColor(156, 39, 176));
fama_p.SetHiding(ShowLins);
AddCloud(if !MamaFamaCloud then na else mama_p, fama_p, CreateColor(41, 98, 255), CreateColor(156, 39, 176), ShowCloudLines);
def alpha = Power((fastLimit * (b - a)) + a, 2);
def kama;
kama = alpha * Source + (1 - alpha) * nz(kama[1], kama(Source[1], Length, 2, 2 / (Length + 1)));
def col = if kama > kama[1] then 1 else if kama < kama[1] then -1 else 0;
plot kamaLine = if !PlotKamaLine then na else kama; # "KAMA"
kamaLine.AssignValueColor(if col > 0 then CreateColor(0, 230, 118) else
if col < 0 then CreateColor(255, 82, 82) else Color.GRAY);
kamaLine.SetLineWeight(2);
#---- Alerts
def upCount = if source>kama then upCount[1] + 1 else 0;
def dnCount = if source<kama then dnCount[1] + 1 else 0;
def AlertUp = upCount==1;
def AlertDn = dnCount==1;
Alert(alerts and AlertUp, "Cross Up!", Alert.BAR, sound);
Alert(alerts and AlertDn, "Cross Dn!", Alert.BAR, sound);
#--- Bar Color
def ExHi = Source > kama and Source > mama and mama > fama and mom > fastLimit;
def Hi = Source > kama and mama > fama and mom > fastLimit;
def WeakHi = Source > kama and mom > fastLimit;
def ExLo = Source < kama and Source < mama and mama < fama and mom < fastLimit;
def Lo = Source < kama and mama < fama and mom < fastLimit;
def WeakLo = Source < kama and mom < fastLimit;
AssignPriceColor( if !BarColor then Color.CURRENT else
if ExHi then Color.GREEN else
if Hi then Color.DARK_GREEN else
if WeakHi then Color.YELLOW else
if ExLo then Color.RED else
if Lo then Color.DARK_RED else
if WeakLo then Color.DARK_ORANGE else Color.GRAY);
#---END Code