Ehlers MESA Adaptive Moving Average [LazyBear]

Another one to add to Ehlers collection.

The MESA Adaptive Moving Average ( MAMA ) adapts to price movement based on the rate of change of phase as measured by the Hilbert Transform Discriminator. This method features a fast attack average and a slow decay average so that composite average rapidly ratchets behind price changes and holds the average value until the next ratchet occurs. Consider FAMA (Following AMA) as the signal.

Here are some of the options:

Fill MAMA/FAMA region (ribbon mode):

Mark Crossovers:

The above options (along with the bar colors) allow this to be used as a standalone system.

BTW             , John Ehlers calls MAMA , "Mother of all Adaptive Moving Averages", lemme know what you think :)

More info:
- MESA Adaptive Moving Average , Stocks and Commodities Magazine, August 2001

List of my public indicators:
List of my app-store indicators:

Remove from Favorite Scripts Add to Favorite Scripts
// @author LazyBear 
// List of my public indicators: 
// List of my app-store indicators: 
study("Ehlers MESA Adaptive Moving Average [LazyBear]", shorttitle="EMAMA_LB", overlay=true, precision=3)
src=input(hl2, title="Source")
fl=input(.5, title="Fast Limit")
sl=input(.05, title="Slow Limit")
sp = (4*src + 3*src[1] + 2*src[2] + src[3]) / 10.0
dt = (.0962*sp + .5769*nz(sp[2]) - .5769*nz(sp[4])- .0962*nz(sp[6]))*(.075*nz(p[1]) + .54)
q1 = (.0962*dt + .5769*nz(dt[2]) - .5769*nz(dt[4])- .0962*nz(dt[6]))*(.075*nz(p[1]) + .54)
i1 = nz(dt[3])
jI = (.0962*i1 + .5769*nz(i1[2]) - .5769*nz(i1[4])- .0962*nz(i1[6]))*(.075*nz(p[1]) + .54)
jq = (.0962*q1 + .5769*nz(q1[2]) - .5769*nz(q1[4])- .0962*nz(q1[6]))*(.075*nz(p[1]) + .54)
i2_ = i1 - jq
q2_ = q1 + jI
i2 = .2*i2_ + .8*nz(i2[1])
q2 = .2*q2_ + .8*nz(q2[1])
re_ = i2*nz(i2[1]) + q2*nz(q2[1])
im_ = i2*nz(q2[1]) - q2*nz(i2[1])
re = .2*re_ + .8*nz(re[1])
im = .2*im_ + .8*nz(im[1])
p1 = iff(im!=0 and re!=0, 360/atan(im/re), nz(p[1]))
p2 = iff(p1 > 1.5*nz(p1[1]), 1.5*nz(p1[1]), iff(p1 < 0.67*nz(p1[1]), 0.67*nz(p1[1]), p1))
p3 = iff(p2<6, 6, iff (p2 > 50, 50, p2))
p = .2*p3 + .8*nz(p3[1])
spp = .33*p + .67*nz(spp[1])
phase = atan(q1 / i1)
dphase_ = nz(phase[1]) - phase
dphase = iff(dphase_< 1, 1, dphase_)
alpha_ = fl / dphase
alpha = iff(alpha_ < sl, sl, iff(alpha_ > fl, fl, alpha_))
mama = alpha*src + (1 - alpha)*nz(mama[1])
fama = .5*alpha*mama + (1 - .5*alpha)*nz(fama[1])
pa=input(false, title="Mark crossover points")
plotarrow(pa?(cross(mama, fama)?mama<fama?-1:1:na):na, title="Crossover Markers")
fr=input(false, title="Fill MAMA/FAMA Region")
duml=plot(fr?(mama>fama?mama:fama):na, style=circles, color=gray, linewidth=0, title="DummyL")
mamal=plot(mama, title="MAMA", color=red, linewidth=2)
famal=plot(fama, title="FAMA", color=green, linewidth=2)
fill(duml, mamal, red, transp=70, title="NegativeFill")
fill(duml, famal, green, transp=70, title="PositiveFill")
ebc=input(false, title="Enable Bar colors")
Excellent! This moving average indicator invented by Ehlers seems to work even better than I expected. Great additional options from you as well. Thank you!

