Indicator for multiple instruments

The following indicator calculates moving average for three instruments: GBPUSD, AUDCAD, EURJPY.

Method onStart

    public void onStart(IIndicatorContext context) {
        console = context.getConsole();     
        IIndicatorsProvider provider = context.getIndicatorsProvider();

        mainInputMA = provider.getIndicator("MA");
        mainInputMA.setOptInputParameter(0, defaultMAPeriod);        
        mainInputMA.setOptInputParameter(1, IIndicators.MaType.SMA.ordinal());
        additionalInputMA = provider.getIndicator("MA");     
        additionalInputMA.setOptInputParameter(0, defaultMAPeriod);
        mainInputMA.setOptInputParameter(1, IIndicators.MaType.SMA.ordinal());

        //indicator info
        indicatorInfo = new IndicatorInfo("INDEXIND", "MA for various instruments", "",
            true, false, true,
            4, 2, 4);

        //indicator inputs
        InputParameterInfo gbpUsdInput = new InputParameterInfo("Input data", InputParameterInfo.Type.BAR);
        gbpUsdInput.setInstrument(Instrument.GBPUSD);
        InputParameterInfo audCadInput = new InputParameterInfo("Input data", InputParameterInfo.Type.BAR);
        audCadInput.setInstrument(Instrument.AUDCAD);
        InputParameterInfo eurJpyInput = new InputParameterInfo("Input data", InputParameterInfo.Type.BAR);
        eurJpyInput.setInstrument(Instrument.EURJPY);        
        inputParameterInfos = new InputParameterInfo[] {
                new InputParameterInfo("Input data", InputParameterInfo.Type.BAR), 
                gbpUsdInput, audCadInput, eurJpyInput};

        //optional parameters
        int[] maValues = new int[IIndicators.MaType.values().length];
        String[] maNames = new String[IIndicators.MaType.values().length];
        for (int i = 0; i < maValues.length; i++) {
            maValues[i] = i;
            maNames[i] = IIndicators.MaType.values()[i].name();
        }        
        optInputParameterInfos = new OptInputParameterInfo[] {
                new OptInputParameterInfo("Time period",
                    OptInputParameterInfo.Type.OTHER,
                    new IntegerRangeDescription(defaultMAPeriod, 2, 100, 1)),
                new OptInputParameterInfo("MA Type",
                    OptInputParameterInfo.Type.OTHER,
                    new IntegerListDescription(IIndicators.MaType.SMA.ordinal(), maValues, maNames))
        };

        OutputParameterInfo gbpUsdOutput = new OutputParameterInfo("gbpUsd_MA",
            OutputParameterInfo.Type.DOUBLE,
            OutputParameterInfo.DrawingStyle.LINE);
        OutputParameterInfo audCadOutput = new OutputParameterInfo("audCad_MA",
            OutputParameterInfo.Type.DOUBLE,
            OutputParameterInfo.DrawingStyle.LINE);
        OutputParameterInfo eurJpyOutput = new OutputParameterInfo("eurJpy_MA",
            OutputParameterInfo.Type.DOUBLE,
            OutputParameterInfo.DrawingStyle.LINE);

        //manual drawing is used here 
        //to display moving averages on any chart (MA values differ for various instruments)   
        gbpUsdOutput.setDrawnByIndicator(true);
        audCadOutput.setDrawnByIndicator(true);
        eurJpyOutput.setDrawnByIndicator(true);

        outputParameterInfos = new OutputParameterInfo[] {
                new OutputParameterInfo("MA",
                                        OutputParameterInfo.Type.DOUBLE,
                                        OutputParameterInfo.DrawingStyle.LINE),
                gbpUsdOutput, audCadOutput, eurJpyOutput};
    }

Method calculate

public IndicatorResult calculate(int startIndex, int endIndex) {
    double[] mmaInput = new double[inputs[0].length];
    for (int i = 0; i < inputs[0].length; i++) {
        IBar bar = inputs[0][i];
        mmaInput[i] = bar.getClose();
    }
    mainInputMA.setInputParameter(0, mmaInput);
    mainInputMA.setOutputParameter(0, outputs[0]);
    IndicatorResult result = mainInputMA.calculate(startIndex, endIndex);        

    for (int i = 1; i < inputs.length; i++){
        calculateMA(i, result);
    }      
    return result;
}

Method calculateMA

private void calculateMA(int inputIndex, IndicatorResult result){
         double[] maInput = new double[inputs[inputIndex].length];
         for (int i = 0; i < inputs[inputIndex].length; i++) {
             IBar bar = inputs[inputIndex][i];
             maInput[i] = bar.getClose();
         }

         if (maInput.length - additionalInputMA.getLookback() > 0) {
             double[] maOutput = new double[maInput.length - additionalInputMA.getLookback()];
             additionalInputMA.setInputParameter(0, maInput);
             additionalInputMA.setOutputParameter(0, maOutput);
             IndicatorResult maResult = additionalInputMA.calculate(0, maInput.length - 1);

             int j = 0;
             for (int i = 0; i < result.getNumberOfElements(); i++) {
                 IBar bar = inputs[0][i + result.getFirstValueIndex()];
                 long barTime = bar.getTime();

                 while (j < maResult.getFirstValueIndex() + maResult.getNumberOfElements()
                         && inputs[inputIndex][j].getTime() < barTime) {
                     j++;
                 }
                 if (j >= maResult.getFirstValueIndex() + maResult.getNumberOfElements()
                         || inputs[inputIndex][j].getTime() != barTime
                         || j < maResult.getFirstValueIndex()) {
                     outputs[inputIndex][i] = Double.NaN;
                 } else {
                     outputs[inputIndex][i] = maOutput[j - maResult.getFirstValueIndex()];
                 }
             }
         } else {
             for (int i = 0; i < result.getNumberOfElements(); i++) {
                 outputs[inputIndex][i] = Double.NaN;
             }
         }
}

Download

MultipleInstrumentIndicatorExample.java

The information on this web site is provided only as general information, which may be incomplete or outdated. Click here for full disclaimer.