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.

Wrong expected count of values in indicator
 Post subject: Wrong expected count of values in indicator Post rating: 0   New post Posted: Thu 13 Jan, 2011, 13:57 

User rating: -
Hello

I found one bug in JForex.
I have created my custom indicator for correlation calculation.
My indicator calculates correlation of any currency pair against EURUSD currency pair.
You can put this indicator into any chart (for example GBPUSD) and it will calculate the correlation value of this chart against EURUSD

I have implemented my custom algorithms for synchronization of data sources (first currency pair is first data source and EURUSD currency pair is second data source).

The bug I found:
You can see the bug when you will put the indicator into any chart (for example GBPUSD) and then right-click on the indicator linechart and EDIT. In the EDIT window when you will change the PERIOD optInputParametr it will throw exception into MESSAGES tabbedPane.
When you will change the PERIOD value to higher value, it will throw different exception like if you will hange the PERIOD value to lower value.

Please take a look at that.
I was looking at that and the exception is saying that indicator returned less values than expected. Then I tried to add one value more (Double.NaN) and that throws another exception saying that there is too much values... Thats weird right?

I attach the source code of the indicator:

package jforex;

import com.dukascopy.api.IBar;
import com.dukascopy.api.Instrument;
import com.dukascopy.api.indicators.*;
import java.util.ArrayList;
import java.util.List;

public class LS_I_DirectionalCorrelation_vs_EURUSD implements IIndicator {


    private IIndicatorContext context;

    private static final String name = "LS_I_DirectionalCorrelation_vs_EURUSD";
    private static final String group = "LorencSoftware.indicators";

    private int period;

    private double[] outputs;
    private IBar[][] inputs;

    private IndicatorInfo indicatorInfo;
    private InputParameterInfo[] inputParameterInfos;
    private OptInputParameterInfo optInputParameterInfo;
    private OutputParameterInfo outputParameterInfo;

    // synchronized data
    private int synchronizedData_newStartIndex = 0;
    private int synchronizedData_newEndIndex = 0;
    private final List<IBar> synchronizedData_defaultChart = new ArrayList<IBar>();
    private final List<IBar> synchronizedData_eurusdChart = new ArrayList<IBar>();
    // synchronized data



    public void onStart(IIndicatorContext context) {
        this.context = context;
        outputs = null;
        inputs = new IBar[2][];

        indicatorInfo = new IndicatorInfo(name, name, group, false, false, false, 2, 1, 1);


        InputParameterInfo inputParamInfo_defaultChart = new InputParameterInfo("Default chart", InputParameterInfo.Type.BAR);
        InputParameterInfo inputParamInfo_eurusd = new InputParameterInfo("EURUSD chart", InputParameterInfo.Type.BAR);
        inputParamInfo_eurusd.setInstrument(Instrument.EURUSD);
        inputParamInfo_eurusd.setPeriod(inputParamInfo_defaultChart.getPeriod());

        inputParameterInfos = new InputParameterInfo[2];
        inputParameterInfos[0] = inputParamInfo_defaultChart;
        inputParameterInfos[1] = inputParamInfo_eurusd;


        optInputParameterInfo = new OptInputParameterInfo("Period",
                OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(14, 1, 100, 1));


        outputParameterInfo = new OutputParameterInfo("Correlation vs EURUSD",
                OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE);
    }








    public IndicatorResult calculate(int startIndex, int endIndex) {
        if (startIndex - getLookback() < 0) {
            startIndex -= startIndex - getLookback();
        }
        if (startIndex>endIndex) {
            return new IndicatorResult(startIndex, 0);
        }
        synchronizedData_createCustomSynchronizedCharts(startIndex, endIndex);
        int i = 0;
        int j = 0;


        if (synchronizedData_defaultChart.isEmpty()) { // if there are no synchronized bars
            for (i = startIndex; i <= endIndex; i++) {
                outputs[j] = Double.NaN;
                j++;
            }
            return new IndicatorResult(startIndex, j);
        }


        for (i = startIndex; i < synchronizedData_newStartIndex; i++) { // Set NaN for all left-side nonsynchronized bars
           outputs[j] = Double.NaN;
           j++;
        }
        int x = getLookback();
        for (i = synchronizedData_newStartIndex; i<=synchronizedData_newEndIndex; i++) {
            double[] defaultChartValues = new double[period];
            double[] eurusdChartValues = new double[period];
            for (int ii = 0; ii<period; ii++) {
                defaultChartValues[ii] = synchronizedData_defaultChart.get(x-ii).getClose();
                eurusdChartValues[ii] = synchronizedData_eurusdChart.get(x-ii).getClose();
            }
            outputs[j] = correl(defaultChartValues, eurusdChartValues);
            j++;
            x++;
        }
        for (i=(synchronizedData_newEndIndex+1); i<=endIndex; i++) { // Set NaN for all right-side nonsynchronized bars
            outputs[j] = Double.NaN;
            j++;
        }
        context.getConsole().getOut().println("startIndex="+startIndex+"   endIndex="+endIndex+"   synchronizedData_newStartIndex="+synchronizedData_newStartIndex+"   synchronizedData_newEndIndex="+synchronizedData_newEndIndex+"   j="+j+"   outputs.length="+outputs.length);
        return new IndicatorResult(startIndex, j);
    }