+1 Reply
YW :)
ChartArt LazyBear
I found in my comparison only one area where Ehlers's other invention, his much cooler named 'Instantaneous Trend Line' ( performed better than his MESA Adaptive Moving Average (MAMA). Here is a screenshot where I annotated the false signals of the iTrend which the MAMA had right at that daily close (both with default settings):

+2 Reply
This is what MAMA thinks of USDJPY 1M :)

+2 Reply
2use LazyBear
This looks interesting!
MAMA or my chart on USDJPY? :)
2use LazyBear
Which one of the ehlers indicators do you prefer most?
+1 Reply
I like all his cycle indicators (but always filter them using other indicators).
+1 Reply
Error lb is not autorized
oliver.pfaff.581 oliver.pfaff.581
eorroe lb rsl is not autorized
LazyBear PRO oliver.pfaff.581
EMAMA_LB is Ehler's MAMA. LB_RSRL is an app-store indicator. You must be subscribed to use it. More info:
+1 Reply
Got it!
Most excellent addition to the library! I've been using Mesa, MAMA for years and swear by it. Nice work LazyBear!
+1 Reply
LazyBear PRO coondawg71
Thx. Have way more Ehlers indies in my collection (he makes everything interesting, what do I do? ;) ), working on publishing one more now.
+1 Reply
Might you have the chance to add the option of MTF? Hourly Mesa on a 15min chart, etc, etc....makes it even more useful for intra-day trading. Thanks!
IvanLabrie PRO coondawg71
Try displacing it a la ichimoku ;)
Here is the MAMA with profiteering calculations (courtesy of Ni6HTH4Wk).
Currently, the profits are calculated using the candle close price after the buy/sell signal is given by the line MAMA/FAMA cross. You can adjust the trade amount, but default is 10 units. Can anyone edit these calculations so that it is using the candle open price of the next candle after the signal is given? I think this would give a more accurate profit estimate.
zmm20 zmm20
Actually, using close price of the signal candle is probably the correct way to do it, since the signal wouldn't be confirmed until candle close. Although it looks great on a chart, this is generally not a very profitable trading strategy.
Here's a view of the link I just posted
I admire LazyBear and his work a lot, he is one of the inspiring person that got me coding indicators for TV for my own use as well.
Unfortunately in the case of MESA - this indicator is simply incorrect and does not work as expected - sadly.
I coded quite a number of indis by now from Ehlers original presentations and books, and at first I could not quite grasp why LB MESA doe not look like anything in Ehlers presentations. You can check how it should look in Ehlers presentation here:
+3 Reply

The stringently examining LazyBear's code I figured where the problem - it is actually in the two crucial parts of calculating the period and phase value.
The issue is that TV uses radians in trigonometric functions, whereas Ehlres formula refers to degrees - and the conversion is required for the formula to work properly.

Period, line 21 must

+1 Reply
(for weird reasons paste operation sometimes posts my comment :) )

p1 = iff(im!=0 and re!=0, 360/atan(im/re), nz(p))

p1 = iff(im!=0 and re!=0, 2*pi/atan(im/re), nz(p)), where pi = 3.14.5926

Phase, line 30
phase = atan(q1 / i1)

phase = 180/pi * atan(q1 / i1)

Until these corrections are made - the alpha value for MAM on line 34 is always bigger than fl=0.5, and as a result it never changes in the later calculation of the EMA. This MESA simply does not adapt to price changes. The alpha value stays constant 0.5 resulting in plotting the EMA(3) basically all the time. And the FAMA becomes EMA(7) of MAMA.

I believe I spotted similar coding issue in some other Ehlers based indicators, I can't unfortunately recall anymore which ones.

But apart from that I can only wish LazyBear to continue his great work for the community, big respect!

And this is how my version of MESA looks like
+1 Reply
+1 Reply
I chose this chart from may 2015 to replicate the original chart in the first LazyBear's post for comparison.
The choppiness of MESA is the confirmation of its adaptive nature. On fast price advances, it quickly slides along, whereas in the congested areas it flattens on retracements, because the alpha decreases and the EMA period increases.
Hope this brings big profits to everybody, all the best!
+1 Reply
Final correction:
>>where pi = 3.14.5926

