Ehler's MAMA Buy and Sell Signals Indicator for ThinkorSwim

BenTen

BenTen

Administrative
Staff
VIP
This is the MAMA and FAMA indicator by John Ehlers. Testing on SPY and few other stocks and it is highly accurate on the certain timeframes and works best with SPY.

It will show MAMA: BEAR as an indication to sell and MAMA: BULL to indicate Bullish move. It was originally made to trade /ES.

The indicator performs worst in times of CHOP. So I would use a choppy indicator to indicate choppiness in the market and avoid taking any trades during that time.

Good Stuff: Overall if you trade(On sell trades) SPY on 2D 5M chart with will end up making roughly ~ $200. Lets not forget its simulation and not real trades



thinkScript Code

Rich (BB code):
# MESA Adaptive Moving Average (MAMA)



# Brian: Made slight changes to display on the price graph to see

# its effectiveness. The first 30 bars will be a simple MA

# 4.7.2016



# hint: <b>Ehler's Mesa Adaptive Moving Average</b> using Ray's clean version

# of the homodyne discriminator.

#

 

# MIT License

# Copyright (c) <2010> <Radford Juang>

#

#Permission is hereby granted, free of charge, to any person obtaining a copy

#of this software and associated documentation files (the "Software"), to deal

#in the Software without restriction, including without limitation the rights

#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

#copies of the Software, and to permit persons to whom the Software is

#furnished to do so, subject to the following conditions:

#

#The above copyright notice and this permission notice shall be included in

#all copies or substantial portions of the Software.

#

#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN

#THE SOFTWARE.

#

 

script WMA_Smooth {

input price = hl2;

plot smooth = (4 * price

+ 3 * price[1]

+ 2 * price[2]

+ price[3]) / 10;

}

 

script Phase_Accumulation {

# This is Ehler's Phase Accumulation code. It has a full cycle delay.

# However, it computes the correction factor to a very high degree.

#

input price = hl2;

 

rec Smooth;

rec Detrender;

rec Period;

rec Q1;

rec I1;

rec I1p;

rec Q1p;

rec Phase1;

rec Phase;

rec DeltaPhase;

rec DeltaPhase1;

rec InstPeriod1;

rec InstPeriod;

def CorrectionFactor;

 

if barNumber() <= 5

then {

Period = 0;

Smooth = 0;

Detrender = 0;

CorrectionFactor = 0;

Q1 = 0;

I1 = 0;

Q1p = 0;

I1p = 0;

Phase = 0;

Phase1 = 0;

DeltaPhase1 = 0;

DeltaPhase = 0;

InstPeriod = 0;

InstPeriod1 = 0;

} else {

CorrectionFactor = 0.075 * Period[1] + 0.54;

 

# Smooth and detrend my smoothed signal:

Smooth = WMA_Smooth(Price);

Detrender = ( 0.0962 * Smooth

+ 0.5769 * Smooth[2]

- 0.5769 * Smooth[4]

- 0.0962 * Smooth[6] ) * CorrectionFactor;

 

# Compute Quadrature and Phase of Detrended signal:

Q1p = ( 0.0962 * Detrender

+ 0.5769 * Detrender[2]

- 0.5769 * Detrender[4]

- 0.0962 * Detrender[6] ) * CorrectionFactor;

I1p = Detrender[3];

 

# Smooth out Quadrature and Phase:

I1 = 0.15 * I1p + 0.85 * I1p[1];

Q1 = 0.15 * Q1p + 0.85 * Q1p[1];

 

# Determine Phase

if I1 != 0 then {

# Normally, ATAN gives results from -pi/2 to pi/2.

# We need to map this to circular coordinates 0 to 2pi

 

if Q1



    >= 0 and I1 > 0 then { # Quarant 1



Phase1 = ATan(absValue(Q1/I1));

} else if Q1 >= 0 and I1 < 0 then { # Quadrant 2

Phase1 = Double.PI - ATan(absValue(Q1/I1));

} else if Q1 < 0 and I1 < 0 then { # Quadrant 3

Phase1 = Double.PI + ATan(absValue(Q1/I1));

} else { # Quadrant 4

Phase1 = 2*Double.PI - ATan(absValue(Q1/I1));

}

} else if Q1 > 0 then { # I1 == 0, Q1 is positive

Phase1 = Double.PI/2;

} else if Q1 < 0 then { # I1 == 0, Q1 is negative

Phase1 = 3*Double.PI/2;

} else { # I1 and Q1 == 0

Phase1 = 0;

}

 

# Convert phase to degrees

Phase = Phase1 * 180 / Double.PI;

 

if Phase[1] < 90 and Phase > 270 then {

# This occurs when there is a big jump from 360-0

DeltaPhase1 = 360 + Phase[1] - Phase;

} else {

DeltaPhase1 = Phase[1] - Phase;

}

 

# Limit our delta phases between 7 and 60

if DeltaPhase1 < 7

then {

DeltaPhase = 7;

} else if DeltaPhase1 > 60 then {

DeltaPhase = 60;

} else {

DeltaPhase = DeltaPhase1;

}

 

# Determine Instantaneous period:

InstPeriod1 =

-1*(fold i=0 to 40 with v=0 do

if v < 0 then

v

else if v > 360 then

-i

else

v + getValue(DeltaPhase, i, 41)

);

 

if InstPeriod1 <= 0 then {

InstPeriod = InstPeriod[1];

} else {

InstPeriod = InstPeriod1;

}

 

Period = 0.25*InstPeriod + 0.75*Period[1];

}

plot DC = period;

}

 

