package jforex;
 
import com.dukascopy.api.indicators.*;
 
public class FOURSMAIndicator implements IIndicator {
    private IndicatorInfo indicatorInfo;
    private InputParameterInfo[] inputParameterInfos;
    private OptInputParameterInfo[] optInputParameterInfos;
    private OutputParameterInfo[] outputParameterInfos;
    private double[][] inputs = new double[1][];
    private int[] timePeriod = new int[4];
    private double[][] outputs = new double[4][];
    private IIndicator sma;
 
    public void onStart(IIndicatorContext context) {
        IIndicatorsProvider indicatorsProvider = context.getIndicatorsProvider();
        sma = indicatorsProvider.getIndicator("SMA");
        indicatorInfo = new IndicatorInfo("FOURSMA", "Shows four different SMA indicators", "My indicators",
        		true, false, true, 1, 3, 3);
        inputParameterInfos = new InputParameterInfo[] {new InputParameterInfo("Input data", InputParameterInfo.Type.DOUBLE)};
        optInputParameterInfos = new OptInputParameterInfo[] {new OptInputParameterInfo("Time period SMA1", OptInputParameterInfo.Type.OTHER,
                new IntegerRangeDescription(10, 2, 1000, 1)), new OptInputParameterInfo("Time period SMA2", OptInputParameterInfo.Type.OTHER,
                new IntegerRangeDescription(20, 2, 1000, 1)), new OptInputParameterInfo("Time period SMA3", OptInputParameterInfo.Type.OTHER,
                new IntegerRangeDescription(60, 2, 1000, 1)), new OptInputParameterInfo("Time period SMA4", OptInputParameterInfo.Type.OTHER,
                new IntegerRangeDescription(100, 2, 1000, 1))};
        outputParameterInfos = new OutputParameterInfo[] {new OutputParameterInfo("SMA1", OutputParameterInfo.Type.DOUBLE,
                OutputParameterInfo.DrawingStyle.LINE), new OutputParameterInfo("SMA2", OutputParameterInfo.Type.DOUBLE,
                OutputParameterInfo.DrawingStyle.LINE), new OutputParameterInfo("SMA3", OutputParameterInfo.Type.DOUBLE,
                OutputParameterInfo.DrawingStyle.LINE), new OutputParameterInfo("SMA4", OutputParameterInfo.Type.DOUBLE,
                OutputParameterInfo.DrawingStyle.LINE)};
    }
 
    public IndicatorResult calculate(int startIndex, int endIndex) {
        //calculating startIndex taking into account lookback value
        if (startIndex - getLookback() < 0) {
            startIndex -= startIndex - getLookback();
        }
 
        sma.setInputParameter(0, inputs[0]);
 
        //calculate first sma
        sma.setOptInputParameter(0, timePeriod[0]);
        sma.setOutputParameter(0, outputs[0]);
        sma.calculate(startIndex, endIndex);
 
        //calculate second sma
        sma.setOptInputParameter(0, timePeriod[1]);
        sma.setOutputParameter(0, outputs[1]);
        sma.calculate(startIndex, endIndex);
 
        //calculate third sma
        sma.setOptInputParameter(0, timePeriod[2]);
        sma.setOutputParameter(0, outputs[2]);
        sma.calculate(startIndex, endIndex);
        
        //calculate fourth sma
        sma.setOptInputParameter(0, timePeriod[3]);
        sma.setOutputParameter(0, outputs[3]);
        return sma.calculate(startIndex, endIndex);
        
    }
 
    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }
 
    public InputParameterInfo getInputParameterInfo(int index) {
        if (index <= inputParameterInfos.length) {
            return inputParameterInfos[index];
        }
        return null;
    }
 
    public int getLookback() {
        sma.setOptInputParameter(0, timePeriod[0]);
        int sma1Lookback = sma.getLookback();
        sma.setOptInputParameter(0, timePeriod[1]);
        int sma2Lookback = sma.getLookback();
        sma.setOptInputParameter(0, timePeriod[2]);
        int sma3Lookback = sma.getLookback();
        sma.setOptInputParameter(0, timePeriod[3]);
        int sma4Lookback = sma.getLookback();
        return Math.max(sma1Lookback, Math.max(sma2Lookback, sma3Lookback,sma4Lookback));
    }
 
    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) {
        timePeriod[index] = (Integer) value;
    }
 
    public void setOutputParameter(int index, Object array) {
        outputs[index] = (double[]) array;
    }
}