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.

EMAs not same value when called from strategy than on screen
 Post subject: EMAs not same value when called from strategy than on screen Post rating: 0   New post Posted: Mon 03 Oct, 2011, 10:58 

User rating: -
Hi support team,

I have written a sample indicator and strategy to demonstrate the issue I am experiencing.

Below is the code of a custom indicator that just calls EMA(34) to populate the 1st output array and calls EMA(34,MaType.EMA) to populate the 2nd output array.

package Indicators;

import com.dukascopy.api.IIndicators;
import com.dukascopy.api.IIndicators.MaType;
import com.dukascopy.api.indicators.*;

import java.awt.Color;
import java.lang.Math;

public class EMATest implements IIndicator {
    private IndicatorInfo indicatorInfo;
    private InputParameterInfo[] inputParameterInfos;
    private OptInputParameterInfo[] optInputParameterInfos;
    private OutputParameterInfo[] outputParameterInfos;
    private double[][] inputs = new double[1][];
    private int emaPeriod;
    private double[][] outputs = new double[2][];
    private IIndicator emaIndi, maIndi;
   
    private IIndicatorContext indiContext;
   
    public void onStart(IIndicatorContext context)
    {
       this.indiContext = context;
       
        indicatorInfo = new IndicatorInfo("EMATest", "Test", "Test", false, false, false, 1, 1, 2);
        inputParameterInfos = new InputParameterInfo[]
        {
           new InputParameterInfo("Input data", InputParameterInfo.Type.DOUBLE) { { setAppliedPrice(IIndicators.AppliedPrice.CLOSE); } }
        };
        optInputParameterInfos = new OptInputParameterInfo[]
        {
           new OptInputParameterInfo("EMA Period", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(34, 1, 100, 1))
        };
        outputParameterInfos = new OutputParameterInfo[]
        {
           new OutputParameterInfo("EMATest EMA", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),
            new OutputParameterInfo("EMATest MA(EMA)", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE)
        };
       
        IIndicatorsProvider indProvider = context.getIndicatorsProvider();
        emaIndi = indProvider.getIndicator("EMA");
        maIndi =  indProvider.getIndicator("MA");
        maIndi.setOptInputParameter(1, MaType.EMA.ordinal());
       
        outputParameterInfos[0].setColor(java.awt.Color.RED);
        outputParameterInfos[1].setColor(java.awt.Color.BLUE);
    }

    public IndicatorResult calculate(int startIndex, int endIndex)
    {
        //calculating startIndex taking into account lookback value
        if (startIndex - getLookback() < 0) {
            startIndex -= startIndex - getLookback();
        }

        //calculate EMA
        emaIndi.setInputParameter(0, inputs[0]);
        emaIndi.setOutputParameter(0, outputs[0]);
        IndicatorResult emaResult = emaIndi.calculate(emaIndi.getLookback(), endIndex);
        if (emaResult.getNumberOfElements() == 0)
        {
            //EMA returned 0 values
            return new IndicatorResult(0, 0);
        }

        //calculate MA
        maIndi.setInputParameter(0, inputs[0]);
        maIndi.setOutputParameter(0, outputs[1]);
        IndicatorResult maResult = maIndi.calculate(maIndi.getLookback(), endIndex);
        if (emaResult.getNumberOfElements() == 0)
        {
            //EMA returned 0 values
            return new IndicatorResult(0, 0);
        }
       
        return maResult;
    }

    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }

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

    public int getLookback() {
        return emaIndi.getLookback(); // assume emaIndi and maIndi have the same getLooback() as they are EMA's of the same period
    }

    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)
    {
       switch (index)
       {
       case 0:
          emaPeriod = (Integer) value;
          emaIndi.setOptInputParameter(0, emaPeriod);
          maIndi.setOptInputParameter(0, emaPeriod);
          break;
       }
    }

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


When this indicator is dropped on a chart along with an EMA(34) and MA(34,MaType.EMA) the values of my indicator's outputs and the other 2 indicators is exactly the same.

I have also written a strategy that calls this custom indicator as well as the EMA(34) and MA(34,MaType.EMA) and simply outputs the values on every OnBar event to the console with a timestamp - refer to code below.

package jforex;

import java.io.File;
import java.util.*;

