package jforex;
  
import com.dukascopy.api.*;
import com.dukascopy.api.indicators.*;
import java.awt.Color;
import java.text.DecimalFormat;
 
  
public class DeriveOnEMA 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[2];
    private double[][] outputs = new double[2][];
    private IIndicator ema;
    private IConsole console;
     
   
  
  
    public void onStart(IIndicatorContext context) {
        console = context.getConsole();
        IIndicatorsProvider indicatorsProvider = context.getIndicatorsProvider();
        ema = indicatorsProvider.getIndicator("EMA");
        indicatorInfo = new IndicatorInfo("DeriveOnEMA2", "Shows the derivative of ema", "My indicators",
                        false, false, true, 1, 1, 2);
        inputParameterInfos = new InputParameterInfo[] {new InputParameterInfo("Input data", InputParameterInfo.Type.DOUBLE)};
        optInputParameterInfos = new OptInputParameterInfo[] {
               new OptInputParameterInfo("Time period EMA1", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(5, 2, 100, 1))
                              };
        outputParameterInfos = new OutputParameterInfo[] {
                 //new OutputParameterInfo("EMA1", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.NONE, false),
                 new OutputParameterInfo("Derive", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),
                 new OutputParameterInfo("Level", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LEVEL_DASH_LINE){{
                     setColor(Color.GRAY);
                 }}
        };
         
        //outputParameterInfos[1].setColor(Color.BLUE);
        
         
    }
  
    public IndicatorResult calculate(int startIndex, int endIndex) {
        //calculating startIndex taking into account lookback value
        if (startIndex - getLookback() < 0) {
            startIndex -= startIndex - getLookback();
        }
        int len = endIndex - startIndex + 1;

        double[] emaOut = new double[len + 1]; 
        // len - outputs length; len+1 - length of ema output, one extra value is used to compute derivative
        ema.setInputParameter(0, inputs[0]);
        
        //calculate  ema
        ema.setOptInputParameter(0, timePeriod[0]);
        ema.setOutputParameter(0, emaOut);
        ema.calculate(endIndex - 1 - emaOut.length, endIndex);
        
        //Calculate simple derivative
        for(int i = 0; i < len; i++) {
            outputs[0][i] = emaOut[i+1] - emaOut[i];
            outputs[1][i] = 0;
        }
        

        //outputs[1][outputs[0].length - 1] = outputs[0][outputs[0].length - 2] - outputs[0][outputs[0].length - 3];

        return new IndicatorResult(startIndex, len);

    }
  
    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }
  
    public InputParameterInfo getInputParameterInfo(int index) {
        if (index <= inputParameterInfos.length) {
            return inputParameterInfos[index];
        }
        return null;
    }
  
    public int getLookback() {
        ema.setOptInputParameter(0, timePeriod[0]);
        int ema1Lookback = ema.getLookback();
        return ema1Lookback + 1;
       
    }
  
    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;
    }
}