import com.dukascopy.api.Configurable;
import com.dukascopy.api.IAccount;
import com.dukascopy.api.IBar;
import com.dukascopy.api.IConsole;
import com.dukascopy.api.IContext;
import com.dukascopy.api.IEngine;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IHistory;
import com.dukascopy.api.IMessage;
import com.dukascopy.api.IOrder;
import com.dukascopy.api.IStrategy;
import com.dukascopy.api.ITick;
import com.dukascopy.api.Instrument;
import com.dukascopy.api.JFException;
import com.dukascopy.api.Period;

public class Tobogan_11_Instruments implements IStrategy {

    // AUDJPY AUDUSD CADJPY EURGBP EURJPY EURUSD GBPUSD NZDJPY NZDUSD USDCAD USDJPY
    
    public int tradesTotalBUY(Instrument XXX) throws JFException {
        int counter1 = 0;
        for (IOrder ORD : engine.getOrders(XXX)) {
            if (ORD.getState() == IOrder.State.FILLED && ORD.isLong()) {
                counter1++;
            }
        }
        return counter1;
    }

    public int tradesTotalSELL(Instrument XXX) throws JFException {
        int counter2 = 0;
        for (IOrder ORD : engine.getOrders(XXX)) {
            if (ORD.getState() == IOrder.State.FILLED && !ORD.isLong()) {
                counter2++;
            }
        }
        return counter2;
    }

    
    
    private IEngine engine;
    private IConsole console;
    private int counter = 0;
    private IHistory history;
    private ITick previousTick = null;
    private String string = "";
    public Period selectedPeriod = Period.TEN_MINS;

// AUDJPY AUDUSD CADJPY EURGBP EURJPY EURUSD GBPUSD NZDJPY NZDUSD USDCAD USDJPY
    public Instrument instrument = Instrument.EURUSD;
    
    public Instrument AUDJPY = Instrument.AUDJPY; // 1
    public Instrument AUDUSD = Instrument.AUDUSD; // 2
    public Instrument CADJPY = Instrument.CADJPY; // 3
    public Instrument EURGBP = Instrument.EURGBP; // 4
    public Instrument EURJPY = Instrument.EURJPY; // 5
    public Instrument EURUSD = Instrument.EURUSD; // 6
    public Instrument GBPUSD = Instrument.GBPUSD; // 7
    public Instrument NZDJPY = Instrument.NZDJPY; // 8
    public Instrument NZDUSD = Instrument.NZDUSD; // 9
    public Instrument USDCAD = Instrument.USDCAD; // 10
    public Instrument USDJPY = Instrument.USDJPY; // 11

    @Configurable("Step pips")
    public double step = 20;

    @Configurable("Slippage")
    public double slippage = 2;

    @Configurable("Amount")
    public double amount = 0.1;

    @Configurable("Stop Loss Pips")
    public int slPips = 100;
    
    @Configurable("Take Profit Pips")
    public int takeProfitPips = 10;

    
    
    @Override
    public void onStart(IContext context) throws JFException {
        this.console = context.getConsole();
        this.engine = context.getEngine();
        this.setHistory(context.getHistory());

    }

