Dukascopy
 
 
Wiki JStore Search Login

Attention! Read the forum rules carefully before posting a topic.

    Try to find an answer in Wiki before asking a question.
    Submit programming questions in this forum only.
    Off topics are strictly forbidden.

Any topics which do not satisfy these rules will be deleted.

Elhers Adaptive Laguerre Filter - debug help
 Post subject: Elhers Adaptive Laguerre Filter - debug help Post rating: 0   New post Posted: Mon 21 Mar, 2011, 05:54 

User rating: 0
Joined: Wed 09 Mar, 2011, 10:40
Posts: 8
I'm trying to port Ehler's adaptive Laguerre filter - an excellent overbought oversold indicator, but my Java inexperience is showing badly. It has two tricky aspects - use of the previous value (j+1) in the current value calculation of filter, and the need to use an simple moving average(1) on median price as input. Could anyone help debug?


package com.dukascopy.indicators;

import com.dukascopy.api.indicators.*;
import com.dukascopy.api.IIndicators;
import java.util.Arrays;

/**
 * @author Simon Kaufmann
 *         Date:    Mar 16, 2011
 *         Time:    9:35:00 PM
 */
public class AdapativeLaguerreFilter implements IIndicator {
    private IndicatorInfo indicatorInfo;
    private InputParameterInfo inputParameterInfos;
    private OptInputParameterInfo[] optInputParameterInfos;
    private OutputParameterInfo[] outputParameterInfos;
    private int Lookback = 20;
    private int Median = 5;
    private double[][] inputs = new double[1][];
    private double[][] outputs = new double[1][];
    private double[] arrayVariables;
    private int barlookback = 300;
    private IIndicator sma;


    public void onStart(IIndicatorContext context)
    {
        IIndicatorsProvider indicatorsProvider = context.getIndicatorsProvider();
        sma = indicatorsProvider.getIndicator("SMA");
        indicatorInfo = new IndicatorInfo("ALF", "Adaptive Laguerre Filter", "Overlay Studies", true, false, false, 1, 2, 1);
        // might need to set price type here on InputParameterInfo.Type
        inputParameterInfos = new InputParameterInfo("Input Data", InputParameterInfo.Type.DOUBLE);
        inputParameterInfos.setAppliedPrice(IIndicators.AppliedPrice.MEDIAN_PRICE);
        optInputParameterInfos = new OptInputParameterInfo[]
        {
            new OptInputParameterInfo("Lookback", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(20, 0, 100, 1)),
            new OptInputParameterInfo("Median", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(5, 0, 50, 1))
            // new OptInputParameterInfo("Applied Price", OptInputParameterInfo.Type.OTHER, new DoubleListDescription() )
        };
        outputParameterInfos = new OutputParameterInfo[]{new OutputParameterInfo("Values", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE)};
        // inputParameterInfos.setAppliedPrice(IIndicators.AppliedPrice.MEDIAN);
    }

