Dukascopy
 
 
Wiki JStore Search Login

Attention! Read the forum rules carefully before posting a topic.

    Try to find an answer in Wiki before asking a question.
    Submit programming questions in this forum only.
    Off topics are strictly forbidden.

Any topics which do not satisfy these rules will be deleted.

what's wrong with this code
 Post subject: what's wrong with this code Post rating: 0   Post Posted: Wed 02 Oct, 2013, 21:54 
User avatar

User rating: 0
Joined: Wed 18 May, 2011, 14:59
Posts: 19
Location: Slovenia, Ljubljana
This code is exactly the same as SMAOverRSIIndicator.java that is in the examples section of indicator docs, except that it uses STOCHRSI instead of RSI. The only things changed from the original are that the indicator has been renamed to SMAOverSTORSIIndicator (filename as well), that it uses getIndicator("STOCHRSI") instead of RSI and the description for IndicatorInfo has been changed to reflect this ("SMA over STORSI").

Unlike the original however this one throws an exception (apparently something to do with getLookback() for STORSI).


package jforex;

import com.dukascopy.api.indicators.*;

public class SMAOverSTORSIIndicator implements IIndicator {
    private IndicatorInfo indicatorInfo;
    private InputParameterInfo[] inputParameterInfos;
    private OptInputParameterInfo[] optInputParameterInfos;
    private OutputParameterInfo[] outputParameterInfos;
    private double[][] inputs = new double[1][];
    private double[][] outputs = new double[2][];
    private IIndicatorContext context;
    private IIndicator rsiIndicator;
    private IIndicator smaIndicator;
   
    public void onStart(IIndicatorContext context) {           
        //getting interfaces of RSI and SMA indicators
        IIndicatorsProvider indicatorsProvider = context.getIndicatorsProvider();
        rsiIndicator = indicatorsProvider.getIndicator("STOCHRSI");
        smaIndicator = indicatorsProvider.getIndicator("SMA");
        //inicator with one input, two optional params and two outputs
        indicatorInfo = new IndicatorInfo("SMA_RSI", "SMA over STORSI", "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)};
    }

    public IndicatorResult calculate(int startIndex, int endIndex) {       
        //calculating rsi
        int rsiLookback = rsiIndicator.getLookback();
        //first alocate buffer for rsi results
        double[] rsiOutput;
        if (startIndex > endIndex || rsiLookback > endIndex) {   
            return new IndicatorResult(0, 0);
        } else {
            //take the greater value (startindex/ lookback)
            rsiOutput = new double[endIndex - (rsiLookback > startIndex ? rsiLookback : startIndex) + 1];
        }
        //init rsi indicator with input data and array for output
        rsiIndicator.setInputParameter(0, inputs[0]);
        rsiIndicator.setOutputParameter(0, rsiOutput);
        IndicatorResult rsiResult = rsiIndicator.calculate(startIndex, endIndex);
        if (rsiResult.getNumberOfElements() < smaIndicator.getLookback()) {
            //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;
    }

    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }

    public InputParameterInfo getInputParameterInfo(int index) {
        if (index <= inputParameterInfos.length) {
            return inputParameterInfos[index];
        }
        return null;
    }

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

 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] = (double[]) array;
    }

    public void setOptInputParameter(int index, Object value) {
        //set optional params in indicators
        switch (index) {
            case 0:
                rsiIndicator.setOptInputParameter(0, value);
                break;
            case 1:
                smaIndicator.setOptInputParameter(0, value);
                break;
        }
    }

    public void setOutputParameter(int index, Object array) {
        outputs[index] = (double[]) array;
    }
}


 
 Post subject: Re: what's wrong with this code Post rating: 1   Post Posted: Fri 04 Oct, 2013, 00:19 
User avatar

User rating: 164
Joined: Mon 08 Oct, 2012, 10:35
Posts: 676
Location: NetherlandsNetherlands
Hi,

It is not that simple :).

StochRSI is also a combination of indicators:RSI + STOCHF (StochasticFastIndicator),
and STOCHF is also using another indicator: MA


the getLookback() function, where you get the Null Pointer exception is calling rsiIndicator.getLookback().
For your modified indicator (SMAOverSTORSI) it will call STORSI's getLookBack(), which is:
public int getLookback() {                 
    return stochFastIndicator.getLookback() + rsiIndicator.getLookback();
}


So I guess that stochFastIndicator was not properly instantiated, that is why you get the exception.


Take a look on the source codes of the RSI and StochRSI indicator and see the differences. For example StochRSI uses much more input params (FastK, FastD, FastD MA), so you need to define these in the modified SMAOverSTORSI code, not just replace RSI with STORSI are one location...

But I think it is doable to merge in StockRSI's stuff.

Good luck!


 

Jump to:  

  © 1998-2026 Dukascopy® Bank SA
On-line Currency forex trading with Swiss Forex Broker - ECN Forex Brokerage,
Managed Forex Accounts, introducing forex brokers, Currency Forex Data Feed and News
Currency Forex Trading Platform provided on-line by Dukascopy.com