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.

problem with an array on indicator
 Post subject: problem with an array on indicator Post rating: 0   New post Posted: Sun 07 Jul, 2013, 20:35 

User rating: 1
Joined: Wed 07 Mar, 2012, 05:56
Posts: 101
Location: New CaledoniaNew Caledonia
hello support,

i try to create an indicator following this article :
https://www.dukascopy.com/wiki/#Indicato ... _indicator

i would like to integrate a tenkanSen line over a Rsi indicator.
i call this indicator for the tenkanSen

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jforex.indicators;

import com.dukascopy.api.indicators.IIndicator;
import com.dukascopy.api.indicators.IIndicatorContext;
import com.dukascopy.api.indicators.IndicatorInfo;
import com.dukascopy.api.indicators.IndicatorResult;
import com.dukascopy.api.indicators.InputParameterInfo;
import com.dukascopy.api.indicators.IntegerRangeDescription;
import com.dukascopy.api.indicators.OptInputParameterInfo;
import com.dukascopy.api.indicators.OutputParameterInfo;
import java.awt.Color;

/**
 *
 * @author eric
 */
public class Tenkanind implements IIndicator {
   
    private IndicatorInfo indicatorInfo;
    private InputParameterInfo[] inputParameterInfos;
    private OptInputParameterInfo[] optInputParameterInfos;
    private OutputParameterInfo[] outputParameterInfos;
    private double[][][] inputs = new double[1][][];
    private double[][] outputs = new double[1][];
   
    private IIndicator tenkanMax;
    private IIndicator tenkanMin;
   
    private int tenkanPeriod = 9;

   
    public void onStart(IIndicatorContext context) {
        tenkanMax = context.getIndicatorsProvider().getIndicator("MAX");
        tenkanMin = context.getIndicatorsProvider().getIndicator("MIN");
       
        indicatorInfo = new IndicatorInfo("TENKAN", "TenkanSen", "My indicators", true, false, false, 1, 1, 1);
       
        inputParameterInfos = new InputParameterInfo[] {
                new InputParameterInfo("Prices", InputParameterInfo.Type.PRICE)
                };
        optInputParameterInfos = new OptInputParameterInfo[] {
                new OptInputParameterInfo("Tenkan period",
                                          OptInputParameterInfo.Type.OTHER,
                                          new IntegerRangeDescription(tenkanPeriod, 2, 100, 1)),
                };
        outputParameterInfos = new OutputParameterInfo[] {
                new OutputParameterInfo("TENKAN",
                                        OutputParameterInfo.Type.DOUBLE,
                                        OutputParameterInfo.DrawingStyle.LINE) {
                    {
                        this.setColor(Color.BLUE);
                    }
                }
                };
    }
    public IndicatorResult calculate(int startIndex, int endIndex) {
       
        if (startIndex - getLookback() < 0) {
            startIndex -= startIndex - getLookback();
        }
       
        if (startIndex > endIndex) {
            return new IndicatorResult(0, 0);
        }
        double[] tenkanMaxD = new double[endIndex - startIndex + 2 + getLookback()];
        double[] tenkanMinD = new double[endIndex - startIndex + 2 + getLookback()];
       
        tenkanMax.setInputParameter(0, inputs[0][2]);
        tenkanMin.setInputParameter(0, inputs[0][3]);
        tenkanMax.setOptInputParameter(0, tenkanPeriod);
        tenkanMin.setOptInputParameter(0, tenkanPeriod);
        tenkanMax.setOutputParameter(0, tenkanMaxD);
        tenkanMin.setOutputParameter(0, tenkanMinD);
       
        IndicatorResult dtenkanMaxResult = tenkanMax.calculate(startIndex - 1, endIndex);
        IndicatorResult dtenkanMinResult = tenkanMin.calculate(startIndex - 1, endIndex);
       
        int i, k;
        for (i = 1, k = dtenkanMaxResult.getNumberOfElements(); i < k; i++) {
            outputs[0][i - 1] = (tenkanMaxD[i] + tenkanMinD[i]) / 2;
        }   
        return new IndicatorResult(startIndex, i - 1);
    }
   
   

    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }

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

    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:
                tenkanPeriod = (Integer) value;
                break;
           default:
                throw new ArrayIndexOutOfBoundsException(index);
        }
    }

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

    public int getLookback() {
       return tenkanPeriod;
    }

    public int getLookforward() {
        return 0;
    }
   
}


this is the indicator tenkanOverRsi
package jforex.indicators;