    public IndicatorResult calculate(int startIndex, int endIndex)
    {
        double[] smaOutput;

        //calculating startIndex taking into account Lookback value - can ignore sma as it has lookback of 1
        if (startIndex - getLookback() < 0)
        {
            startIndex -= startIndex - getLookback();
        }
        if (startIndex > endIndex)
        {
            return new IndicatorResult(0, 0);
        }
        else
        {
            smaOutput = new double[endIndex - startIndex + Lookback + 1];   
        }   
        sma.setInputParameter(0, inputs[0]);
        sma.setOutputParameter(0, smaOutput);
       
        double alpha = 0.0;
        double Price = 0.0;
        double HH = 0.0;
        double LL = 0.0;
       
        double[] Filter = new double[endIndex - startIndex + Lookback + 1];
        double[] Diff = new double[endIndex - startIndex + Lookback + 1];
        double[] L0= new double[endIndex - startIndex + Lookback + 1];
        double[] L1= new double[endIndex - startIndex + Lookback + 1];
        double[] L2= new double[endIndex - startIndex + Lookback + 1];
        double[] L3= new double[endIndex - startIndex + Lookback + 1];
       
        double[] SortDiff= new double[endIndex - startIndex + Lookback + 1];
           
  /*
 
        double Price, HH,LL;
      double alpha;
      
      double Filter[];
      double Diff[];
      double L0[];
      double L1[];
      double L2[];
      double L3[];

        double sortDiff[];
       
       for (i=limit;i>=0;i--)
      {
         Price = iMA(NULL,0,1,0,MODE_SMA,PriceType,i);
   
         Diff[i] = MathAbs(Price - Filter[i+1]);
   
         HH = Diff[i];
         LL = Diff[i];
   
         for (j=0;j<LookBack;j++)
         {
            if (Diff[i+j] > HH)
            {HH = Diff[i+j];}
            
            if (Diff[i+j] < LL)
            {LL = Diff[i+j];}
         }
   
         if (!CompareDoubles(HH-LL,0))
         {
            for (int j=0;j<Median;j++)
            {
               sortDiff[j] = (Diff[i+j] - LL) / (HH - LL);
            }
            ArraySort(sortDiff,WHOLE_ARRAY,0,MODE_ASCEND);
            if (MathMod(Median,2.0) != 0)
            {
               alpha = sortDiff[Median/2];         
            }
            else
            {
               alpha = (sortDiff[Median/2]+sortDiff[(Median/2)-1])/2;
            }   
         }
         L0[i] = alpha*Price + (1 - alpha)*L0[i+1];
         L1[i] = -(1 - alpha)*L0[i] + L0[i+1] + (1 - alpha)*L1[i+1];
         L2[i] = -(1 - alpha)*L1[i] + L1[i+1] + (1 - alpha)*L2[i+1];
         L3[i] = -(1 - alpha)*L2[i] + L2[i+1] + (1 - alpha)*L3[i+1];
         Filter[i] = (L0[i] + 2.0 * L1[i] + 2.0 * L2[i] + L3[i]) / 6.0;
        
      }
 
  */ 
          IndicatorResult SmaResult = sma.calculate(startIndex+1, endIndex);
          int i, j, z;
          for (i = endIndex, j = endIndex; i > startIndex+1; i--, j--)
          {
            Price = smaOutput[j]; // assigns sma(1) of instrument price  to Price?
            Diff[j] = Math.abs(Price - arrayVariables[j+1]);
            HH = Diff[j];
            LL = Diff[j];
           
            for (z=0; z < Lookback; z++)
            {
               if (Diff[j+z] > HH)  {HH = Diff[j+z];}
               if (Diff[j+z] < LL)  {LL = Diff[j+z];}
            }
           
            if (Math.abs(HH - LL) > 0.00000001)
           {
              for (z=0; z < Median; z++)
             {
                SortDiff[z] = (Diff[j+z] - LL) / (HH - LL);
             }
               
             Arrays.sort(SortDiff);
               
             if ( (Median%2) != 0)
             {
                 alpha = SortDiff[ (int) Math.floor(Median/2)];         
             }
             else
             {
                alpha = (SortDiff[ (int) Math.floor(Median/2)] + SortDiff[ (int) Math.floor((Median/2)-1)])/2;
             }   
           }
           
            L0[j] = alpha*Price + (1 - alpha)*L0[j+1];
            L1[j] = -(1 - alpha)*L0[j] + L0[j+1] + (1 - alpha)*L1[j+1];
            L2[j] = -(1 - alpha)*L1[j] + L1[j+1] + (1 - alpha)*L2[j+1];
            L3[j] = -(1 - alpha)*L2[j] + L2[j+1] + (1 - alpha)*L3[j+1];
            Filter[j] = (L0[j] + 2.0 * L1[j] + 2.0 * L2[j] + L3[j]) / 6.0;
           
            arrayVariables[j] = Filter[j];
            outputs[0][j] = arrayVariables[j];
        }
        return new IndicatorResult(startIndex, j);
    }

    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }

    public InputParameterInfo getInputParameterInfo(int index) {
        return inputParameterInfos;
    }

    public int getLookback() {
        return barlookback;
    }

    public OptInputParameterInfo getOptInputParameterInfo(int index) {
        if (index <= optInputParameterInfos.length) {
            return optInputParameterInfos[index];
        }
        return null;
    }

    public OutputParameterInfo getOutputParameterInfo(int index) {
        if (index <= outputParameterInfos.length) {
            return outputParameterInfos[index];
        }
        return null;
    }

    public void setInputParameter(int index, Object array) {
        inputs[index] = (double[]) array;
        int length = inputs[index].length;
        arrayVariables = new double[length];
    }

    public void setOptInputParameter(int index, Object value) {
        if (index == 0) Lookback = (Integer) value;
        if (index == 1) Median = (Integer) value;
    }

    public void setOutputParameter(int index, Object array) {
        outputs[index] = (double[]) array;
    }

    public int getLookforward() {
        return 0;
    }
}


 
 Post subject: Re: Elhers Adaptive Laguerre Filter - debug help Post rating: 0   New post Posted: Tue 22 Mar, 2011, 07:13 

