Stock Portfolio Organizer

The ultimate porfolio management solution.

Shares, Margin, CFD's, Futures and Forex
EOD and Realtime
Dividends and Trust Distributions
And Much More ....
For Portfolio Manager Click Here

WiseTrader Toolbox

#1 Selling Amibroker Plugin featuring:

Advanced Adaptive Indicators
Advanced Pattern Exploration
Neural Networks
And Much More ....
Find Out More Here

The Real Jurik Moving Average (JMA) (Translated to Amibroker) for Amibroker (AFL)

Rating:
3 / 5 (Votes 2)
Tags:
amibroker

I don’t remember where I got this formula but if I am not mistaken it was translated from MT4 to Amibroker by a German programmer. I’ve tested with original JMA, and the results are the same/accurate (if I’m not mistaken) but there are drawbacks, maybe because the translation is not perfect, sometimes we got an error. For example, the error (Error 10. Array subscript out of range) sometimes appears when changing timeframe to monthly. Maybe someone can fix it?

Many thanks are for Jurik, to the original coder and anyone who can fix the error and share the fix.

Screenshots

Indicator / Formula

Copy & Paste Friendly
//+------------------------------------------------------------------+
//SetBarsRequired(ceil(20+80*(r1^0.36)));
//SetBarsRequired(200,0);
function IntPortion( Paramet )
{
    return IIf( Paramet > 0, floor( Paramet ), ceil( Paramet ) );
};

