Hi,
I'm writting my first Ask/Bid comparison indicator but it raise some errors.
The indicator uses two inputs:
InputParameterInfo iAsk = new InputParameterInfo("Ask Price",
InputParameterInfo.Type.BAR);
InputParameterInfo iBid = new InputParameterInfo("Bid Price",
InputParameterInfo.Type.BAR);
iAsk.setOfferSide(OfferSide.ASK);
iBid.setOfferSide(OfferSide.BID);
But, sometimes in calculations, it produces OutOfBounds exception, with no reason.
Then I put this comprobation code in setInputParameter:
public void setInputParameter(int index, Object array) {
inputs[index] = (IBar[]) array;
if (index == 1)
{
if (inputs[0] != null)
{
if (inputs[1].length != inputs[0].length)
{
consoleT.getErr().format("Inputs error; input[0]: %d elements from %tc to %tc input[1]: %d elements from %tc to %tc",
inputs[0].length, new Date(inputs[0][0].getTime()), new Date(inputs[0][inputs[0].length - 1].getTime()),
inputs[1].length, new Date(inputs[1][0].getTime()), new Date(inputs[1][inputs[1].length - 1].getTime())).println();
}
}
}
}
And, for example, using EUR/USD chart in one hour ticks. When i reduce zoom to maximum and go to 2013 year, my code raises this error.
Inputs error; input[0]: 5029 elements from Fri Apr 19 00:00:00 CEST 2013 to Tue Jan 21 12:00:00 CET 2014 input[1]: 4000 elements from Fri May 31 21:00:00 CEST 2013 to Tue Jan 21 12:00:00 CET 2014
What is wrong?, why input[1] (BID side) is only 4000 elements long?
Another error produces when i change the Bid to Ask in the graphics. Then the error changes to:
Inputs error; input[0]: 4000 elements from Fri May 31 22:00:00 CEST 2013 to Tue Jan 21 13:00:00 CET 2014 input[1]: 5653 elements from Thu Mar 28 00:00:00 CET 2013 to Tue Jan 21 13:00:00 CET 2014
Now, input[0] (ASK side) gives only 4000 elements?
Could be a graphics (side Ask/Bid) interrelation with my indicator asking for both sides?
Best regards,
Víctor
Here is the whole Java code:
package jforex;
import java.util.ArrayList;
import java.util.Date;
import java.awt.Color;
import com.dukascopy.api.IBar;
import com.dukascopy.api.IConsole;
import com.dukascopy.api.OfferSide;
import com.dukascopy.api.indicators.*;
public class TestAskBid implements IIndicator {
protected IndicatorInfo indicatorInfo;
protected ArrayList<InputParameterInfo> listInputParameterInfos = new ArrayList<InputParameterInfo>();
protected InputParameterInfo[] inputParameterInfos;
protected ArrayList<OptInputParameterInfo> listOptInputParameterInfos = new ArrayList<OptInputParameterInfo>();
protected OptInputParameterInfo[] optInputParameterInfos;
protected ArrayList<OutputParameterInfo> listOutputParameterInfos = new ArrayList<OutputParameterInfo>();
protected OutputParameterInfo[] outputParameterInfos;
protected IBar[][] inputs = new IBar[2][];
private int timePeriod = 20;
protected double[][] outputs = new double[1][];
private IConsole consoleT;
public void onStart(IIndicatorContext context) {
consoleT = context.getConsole();
indicatorInfo = new IndicatorInfo("TestAskBid", "TestAskBid", "My indicators",
false, false, false, 2, 1, 1);
InputParameterInfo iAsk = new InputParameterInfo("Ask Price",
InputParameterInfo.Type.BAR);
InputParameterInfo iBid = new InputParameterInfo("Bid Price",
InputParameterInfo.Type.BAR);
iAsk.setOfferSide(OfferSide.ASK);
iBid.setOfferSide(OfferSide.BID);
listInputParameterInfos.add(iAsk);
listInputParameterInfos.add(iBid);
listOptInputParameterInfos
.add(new OptInputParameterInfo("Period",
OptInputParameterInfo.Type.OTHER,
new IntegerRangeDescription(20,
1, 100, 1)));
listOutputParameterInfos.add(new OutputParameterInfo("TestAskBid",
OutputParameterInfo.Type.DOUBLE,
OutputParameterInfo.DrawingStyle.HISTOGRAM)
{
{
setColor(new Color(255, 0, 0));
}
});
/* Generic */
indicatorInfo.setRecalculateOnNewCandleOnly(true);
inputParameterInfos = new InputParameterInfo[listInputParameterInfos
.size()];
listInputParameterInfos.toArray(inputParameterInfos);
optInputParameterInfos = new OptInputParameterInfo[listOptInputParameterInfos
.size()];
listOptInputParameterInfos.toArray(optInputParameterInfos);
outputParameterInfos = new OutputParameterInfo[listOutputParameterInfos
.size()];
listOutputParameterInfos.toArray(outputParameterInfos);
}
public IndicatorResult calculate(int startIndex, int endIndex) {
//calculating startIndex taking into account lookback value
if (startIndex - getLookback() < 0) {
startIndex -= startIndex - getLookback();
}
int i, j;
for (i = startIndex, j = 0; i <= endIndex; i++, j++) {
// Do calculation.
}
return new IndicatorResult(startIndex, endIndex - startIndex + 1);
}
public IndicatorInfo getIndicatorInfo() {
return indicatorInfo;
}
public InputParameterInfo getInputParameterInfo(int index) {
if (index <= inputParameterInfos.length) {
return inputParameterInfos[index];
}
return null;
}
public int getLookback() {
return timePeriod;
}
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] = (IBar[]) array;
if (index == 1)
{
if (inputs[0] != null)
{
if (inputs[1].length != inputs[0].length)
{
consoleT.getErr().format("Inputs error; input[0]: %d elements from %tc to %tc input[1]: %d elements from %tc to %tc",
inputs[0].length, new Date(inputs[0][0].getTime()), new Date(inputs[0][inputs[0].length - 1].getTime()),
inputs[1].length, new Date(inputs[1][0].getTime()), new Date(inputs[1][inputs[1].length - 1].getTime())).println();
}
}
}
}
public void setOptInputParameter(int index, Object value) {
timePeriod = (Integer) value;
}
public void setOutputParameter(int index, Object array) {
outputs[index] = (double[]) array;
}
}
Hey,
i am not are if getting ASK and BID prices from the chart for an Indicator at the same time is properly defined - note that one Value defaults to 4000, irregardless of set interval. Also the charts allows to display either BID or ASK prices.
A Solution would be to build a custom strategy and overloading "onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) " to calculate the difference while plotting it with an primitive Indicator