script Ehler_MAMA {

input price = hl2;

input FastLimit = 0.5;

input SlowLimit = 0.05;

 

rec Period;

rec Period_raw;

rec Period_cap;

rec Period_lim;

 

rec Smooth;

rec Detrender;

rec I1;

rec Q1;

rec jI;

rec jQ;

rec I2;

rec Q2;

rec I2_raw;

rec Q2_raw;

 

rec Phase;

rec DeltaPhase;

rec DeltaPhase_raw;

rec alpha;

rec alpha_raw;

 

rec Re;

rec Im;

rec Re_raw;

rec Im_raw;

 

rec SmoothPeriod;

rec vmama;

rec vfama;

 

def CorrectionFactor = Phase_Accumulation(price).CorrectionFactor;

 

if barNumber() <= 5

then {

Smooth = 0;

Detrender = 0;

 

Period = 0;

Period_raw = 0;

Period_cap = 0;

Period_lim = 0;

I1 = 0;

Q1 = 0;

I2 = 0;

Q2 = 0;

jI = 0;

jQ = 0;

I2_raw = 0;

Q2_raw = 0;

Re = 0;

Im = 0;

Re_raw = 0;

Im_raw = 0;

SmoothPeriod = 0;

Phase = 0;

DeltaPhase = 0;

DeltaPhase_raw = 0;

alpha = 0;

alpha_raw = 0;

vmama = 0;

vfama = 0;

} else {

# Smooth and detrend my smoothed signal:

Smooth = WMA_Smooth(Price);

Detrender = ( 0.0962 * Smooth

+ 0.5769 * Smooth[2]

- 0.5769 * Smooth[4]

- 0.0962 * Smooth[6] ) * CorrectionFactor;

 

Q1 = ( 0.0962 * Detrender

+ 0.5769 * Detrender[2]

- 0.5769 * Detrender[4]

- 0.0962 * Detrender[6] ) * CorrectionFactor;

I1 = Detrender[3];

 

jI = ( 0.0962 * I1

+ 0.5769 * I1[2]

- 0.5769 * I1[4]

- 0.0962 * I1[6] ) * CorrectionFactor;

 

jQ = ( 0.0962 * Q1

+ 0.5769 * Q1[2]

- 0.5769 * Q1[4]

- 0.0962 * Q1[6] ) * CorrectionFactor;

 

# This is the complex conjugate

I2_raw = I1 - jQ;

Q2_raw = Q1 + jI;

 

I2 = 0.2*I2_raw + 0.8*I2_raw[1];

Q2 = 0.2*Q2_raw + 0.8*Q2_raw[1];

 

Re_raw = I2*I2[1] + Q2*Q2[1];

Im_raw = I2*Q2[1] - Q2*I2[1];

 

Re = 0.2*Re_raw + 0.8*Re_raw[1];

Im = 0.2*Im_raw + 0.8*Im_raw[1];

 

# Compute the phase

if Re != 0 and Im != 0 then {

Period_raw = 2*double.PI / atan(Im/Re);

} else {

Period_raw = 0;

}

 

if Period_raw > 1.5*Period_raw[1] then {

Period_cap = 1.5*Period_raw[1];

} else if Period_raw < 0.67 * Period_raw[1] {

Period_cap = 0.67 * Period_raw[1];

} else {

Period_cap = Period_raw;

}

 

if Period_cap < 6 then {

Period_lim = 6;

} else if Period_cap > 50 then {

Period_lim = 50;

} else {

Period_lim = Period_cap;

}

 

Period = 0.2*Period_lim + 0.8*Period_lim[1];

SmoothPeriod = 0.33*Period + 0.67*SmoothPeriod[1];

 

if I1 != 0 then {

Phase = ATan(Q1 / I1);

} else if Q1 > 0 then { # Quadrant 1:

Phase = Double.Pi/2;

} else if Q1 < 0 then { # Quadrant 4:

Phase = -Double.Pi/2;

} else { # Both numerator and denominator are 0.

Phase = 0;

}

 

DeltaPhase_raw = Phase[1] - Phase;

If DeltaPhase_raw < 1 then {

DeltaPhase = 1;

} else {

DeltaPhase = DeltaPhase_raw;

}

 

alpha_raw = FastLimit / DeltaPhase;

If alpha_raw < SlowLimit then {

alpha = SlowLimit;

} else {

alpha = alpha_raw;

}

vmama = alpha*Price + (1 - alpha)*vmama[1];

vfama = 0.5*alpha*vmama + (1 - 0.5*alpha)*vfama[1];

}

 

plot MAMA = vmama;

plot FAMA = vfama;

}

 

