I encoded the following TickCount indicator:
package jForex;
import com.dukascopy.api.indicators.*;
import com.dukascopy.api.JFException;
import com.dukascopy.api.IHistory;
import com.dukascopy.api.IBar;
import com.dukascopy.api.ITick;
import java.util.List;
import java.awt.Color;
public class TCNT implements IIndicator
{
private IHistory clsHistory;
private IndicatorInfo clsIndicatorInfo;
private IIndicatorContext clsIndicatorContext;
private InputParameterInfo[] clsInputParameterInfos;
private OutputParameterInfo[] clsOutputParameterInfos;
private IBar[][] clsBarInputs = new IBar[1][];
private double[][] clsdOutputs = new double[1][];
public void onStart(IIndicatorContext context)
{
clsIndicatorContext = context;
clsHistory = context.getHistory();
clsIndicatorInfo = new IndicatorInfo("TCNT", "Tick Count", "My Indicators", false, false, false, 1, 0, 1);
clsIndicatorInfo.setRecalculateAll(false);
clsIndicatorInfo.setRecalculateOnNewCandleOnly(false);
clsInputParameterInfos = new InputParameterInfo[] { new InputParameterInfo("BarInputs", InputParameterInfo.Type.BAR) };
clsOutputParameterInfos = new OutputParameterInfo[] { new OutputParameterInfo("TickCount", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM) {{ setColor(Color.darkGray); }} };
}
public IndicatorResult calculate(int iStartIndex, int iEndIndex)
{
int iInIndex = 0, iOutIndex = 0, iTickCount = 0, iIndex = 0;
long lInterval = clsIndicatorContext.getFeedDescriptor().getPeriod().getInterval(),
lTickTime = 0L, lPeriodStartTime = 0L;
List<ITick> listTicks;
ITick[] arrayTicks;
if (iStartIndex > iEndIndex)
return new IndicatorResult(0, 0);
try
{
listTicks = clsHistory.getTicks(clsIndicatorContext.getFeedDescriptor().getInstrument(), ((IBar)clsBarInputs[0][iStartIndex]).getTime(), ((IBar)clsBarInputs[0][iEndIndex]).getTime());
arrayTicks = (ITick[])listTicks.toArray(new ITick[0]);
}
catch (JFException jFExc)
{
clsIndicatorContext.getConsole().getErr().println("getTicks Error: " + jFExc.getMessage());
listTicks = null;
arrayTicks = null;
}
for (iInIndex = iStartIndex, iOutIndex = 0 ; iInIndex <= iEndIndex ; iInIndex++, iOutIndex++)
{
iTickCount = -1;
if (arrayTicks != null)
{
iTickCount = 0;
for (iIndex = 0 ; iIndex < arrayTicks.length ; iIndex++)
{
lTickTime = arrayTicks[iIndex].getTime();
lPeriodStartTime = ((IBar)clsBarInputs[0][iInIndex]).getTime();
if (lTickTime >= lPeriodStartTime && lTickTime < lPeriodStartTime + lInterval)
iTickCount++;
}
}
clsdOutputs[0][iOutIndex] = iTickCount;
}
return new IndicatorResult(iStartIndex, iOutIndex);
}
public int getLookback()
{
return 0;
}
public int getLookforward()
{
return 0;
}
public IndicatorInfo getIndicatorInfo()
{
return clsIndicatorInfo;
}
public InputParameterInfo getInputParameterInfo(int iIndex)
{
return (iIndex <= clsInputParameterInfos.length ? clsInputParameterInfos[iIndex] : null);
}
public OptInputParameterInfo getOptInputParameterInfo(int iIndex)
{
return null;
}
public OutputParameterInfo getOutputParameterInfo(int iIndex)
{
return (iIndex <= clsOutputParameterInfos.length ? clsOutputParameterInfos[iIndex] : null);
}
public void setInputParameter(int iIndex, Object oArray)
{
clsBarInputs[iIndex] = (IBar[]) oArray;
}
public void setOptInputParameter(int iIndex, Object oValue)
{
return;
}
public void setOutputParameter(int iIndex, Object oArray)
{
clsdOutputs[iIndex] = (double[]) oArray;
}
}
I can start the indicator, but I have several problems / questions:
I don't get histogram values for periods after I started the indicator.
Should I use readTicks() instead of getTicks(), as you suggested in the following thread:
viewtopic.php?f=65&t=47579&p=65212 ?
But this solution is for a strategy, not for an indicator, and I'm not sure if it's recommended to use asynchronous methods inside indicators.
Also I got an ArrayIndexOutOfBoundsException while indicator was running, but until now only once, and I don't know exactly at which code line - I assume between line 55 and 70 in the calculate() method.
After start of indicator, all histogram values are 0 about a half minute. Only after this waiting time plausible values greater then 0 are shown.
In addition, I'm not sure if the ticks inside the list I get from getTicks() are sorted by timestamp or not, therefore I coded a double nested for(....) loop which is not performance optimised.
Regards
AbsoluteReturner