User rating: 0
Joined: Thu 19 Aug, 2010, 13:53
Posts: 62
Where do I find an exact description/functionality of the Ehler's adaptive Laguerre filter ?


 
 Post subject: Re: Elhers Adaptive Laguerre Filter - debug help Post rating: 0   New post Posted: Tue 22 Mar, 2011, 10:42 

User rating: 0
Joined: Wed 09 Mar, 2011, 10:40
Posts: 8
The ALF is described in the technical paper "time warp without space travel" which can be found here
https://www.mesasoftware.com/technicalpapers.htm.

ALF is a very effective overbought oversold indicator that overlays the chart like a moving average.

Commented out section in the java code above is the MT4 code.

regards
f451


 
 Post subject: Re: Elhers Adaptive Laguerre Filter - debug help Post rating: 0   New post Posted: Mon 04 Apr, 2011, 16:46 
User avatar

User rating: 2
Joined: Tue 17 May, 2011, 16:35
Posts: 10
Location: ItalyItaly
forex451 wrote:
ALF is a very effective overbought oversold indicator that overlays the chart like a moving average.


Hey f451, I totally agree with you.. very good indie.

Here it is the gift..

best,
chriz

package jforex;

import com.dukascopy.api.indicators.*;
import com.dukascopy.api.IIndicators;
import java.util.Arrays;
import java.awt.*;

/**
* original @author Simon Kaufmann
* review by chriz [Indiana Pips]
* Date: Apr 04, 2011
* Time: undef
* email: puntasabbioni/AT/gmail.com
*/

public class ALF implements IIndicator {
    private IndicatorInfo indicatorInfo;
   
    private InputParameterInfo[] inputParameterInfos;
    private OutputParameterInfo[] outputParameterInfos;
    private OptInputParameterInfo[] optInputParameterInfos;

    private int LookBack = 20;
    private int Median = 5;
   
   private double[][] inputs = new double[1][];
   private double[][] outputs = new double[1][];
   
    private IIndicatorContext context;
   