//+------------------------------------------------------------------+
function JJMA( Array, Length, Phase )
{
	//----buffers
    fC0Buffer = fC8Buffer = fA8Buffer = 0;
    JMAValueBuffer = Array;
    JMAValue = 0;
    loopCriteria = cycleDelta = cycleLimit = counterA = counterB = JMATempValue = 0;
	//+------------------------------------------------------------------+
	//|JMAinitFlagizationfunction|
	//+------------------------------------------------------------------+
    ring2 = 0;
    ring1 = 0;
    buffer = 0;
	//----initialpart
    limitValue = 63;
    startValue = 64;
	//----

    for( i = 0; i <= limitValue; i++ )
        list[i] = -1000000;

    for( i = startValue; i <= 127; i++ )
        list[i] = 1000000;

	//----
    initFlag = True;

    lengthParam = IIf( Length < 1.0000000002, 0.0000000001, ( Length - 1 ) / 2.0 );

	//----
    if( Phase < -100 )
        phaseParam = 0.5;
    else
        if( Phase > 100 )
            phaseParam = 2.5;
        else
            phaseParam = Phase / 100.0 + 1.5;

	//----
    logParam = log( sqrt( lengthParam ) ) / log( 2.0 );

	//----
    logParam = IIf( ( logParam + 2.0 ) < 0, 0, logParam + 2.0 );

	//----
    sqrtParam = sqrt( lengthParam ) * logParam;

    lengthParam = lengthParam * 0.9;

    lengthDivider = lengthParam / ( lengthParam + 2.0 );

	//----
	//+------------------------------------------------------------------+
	//|JMAiterationfunction|
	//+------------------------------------------------------------------+
	//----maincycle
    loopParam = 0;

    for( shift = 0; shift <= BarCount - 1; shift++ )
    {
        series = Array[shift];

        if( loopParam < 61 )
        {
            loopParam++;
            buffer[loopParam] = series;
        }

        if( loopParam > 30 )
        {
            if( initFlag )
            {
                initFlag = False;

                diffFlag = 0;

                for( i = 1; i <= 29; i++ )
                {
                    if( buffer[i + 1] != buffer[i] )
                        diffFlag = 1;
                }

                highLimit = diffFlag * 30;

                if( highLimit == 0 )
                    paramB = series;
                else
                    paramB = buffer[1];

                paramA = paramB;

                if( highLimit > 29 )
                    highLimit = 29;
            }
            else
                highLimit = 0;

			//----bigcycle
            for( i = highLimit; i >= 0; i-- )
            {
                if( i == 0 )
                    sValue = series;
                else
                    sValue = buffer[31 - i];

                if( abs( sValue - paramA ) > abs( sValue - paramB ) )
                    absValue = abs( sValue - paramA );
                else
                    absValue = abs( sValue - paramB );

                dValue = absValue + 0.0000000001; //1.0e-10;

                if( counterA <= 1 )
                    counterA = 127;
                else
                    counterA--;

                if( counterB <= 1 )
                    counterB = 10;
                else
                    counterB--;

                if( cycleLimit < 128 )
                    cycleLimit++;

                cycleDelta = cycleDelta + ( dValue - ring2[counterB] );

                ring2[counterB] = dValue;

                if( cycleLimit > 10 )
                    highDValue = cycleDelta / 10.0;
                else
                    highDValue = cycleDelta / cycleLimit;

                if( cycleLimit > 127 )
                {
                    dValue = ring1[counterA];
                    ring1[counterA] = highDValue;
                    s68 = 64;
                    s58 = s68;

                    while( s68 > 1 )
                    {
                        if( list[s58] < dValue )
                        {
                            s68 = s68 / 2.0;
                            s58 = s58 + s68;
                        }
                        else
                            if( list[s58] <= dValue )
                            {
                                s68 = 1;
                            }
                            else
                            {
                                s68 = s68 / 2.0;
                                s58 = s58 - s68;
                            }
                    }
                }
                else
                {
                    ring1[counterA] = highDValue;

                    if( ( limitValue + startValue ) > 127 )
                    {
                        startValue--;
                        s58 = startValue;
                    }
                    else
                    {
                        limitValue++;
                        s58 = limitValue;
                    }

                    if( limitValue > 96 )
                        s38 = 96;
                    else
                        s38 = limitValue;

                    if( startValue < 32 )
                        s40 = 32;
                    else
                        s40 = startValue;
                }

				//----
                s68 = 64;

                s60 = s68;

                while( s68 > 1 )
                {
                    if( list[s60] >= highDValue )
                    {
                        if( list[s60 - 1] <= highDValue )
                        {
                            s68 = 1;
                        }
                        else
                        {
                            s68 = s68 / 2.0;
                            s60 = s60 - s68;
                        }
                    }
                    else
                    {
                        s68 = s68 / 2.0;
                        s60 = s60 + s68;
                    }

                    if( ( s60 == 127 ) && ( highDValue > list[127] ) )
                        s60 = 128;
                }

                if( cycleLimit > 127 )
                {
                    if( s58 >= s60 )
                    {
                        if( ( ( s38 + 1 ) > s60 ) && ( ( s40 - 1 ) < s60 ) )
                            lowDValue = lowDValue + highDValue;
                        else
                            if( ( s40 > s60 ) && ( ( s40 - 1 ) < s58 ) )
                                lowDValue = lowDValue + list[s40 - 1];
                    }
                    else
                        if( s40 >= s60 )
                        {
                            if( ( ( s38 + 1 ) < s60 ) && ( ( s38 + 1 ) > s58 ) )
                                lowDValue = lowDValue + list[s38 + 1];
                        }
                        else
                            if( ( s38 + 2 ) > s60 )
                                lowDValue = lowDValue + highDValue;
                            else
                                if( ( ( s38 + 1 ) < s60 ) && ( ( s38 + 1 ) > s58 ) )
                                    lowDValue = lowDValue + list[s38 + 1];

                    if( s58 > s60 )
                    {
                        if( ( ( s40 - 1 ) < s58 ) && ( ( s38 + 1 ) > s58 ) )
                            lowDValue = lowDValue - list[s58];
                        else
                            if( ( s38 < s58 ) && ( ( s38 + 1 ) > s60 ) )
                                lowDValue = lowDValue - list[s38];
                    }
                    else
                    {
                        if( ( ( s38 + 1 ) > s58 ) && ( ( s40 - 1 ) < s58 ) )
                            lowDValue = lowDValue - list[s58];
                        else
                            if( ( s40 > s58 ) && ( s40 < s60 ) )
                                lowDValue = lowDValue - list[s40];
                    }
                }

                if( s58 <= s60 )
                {
                    if( s58 >= s60 )
                        list[s60] = highDValue;
                    else
                    {
                        for( j = s58 + 1; j <= ( s60 - 1 ); j++ )
                        {
                            list[j - 1] = list[j];
                        }

                        list[s60 - 1] = highDValue;
                    }
                }
                else
                {
                    for( j = s58 - 1; j >= s60; j-- )
                    {
                        list[j + 1] = list[j];
                    }

                    list[s60] = highDValue;
                }

                if( cycleLimit <= 127 )
                {
                    lowDValue = 0;

                    for( j = s40; j <= s38; j++ )
                    {
                        lowDValue = lowDValue + list[j];
                    }
                }

				//----
                if( ( loopCriteria + 1 ) > 31 )
                    loopCriteria = 31;
                else
                    loopCriteria++;

                JMATempValue = sqrtDivider = sqrtParam / ( sqrtParam + 1.0 );

                if( loopCriteria <= 30 )
                {
                    if( sValue - paramA > 0 )
                        paramA = sValue;
                    else
                        paramA = sValue - ( sValue - paramA ) * sqrtDivider;

                    if( sValue - paramB < 0 )
                        paramB = sValue;
                    else
                        paramB = sValue - ( sValue - paramB ) * sqrtDivider;

                    JMATempValue = series;

                    if( loopCriteria == 30 )
                    {
                        fC0Buffer[shift] = series;

                        if( ceil( sqrtParam ) >= 1 )
                            intPart = ceil( sqrtParam );
                        else
                            intPart = 1;

                        leftInt = IntPortion( intPart );

                        if( floor( sqrtParam ) >= 1 )
                            intPart = floor( sqrtParam );
                        else
                            intPart = 1;

                        rightPart = IntPortion( intPart );

                        if( leftInt == rightPart )
                            dValue = 1.0;
                        else
                            dValue = ( sqrtParam - rightPart ) / ( leftInt - rightPart );

                        if( rightPart <= 29 )
                            upShift = rightPart;
                        else
                            upShift = 29;

                        if( leftInt <= 29 )
                            dnShift = leftInt;
                        else
                            dnShift = 29;

                        fA8Buffer[shift] = ( series - buffer[loopParam - upShift] ) * ( 1 - dValue ) / rightPart + ( series - buffer[loopParam - dnShift] ) * dValue / leftInt;
                    }
                }
                else
                {

                    dValue = lowDValue / ( s38 - s40 + 1 );

                    if( 0.5 <= logParam - 2.0 )
                        powerValue = logParam - 2.0;
                    else
                        powerValue = 0.5;

                    if( logParam >= ( absValue / dValue )^powerValue )
                        dValue = ( absValue / dValue )^powerValue;
                    else
                        dValue = logParam;

                    if( dValue < 1 )
                        dValue = 1;

                    powerValue = sqrtDivider ^ ( sqrt( dValue ) );

                    if( sValue - paramA > 0 )
                        paramA = sValue;
                    else
                        paramA = sValue - ( sValue - paramA ) * powerValue;

                    if( sValue - paramB < 0 )
                        paramB = sValue;
                    else
                        paramB = sValue - ( sValue - paramB ) * powerValue;
                }
            }

			//----endofbigcycle
            if( loopCriteria > 30 )
            {
                JMATempValue = JMAValueBuffer[shift - 1];
                powerValue = lengthDivider ^ dValue;
                squareValue = powerValue ^ 2;

                fC0Buffer[shift] = ( 1 - powerValue ) * series + powerValue * fC0Buffer[shift - 1];
                fC8Buffer[shift] = ( series - fC0Buffer[shift] ) * ( 1 - lengthDivider ) + lengthDivider * fC8Buffer[shift - 1];

                fA8Buffer[shift] = ( phaseParam * fC8Buffer[shift] + fC0Buffer[shift] - JMATempValue ) *
                                   ( powerValue * ( -2.0 ) + squareValue + 1 ) + squareValue * fA8Buffer[shift - 1];
                JMATempValue = JMATempValue + fA8Buffer[shift];
            }

            JMAValue = JMATempValue;
        }

        if( loopParam <= 30 )
            JMAValue = C[BarCount - 1];

        JMAValueBuffer[shift] = JMAValue;
		//----Endofmaincycle
    }

    return JMAValueBuffer;
}

P = ParamField( "Price field", -1 );
Periods = Param( "Periods", 15, 2, 300, 1, 10 );
phase = Param( "Phase", 0, -100, 100, 1, 1 );
SetBarsRequired( ceil( 20 + 80 * ( Periods ^ 0.36 ) ) );
Plot( JJMA( P, Periods, phase ), "JurikJMA", ParamColor( "Color", colorCycle ), ParamStyle( "Style" ) );

2 comments

1. HelpingEachOther

i’m not the translator not the creator of this program, not 100% perfect, hope someone can improve it.

2. kareda0077

change last line like to this line:

Plot ( JJMA( P, Periods, phase ), "JurikJMA", ParamColor( "Color", colorCycle ),ParamStyle("Style") ) ;

Leave Comment

Please login here to leave a comment.

Back