declare upper;

input price = hl2;

input FastLimit = 0.5;

input SlowLimit = 0.05;

 

### plot MAMA = Ehler_MAMA(price, FastLimit, SlowLimit).MAMA;

### Plot FAMA = Ehler_MAMA(price, FastLimit, SlowLimit).FAMA;



plot MAMA = compoundValue(20,Ehler_MAMA(price, FastLimit, SlowLimit).MAMA,average(close,3));

plot FAMA = compoundValue(30,Ehler_MAMA(price, FastLimit, SlowLimit).FAMA,average(close,7));

 

### Plot MADIFF = (mama-fama);

### madiff.SetPaintingStrategy(paintingStrategy.HISTOGRAM);

### madiff.AssignValueColor (if madiff >= 0.00 then (color.green) else (color.red));

 

### Plot MALine = madiff;

### maline.AssignValueColor (if madiff >= 0.00 then (color.green) else (color.red));



# End Study

Shareable Link

http://tos.mx/1BjtpK



http://tos.mx/nw7xS1

@jerrydinvestor contributed to this post.
 
Last edited:
borntostun

borntostun

New member
VIP
Would it be possible to get a watchlist column that shows the MAMA:bull or MAMA:bear indicator?
 
Rojo Grande

Rojo Grande

Member
VIP
Hello Ben,
Can an audible crossover alert be generated? I tried doing it in my watch lists, but no luck.
 
T

tomsk

Well-known member
VIP
There are two plots in that Ehlers MESA study - MAMA and FAMA. Depending on the plot of interest your condition can be as simple as "closes crosses above MAMA" for a bullish interest.
 
Rojo Grande

Rojo Grande

Member
VIP
There are two plots in that Ehlers MESA study - MAMA and FAMA. Depending on the plot of interest your condition can be as simple as "closes crosses above MAMA" for a bullish interest.
Thank you for your reply tomsk,
When I do as you instructed, I get the following:

Error processing referenced script MAMA: No such function: BarNumber at 1:1
Error processing referenced script MAMA: No such function: BarNumber at 1:23
Expected interface com.devexperts.tos.thinkscript.data.IDataHolder at 1:15
Expected interface com.devexperts.tos.thinkscript.data.IDataHolder at 1:15

I am using the shareable link, which appears to be different from the copy & paste version. When I saved the study, I named it MAMA. Was this wrong?
 
T

tomsk

Well-known member
VIP
Well it all depends on what/how you've implemented it, whether on a watchlist, study, strategy, scan, etc Whenever you run into errors, it is always best to provide the entire exact code as well as other pertinent info so that other folks can help you. This provides context. Otherwise it will be an uphill task for anyone to assist you
 
Rojo Grande

Rojo Grande

Member
VIP
Well it all depends on what/how you've implemented it, whether on a watchlist, study, strategy, scan, etc Whenever you run into errors, it is always best to provide the entire exact code as well as other pertinent info so that other folks can help you. This provides context. Otherwise it will be an uphill task for anyone to assist you
I am using the code as a study. It works well on my graphs. Here is the exact code. Thank you.
Code:
# hint: <b>Ehler's Mesa Adaptive Moving Average</b> using Ray's clean version
# of the homodyne discriminator.
#

# MIT License
# Copyright (c) <2010> <Radford Juang>
#
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in
#all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.
#

script WMA_Smooth {
    input price = hl2;
    plot smooth = (4 * price
[LIST]
[*]3 * price[1]
[*]2 * price[2]
[*]price[3]) / 10;
[/LIST]
}

