package jforex.feed.test;

import java.util.Arrays;
import java.util.HashSet;

import com.dukascopy.api.*;
import com.dukascopy.api.IIndicators.AppliedPrice;
import com.dukascopy.api.drawings.IOhlcChartObject;
import com.dukascopy.api.feed.*;
import com.dukascopy.api.feed.util.*;

public class FeedSmaOnTickTickBarRangeBar implements IStrategy {

    private IConsole console;
    private IIndicators indicators;
    private IHistory history;

    @Configurable("Feed data count for indicator calculation")
    public int dataCount = 5;
    @Configurable("")
    public int smaPeriod = 10;

    @Configurable("feed type")
    public MyFeeds feed = MyFeeds.RANGE_BARS_2;
    @Configurable("open chart")
    public boolean openChart = false;    


    enum MyFeeds {
        RANGE_BARS_2(new RangeBarFeedDescriptor(Instrument.EURUSD, PriceRange.TWO_PIPS, OfferSide.ASK)),
        TICK_BARS_20(new TickBarFeedDescriptor(Instrument.EURUSD, TickBarSize.valueOf(20), OfferSide.ASK));

        private final IFeedDescriptor feedDescriptor;

        MyFeeds(IFeedDescriptor feedDescriptor) {
            this.feedDescriptor = feedDescriptor;
        }

        public IFeedDescriptor getFeedDescriptor() {
            return feedDescriptor;
        }
    }   
    
    private IChart chart;

    @Override
    public void onStart(IContext context) throws JFException {

        console = context.getConsole();
        indicators = context.getIndicators();
        history = context.getHistory();

        IFeedDescriptor feedDescriptor = feed.getFeedDescriptor();
        context.setSubscribedInstruments(new HashSet<Instrument>(Arrays.asList(new Instrument[] { feedDescriptor.getInstrument() })), true);

        if (openChart) {
            chart = context.openChart(feedDescriptor);
            chart.add(indicators.getIndicator("SMA"), new Object[] { smaPeriod });
            IOhlcChartObject ohlc = null;
            for (IChartObject obj : chart.getAll()) {
                if (obj instanceof IOhlcChartObject) {
                    ohlc = (IOhlcChartObject) obj;
                }
            }
            if(ohlc == null){
                ohlc = chart.getChartObjectFactory().createOhlcInformer();
                chart.add(ohlc);
            }
            
            ohlc.setShowIndicatorInfo(true);
                        
        }
        
        print("subscribe to feed=" + feedDescriptor);
        context.subscribeToFeed(feedDescriptor, new IFeedListener() {
            @Override
            public void onFeedData(IFeedDescriptor feedDescriptor, ITimedData feedData) {
                console.getInfo().println("completed " + feedData + " of feed: " + feedDescriptor);
            }
        });

    }
    
    @Override
    public void onTick(Instrument instrument, ITick tick) throws JFException {        
        if(instrument != feed.getFeedDescriptor().getInstrument()){
            return;
        }
        
        ITimedData feedData = history.getFeedData(feed.getFeedDescriptor(), 0); 
        if(feed.getFeedDescriptor().getDataType() == DataType.TICK_BAR && feedData == null){
            //There are 0 ticks in the current tick bar, take the previously finished bar
            feedData = history.getFeedData(feed.getFeedDescriptor(), 1); 
        }
        // calculate SMA for the last 3 feed data
        Object[] macdFeed = indicators.calculateIndicator(feed.getFeedDescriptor(), new OfferSide[] { feed.getFeedDescriptor().getOfferSide() }, "SMA",
                new AppliedPrice[] { AppliedPrice.CLOSE }, new Object[] { smaPeriod },
                dataCount, feedData.getTime(), 0);
        double[] sma =(double[]) macdFeed[0];
        print("sma calculation on feed" + arrayToString(sma));
        print("last bar value: %.5f", sma[dataCount-1]);

    }
    
    private void print(String format, Object... args) {
        print(String.format(format, args));
    }

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

    private static String arrayToString(double[] arr) {
        String str = "";
        for (int r = 0; r < arr.length; r++) {
            str += String.format("[%s] %.5f; ", r, arr[r]);
        }
        return str;
    }

    @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 onAccount(IAccount account) throws JFException {
    }

    @Override
    public void onStop() throws JFException {}

}