    // SET METHODS
    public void setInputParameter(int index, Object array) {
        if (index < inputs.length) {
            inputs[index] = (IBar[]) array;
        }
    }

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

    public void setOptInputParameter(int index, Object value) {
        Integer i_value = (Integer) value;
        this.period = i_value;
    }








    // GET METHODS
    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }

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

    public OptInputParameterInfo getOptInputParameterInfo(int index) {
        return optInputParameterInfo;
    }

    public OutputParameterInfo getOutputParameterInfo(int index) {
        return outputParameterInfo;
    }







    // LOOKBACK AND LOOKFORWARD
    public int getLookback() {
        return period-1;
    }

    public int getLookforward() {
        return 0;
    }







    //CUSTOM METHODS
    private void synchronizedData_createCustomSynchronizedCharts(int startIndex, int endIndex) {
        synchronizedData_defaultChart.clear();
        synchronizedData_eurusdChart.clear();
        synchronizedData_newStartIndex = 0;
        synchronizedData_newEndIndex = 0;

        for (int i = (startIndex-getLookback()); i<=endIndex; i++) {
            IBar mainBar = inputs[0][i];
            IBar equivalentBar = synchronizedData_findIBarEquivalent(mainBar, inputs[1]);
            if (equivalentBar!=null) {
                if (synchronizedData_defaultChart.isEmpty()) { // if this is first synchronized bar
                    synchronizedData_newStartIndex = i;
                }
                synchronizedData_defaultChart.add(mainBar);
                synchronizedData_eurusdChart.add(equivalentBar);
                synchronizedData_newEndIndex = i;
            } else {
                if (synchronizedData_defaultChart.isEmpty()) {
                    continue;
                } else {
                    break;
                }
            }
        }


        if (synchronizedData_defaultChart.isEmpty()==false) {
            synchronizedData_newStartIndex += getLookback();
            if (synchronizedData_newStartIndex>synchronizedData_newEndIndex) { // if there is not enought of synchronized bars
                synchronizedData_defaultChart.clear();
                synchronizedData_eurusdChart.clear();
                synchronizedData_newStartIndex = 0;
                synchronizedData_newEndIndex = 0;
            }
        }
    }

    private IBar synchronizedData_findIBarEquivalent(IBar templateBar, IBar[] whereToFind) {
        for (IBar b : whereToFind) {
            if (b.getTime()==templateBar.getTime()) {
                return b;
            }
        }
        return null;
    }



    private double correl(double[] xArray, double[] yArray) {

        double x = average(xArray);
        double y = average(yArray);


        double up = 0;
        for (int i = 0; i<xArray.length; i++) {
            up += ( (x-xArray[i]) * (y-yArray[i]) );
        }


        double firstSumOfDown = 0;
        double secondSumOfDown = 0;
        for (int i=0; i<xArray.length; i++) {
            firstSumOfDown += twice((x-xArray[i]));
        }
        for (int i=0; i<yArray.length; i++) {
            secondSumOfDown += twice((y-yArray[i]));
        }
        double down = firstSumOfDown*secondSumOfDown;
        down = Math.sqrt(down);


        return (up/down);
    }

    private double twice(double d) {
        return d*d;
    }

    private double average(double[] pointsArray) {
        double result = 0;
        for (int i=0; i<pointsArray.length; i++)  {
            result += pointsArray[i];
        }
        return result / pointsArray.length;
    }

}


 
 Post subject: Re: JFOREX-2639 wrong expected count of values in indicator Post rating: 0   New post Posted: Tue 18 Jan, 2011, 11:41 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
Hi,
This is not a bug, please make sure you are specifying the correct startIndex and numberOfElements in your IndicatorResult.


 

Jump to:  

cron
  © 1998-2024 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