    public void onStart(IIndicatorContext context) {
        this.context = context ;

      indicatorInfo = new IndicatorInfo("ALF", "Adaptive Laguerre Filter", "Overlay Studies", true, false, false, 1, 2, 1);
      indicatorInfo.setRecalculateAll(true);
       
        inputParameterInfos =  new InputParameterInfo[] {
            new InputParameterInfo("Input Data", InputParameterInfo.Type.DOUBLE)
             {{
                 setAppliedPrice(IIndicators.AppliedPrice.MEDIAN_PRICE);
             }}
         };

        outputParameterInfos = new OutputParameterInfo[]{
            new OutputParameterInfo("Values", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE)
            {{               
                setColor(Color.BLUE);
            }}
        };
       
      optInputParameterInfos = new OptInputParameterInfo[]
      {
         new OptInputParameterInfo("Lookback", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(20, 0, 100, 1)),
         new OptInputParameterInfo("Median", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(5, 0, 50, 1))
      };
                 
    }

     
    public IndicatorResult calculate(int startIndex, int endIndex) {
        //calculating startIndex taking into account lookback value
        if (startIndex - getLookback() < 0) {
            startIndex -= startIndex - getLookback();
        }       
           
        double[] tempbufferDiff = new double[endIndex - startIndex + 1 ] ;   
        double[] Filter = new double[endIndex - startIndex + 1];       
      double[] L0 = new double[endIndex - startIndex + 1];
      double[] L1 = new double[endIndex - startIndex + 1];
      double[] L2 = new double[endIndex - startIndex + 1];
      double[] L3 = new double[endIndex - startIndex + 1];
        double[] SortDiff = new double[Median] ;                         
       
        int i, j, k;
           
        for (i = startIndex , j = 0; i <= endIndex; i++, j++) {
       
           double HH = 0.0;
           double LL = 0.0;
           double alpha = 0.0 ;
            double Price = inputs[0][i] ;
       
            if(j == 0 && startIndex != endIndex)
            {           
                tempbufferDiff[j] = 0;
            }else{
                tempbufferDiff[j] = Math.abs(Price - Filter[j-1] );
            }
               
            if(j>0)
            {     
                k = 0 ;
                while( j-k>0 )               
                {             
                    if(k<LookBack){                                                                                                                                                                                                                     
                      if (tempbufferDiff[j-k-1] > HH) {HH = tempbufferDiff[j-k-1];}
                      if (tempbufferDiff[j-k-1] < LL) {LL = tempbufferDiff[j-k-1];}
                    }
                    k++;
                }
            }
           

            if (Math.abs(HH - LL) != 0 && j>=Median)
            {
                for (int q=0; q < Median; q++)
                {
                    SortDiff[q] = (tempbufferDiff[j-q] - LL) / (HH - LL);
                }                   
                           
                Arrays.sort(SortDiff);
               
                if ( (Median%2) != 0)
                {
                    alpha = SortDiff[ (int) Math.floor(Median/2)];
                }
                else
                {
                    alpha = (SortDiff[ (int) Math.floor(Median/2)] + SortDiff[ (int) Math.floor((Median/2)-1)])/2;
                }                               
            }   
                       
                                   
            if(j==0 && startIndex != endIndex)
            {
                L0[j] = Price ;
                L1[j] = Price ;
                L2[j] = Price ;
                L3[j] = Price ;
                Filter[j] = (L0[j] + 2.0 * L1[j] + 2.0 * L2[j] + L3[j]) / 6.0;                                       
            }
            else{
                L0[j] = alpha*Price + (1 - alpha)*L0[j-1];
                L1[j] = -(1 - alpha)*L0[j] + L0[j-1] + (1 - alpha)*L1[j-1];
                L2[j] = -(1 - alpha)*L1[j] + L1[j-1] + (1 - alpha)*L2[j-1];
                L3[j] = -(1 - alpha)*L2[j] + L2[j-1] + (1 - alpha)*L3[j-1];
                Filter[j] = (L0[j] + 2.0 * L1[j] + 2.0 * L2[j] + L3[j]) / 6.0;                   
            }

            outputs[0][j] = Filter[j] ;     
        }                   

        return new IndicatorResult(startIndex, j);
    }

    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }

    public InputParameterInfo getInputParameterInfo(int index) {
        if (index <= inputParameterInfos.length) {
            return inputParameterInfos[index];
        }
        return null;
    }
   

    public int getLookback() {
        return LookBack;
    }

    public int getLookforward() {
        return 0;
    }

    public OptInputParameterInfo getOptInputParameterInfo(int index) {
        if (index <= optInputParameterInfos.length) {
            return optInputParameterInfos[index];
        }
        return null;
    }

    public OutputParameterInfo getOutputParameterInfo(int index) {
        if (index <= outputParameterInfos.length) {
            return outputParameterInfos[index];
        }
        return null;
    }

    public void setInputParameter(int index, Object array) {
        inputs[index] = (double[]) array;
    }

   public void setOptInputParameter(int index, Object value) {
       if (index == 0) LookBack = (Integer) value;
       if (index == 1) Median = (Integer) value;
   }
   
    public void setOutputParameter(int index, Object array) {
        outputs[index] = (double[]) array;
    }
   
    private void print(String sss)
    {
        context.getConsole().getOut().println(sss) ;
    }       
           
}


 
 Post subject: Re: Elhers Adaptive Laguerre Filter - debug help Post rating: 0   New post Posted: Tue 05 Apr, 2011, 12:12 

User rating: 0
Joined: Wed 09 Mar, 2011, 10:40
Posts: 8
Thank you Chriz! Terrific work! I've checked it out again the MT4 version and it seems to be exactly same results.


 
 Post subject: Another digital filter - ALMA Arnaud-Legoux-Moving-Average Post rating: 0   New post Posted: Wed 06 Apr, 2011, 23:31 
User avatar

User rating: 2
Joined: Tue 17 May, 2011, 16:35
Posts: 10
Location: ItalyItaly
Hi,
another interesting digital filter applied on MA .
ALMA https://www.arnaudlegoux.com/wp-content/ ... verage.pdf
based on Gaussian filters.

Here's the code.

https://www.forexfactory.com/showpost.ph ... stcount=13

best,
chriz


 

Jump to:  

cron
  © 1998-2025 Dukascopy® Bank SA
On-line Currency forex trading with Swiss Forex Broker - ECN Forex Brokerage,
Managed Forex Accounts, introducing forex brokers, Currency Forex Data Feed and News
Currency Forex Trading Platform provided on-line by Dukascopy.com