script Phase_Accumulation {
# This is Ehler's Phase Accumulation code. It has a full cycle delay.
# However, it computes the correction factor to a very high degree.
#
    input price = hl2;

    rec Smooth;
    rec Detrender;
    rec Period;
    rec Q1;
    rec I1;
    rec I1p;
    rec Q1p;
    rec Phase1;
    rec Phase;
    rec DeltaPhase;
    rec DeltaPhase1;
    rec InstPeriod1;
    rec InstPeriod;
    def CorrectionFactor;

    if BarNumber() <= 5
    then {
        Period = 0;
        Smooth = 0;
        Detrender = 0;
        CorrectionFactor = 0;
        Q1 = 0;
        I1 = 0;
        Q1p = 0;
        I1p = 0;
        Phase = 0;
        Phase1 = 0;
        DeltaPhase1 = 0;
        DeltaPhase = 0;
        InstPeriod = 0;
        InstPeriod1 = 0;
    } else {
        CorrectionFactor = 0.075 * Period[1] + 0.54;

# Smooth and detrend my smoothed signal:
        Smooth = WMA_Smooth(price);
        Detrender = ( 0.0962 * Smooth
+ 0.5769 * Smooth[2]
[LIST]
[*]0.5769 * Smooth[4]
[*]0.0962 * Smooth[6] ) * CorrectionFactor;
[/LIST]

# Compute Quadrature and Phase of Detrended signal:
        Q1p = ( 0.0962 * Detrender
+ 0.5769 * Detrender[2]
[LIST]
[*]0.5769 * Detrender[4]
[*]0.0962 * Detrender[6] ) * CorrectionFactor;
[/LIST]
        I1p = Detrender[3];

# Smooth out Quadrature and Phase:
        I1 = 0.15 * I1p + 0.85 * I1p[1];
        Q1 = 0.15 * Q1p + 0.85 * Q1p[1];

# Determine Phase
        if I1 != 0
        then {
# Normally, ATAN gives results from -pi/2 to pi/2.
# We need to map this to circular coordinates 0 to 2pi

            if Q1 >= 0 and I1 > 0
            then { # Quarant 1
                Phase1 = ATan(AbsValue(Q1 / I1));
            } else if Q1 >= 0 and I1 < 0
            then { # Quadrant 2
                Phase1 = Double.Pi - ATan(AbsValue(Q1 / I1));
            } else if Q1 < 0 and I1 < 0
            then { # Quadrant 3
                Phase1 = Double.Pi + ATan(AbsValue(Q1 / I1));
            } else { # Quadrant 4
                Phase1 = 2 * Double.Pi - ATan(AbsValue(Q1 / I1));
            }
        } else if Q1 > 0
        then { # I1 == 0, Q1 is positive
            Phase1 = Double.Pi / 2;
        } else if Q1 < 0
        then { # I1 == 0, Q1 is negative
            Phase1 = 3 * Double.Pi / 2;
        } else { # I1 and Q1 == 0
            Phase1 = 0;
        }

# Convert phase to degrees
        Phase = Phase1 * 180 / Double.Pi;

        if Phase[1] < 90 and Phase > 270
        then {
# This occurs when there is a big jump from 360-0
            DeltaPhase1 = 360 + Phase[1] - Phase;
        } else {
            DeltaPhase1 = Phase[1] - Phase;
        }

# Limit our delta phases between 7 and 60
        if DeltaPhase1 < 7
        then {
            DeltaPhase = 7;
        } else if DeltaPhase1 > 60
        then {
            DeltaPhase = 60;
        } else {
            DeltaPhase = DeltaPhase1;
        }

# Determine Instantaneous period:
        InstPeriod1 =
-1 * (fold i = 0 to 40 with v=0 do
if v < 0 then
v
else if v > 360 then
-i
else
v + GetValue(DeltaPhase, i, 41)
);

        if InstPeriod1 <= 0
        then {
            InstPeriod = InstPeriod[1];
        } else {
            InstPeriod = InstPeriod1;
        }

        Period = 0.25 * InstPeriod + 0.75 * Period[1];
    }
    plot DC = Period;
}