import com.dukascopy.api.IConsole;
import com.dukascopy.api.indicators.DoubleRangeDescription;
import com.dukascopy.api.indicators.IIndicator;
import com.dukascopy.api.indicators.IIndicatorContext;
import com.dukascopy.api.indicators.IndicatorInfo;
import com.dukascopy.api.indicators.IndicatorResult;
import com.dukascopy.api.indicators.InputParameterInfo;
import com.dukascopy.api.indicators.IntegerListDescription;
import com.dukascopy.api.indicators.IntegerRangeDescription;
import com.dukascopy.api.indicators.OptInputParameterInfo;
import com.dukascopy.api.indicators.OutputParameterInfo;
import java.awt.Color;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

public class TenkanOverRsi implements IIndicator {
    public static final int OPEN = 0;
    public static final int CLOSE = 1;
    public static final int LOW= 2;
    public static final int HIGH = 3;
    public static final int AVE = 4;
   
    private IndicatorInfo           indicatorInfo;

    // INPUTS
    private InputParameterInfo[]    inputParameterInfos;
    private double[][] inputs = new double[1][];
   
    // OPT INPUTS
    private OptInputParameterInfo[] optInputParameterInfos;

    private int                     rsiPeriod;
    private int                     tenkanPeriod;

   
    // OUTPUTS
    private OutputParameterInfo[]   outputParameterInfos;
    private double[][] outputs = new double[2][];

    // CONTEXT
    private IConsole                console;

    private IIndicator              rsi;
    private IIndicator              tenkan;
   
    public int getLookback() {
        return rsi.getLookback()+tenkan.getLookback();
    }

    public int getLookforward() {
        return 0;
    }

    /**************
     * CALCULATE
     **************/
    public IndicatorResult calculate(int startIndex, int endIndex) {
           
        int rsiLookback = rsi.getLookback();
        double[] rsiOutput;
        if (startIndex - getLookback() < 0) {
            startIndex -= startIndex - getLookback();
        }
        if (startIndex > endIndex || rsi.getLookback()>endIndex) {
            return new IndicatorResult(0, 0);
        }else{
            rsiOutput = new double[endIndex - (rsiLookback > startIndex ? rsiLookback : startIndex) + 1];
        }
   
        // rsi
        rsi.setInputParameter(0, inputs);
        rsi.setOptInputParameter(0, rsiPeriod);
        rsi.setOutputParameter(0, rsiOutput);
       
        IndicatorResult rsiResult = rsi.calculate(startIndex, endIndex);
        if (rsiResult.getNumberOfElements() < tenkan.getLookback()) {
            //not enough data to calculate tenkan
            return new IndicatorResult(0, 0);
        }
       
        // tenkan
        tenkan.setInputParameter(0, rsiOutput);     
        tenkan.setOptInputParameter(0, tenkanPeriod);
        tenkan.setOutputParameter(0, outputs[0]);   
        IndicatorResult tenkanResult = tenkan.calculate(0, rsiResult.getNumberOfElements() - 1);
        if (tenkanResult.getNumberOfElements() == 0) {
            //tenkan returned 0 values
            return new IndicatorResult(0, 0);
        }
        System.arraycopy(rsiOutput, tenkanResult.getFirstValueIndex(), outputs[0], 0, tenkanResult.getNumberOfElements());
     
        IndicatorResult result = new IndicatorResult(rsiResult.getFirstValueIndex() + tenkanResult.getFirstValueIndex(), tenkanResult.getNumberOfElements());
        return result;
    }