import com.dukascopy.api.*;
import com.dukascopy.api.IIndicators.MaType;

public class EMATestStrategy implements IStrategy {
   private IEngine engine;
   private IConsole console;
   private IHistory history;
   private IContext context;
   private IIndicators indicators;
   private IUserInterface userInterface;
   
    @Configurable("Instrument") public Instrument instrument = Instrument.EURUSD;   
    @Configurable("Period") public Period period = Period.ONE_HOUR;//FOUR_HOURS;// DAILY_SUNDAY_IN_MONDAY ;//DAILY;ONE_HOUR;//
    @Configurable("EMA Length") public int emaLength = 34;

   public void onStart(IContext context) throws JFException
   {
      this.engine = context.getEngine();
      this.console = context.getConsole();
      this.history = context.getHistory();
      this.context = context;
      this.indicators = context.getIndicators();
      this.userInterface = context.getUserInterface();
      
        this.indicators.registerCustomIndicator(new File(context.getFilesDir() + System.getProperty("file.separator") + "EMATest.jfx"));

   }

   public void onAccount(IAccount account) throws JFException {
   }

   public void onMessage(IMessage message) throws JFException {
   }

   public void onStop() throws JFException {
   }

   public void onTick(Instrument instrument, ITick tick) throws JFException {
   }
   
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException
    {
        // return on events we are not interested in
        if (instrument != this.instrument) return;

        // skip all other periods
        if (period != this.period)    return;       

        Object[] EMATestResult =  indicators.calculateIndicator(this.instrument,
                                                 this.period,
                                                 new OfferSide[] {OfferSide.BID},
                                                 "EMATest",
                                                 new IIndicators.AppliedPrice[]{IIndicators.AppliedPrice.CLOSE},
                                                 new Object[]{emaLength},
                                                 Filter.WEEKENDS,
                                                 1,
                                                 bidBar.getTime(),
                                                 0);

        Object[] EMAResult =  indicators.calculateIndicator(this.instrument,
                                                            this.period,
                                                            new OfferSide[] {OfferSide.BID},
                                                            "EMA",
                                                            new IIndicators.AppliedPrice[]{IIndicators.AppliedPrice.CLOSE},
                                                            new Object[]{emaLength},
                                                            Filter.WEEKENDS,
                                                            1,
                                                            bidBar.getTime(),
                                                            0);

        Object[] MAResult =  indicators.calculateIndicator(this.instrument,
                                                            this.period,
                                                            new OfferSide[] {OfferSide.BID},
                                                            "MA",
                                                            new IIndicators.AppliedPrice[]{IIndicators.AppliedPrice.CLOSE},
                                                            new Object[]{emaLength, MaType.EMA.ordinal()},
                                                            Filter.WEEKENDS,
                                                            1,
                                                            bidBar.getTime(),
                                                            0);

        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        cal.setTimeInMillis(bidBar.getTime());
       
        console.getOut().println(cal.get(Calendar.DAY_OF_MONTH) + "." + (cal.get(Calendar.MONTH)+1) + "." + cal.get(Calendar.YEAR) + " " + cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) +
                               " - EMA(" + emaLength + ") = " + ((double[])EMAResult[0])[0] +
                               ", MA(" + emaLength + ", MaType.EMA) = " + ((double[])MAResult[0])[0] +
                               ", EMATest(" + emaLength + ") = " + ((double[])EMATestResult[0])[0] +
                               ", EMATest(" + emaLength + ", MaType.EMA) = " + ((double[])EMATestResult[1])[0]);

    }
}


The console output of this strategy clearly illustrates that calling the EMA(34) and MA(34,MaType.EMA) straight from the strategy provides the same values as the indicators on the chart, but the 2 output arrays from the custom indicator are the same as each other, but different than the direct indicator calls.

Can you please explain the results and help me to get around this please?


thanks in advance,
Christian


 
 Post subject: Re: EMAs not same value when called from strategy than on sc Post rating: 0   New post Posted: Tue 04 Oct, 2011, 10:53 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
Please use unstable period property, i.e.:
 indicatorInfo = new IndicatorInfo("EMATest", "Test", "Test", false, false, true, 1, 1, 2);


 

Jump to:  

  © 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