script Ehler_MAMA {
    input price = hl2;
    input FastLimit = 0.5;
    input SlowLimit = 0.05;


    rec Period;
    rec Period_raw;
    rec Period_cap;
    rec Period_lim;

    rec Smooth;
    rec Detrender;
    rec I1;
    rec Q1;
    rec jI;
    rec jQ;
    rec I2;
    rec Q2;
    rec I2_raw;
    rec Q2_raw;

    rec Phase;
    rec DeltaPhase;
    rec DeltaPhase_raw;
    rec alpha;
    rec alpha_raw;

    rec Re;
    rec Im;
    rec Re_raw;
    rec Im_raw;

    rec SmoothPeriod;
    rec vmama;
    rec vfama;

    def CorrectionFactor = Phase_Accumulation(price).CorrectionFactor;

    if BarNumber() <= 5
    then {
        Smooth = 0;
        Detrender = 0;

        Period = 0;
        Period_raw = 0;
        Period_cap = 0;
        Period_lim = 0;
        I1 = 0;
        Q1 = 0;
        I2 = 0;
        Q2 = 0;
        jI = 0;
        jQ = 0;
        I2_raw = 0;
        Q2_raw = 0;
        Re = 0;
        Im = 0;
        Re_raw = 0;
        Im_raw = 0;
        SmoothPeriod = 0;
        Phase = 0;
        DeltaPhase = 0;
        DeltaPhase_raw = 0;
        alpha = 0;
        alpha_raw = 0;
        vmama = 0;
        vfama = 0;
    } else {
# Smooth and detrend my smoothed signal:
        Smooth = WMA_Smooth(price);
        Detrender = ( 0.0962 * Smooth
+ 0.5769 * Smooth[2]
[LIST]
[*]0.5769 * Smooth[4]
[*]0.0962 * Smooth[6] ) * CorrectionFactor;
[/LIST]

        Q1 = ( 0.0962 * Detrender
+ 0.5769 * Detrender[2]
[LIST]
[*]0.5769 * Detrender[4]
[*]0.0962 * Detrender[6] ) * CorrectionFactor;
[/LIST]
        I1 = Detrender[3];

        jI = ( 0.0962 * I1
+ 0.5769 * I1[2]
[LIST]
[*]0.5769 * I1[4]
[*]0.0962 * I1[6] ) * CorrectionFactor;
[/LIST]

        jQ = ( 0.0962 * Q1
+ 0.5769 * Q1[2]
[LIST]
[*]0.5769 * Q1[4]
[*]0.0962 * Q1[6] ) * CorrectionFactor;
[/LIST]

# This is the complex conjugate
        I2_raw = I1 - jQ;
        Q2_raw = Q1 + jI;

        I2 = 0.2 * I2_raw + 0.8 * I2_raw[1];
        Q2 = 0.2 * Q2_raw + 0.8 * Q2_raw[1];

        Re_raw = I2 * I2[1] + Q2 * Q2[1];
        Im_raw = I2 * Q2[1] - Q2 * I2[1];

        Re = 0.2 * Re_raw + 0.8 * Re_raw[1];
        Im = 0.2 * Im_raw + 0.8 * Im_raw[1];

# Compute the phase
        if Re != 0 and Im != 0
        then {
            Period_raw = 2 * Double.Pi / ATan(Im / Re);
        } else {
            Period_raw = 0;
        }

        if Period_raw > 1.5 * Period_raw[1]
        then {
            Period_cap = 1.5 * Period_raw[1];
        } else if Period_raw < 0.67 * Period_raw[1] {
            Period_cap = 0.67 * Period_raw[1];
        } else {
            Period_cap = Period_raw;
        }

        if Period_cap < 6
        then {
            Period_lim = 6;
        } else if Period_cap > 50
        then {
            Period_lim = 50;
        } else {
            Period_lim = Period_cap;
        }

        Period = 0.2 * Period_lim + 0.8 * Period_lim[1];
        SmoothPeriod = 0.33 * Period + 0.67 * SmoothPeriod[1];

        if I1 != 0
        then {
            Phase = ATan(Q1 / I1);
        } else if Q1 > 0
        then { # Quadrant 1:
            Phase = Double.Pi / 2;
        } else if Q1 < 0
        then { # Quadrant 4:
            Phase = -Double.Pi / 2;
        } else { # Both numerator and denominator are 0.
            Phase = 0;
        }

        DeltaPhase_raw = Phase[1] - Phase;
        if DeltaPhase_raw < 1
        then {
            DeltaPhase = 1;
        } else {
            DeltaPhase = DeltaPhase_raw;
        }

        alpha_raw = FastLimit / DeltaPhase;
        if alpha_raw < SlowLimit
        then {
            alpha = SlowLimit;
        } else {
            alpha = alpha_raw;
        }
        vmama = alpha * price + (1 - alpha) * vmama[1];
        vfama = 0.5 * alpha * vmama + (1 - 0.5 * alpha) * vfama[1];
    }

    plot MAMA = vmama;
    plot FAMA = vfama;
}

declare upper;
input price = hl2;
input FastLimit = 0.5;
input SlowLimit = 0.05;