pi = 3.1415926 indeed.
fede2.0 ekoronin
Hi! I would like to see your version of the MESA as you commented on LazyBear description of his own version. Could you publish it?
I can't code the corrections you made, error message...
Thank a lot for your contribution!!!
I am not publishing yet as I need to bring my scripts to a common standard, but i'm guessing you have forgot to define the pi variable. It would be good if you post the actual error.

Once again:
Add between line 10 and 11:
pi = 3.1415926

Change line 21 (old count before you added pi)
+1 Reply
line 21:
p1 = iff(im!=0 and re!=0, 2*pi/atan(im/re), nz(p))

line 30 (old count again):
phase = 180/pi * atan(q1 / i1)

that should be all.

And I think I've finally figured out what causes earlier submission of my messages = if I paste a piece of code that has an invisible end-of-line character (cr/lf), the form treats it as ENTER button and submits the message. maybe this his something TradingView team can fix?
fede2.0 ekoronin
Thank you ekoronin, I made the modifictions but I still have an error, perhaps it is a little long to post but I publish a copy version of the indicator with the modifications as:
I don't know where my error is
hi.. thanks for ur effort but it shows error when I pasted the script with ur advised modifications. Could u please make complete script n post or mail me to ,. its a humble request. thanks.
B120626 ekoronin
I think at the end of line 21, you need to lookback 1 bar of p
without that, the script throws an error during compile,
Error: Undeclared identifier `p`;
please confirm your working script contains p
B120626 B120626
well... it appears the web form strips out regular square brackets typed from the keyboard

so the prior post, you need p&#91;1&#93; typed using html entity code
p open square bracket 1 closed square bracket
+1 Reply
B120626 ekoronin

here is the chart with Lazy Bears original script (green & red lines), vs the modifications by ekoronin (pink & aqua lines)

Lazy Bear's script hugs the price closer, which helps you get in/ out faster with a change in the trend at the ma crossover. that seems to be better for reversion to the mean instruments such as forex.

Ekoronin's modification may be truer to Ehler's original script, which may be targeted toward equities with strong trends and help you stay in the trade longer (months) without being stopped out due to pullbacks, which is described by Ehler in his original paper.

Ekoronin I appreciate the mods you have made, but for my use in 2 hour forex binary trades, I will stick with the original script, even if it is technically incorrect ;)
B120626 B120626

I compared this script vs 2 exp moving averages, and it behaves very close to EMA 8 hl2 and EMA 3 hl2, on both 5 min bars and 2 hr bars.

so now I'm probably dropping this concept.

I searched for Ehler because I just listened to his interview on Better Systems Trader podcast, and his comments on the MESA stuff sounded great. Now I'm having doubts. I'll check out some more of LB's Ehler scripts to see if those work better for my needs.
EKGPlus B120626
@B120626, this is exactly what I said originally, that due to the error in conversion of degrees vs radians, these two lines simply become EMA(7) and EMA(3), so there is no point in all of this complex math if the lines do not adapt.
+1 Reply
scarf PRO ekoronin
@ekoronin, I'm fairly sure I've incorporated all the changes below into this script. It's all a bit fragmented so I figured I'd try and make sense of it:
EKGPlus scarf
@scarf, Yes as far as I can see you've done the degree conversion correctly.
But there is one more difference in Ehlers original work and this is on your line 36:
alpha_ = fl / dphase

In his work Ehlers introduces an additional variable called "speed", and this is used in calculating alpha_ instead of fast limit "fl" like this:
alpha_ = speed/dphase

So I added in the beginning of the code on lines 9-10 an extra input:
speed=input(.5, title="Speed", step=0.1)

But I found that it has no effect when greater than fast limit "fl", because delta phase is always greater or equals to 1, So perhaps the use of "fl" as a divider is entirely justified.
Good luck!
Good catch! I missed to add deg2rad conv in most of EasyLanguage ports...Thanks @ekoronin,
Ideas Scripts Chart
United States
United Kingdom
Home Stock Screener Forex Signal Finder Economic Calendar How It Works Chart Features House Rules Moderators For the WEB Widgets Stock Charting Library Priority Support Feature Request Blog & News FAQ Help & Wiki Twitter
Private Messages Chat Ideas Published Followers Following Priority Support Public Profile Profile Settings Account and Billing Sign Out