    @Override
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
        if (period != this.selectedPeriod || instrument != this.instrument) {
            return;
        }
    }

    public void onTick(Instrument instrument, ITick tick) throws JFException {
        if (instrument != this.instrument) {
            return;
        }

        if (previousTick == null) {
            previousTick = tick;
            return;
        }

        if (tick.getBid() >= previousTick.getBid() + instrument.getPipValue()*(step)) {
            
            if (tradesTotalSELL(AUDJPY) == 0) {string = "SELL_"+AUDJPY;submitOrder(OrderCommand.SELL, AUDJPY);}
            if (tradesTotalSELL(AUDUSD) == 0) {string = "SELL_"+AUDUSD;submitOrder(OrderCommand.SELL, AUDUSD);}
            if (tradesTotalSELL(CADJPY) == 0) {string = "SELL_"+CADJPY;submitOrder(OrderCommand.SELL, CADJPY);}
            if (tradesTotalSELL(EURGBP) == 0) {string = "SELL_"+EURGBP;submitOrder(OrderCommand.SELL, EURGBP);}
            if (tradesTotalSELL(EURJPY) == 0) {string = "SELL_"+EURJPY;submitOrder(OrderCommand.SELL, EURJPY);}
            if (tradesTotalSELL(EURUSD) == 0) {string = "SELL_"+EURUSD;submitOrder(OrderCommand.SELL, EURUSD);}
            if (tradesTotalSELL(GBPUSD) == 0) {string = "SELL_"+GBPUSD;submitOrder(OrderCommand.SELL, GBPUSD);}
            if (tradesTotalSELL(NZDJPY) == 0) {string = "SELL_"+NZDJPY;submitOrder(OrderCommand.SELL, NZDJPY);}
            if (tradesTotalSELL(NZDUSD) == 0) {string = "SELL_"+NZDUSD;submitOrder(OrderCommand.SELL, NZDUSD);}
            if (tradesTotalSELL(USDCAD) == 0) {string = "SELL_"+USDCAD;submitOrder(OrderCommand.SELL, USDCAD);}
            if (tradesTotalSELL(USDJPY) == 0) {string = "SELL_"+USDJPY;submitOrder(OrderCommand.SELL, USDJPY);}
               
                previousTick = tick;
                
        } 
        
        else if (tick.getAsk() <= previousTick.getAsk() - instrument.getPipValue()*(step)) {

            if (tradesTotalBUY(AUDJPY) == 0) {string = "BUY_"+AUDJPY;submitOrder(OrderCommand.BUY, AUDJPY);}
            if (tradesTotalBUY(AUDUSD) == 0) {string = "BUY_"+AUDUSD;submitOrder(OrderCommand.BUY, AUDUSD);}
            if (tradesTotalBUY(CADJPY) == 0) {string = "BUY_"+CADJPY;submitOrder(OrderCommand.BUY, CADJPY);}
            if (tradesTotalBUY(EURGBP) == 0) {string = "BUY_"+EURGBP;submitOrder(OrderCommand.BUY, EURGBP);}
            if (tradesTotalBUY(EURJPY) == 0) {string = "BUY_"+EURJPY;submitOrder(OrderCommand.BUY, EURJPY);}
            if (tradesTotalBUY(EURUSD) == 0) {string = "BUY_"+EURUSD;submitOrder(OrderCommand.BUY, EURUSD);}
            if (tradesTotalBUY(GBPUSD) == 0) {string = "BUY_"+GBPUSD;submitOrder(OrderCommand.BUY, GBPUSD);}
            if (tradesTotalBUY(NZDJPY) == 0) {string = "BUY_"+NZDJPY;submitOrder(OrderCommand.BUY, NZDJPY);}
            if (tradesTotalBUY(NZDUSD) == 0) {string = "BUY_"+NZDUSD;submitOrder(OrderCommand.BUY, NZDUSD);}
            if (tradesTotalBUY(USDCAD) == 0) {string = "BUY_"+USDCAD;submitOrder(OrderCommand.BUY, USDCAD);}
            if (tradesTotalBUY(USDJPY) == 0) {string = "BUY_"+USDJPY;submitOrder(OrderCommand.BUY, USDJPY);}
               
                previousTick = tick;
        }
    }


    private String getLabel(Instrument instrument) {
        String label = instrument.name();
        label = label + (counter++);
        label = label.toUpperCase();
        return label;
    }

    public void onMessage(IMessage message) throws JFException {
        print(message);
    }

    public void onStop() throws JFException {
    }

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

    public IHistory getHistory() {
        return history;
    }

    public void setHistory(IHistory history) {
        this.history = history;
    }

    private IOrder submitOrder(OrderCommand orderCmd, Instrument instrument) throws JFException {
        double stopLossPrice = 0.0, takeProfitPrice = 0.0;
        if (orderCmd == OrderCommand.BUY) {
            if (slPips > 0) {
                stopLossPrice = history.getLastTick(instrument).getBid() - instrument.getPipValue()*(slPips);
            }
            if (takeProfitPips > 0) {
                takeProfitPrice = history.getLastTick(instrument).getBid() + instrument.getPipValue()*(takeProfitPips);
            }
        } else if (orderCmd == OrderCommand.SELL) {
            if (slPips > 0) {
                stopLossPrice = history.getLastTick(instrument).getBid() + instrument.getPipValue()*(slPips);
            }
            if (takeProfitPips > 0) {
                takeProfitPrice = history.getLastTick(instrument).getBid() - instrument.getPipValue()*(takeProfitPips);
            }
        }

        return engine.submitOrder(getLabel(instrument), instrument, orderCmd, amount, 0, slippage, stopLossPrice,takeProfitPrice,0,string);
    }
    public void onAccount(IAccount account) throws JFException {
}
}