Pine Script Translation Failure for ELMA

Instead of the expected moving average I get a straight line with the following script

_SECTION_BEGIN("ELMA");
//Exponential Logarithmic Moving Average
function ELMA(src, len, lambda)
{
	weightedLogSum = 0.0;
    totalWeight = 0.0;

	for(i = 0; i < len; i++)
	{
	    weight = exp(-lambda * i);
        logValue = log(src[i]);
        weightedLogSum = weightedLogSum + logValue * weight;
        totalWeight = totalWeight + weight;
        result = exp(weightedLogSum / totalWeight);
	}
return result;
} 

length = Param("length", 21, 2, 100, 1);
lambda = Param("Decay Rate", 0.0618, 0.0118, 0.0918, 0.01);
ELMAValue = ELMA(C, length, lambda);
Plot(ELMAValue, "ELMA", ColorGreen, StyleThick  );
_SECTION_END();

Thank you for assistance !

I forgot the link for the original Pine script
[ChartRage - ELMA — Indicateur par ChartRage — TradingView]

AmiBroker != TradingView and you don't need "for" or "if".
You may be able to do this using only AFL Code Wizard.

Thank you for your answer, I know that AFL != Pine,
but I'm not used to the code Wizard, also my code
compiles normally, the function also looks like
similar functions in other scripts, so I wonder
what exactly is wrong with it....

shouldn't that be a loop within a loop? Below my attempt. I added another function MA2 as a test function to compare with the built-in MA function.

_SECTION_BEGIN( "ELMA" );
//Exponential Logarithmic Moving Average
function ELMA( src, len, lambda )
{
    res = Null;

    for( i = len; i < BarCount; i++ )
    {
        weightedLogSum = 0.0;
        totalWeight = 0.0;

        for( j = 0; j < len; j++ )
        {
            weight = exp( -lambda * j );
            logValue = log( src[i - j] );
            weightedLogSum = weightedLogSum + ( logValue * weight );
            totalWeight = totalWeight + weight;
            res1 = exp( weightedLogSum / totalWeight );
        }

        res[i] = res1;
    }

    return res;
}

function MA2( src, len )
{
    res = Null;

    for( i = len; i < BarCount; i++ )
    {
        for( j = 0; j < len; j++ )
        {
            res[i] = Nz( res[i] ) + src[i - j];
        }

        res[i] = res[i] / len;
    }

    return res;
}

length = Param( "length", 20, 2, 100, 1 );
lambda = Param( "Decay Rate", 0.0618, 0.0118, 0.0918, 0.01 );
ELMAValue = ELMA( C, length, lambda );

SetChartBkColor( ColorRGB( 0, 0, 0 ) );
SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "C", colorWhite, styleCandle, Null, Null, 0, 0, 0 );
Plot( ELMAValue, "ELMA", ColorGreen, StyleThick );
Plot( EMA( C, length ), "EMA", colorGold, styleLine, Null, Null, 0, 0, 1 );
Plot( MA( C, length ), "MA", colorRed, styleLine, Null, Null, 0, 0, 1 );
Plot( MA2( C, length ), "MA1", colorBlue, styleLine, Null, Null, 0, 0, 1 );
_SECTION_END();
1 Like

Thank you ! Just perfect ! :slightly_smiling_face:

yes I looked at the formula they give and written it in another form but gives same result:

_SECTION_BEGIN( "ELMA" );
//Exponential Logarithmic Moving Average
function ELMA( src, len, lambda )
{
    res = Null;

    for( i = len; i < BarCount; i++ )
    {
        weightedLogSum = 0.0;
        totalWeight = 0.0;

        for( j = 0; j < len; j++ )
        {
            weight = exp( -lambda * j );
            logValue = log( src[i - j] );
            weightedLogSum = weightedLogSum + ( logValue * weight );
            totalWeight = totalWeight + weight;
        }

        res[i] = exp( weightedLogSum / totalWeight );
    }

    return res;
}

function ELMA2( src, len, lambda )
{
    res = Null;

    for( i = len; i < BarCount; i++ )
    {
        numerator = 0;
        denominator = 0;

        for( j = 0; j < len; j++ )
        {
            numerator = numerator + exp( -lambda * j ) * log( src[i - j] );
            denominator = denominator + exp( -lambda * j );
        }

        res[i] = exp( SafeDivide( numerator, denominator ) );
    }

    return res;
}

function MA2( src, len )
{
    res = Null;

    for( i = len; i < BarCount; i++ )
    {
        for( j = 0; j < len; j++ )
        {
            res[i] = Nz( res[i] ) + src[i - j];
        }

        res[i] = res[i] / len;
    }

    return res;
}

length = Param( "length", 20, 2, 100, 1 );
lambda = Param( "Decay Rate", 0.0618, 0.0118, 0.0918, 0.01 );
ELMAValue = ELMA( C, length, lambda );
ELMAValue2 = ELMA2( C, length, lambda );

SetChartBkColor( ColorRGB( 0, 0, 0 ) );
SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "C", colorWhite, styleCandle, Null, Null, 0, 0, 0 );
Plot( ELMAValue, "ELMA", ColorGreen, StyleThick );
Plot( ELMAValue2, "ELMA2", colorOrange, StyleThick );
Plot( EMA( C, length ), "EMA", colorGold, styleLine, Null, Null, 0, 0, 1 );
//Plot( MA( C, length ), "MA", colorRed, styleLine, Null, Null, 0, 0, 1 );
//Plot( MA2( C, length ), "MA2", colorBlue, styleLine, Null, Null, 0, 0, 1 );
_SECTION_END();

You don't need nested loop at all. That's crazy.

Just use Ref() function.

_SECTION_BEGIN("ELMA");
//Exponential Logarithmic Moving Average
function ELMA(src, len, lambda)
{
  weightedLogSum = 0;
  totalWeight = 0;

  for(i = 0; i < len; i++)
  {
        weight = exp(-lambda * i);
        logValue = log(Ref(src,-i));
        weightedLogSum += (logValue * weight);
        totalWeight += weight;        
  }
  
  result = exp(weightedLogSum / totalWeight);
  return result;
} 

length = Param("length", 21, 2, 100, 1);
lambda = Param("Decay Rate", 0.0618, 0.0118, 0.0918, 0.01);
ELMAValue = ELMA(C, length, lambda);
Plot(ELMAValue, "ELMA", ColorRed, StyleThick  );
_SECTION_END();

4 Likes

Indeed crazy with so few modifications to my
initial code, but less obvious than the double loop.

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.