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.