Indicator that uses the output of another indicator

Overview

The following example demonstrates the use of one indicator output inside the other indicator by calculating SMA over RSI values.

Method onStart

The indicator has one input, two outputs for both SMA and RSI indicators and two optional parameters that let you set a separate time period for each indicator. IIndicatorsProvider is used to get acces to indicators.

public void onStart(IIndicatorContext context) {       
        //getting interfaces of RSI and SMA indicators
        IIndicatorsProvider indicatorsProvider = context.getIndicatorsProvider();
        rsiIndicator = indicatorsProvider.getIndicator("RSI");
        smaIndicator = indicatorsProvider.getIndicator("SMA");
        //inicator with one input, two optional params and two outputs
        indicatorInfo = new IndicatorInfo("SMA_RSI", "SMA over RSI", "My indicators",
                false, false, false, false, 1, 2, 2);
        //one input array of doubles
        inputParameterInfos = new InputParameterInfo[] {new InputParameterInfo("Input data", InputParameterInfo.Type.DOUBLE)};
        //two optional params, one for every indicator
        optInputParameterInfos = new OptInputParameterInfo[] {new OptInputParameterInfo("RSI Time Period", OptInputParameterInfo.Type.OTHER,
                new IntegerRangeDescription(14, 2, 100, 1)), new OptInputParameterInfo("SMA Time Period", OptInputParameterInfo.Type.OTHER,
                new IntegerRangeDescription(14, 2, 100, 1))};
        //two output arrays, one for RSI and one for SMA over RSI
        outputParameterInfos = new OutputParameterInfo[] {new OutputParameterInfo("RSI line", OutputParameterInfo.Type.DOUBLE,
                OutputParameterInfo.LINE), new OutputParameterInfo("SMA line", OutputParameterInfo.Type.DOUBLE,
                OutputParameterInfo.LINE)};
}

Method getLookback

Note that the total lookback value must include both SMA lookback and RSI lookback.

public int getLookback() {
  return rsiIndicator.getLookback() + smaIndicator.getLookback();
}

Method calculate

Indicator values are calculated inside the calculate method. See comments for more details.

    public IndicatorResult calculate(int startIndex, int endIndex) {        
        if (startIndex < getLookback()) {
            startIndex = getLookback();
        }
        if (startIndex > endIndex) {
            //not enough data to calculate indicator
            return new IndicatorResult(0, 0);
        }

        //calculating rsi
        int smaLookback = smaIndicator.getLookback();
        //first alocate buffer for rsi results
        double[] rsiOutput = new double[endIndex - startIndex + 1 + smaLookback];
        //init rsi indicator with input data and array for output
        rsiIndicator.setInputParameter(0, inputs[0]);
        rsiIndicator.setOutputParameter(0, rsiOutput);
        IndicatorResult rsiResult = rsiIndicator.calculate(startIndex - smaLookback, endIndex);
        if (rsiResult.getNumberOfElements() < smaLookback) {
            //not enough data to calculate sma
            return new IndicatorResult(0, 0);
        }

        //calculating sma
        smaIndicator.setInputParameter(0, rsiOutput);
        smaIndicator.setOutputParameter(0, outputs[1]);
        IndicatorResult smaResult = smaIndicator.calculate(0, rsiResult.getNumberOfElements() - 1);
        if (smaResult.getNumberOfElements() == 0) {
            //sma returned 0 values
            return new IndicatorResult(0, 0);
        }

        //copy rsi values to output excluding first values used for sma lookback
        System.arraycopy(rsiOutput, smaResult.getFirstValueIndex(), outputs[0], 0, smaResult.getNumberOfElements());
        //creating result, first value index for our input is FVI for rsi + FVI for sma, because we calculated sma starting from 0 element
        IndicatorResult result = new IndicatorResult(rsiResult.getFirstValueIndex() + smaResult.getFirstValueIndex(), smaResult.getNumberOfElements());
        return result;
    }

Download

SMAOverRSIIndicator.java

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