plot MAMA = Ehler_MAMA(price, FastLimit, SlowLimit).MAMA;
plot FAMA = Ehler_MAMA(price, FastLimit, SlowLimit).FAMA;

plot Crossing = Crosses((MAMA < FAMA), yes);
Crossing.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);

plot Crossing1 = Crosses((MAMA > FAMA), yes);
Crossing1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);

AddLabel(yes, Concat("MAMA: ", Concat("",
if MAMA > FAMA then "Bull" else "Bear")),

if MAMA > FAMA then Color.GREEN else Color.RED);
 
Last edited by a moderator:
D

dhruvchauhan11

New member
I am using the code as a study. It works well on my graphs. Here is the exact code. Thank you.

# hint: <b>Ehler's Mesa Adaptive Moving Average</b> using Ray's clean version
# of the homodyne discriminator.
#

# MIT License
# Copyright (c) <2010> <Radford Juang>
#
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in
#all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.
#

script WMA_Smooth {
input price = hl2;
plot smooth = (4 * price
  • 3 * price[1]
  • 2 * price[2]
  • price[3]) / 10;
}

script Phase_Accumulation {
# This is Ehler's Phase Accumulation code. It has a full cycle delay.
# However, it computes the correction factor to a very high degree.
#
input price = hl2;

rec Smooth;
rec Detrender;
rec Period;
rec Q1;
rec I1;
rec I1p;
rec Q1p;
rec Phase1;
rec Phase;
rec DeltaPhase;
rec DeltaPhase1;
rec InstPeriod1;
rec InstPeriod;
def CorrectionFactor;

if BarNumber() <= 5
then {
Period = 0;
Smooth = 0;
Detrender = 0;
CorrectionFactor = 0;
Q1 = 0;
I1 = 0;
Q1p = 0;
I1p = 0;
Phase = 0;
Phase1 = 0;
DeltaPhase1 = 0;
DeltaPhase = 0;
InstPeriod = 0;
InstPeriod1 = 0;
} else {
CorrectionFactor = 0.075 * Period[1] + 0.54;

# Smooth and detrend my smoothed signal:
Smooth = WMA_Smooth(price);
Detrender = ( 0.0962 * Smooth
+ 0.5769 * Smooth[2]
  • 0.5769 * Smooth[4]
  • 0.0962 * Smooth[6] ) * CorrectionFactor;

# Compute Quadrature and Phase of Detrended signal:
Q1p = ( 0.0962 * Detrender
+ 0.5769 * Detrender[2]
  • 0.5769 * Detrender[4]
  • 0.0962 * Detrender[6] ) * CorrectionFactor;
I1p = Detrender[3];

# Smooth out Quadrature and Phase:
I1 = 0.15 * I1p + 0.85 * I1p[1];
Q1 = 0.15 * Q1p + 0.85 * Q1p[1];

# Determine Phase
if I1 != 0
then {
# Normally, ATAN gives results from -pi/2 to pi/2.
# We need to map this to circular coordinates 0 to 2pi

if Q1 >= 0 and I1 > 0
then { # Quarant 1
Phase1 = ATan(AbsValue(Q1 / I1));
} else if Q1 >= 0 and I1 < 0
then { # Quadrant 2
Phase1 = Double.Pi - ATan(AbsValue(Q1 / I1));
} else if Q1 < 0 and I1 < 0
then { # Quadrant 3
Phase1 = Double.Pi + ATan(AbsValue(Q1 / I1));
} else { # Quadrant 4
Phase1 = 2 * Double.Pi - ATan(AbsValue(Q1 / I1));
}
} else if Q1 > 0
then { # I1 == 0, Q1 is positive
Phase1 = Double.Pi / 2;
} else if Q1 < 0
then { # I1 == 0, Q1 is negative
Phase1 = 3 * Double.Pi / 2;
} else { # I1 and Q1 == 0
Phase1 = 0;
}

# Convert phase to degrees
Phase = Phase1 * 180 / Double.Pi;

if Phase[1] < 90 and Phase > 270
then {
# This occurs when there is a big jump from 360-0
DeltaPhase1 = 360 + Phase[1] - Phase;
} else {
DeltaPhase1 = Phase[1] - Phase;
}

# Limit our delta phases between 7 and 60
if DeltaPhase1 < 7
then {
DeltaPhase = 7;
} else if DeltaPhase1 > 60
then {
DeltaPhase = 60;
} else {
DeltaPhase = DeltaPhase1;
}

# Determine Instantaneous period:
InstPeriod1 =
-1 * (fold i = 0 to 40 with v=0 do
if v < 0 then
v
else if v > 360 then
-i
else
v + GetValue(DeltaPhase, i, 41)
);

if InstPeriod1 <= 0
then {
InstPeriod = InstPeriod[1];
} else {
InstPeriod = InstPeriod1;
}

Period = 0.25 * InstPeriod + 0.75 * Period[1];
}
plot DC = Period;
}

