Hello,API Support
I have a indicator,but the platform says "Error in indicator: java.lang.ArrayIndexOutOfBoundsException: 3996 @ jforex.indicators.ATRTrailInd.calculate(ATRTrailInd.java:213)" when the indicator is running. I can't found what's the wrong. Can you help me?
package jforex.indicators;
import java.awt.Color;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import com.dukascopy.api.IConsole;
import com.dukascopy.api.IIndicators.AppliedPrice;
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.IntegerRangeDescription;
import com.dukascopy.api.indicators.OptInputParameterInfo;
import com.dukascopy.api.indicators.OutputParameterInfo;
public class ATRTrailInd implements IIndicator {
public static final int OPEN = 0;
public static final int CLOSE = 1;
public static final int HIGH = 2;
public static final int LOW = 3;
public static final int AVE = 4;
public static int MARK=0;
public static int lastzig=0;
public static double prev=0;
public static double zhu=0;
private IndicatorInfo indicatorInfo;
// INPUTS
private InputParameterInfo[] inputParameterInfos;
private double[][] inPrice;
// OPT INPUTS
private OptInputParameterInfo[] optInputParameterInfos;
private int period = 5;
private double mult = 3.5;
// OUTPUTS
private OutputParameterInfo[] outputParameterInfos;
private double[][] output;
private int ATR = 0;
// CONTEXT
private IConsole console;
private IIndicator atr;
public int getLookback() {
atr.setOptInputParameter(0, period);
return atr.getLookback();
}
public int getLookforward() {
return 0;
}
/***********
* START *
***********/
public void onStart(IIndicatorContext context) {
this.console = context.getConsole();
int[] priceValues = new int[AppliedPrice.values().length];
String[] priceNames = new String[AppliedPrice.values().length];
for (int i = 0; i < priceValues.length; i++) {
priceValues[i] = i;
priceNames[i] = AppliedPrice.values()[i].name();
}
inputParameterInfos = new InputParameterInfo[]{
new InputParameterInfo("price", InputParameterInfo.Type.PRICE)
};
optInputParameterInfos = new OptInputParameterInfo[]{
new OptInputParameterInfo("ATR period", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(period, 2, 1000, 1)),
new OptInputParameterInfo("ATR multiplication", OptInputParameterInfo.Type.OTHER, new DoubleRangeDescription(mult, -100.0, 100.0, 0.1, 10)),};
outputParameterInfos = new OutputParameterInfo[]{
new OutputParameterInfo("ATR", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.DOT_LINE) {
{
this.setColor(Color.BLUE);
}
},
new OutputParameterInfo("ZHU", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE) {
{
this.setColor(Color.BLUE);
}
},
new OutputParameterInfo("ZIG", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE) {
{
this.setColor(Color.RED);
}
}
};
output = new double[outputParameterInfos.length][];
atr = context.getIndicatorsProvider().getIndicator("ATR");
indicatorInfo = new IndicatorInfo("ATR trail", "ATR trail", "My indicators", true, false, false, inputParameterInfos.length, optInputParameterInfos.length, outputParameterInfos.length);
indicatorInfo.setRecalculateAll(true);
}
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) {
// print(index + ". input: " + arrayToString((double[]) array));
if (array instanceof double[][]) {
inPrice = (double[][]) array;
}
}
public void setOptInputParameter(int index, Object value) {
switch (index) {
case 0:
period = (Integer) value;
break;
case 1:
mult = (Double) value;
break;
}
}
public void setOutputParameter(int index, Object array) {
output[index] = (double[]) array;
}
/*************
* CALCULATE *
*************/
public IndicatorResult calculate(int startIndex, int endIndex) {
if (startIndex - getLookback() < 0) {
startIndex -= startIndex - getLookback();
}
if (startIndex > endIndex) {
return new IndicatorResult(0, 0);
}
int len = endIndex - startIndex + 1;
// atr
atr.setInputParameter(0, inPrice);
atr.setOutputParameter(0, output[ATR]);
atr.calculate(startIndex, endIndex);
int atrLB = atr.getLookback();
for (int i = 0; i < output[ATR].length; i++) {
int inIdx = i + atr.getLookback();
double stoploss = mult * output[ATR][i];
output[2][i] = Double.NaN ;
switch (MARK) {
case 0:
if(inPrice[CLOSE][atrLB - 1] > inPrice[CLOSE][atr.getLookback()]) {
prev = inPrice[LOW][atr.getLookback()] + mult * output[ATR][0];
zhu = inPrice[LOW][atr.getLookback()] ;
MARK=1;
} else {
prev = inPrice[HIGH][atr.getLookback()] - mult * output[ATR][0];
zhu = inPrice[HIGH][atr.getLookback()] ;
MARK=-1;
}
break;
case 1:
if(inPrice[HIGH][inIdx] > zhu) {
output[ATR][i] = inPrice[HIGH][inIdx] - stoploss;
output[1][i] = inPrice[HIGH][inIdx] ;
lastzig = i ;
} else if(inPrice[LOW][inIdx] < prev && lastzig != i) {
output[ATR][i] = inPrice[LOW][inIdx] + stoploss;
output[1][i] = inPrice[LOW][inIdx] ;
output[2][lastzig] = inPrice[HIGH][lastzig+ atr.getLookback()] ;
lastzig = i ;
MARK=-1;
} else {
output[ATR][i] = prev;
output[1][i] = zhu ;
}
break;
case -1:
if( inPrice[LOW][inIdx] < zhu) {
output[ATR][i] = inPrice[LOW][inIdx] + stoploss;
output[1][i] = inPrice[LOW][inIdx] ;
lastzig = i ;
} else if(inPrice[HIGH][inIdx] > prev && lastzig != i ) {
output[ATR][i] = inPrice[HIGH][inIdx] - stoploss;
output[1][i] = inPrice[HIGH][inIdx] ;
output[2][lastzig] = inPrice[LOW][lastzig+ atr.getLookback()] ;
lastzig = i ;
MARK=1;
} else {
output[ATR][i] = prev;
output[1][i] = zhu ;
}
break;
default:
break;
}
/*
if(inPrice[LOW][inIdx] > prev && inPrice[LOW][inIdx - 1] > prev) {
output[ATR][i] = Math.max(prev, inPrice[HIGH][inIdx] - stoploss);
} else if(inPrice[HIGH][inIdx] < prev && inPrice[HIGH][inIdx - 1] < prev) {
output[ATR][i] = Math.min(prev, inPrice[LOW][inIdx] + stoploss);
} else if(inPrice[LOW][inIdx] < prev) {
output[ATR][i] = inPrice[HIGH][inIdx] +stoploss;
} else {
output[ATR][i] = inPrice[LOW][inIdx] - stoploss;
}
*/
prev = output[ATR][i];
zhu = output[1][i] ;
}
return new IndicatorResult(startIndex, len);
}
// ________________________________
// Support: Some helper methods for printing
private void print(Object... o) {
for (Object ob : o) {
//console.getOut().print(ob + " ");
if (ob instanceof double[]) {
print2((double[]) ob);
} else if (ob instanceof double[][]) {
print2((double[][]) ob);
} else if (ob instanceof Long) {
print2(dateToStr((Long) ob));
} else {
print2(ob);
}
print2(" ");
}
console.getOut().println();
}
private void print(Object o) {
console.getOut().println(o);
}
private void print2(Object o) {
console.getOut().print(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);
}
// ________________________________
}