|
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.
| Linear Regression/volume |
|
barrett
|
| Post subject: Linear Regression/volume |
Post rating: 0
|
Posted: Tue 12 Jul, 2011, 01:04
|
|
User rating: -
|
Hi, i've been trying to make an indicator that would calculate the quotient of the linear regression and the volume, presenting it as a line. This is the first time i am messing with indicators. I have taken the SMAoverRSI indicator from the wiki and tried to adapt it, but i get the following error message, when running it: 23:58:59 Error in indicator: java.lang.ClassCastException: [D cannot be cast to [[D @ jforex.SMAOverRSIIndicator.calculate(SMAOverRSIIndicator.java:54) Since the compilation was successful, I hope that the problem can easily be fixed. Can anyone help? Thanks in advance! package jforex;
import com.dukascopy.api.indicators.*;
public class SMAOverRSIIndicator 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[2][]; private IIndicatorContext context; private IIndicator linreg; private IIndicator volume; public void onStart(IIndicatorContext context) { IIndicatorsProvider indicatorsProvider = context.getIndicatorsProvider(); linreg = indicatorsProvider.getIndicator("linearreg"); volume = indicatorsProvider.getIndicator("volume");
indicatorInfo = new IndicatorInfo("linreg/volume", "linearreg over volume", "My indicators", false, false, false, false, 1, 1, 1);
inputParameterInfos = new InputParameterInfo[] {new InputParameterInfo("Input data", InputParameterInfo.Type.DOUBLE)};
optInputParameterInfos = new OptInputParameterInfo[] {new OptInputParameterInfo("Linear Regression Time Period", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(14, 2, 100, 1))};
outputParameterInfos = new OutputParameterInfo[] {new OutputParameterInfo("Linreg line", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.LINE), new OutputParameterInfo("volumes", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM)}; }
public IndicatorResult calculate(int startIndex, int endIndex) { //calculating rsi int linregLookback = linreg.getLookback(); //first alocate buffer for rsi results double[] linregOutput; if (startIndex > endIndex || linregLookback > endIndex) { return new IndicatorResult(0, 0); } else { //take the greater value (startindex/ lookback) linregOutput = new double[endIndex - (linregLookback > startIndex ? linregLookback : startIndex) + 1]; } //init rsi indicator with input data and array for output linreg.setInputParameter(0, inputs[0]); linreg.setOutputParameter(0, linregOutput); IndicatorResult linregResult = linreg.calculate(startIndex, endIndex); if (linregResult.getNumberOfElements() < volume.getLookback()) { //not enough data to calculate sma return new IndicatorResult(0, 0); } //calculating sma volume.setInputParameter(0, inputs[0]); volume.setOutputParameter(0, outputs[1]); IndicatorResult volumeResult = volume.calculate(0, linregResult.getNumberOfElements() - 1); if (volumeResult.getNumberOfElements() == 0) { //sma returned 0 values return new IndicatorResult(0, 0); } //copy rsi values to output excluding first values used for sma lookback System.arraycopy(linregOutput, volumeResult.getFirstValueIndex(), outputs[0], 0, volumeResult.getNumberOfElements()); //creating result, first value index for our input is FVI for rsi + FVI for sma, because we calculated sma starting from 0 element IndicatorResult result = new IndicatorResult(linregResult.getFirstValueIndex() + volumeResult.getFirstValueIndex(), volumeResult.getNumberOfElements()); return result; }
public IndicatorInfo getIndicatorInfo() { return indicatorInfo; }
public InputParameterInfo getInputParameterInfo(int index) { if (index <= inputParameterInfos.length) { return inputParameterInfos[index]; } return null; }
public int getLookback() { return linreg.getLookback() + volume.getLookback(); }
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) { //set optional params in indicators switch (index) { case 0: linreg.setOptInputParameter(0, value); break; case 1: volume.setOptInputParameter(0, value); break; } }
public void setOutputParameter(int index, Object array) { outputs[index] = (double[]) array; } }
|
|
|
|
|
 |
