package singlejartest;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;

import java.util.TimeZone;
import java.util.logging.Level;
import java.util.logging.Logger;


import com.dukascopy.api.*;
import com.dukascopy.api.IIndicators.AppliedPrice;
import com.dukascopy.api.feed.FeedDescriptor;
import com.dukascopy.api.feed.IRenkoBar;
import com.dukascopy.api.feed.IRenkoBarFeedListener;
import com.dukascopy.api.IIndicators.MaType;




public class RenkoMAOutByOne implements IStrategy, IRenkoBarFeedListener {

    private IConsole console;
    private IIndicators indicators;
    

    private FeedDescriptor feedDescriptor;
    
    private static int LAST = 2;
    private static int PREV = 1;
    private static int SCND_TO_LAST = 0;
    
    private SimpleDateFormat gmtSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
    public Instrument instrument = Instrument.AUDUSD;
    public int renkoRange = 2;
    public int maPeriod = 5;
    public MaType maType = MaType.EMA;
    public Instrument selectedInstr = Instrument.AUDUSD;  
    public OfferSide offerSide = OfferSide.BID;
    public Filter filter = Filter.ALL_FLATS;
    public AppliedPrice appliedPrice = AppliedPrice.CLOSE; 
    private Object[] maOptInputs;
    
    @Override
    public void onStart(IContext context) throws JFException {
        this.console = context.getConsole();
        this.indicators = context.getIndicators();
        this.

        feedDescriptor = new FeedDescriptor();
        feedDescriptor.setDataType(DataType.RENKO);
        feedDescriptor.setOfferSide(offerSide);
        feedDescriptor.setInstrument(instrument);
        feedDescriptor.setPriceRange(PriceRange.valueOf(renkoRange));
        feedDescriptor.setFilter(filter);

        maOptInputs = new Object[] {maPeriod, maType.ordinal()};
        
        context.subscribeToRenkoBarFeed(instrument, offerSide, PriceRange.valueOf(renkoRange), this);
    }

    // on RENKO bars, calculate indicator and execute alerts and orders on crossover or trend change
    
    @Override
    public void onBar(Instrument instrument, OfferSide offerSide, PriceRange priceRange, IRenkoBar bar) {
        try {

            int candlesBefore = 3;
            int candlesAfter = 0;
            
            double[] maOutput = (double[]) indicators.calculateIndicator(
                    feedDescriptor,
                    new OfferSide[]{OfferSide.BID},
                    "MA",
                    new AppliedPrice[]{AppliedPrice.CLOSE},
                    maOptInputs,
                    candlesBefore, //  3 for trend change 
                    bar.getTime(), 
                    candlesAfter) 
                    [0];
                    

            // Print indicator outputs 
            print(String.format("%s print: last - %.5f, previous - %.5f; 2nd last - %.5f",
            gmtSdf.format(bar.getTime()), maOutput[LAST], maOutput[PREV], maOutput[SCND_TO_LAST]));
            
                    
                  // If indicator trend changes upwards  
                  if  (maOutput[PREV] < maOutput[SCND_TO_LAST] && maOutput[LAST] > maOutput[PREV]) {
                	  
                        System.out.println();
                    	print(String.format("%s up   : last - %.5f, previous - %.5f; 2nd last - %.5f",
                                gmtSdf.format(bar.getTime()), maOutput[LAST], maOutput[PREV], maOutput[SCND_TO_LAST]));
                    	System.out.println();

                  }
                  
                  
                  // If indicator trend changes downwards
                  if (maOutput[PREV] > maOutput[SCND_TO_LAST] && maOutput[LAST] < maOutput[PREV]) {
                      
                	  System.out.println();
                	  print(String.format("%s down : last - %.5f, previous - %.5f; 2nd last - %.5f",
                              gmtSdf.format(bar.getTime()), maOutput[LAST], maOutput[PREV], maOutput[SCND_TO_LAST]));
                	  System.out.println();
                  }  
                    
                    
                  
        } catch (JFException ex) {
            Logger.getLogger(RenkoMAOutByOne.class.getName()).log(Level.SEVERE, null, ex);
        }
    }



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

    @Override
    public void onTick(Instrument instrument, ITick tick) throws JFException {
    }

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

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

    @Override
    public void onStop() throws JFException {
    }

    /**************** debug print functions ***********************/
    private void print(Object... o) {
        for (Object ob : o) {
            //console.getOut().print(ob + "  ");
            if (ob instanceof Double) {
                print2(toStr((Double) ob));
            } else if (ob instanceof double[]) {
                print((double[]) ob);
            } else if (ob instanceof double[]) {
                print((double[][]) ob);
            } else if (ob instanceof Long) {
                print2(toStr((Long) ob));
            } else if (ob instanceof IBar) {
                print2(toStr((IBar) ob));
            } else {
                print2(ob);
            }
            print2(" ");
        }
        console.getOut().println();
    }

    private void print(Object o) {
        console.getOut().println(o);
    }

    private void print2(Object o) {
        console.getOut().print(o);
    }



    private void print(double[] arr) {
        print(toStr(arr));
    }

    private void print(double[][] arr) {
        print(toStr(arr));
    }

    public static String toStr(double[] arr) {
        String str = "";
        for (int r = 0; r < arr.length; r++) {
            str += "[" + r + "] " + (new DecimalFormat("#.#######")).format(arr[r]) + "; ";
        }
        return str;
    }

    public static String toStr(double[][] arr) {
        String str = "";
        if (arr == null) {
            return "null";
        }
        for (int r = 0; r < arr.length; r++) {
            for (int c = 0; c < arr[r].length; c++) {
                str += "[" + r + "][" + c + "] " + (new DecimalFormat("#.#######")).format(arr[r][c]);
            }
            str += "; ";
        }
        return str;
    }

    public String toStr(double d) {
        return (new DecimalFormat("#.#######")).format(d);
    }

    public String toStr(Long time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") {

            {
                setTimeZone(TimeZone.getTimeZone("GMT"));
            }
        };
        return sdf.format(time);
    }

    private String toStr(IBar bar) {
        return toStr(bar.getTime()) + "  O:" + bar.getOpen() + " C:" + bar.getClose() + " H:" + bar.getHigh() + " L:" + bar.getLow();
    }


}

    
    