    public void onStart(IIndicatorContext context) {
        this.console = context.getConsole();

        int[] priceValues = new int[]{0,1,2,3,4};
        String[] priceNames = new String[]{"Open","Close","High","Low","Volume"};
       
        inputParameterInfos = new InputParameterInfo[] {

                new InputParameterInfo("prices", InputParameterInfo.Type.PRICE)

        };

        optInputParameterInfos = new OptInputParameterInfo[] {
               
                new OptInputParameterInfo("Tenkan period",
                                          OptInputParameterInfo.Type.OTHER,
                                          new IntegerRangeDescription(9, 2, 100, 1)),
                new OptInputParameterInfo("Rsi period",
                                          OptInputParameterInfo.Type.OTHER,
                                          new IntegerRangeDescription(9, 2, 100, 1))
        };

        outputParameterInfos = new OutputParameterInfo[] {
                new OutputParameterInfo("TENKAN",
                                        OutputParameterInfo.Type.DOUBLE,
                                        OutputParameterInfo.DrawingStyle.LINE) {
                    {
                        this.setColor(Color.ORANGE);
                    }
                },
                new OutputParameterInfo("RSI",
                                        OutputParameterInfo.Type.DOUBLE,
                                        OutputParameterInfo.DrawingStyle.LINE) {
                    {
                        this.setColor(Color.BLACK);
                    }
                }
               };

 
       
        rsi = context.getIndicatorsProvider().getIndicator("RSI");
        tenkan = context.getIndicatorsProvider().getIndicator("TENKAN");
       
       
       
        indicatorInfo = new IndicatorInfo("TENKAN_RSI", "Tenkan over RSI", "My indicators", false, false, false, inputParameterInfos.length, optInputParameterInfos.length, outputParameterInfos.length);
    }

    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }

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

    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:
                rsiPeriod = (Integer) value;
                break;
            case 1:
                tenkanPeriod = (Integer) value;
                break;           
           
           
        }
    }

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

    // ________________________________
    // Support: Some helper methods for printing

    private void print(Object... o) {
        for (Object ob : o) {
            console.getOut().print(ob + "  ");
        }
        console.getOut().println();
    }

    private void print(Object o) {
        console.getOut().println(o);
    }

    private void print(double[] arr) {
        print(arrayToString(arr));
    }

    private void print(double[][] arr) {
        print(arrayToString(arr));
    }

    private void printIndicatorInfos(IIndicator ind) {
        for (int i = 0; i < ind.getIndicatorInfo().getNumberOfInputs(); i++) {
            print(ind.getIndicatorInfo().getName() + " Input " + ind.getInputParameterInfo(i).getName() + " " + ind.getInputParameterInfo(i).getType());
        }
        for (int i = 0; i < ind.getIndicatorInfo().getNumberOfOptionalInputs(); i++) {
            print(ind.getIndicatorInfo().getName() + " Opt Input " + ind.getOptInputParameterInfo(i).getName() + " " + ind.getOptInputParameterInfo(i).getType());
        }
        for (int i = 0; i < ind.getIndicatorInfo().getNumberOfOutputs(); i++) {
            print(ind.getIndicatorInfo().getName() + " Output " + ind.getOutputParameterInfo(i).getName() + " " + ind.getOutputParameterInfo(i).getType());
        }
    }

    public static String arrayToString(double[] arr) {
        String str = "";
        for (int r = 0; r < arr.length; r++) {
            str += "[" + r + "] " + (new DecimalFormat("#.#######")).format(arr[r]) + "; ";
        }
        return str;
    }

    public static String arrayToString(double[][] arr) {
        String str = "";
        if (arr == null)
            return "null";
        for (int r = 0; r < arr.length; r++) {
            for (int c = 0; c < arr[r].length; c++) {
                str += "[" + r + "][" + c + "] " + (new DecimalFormat("#.#######")).format(arr[r][c]);
            }
            str += "; ";
        }
        return str;
    }

    public String toDecimalToStr(double d) {
        return (new DecimalFormat("#.#######")).format(d);
    }

    public String dateToStr(long time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") {
            {
                setTimeZone(TimeZone.getTimeZone("GMT"));
            }
        };
        return sdf.format(time);
    }

    // ________________________________

}


compilation is successfull but when i apply it i have this message :
java.lang.ClassCastException: [[D cannot be cast to [D
at jforex.indicators.TenkanOverRsi.setInputParameter(TenkanOverRsi.java:175)
at com.dukascopy.charts.math.a.a.a(Unknown Source)
at com.dukascopy.charts.math.dataprovider.AbstractDataProvider$e.c(Unknown Source)
at com.dukascopy.charts.math.dataprovider.AbstractDataProvider$e.run(Unknown Source)

so, i believe the problem come from the different array for the inputs for tenkanind and the inputs of tenkanOverRsi but i'm not sure.
i turn around the problem but i don't find the solution.
can please help me?


 
 Post subject: Re: problem with an array on indicator Post rating: 0   New post Posted: Mon 08 Jul, 2013, 08:29 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
You are attempting to assign a double[][] value to a variable of type double[]. Note that different indicators have different input types, therefore you need to treat them differently, please check in platform indicator sources what other indicators use InputParameterInfo.Type.PRICE and how they go about it.
Also see if your indicator logic actually does require InputParameterInfo.Type.PRICE maybe it suffices to use InputParameterInfo.Type.DOUBLE, especially given that the RSI indicator uses the InputParameterInfo.Type.PRICE input, find its source in RSIIndicator.java.


 

Jump to:  

  © 1998-2026 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