script Ehler_MAMA {
input price = hl2;
input FastLimit = 0.5;
input SlowLimit = 0.05;


rec Period;
rec Period_raw;
rec Period_cap;
rec Period_lim;

rec Smooth;
rec Detrender;
rec I1;
rec Q1;
rec jI;
rec jQ;
rec I2;
rec Q2;
rec I2_raw;
rec Q2_raw;

rec Phase;
rec DeltaPhase;
rec DeltaPhase_raw;
rec alpha;
rec alpha_raw;

rec Re;
rec Im;
rec Re_raw;
rec Im_raw;

rec SmoothPeriod;
rec vmama;
rec vfama;

def CorrectionFactor = Phase_Accumulation(price).CorrectionFactor;

if BarNumber() <= 5
then {
Smooth = 0;
Detrender = 0;

Period = 0;
Period_raw = 0;
Period_cap = 0;
Period_lim = 0;
I1 = 0;
Q1 = 0;
I2 = 0;
Q2 = 0;
jI = 0;
jQ = 0;
I2_raw = 0;
Q2_raw = 0;
Re = 0;
Im = 0;
Re_raw = 0;
Im_raw = 0;
SmoothPeriod = 0;
Phase = 0;
DeltaPhase = 0;
DeltaPhase_raw = 0;
alpha = 0;
alpha_raw = 0;
vmama = 0;
vfama = 0;
} else {
# Smooth and detrend my smoothed signal:
Smooth = WMA_Smooth(price);
Detrender = ( 0.0962 * Smooth
+ 0.5769 * Smooth[2]
  • 0.5769 * Smooth[4]
  • 0.0962 * Smooth[6] ) * CorrectionFactor;

Q1 = ( 0.0962 * Detrender
+ 0.5769 * Detrender[2]
  • 0.5769 * Detrender[4]
  • 0.0962 * Detrender[6] ) * CorrectionFactor;
I1 = Detrender[3];

jI = ( 0.0962 * I1
+ 0.5769 * I1[2]
  • 0.5769 * I1[4]
  • 0.0962 * I1[6] ) * CorrectionFactor;

jQ = ( 0.0962 * Q1
+ 0.5769 * Q1[2]
  • 0.5769 * Q1[4]
  • 0.0962 * Q1[6] ) * CorrectionFactor;

# This is the complex conjugate
I2_raw = I1 - jQ;
Q2_raw = Q1 + jI;

I2 = 0.2 * I2_raw + 0.8 * I2_raw[1];
Q2 = 0.2 * Q2_raw + 0.8 * Q2_raw[1];

Re_raw = I2 * I2[1] + Q2 * Q2[1];
Im_raw = I2 * Q2[1] - Q2 * I2[1];

Re = 0.2 * Re_raw + 0.8 * Re_raw[1];
Im = 0.2 * Im_raw + 0.8 * Im_raw[1];

# Compute the phase
if Re != 0 and Im != 0
then {
Period_raw = 2 * Double.Pi / ATan(Im / Re);
} else {
Period_raw = 0;
}

if Period_raw > 1.5 * Period_raw[1]
then {
Period_cap = 1.5 * Period_raw[1];
} else if Period_raw < 0.67 * Period_raw[1] {
Period_cap = 0.67 * Period_raw[1];
} else {
Period_cap = Period_raw;
}

if Period_cap < 6
then {
Period_lim = 6;
} else if Period_cap > 50
then {
Period_lim = 50;
} else {
Period_lim = Period_cap;
}

Period = 0.2 * Period_lim + 0.8 * Period_lim[1];
SmoothPeriod = 0.33 * Period + 0.67 * SmoothPeriod[1];

if I1 != 0
then {
Phase = ATan(Q1 / I1);
} else if Q1 > 0
then { # Quadrant 1:
Phase = Double.Pi / 2;
} else if Q1 < 0
then { # Quadrant 4:
Phase = -Double.Pi / 2;
} else { # Both numerator and denominator are 0.
Phase = 0;
}

DeltaPhase_raw = Phase[1] - Phase;
if DeltaPhase_raw < 1
then {
DeltaPhase = 1;
} else {
DeltaPhase = DeltaPhase_raw;
}

alpha_raw = FastLimit / DeltaPhase;
if alpha_raw < SlowLimit
then {
alpha = SlowLimit;
} else {
alpha = alpha_raw;
}
vmama = alpha * price + (1 - alpha) * vmama[1];
vfama = 0.5 * alpha * vmama + (1 - 0.5 * alpha) * vfama[1];
}

plot MAMA = vmama;
plot FAMA = vfama;
}

