

import java.awt.Color;

import com.dukascopy.api.OfferSide;
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.IntegerRangeDescription;
import com.dukascopy.api.indicators.OptInputParameterInfo;
import com.dukascopy.api.indicators.OutputParameterInfo;

/**
 * Created by: chriz aka Indiana Pips
 * Review: Mar 12, 2011
 * email: puntasabbioni/AT/gmail.com
 */

public class AskBidVolumeIndiPrice2 implements IIndicator {
    private IndicatorInfo indicatorInfo;
    private InputParameterInfo[] inputParameterInfos;
    private OptInputParameterInfo[] optInputParameterInfos;
    private OutputParameterInfo[] outputParameterInfos;

    private double[][] iBidVolumes, iAskVolumes;

    private double[][] outputs = new double[3][];
    private IIndicatorContext context;

    public void onStart(IIndicatorContext context) {
        this.context = context;
        indicatorInfo = new IndicatorInfo("AskBidVolumeIndiPrice", "Ask+Bid Volume Indi Price", "AskBid", false, false, true, 2, 0, 3);

        inputParameterInfos = new InputParameterInfo[] { new InputParameterInfo("Input data Ask", InputParameterInfo.Type.PRICE) {
            {
                setOfferSide(OfferSide.ASK);
            }
        }, new InputParameterInfo("Input data Bid", InputParameterInfo.Type.PRICE) {
            {
                setOfferSide(OfferSide.BID);
            }
        } };

        optInputParameterInfos = new OptInputParameterInfo[] { new OptInputParameterInfo("MA Period", OptInputParameterInfo.Type.OTHER,
                new IntegerRangeDescription(100, 2, 1000, 1)) };
        outputParameterInfos = new OutputParameterInfo[] {
                new OutputParameterInfo("Ask+Bid", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM) {
                    {
                        setColor(Color.BLUE);
                    }
                },
                new OutputParameterInfo("Ask Vol > Bid Vol ", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM) {
                    {
                        setColor(Color.GREEN);
                    }
                },
                new OutputParameterInfo("Bid Vol > Ask Vol ", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM) {
                    {
                        setColor(Color.RED);
                    }
                } };
    }

    public IndicatorResult calculate(int startIndex, int endIndex) {

        double currentAskVolume = 0, currentBidVolume = 0;

        if (startIndex - getLookback() < 0) {
            startIndex -= startIndex - getLookback();
        }

        if (startIndex > endIndex) {
            return new IndicatorResult(0, 0);
        }

        int i, j;

        for (i = startIndex, j = 0; i <= endIndex; i++, j++) {
            
            if(i >= iAskVolumes[4].length || i >= iBidVolumes[4].length){ //not enough data for calculation on the given candle
                continue;
            }

            //InputParameterInfo.Type.PRICE consists of 5 arrays open, close, high, low, volume -> volume is with index 4
            currentAskVolume = iAskVolumes[4][i];
            currentBidVolume = iBidVolumes[4][i];


            outputs[0][j] = (currentAskVolume + currentBidVolume);

            if (currentAskVolume >= currentBidVolume) {
                outputs[1][j] = -(currentAskVolume - currentBidVolume);
                outputs[2][j] = Double.NaN;
            } else if (currentAskVolume < currentBidVolume) {
                outputs[2][j] = -(currentBidVolume - currentAskVolume);
                outputs[1][j] = Double.NaN;
            }
        }

        return new IndicatorResult(startIndex, j);
    }

    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }

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

    public int getLookback() {
        return 5;
    }

    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) {
        switch (index) {
        case 0:
            iAskVolumes = (double[][]) array;
            break;
        case 1:
            iBidVolumes = (double[][]) array;
            break;
        default:
            throw new ArrayIndexOutOfBoundsException(" setInputParameter(). Invalid index: " + index);
        }
    }

    public void setOptInputParameter(int index, Object value) {

    }

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

    @SuppressWarnings("unused")
    private void print(String sss) {
        context.getConsole().getOut().println(sss);
    }

}