Hi support,
I'm working on an indicator that incorporates several instruments.
I based on your sample:
https://www.dukascopy.com/wiki/#Indicato ... nstrumentsThe indicator shows the curves but generates the following errors:
09:32:47 Error in indicator: java.lang.NullPointerException @ jforex.indicators.MultipleInstrumentIndicatorExample.calculate(MultipleInstrumentIndicatorExample.java:74)
The errors are not constant ... what is the problem ?
Below is the code of my indicator that has the same problems :
package jforex;
import com.dukascopy.api.IBar;
import com.dukascopy.api.indicators.IDrawingIndicator;
import com.dukascopy.api.indicators.IIndicator;
import com.dukascopy.api.indicators.IIndicatorContext;
import com.dukascopy.api.indicators.IIndicatorDrawingSupport;
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 com.dukascopy.api.IConsole;
import com.dukascopy.api.Instrument;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Shape;
import java.awt.Stroke;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Map;
import java.util.TimeZone;
public class multi implements IIndicator {
// Afficher messages dans la console
private boolean userDebug = true;
// Declaration de l'indicateur
private IndicatorInfo indicatorInfo;
// Declaration du conteneur des flux d'entres (Data feed)
private InputParameterInfo[] inputParameterInfos;
// Declaration du conteneur des parametres modifiables
private OptInputParameterInfo[] optInputParameterInfos;
// Declaration du conteneur des decriptions du flux de sortie (le graphique)
private OutputParameterInfo[] outputParameterInfos;
// ----------- Description de l'indicateur
private boolean overChart = false;
private boolean overVolumes = false;
private boolean unstablePeriod = true;
// Number of inputs for indicator calculations.
private int numberOfInputs = 11;
// Number of parameters like SMA time period.
private int numberOptInputs = 0;
// Number of calculated values for every element of the input.
private int numberOfOutputs = 1;
// Declaration pour envoi de message dans la console
private IConsole console;
private IBar[][] inputs = new IBar[11][];
private double[][] outputs = new double[1][];
// -------------------------------------------------------------------------
// Ecrire un message
public void Print (String message) {
this.console.getOut( ).println(message);
}
// -------------------------------------------------------------------------
@Override
public void onStart(IIndicatorContext context) {
// Initialisation de la console
console = context.getConsole();
// Construction de l'indicateur
indicatorInfo = new IndicatorInfo("IA", "Multi", "",
overChart, overVolumes, unstablePeriod, numberOfInputs, numberOptInputs, numberOfOutputs);
// Ajout et description des flux dans le conteneur (Data feed)
InputParameterInfo eurusdInput = new InputParameterInfo("EURUSD", InputParameterInfo.Type.BAR);
eurusdInput.setInstrument(Instrument.EURUSD);
InputParameterInfo eurchfInput = new InputParameterInfo("EURCHF", InputParameterInfo.Type.BAR);
eurchfInput.setInstrument(Instrument.EURCHF);
InputParameterInfo eurgbpInput = new InputParameterInfo("EURGBP", InputParameterInfo.Type.BAR);
eurgbpInput.setInstrument(Instrument.EURGBP);
InputParameterInfo eurjpyInput = new InputParameterInfo("EURJPY", InputParameterInfo.Type.BAR);
eurjpyInput.setInstrument(Instrument.EURJPY);
InputParameterInfo eurcadInput = new InputParameterInfo("EURCAD", InputParameterInfo.Type.BAR);
eurcadInput.setInstrument(Instrument.EURCAD);
InputParameterInfo euraudInput = new InputParameterInfo("EURAUD", InputParameterInfo.Type.BAR);
euraudInput.setInstrument(Instrument.EURAUD);
InputParameterInfo usdjpyInput = new InputParameterInfo("USDJPY", InputParameterInfo.Type.BAR);
usdjpyInput.setInstrument(Instrument.USDJPY);
InputParameterInfo gbpusdInput = new InputParameterInfo("GBPUSD", InputParameterInfo.Type.BAR);
gbpusdInput.setInstrument(Instrument.GBPUSD);
InputParameterInfo usdcadInput = new InputParameterInfo("USDCAD", InputParameterInfo.Type.BAR);
usdcadInput.setInstrument(Instrument.USDCAD);
InputParameterInfo usdsekInput = new InputParameterInfo("USDSEK", InputParameterInfo.Type.BAR);
usdsekInput.setInstrument(Instrument.USDSEK);
InputParameterInfo usdchfInput = new InputParameterInfo("USDCHF", InputParameterInfo.Type.BAR);
usdchfInput.setInstrument(Instrument.USDCHF);
inputParameterInfos = new InputParameterInfo[] {
new InputParameterInfo("Input data", InputParameterInfo.Type.BAR),
eurusdInput,
eurchfInput,
eurgbpInput,
eurjpyInput,
eurcadInput,
euraudInput,
usdjpyInput,
gbpusdInput,
usdcadInput,
usdsekInput,
usdchfInput
};
// Ajout et descrition des flux de sortie (le graphique)
outputParameterInfos = new OutputParameterInfo[] {new OutputParameterInfo("out", OutputParameterInfo.Type.DOUBLE,
OutputParameterInfo.DrawingStyle.LINE)
};
}
// -------------------------------------------------------------------------
@Override
public IndicatorResult calculate(int startIndex, int endIndex) {
int loop;
for (loop = startIndex ; loop <= endIndex; loop++) {
outputs[0][loop] = inputs[4][loop].getClose(); // EURJPY
}
return new IndicatorResult(startIndex,loop);
}
// -------------------------------------------------------------------------
@Override
public IndicatorInfo getIndicatorInfo() {
return indicatorInfo;
}
// -------------------------------------------------------------------------
@Override
public InputParameterInfo getInputParameterInfo(int index) {
if (index <= inputParameterInfos.length) {
return inputParameterInfos[index];
}
return null;
}
// -------------------------------------------------------------------------
@Override
public int getLookback() {
return 0;
}
// -------------------------------------------------------------------------
@Override
public int getLookforward(){
return 0;
}
// -------------------------------------------------------------------------
@Override
public OptInputParameterInfo getOptInputParameterInfo(int index) {
if (index <= optInputParameterInfos.length) {
return optInputParameterInfos[index];
}
return null;
}
// -------------------------------------------------------------------------
@Override
public OutputParameterInfo getOutputParameterInfo(int index){
if (index <= outputParameterInfos.length) {
return outputParameterInfos[index];
}
return null;
}
// -------------------------------------------------------------------------
@Override
public void setInputParameter(int index, Object array) {
inputs[index] = (IBar[]) array;
}
// -------------------------------------------------------------------------
@Override
public void setOptInputParameter(int index, Object value) {
}
// -------------------------------------------------------------------------
@Override
public void setOutputParameter(int index, Object array) {
outputs[index] = (double[]) array;
}
/***************************************************************************
* debug print functions
***************************************************************************/
private void print(Object... o) {
if (userDebug) {
for (Object ob : o) {
if (ob instanceof String) {
console.getOut().print(ob);
} else if (ob instanceof Double) {
console.getOut().print(toStr((Double) ob,5));
} else if (ob instanceof Long) {
console.getOut().print(dateToStr((Long) ob));
} else if (ob instanceof Integer) {
console.getOut().print(toStr((Integer) ob));
} else if (ob instanceof Boolean) {
console.getOut().print( ob);
}
}
console.getOut().println();
}
}
// -------------------------------------------------------------------------
public String toStr(double d, int decimal) {
switch (decimal) {
case 1: return (new DecimalFormat("#.#")).format(d);
case 2: return (new DecimalFormat("#.##")).format(d);
case 3: return (new DecimalFormat("#.###")).format(d);
case 4: return (new DecimalFormat("#.####")).format(d);
case 5: return (new DecimalFormat("#.#####")).format(d);
case 6: return (new DecimalFormat("#.######")).format(d);
default : return (new DecimalFormat("#.#")).format(d);
}
}
// -------------------------------------------------------------------------
public String toStr(int i) {
return (new DecimalFormat("#")).format(i);
}
// -------------------------------------------------------------------------
public String dateToStr(Long time) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") { {
setTimeZone(TimeZone.getTimeZone("GMT"));
}};
return sdf.format(time);
}
// -------------------------------------------------------------------------
}
what is the problem ?
On this basis can you give me an sample that shows a few different instruments curves in a separate windows ?
Thank you very much !
Sacha