declare upper;
input price = hl2;
input FastLimit = 0.5;
input SlowLimit = 0.05;

plot MAMA = Ehler_MAMA(price, FastLimit, SlowLimit).MAMA;
plot FAMA = Ehler_MAMA(price, FastLimit, SlowLimit).FAMA;

plot Crossing = Crosses((MAMA < FAMA), yes);
Crossing.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);

plot Crossing1 = Crosses((MAMA > FAMA), yes);
Crossing1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);

AddLabel(yes, Concat("MAMA: ", Concat("",
if MAMA > FAMA then "Bull" else "Bear")),

if MAMA > FAMA then Color.GREEN else Color.RED);
its not working
 
T

tomsk

Well-known member
VIP
There is major problem with the code that @Rojo Grande posted in post # 7. Many math operators have been dropped which suggests that he might have stored the code in a word processor like Word. For best results all ThinkScript code should be stored in NotePad or NotePad++ or strange things will happen. I tested the version that @BenTen posted in post # 1 of this thread - it works fine on a lower aggregation chart e.g. 5 mins
 
Rojo Grande

Rojo Grande

Member
VIP
I went ahead and enlarged the arrow size to 5 and changed the colors, that should catch my eyes as an alert in my charts. Thanks everyone for your time. (y) :)
 
Rojo Grande

Rojo Grande

Member
VIP
Me again. After reading probably a dozen posts on here, I was able to come up with the following lines that provide audible alerts to the crossings. I intentionally left both as bell, as this was only to get my attention. Many thanks to all who contribute to this site.:)

alert( MAMA Crosses Above FAMA, "Bull", Alert.BAR, Sound.Bell );
alert( MAMA Crosses Below FAMA, "Bear", Alert.BAR, Sound.Bell );
 
D

dhruvchauhan11

New member
Code not working for me. I tried to copy and paste yours
Me again. After reading probably a dozen posts on here, I was able to come up with the following lines that provide audible alerts to the crossings. I intentionally left both as bell, as this was only to get my attention. Many thanks to all who contribute to this site.:)

alert( MAMA Crosses Above FAMA, "Bull", Alert.BAR, Sound.Bell );
alert( MAMA Crosses Below FAMA, "Bear", Alert.BAR, Sound.Bell );
 
D

DB01

New member
Did anyone come up with a TOS scan for stocks that have an alert signal (buy or sell) from this indy? I'm just looking for stocks where the FAMA has crossed the MAMA in either direction. When I try and build it custom in the TOS scanner custom filter, I get a "Too complex exception" and that the scan is too complex for reliable real time data. All Im asking for is a 2 lines cross, not that complex. Any help?
 
horserider

horserider

Well-known member
VIP
@DB01 Use EMA 3 and EMA 8 should give essentially same crosses. Try it and see.
 
T

tomsk

Well-known member
VIP
Did anyone come up with a TOS scan for stocks that have an alert signal (buy or sell) from this indy? I'm just looking for stocks where the FAMA has crossed the MAMA in either direction. When I try and build it custom in the TOS scanner custom filter, I get a "Too complex exception" and that the scan is too complex for reliable real time data. All Im asking for is a 2 lines cross, not that complex. Any help?

My assumption is that you're referring to Ben's posted study in post#1 of this thread. Tere are two basic plots therein - FAMA and MAMA. This works very well on a chart study. However because the manner in which the underlying study is derived and written, it is too complex to be used on the scanner. That is why you see the message that the scan is too complex for real time data. That said, there is a workaround alternative.

Stepping back for a moment you'll note that this study parallels a very fast moving average and appears to resemble two fast moving averages. The suggestion that @horserider gave above is a good one. It not only gives you a similar look and feel to the FAMA/MAMA study, but is very simple that it can be scanned with no problems. Hence do try the suggestion made in post # 15
 
D

DB01

New member
Yep. Gives very similar results when you take the scanner list and put the MAMA study on it. Thanks for the help.
 
Billions

Billions

Active member
2019 Donor
VIP
@tomsk what settings are you using on this?
 
M

muztem

New member
can we use on es or it needs different settings?
thank you
 
D

DB01

New member
I've been using it right out of the box with no adjustments to the settings. I've been looking at it with ES, but I haven't actually traded it.
 
Top