|
API Support
|
| Post subject: Re: Linear Regression/volume |
Post rating: 0
|
Posted: Tue 12 Jul, 2011, 13:36
|
|
User rating: ∞
Joined: Fri 31 Aug, 2007, 09:17 Posts: 6139
|
There were multiple issues, like incompatibility between parameter types and incorrect parameter counts at indicator info declaration. See our comments in the modified indicator: package jforex.indicators;
import java.text.DecimalFormat;
import com.dukascopy.api.IConsole; import com.dukascopy.api.indicators.*; public class SMAOverRSIIndicator implements IIndicator { private IndicatorInfo indicatorInfo; private InputParameterInfo[] inputParameterInfos; private OptInputParameterInfo[] optInputParameterInfos; private OutputParameterInfo[] outputParameterInfos; private double[][] inputDouble = new double[1][]; private double[][][] inputPrice = new double[1][][]; private double[][] outputs = new double[2][]; private IIndicatorContext context; private IIndicator linreg; private IIndicator volume; private IConsole console; public void onStart(IIndicatorContext context) { IIndicatorsProvider indicatorsProvider = context.getIndicatorsProvider(); linreg = indicatorsProvider.getIndicator("linearreg"); volume = indicatorsProvider.getIndicator("volume"); //Support: you had number of outputs set to 1, although they were 2 - make sure that the parameter counts match //the ones that you pass later on in onStart method indicatorInfo = new IndicatorInfo("linreg volume", "linearreg over volume", "My indicators", false, false, false, 2, 1, 2); inputParameterInfos = new InputParameterInfo[] { new InputParameterInfo("Input data double", InputParameterInfo.Type.DOUBLE), new InputParameterInfo("Input data price", InputParameterInfo.Type.PRICE) }; optInputParameterInfos = new OptInputParameterInfo[] { new OptInputParameterInfo("Linear Regression Time Period", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(14, 2, 100, 1))}; outputParameterInfos = new OutputParameterInfo[] { new OutputParameterInfo("Linreg line", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE), new OutputParameterInfo("volumes", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM)};
//Support: print parameter infos - so that you see what types of inputs and outputs you need to pass. //Comment this out when you don't need it no more this.console = context.getConsole(); printIndicatorInfos(linreg); printIndicatorInfos(volume); } public IndicatorResult calculate(int startIndex, int endIndex) { //calculating rsi int linregLookback = linreg.getLookback(); //first alocate buffer for rsi results double[] linregOutput; if (startIndex > endIndex || linregLookback > endIndex) { return new IndicatorResult(0, 0); } else { //take the greater value (startindex/ lookback) linregOutput = new double[endIndex - (linregLookback > startIndex ? linregLookback : startIndex) + 1]; } //Support: comment this out once you don't need to know what inputs you pass to the indicators print ("received inputs onCalculate - inputsDouble: " + arrayToString(inputDouble[0]) + " inputPrice: " + arrayToString(inputPrice[0])); //init rsi indicator with input data and array for output linreg.setInputParameter(0, inputDouble[0]); linreg.setOutputParameter(0, linregOutput); IndicatorResult linregResult = linreg.calculate(startIndex, endIndex); if (linregResult.getNumberOfElements() < volume.getLookback() || linregResult.getNumberOfElements() == 0) { //not enough data to calculate sma return new IndicatorResult(0, 0); } //calculating sma //Support: here you got exception because volume input parameter was of type PRICE, but you passed to it DOUBLE volume.setInputParameter(0, inputPrice[0]); volume.setOutputParameter(0, outputs[1]); //Support: here you had not received outputs[1] since in indicatorInfo declaration you had set output size to 1.
IndicatorResult volumeResult = volume.calculate(0, linregResult.getNumberOfElements() - 1); if (volumeResult.getNumberOfElements() == 0) { //sma returned 0 values return new IndicatorResult(0, 0); } //copy rsi values to output excluding first values used for sma lookback System.arraycopy(linregOutput, volumeResult.getFirstValueIndex(), outputs[0], 0, volumeResult.getNumberOfElements()); //creating result, first value index for our input is FVI for rsi + FVI for sma, because we calculated sma starting from 0 element IndicatorResult result = new IndicatorResult(linregResult.getFirstValueIndex() + volumeResult.getFirstValueIndex(), volumeResult.getNumberOfElements()); return result; } //________________________________ //Support: Some helper methods for printing private void print(Object o){ console.getOut().println(o); } 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 IndicatorInfo getIndicatorInfo() { return indicatorInfo; } public InputParameterInfo getInputParameterInfo(int index) { if (index <= inputParameterInfos.length) { return inputParameterInfos[index]; } return null; } public int getLookback() { return linreg.getLookback() + volume.getLookback(); } 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; } //Support: if you have inputs of different types, it is more convenient to keep them in separate variables public void setInputParameter(int index, Object array) { if (index == 0){ inputDouble[0] = (double[]) array; } else { inputPrice[0] = (double[][]) array; } } public void setOptInputParameter(int index, Object value) { //set optional params in indicators switch (index) { case 0: linreg.setOptInputParameter(0, value); break; case 1: volume.setOptInputParameter(0, value); break; } } public void setOutputParameter(int index, Object array) { outputs[index] = (double[]) array; } }
|
|
|
|
|
 |
|
Guest
|
| Post subject: Re: Linear Regression/volume |
Post rating: 0
|
Posted: Tue 12 Jul, 2011, 13:40
|
|
User rating: -
|
Quote: There were multiple issues, like incompatibility between parameter types and incorrect parameter counts at indicator info declaration. Sorry about that. Thanks a lot!
|
|
|
|
|
 |
|
Pages: [
1
]
|
|
|
|
|