import com.dukascopy.api.IAccount;
import com.dukascopy.api.IBar;
import com.dukascopy.api.IContext;
import com.dukascopy.api.IMessage;
import com.dukascopy.api.IStrategy;
import com.dukascopy.api.ITick;
import com.dukascopy.api.Instrument;
import com.dukascopy.api.JFException;
import com.dukascopy.api.OfferSide;
import com.dukascopy.api.Period;
import com.dukascopy.api.IIndicators.AppliedPrice;
import com.dukascopy.api.indicators.IIndicator;
import com.dukascopy.api.indicators.IIndicatorContext;
import com.dukascopy.api.indicators.IndicatorInfo;
import com.dukascopy.api.indicators.IndicatorResult;
import com.dukascopy.api.indicators.InputParameterInfo;
import com.dukascopy.api.indicators.OptInputParameterInfo;
import com.dukascopy.api.indicators.OutputParameterInfo;

public class CustomIndicatorStrategy implements IStrategy {

    IContext context;

    @Override
    public void onStart(IContext context) throws JFException {
        this.context = context;
        context.getIndicators().registerCustomIndicator(CustomIndicator.class);
    }

    @Override
    public void onStop() throws JFException {
        
    }

    @Override
    public void onAccount(IAccount account) throws JFException {

    }

    @Override
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {

    }

    @Override
    public void onMessage(IMessage message) throws JFException {

    }


    @Override
    public void onTick(Instrument instrument, ITick tick) throws JFException {
        //context.getConsole().getOut().println("Custom idnicator : " +
            //context.getIndicators().getIndicator("CustomIndicator").calculate(0, 0)
            context.getIndicators().calculateIndicator(
                instrument,
                Period.DAILY,
                new OfferSide[] { OfferSide.ASK},
                "CustomIndicator",
                new AppliedPrice[] {AppliedPrice.CLOSE},
                null,
                0
            );
        //);
    }
    
    public static class CustomIndicator implements IIndicator {

    private IIndicator signalMa;
    private int signalPeriod = 9;   
    private InputParameterInfo[] inputParameterInfos;
    private double[][][] inputs = new double[1][][];
    private IIndicatorContext iContext ;
    
    @Override
    public IndicatorResult calculate(int startIndex, int endIndex) {
        
        double[] smaA = new double[endIndex - startIndex + 1];
        // set signal ma period    
        signalMa.setOptInputParameter(0, signalPeriod);        
        signalMa.setInputParameter(0, inputs[0][1]);
        signalMa.setOutputParameter(0, smaA);
      
        IndicatorResult signalMAResult = signalMa.calculate(startIndex, endIndex);        
        return signalMAResult;
    }

    @Override
    public IndicatorInfo getIndicatorInfo() {
        IndicatorInfo info = new IndicatorInfo(
            "CustomIndicator",
            "Custom indicator title",
            "Custom",
            false,
            false,
            true,
            1,
            0,
            0
        );
        return info;
    }


    @Override
    public int getLookback() {
        //iContext.getConsole().getOut().println("CUSTOM INDICATOR getLookback");
        //return signalMa.getLookback();
        return signalPeriod;
    }

    @Override
    public int getLookforward() {
        return 0;
    }
    
    @Override
    public InputParameterInfo getInputParameterInfo(int index) {
        if (index <= inputParameterInfos.length) {
            return inputParameterInfos[index];
        }
        return null;
    }
    
    @Override
    public OptInputParameterInfo getOptInputParameterInfo(int index) {
        return null;
    }

    @Override
    public OutputParameterInfo getOutputParameterInfo(int index) {
        return null;
    }

    @Override
    public void onStart(IIndicatorContext context) {
        iContext = context;
        context.getConsole().getOut().println("CUSTOM INDICATOR START");
        inputParameterInfos = new InputParameterInfo[] {new InputParameterInfo("Price", InputParameterInfo.Type.PRICE)}; 
        signalMa = context.getIndicatorsProvider().getIndicator("SMA");
    }

    @Override
    public void setInputParameter(int index, Object array) {
        //iContext.getConsole().getOut().println("CUSTOM INDICATOR setInputParameter");
        inputs[index] = (double[][]) array;
    }

    @Override
    public void setOptInputParameter(int index, Object value) {
        //iContext.getConsole().getOut().println("CUSTOM INDICATOR setOptInputParameter");
        if (index == 0) {
            signalPeriod = (Integer) value;
            //signalMa.setOptInputParameter(0, signalPeriod);
        }        

    }

    @Override
    public void setOutputParameter(int index, Object array) {
        //iContext.getConsole().getOut().println("CUSTOM INDICATOR setOutputParameter");
    }
}
}