import java.util.HashSet;
import java.util.Set;
import com.dukascopy.api.IConsole;
import com.dukascopy.api.Configurable;
import com.dukascopy.api.Filter;
import com.dukascopy.api.IAccount;
import com.dukascopy.api.IBar;
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.IIndicators;
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.OfferSide;
import com.dukascopy.api.Period;

public class Darkbull_EU2 implements IStrategy {

    private IEngine engine;
    private IHistory history;
    private IIndicators indicators;
    private int counter = 1;
    private IConsole console;

    @Configurable("Instrument")
    public Instrument instrument = Instrument.EURUSD;

    @Configurable("Select Period")
    public Period selectedPeriod = Period.FIFTEEN_MINS;

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

    @Configurable("Stop Loss")
    public int stopLossPips = 0;

    @Configurable("Take profit")
    public int takeProfitPips = 0;

    @Configurable("BASE")
    public double base = 1;

    @Configurable("Indicator Filter")
    public Filter indicatorFilter = Filter.NO_FILTER;

    public void onStart(IContext context) throws JFException {

        this.console = context.getConsole();
        this.engine = context.getEngine();
        this.history = context.getHistory();
        this.indicators = context.getIndicators();
        Set<Instrument> subscribedInstruments = new HashSet<Instrument>();
        subscribedInstruments.add(instrument);
        context.setSubscribedInstruments(subscribedInstruments);
    }

    public void onAccount(IAccount account) throws JFException {
    }

    public void onMessage(IMessage message) throws JFException {
        print(message);
        if (message.getType().equals(IMessage.Type.ORDER_CLOSE_OK)) {
            IOrder order = message.getOrder();
            if (order.getProfitLossInAccountCurrency() < 0)
            {amount = 0.01;}}

    }

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

    public void onStop() throws JFException {

        // close all orders

        for (IOrder order : engine.getOrders()) {

            engine.getOrder(order.getLabel()).close();

        }

    }

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

    }

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

        if (!instrument.equals(instrument) || !period.equals(selectedPeriod))

            return;

        IBar prevBar = history.getBar(instrument, selectedPeriod, OfferSide.BID, 1);

        double oc = bidBar.getOpen() - bidBar.getClose();

        double co = bidBar.getClose() - bidBar.getOpen();

        @SuppressWarnings("unused")
        double hc = bidBar.getHigh() - bidBar.getClose();

        @SuppressWarnings("unused")
        double cl = bidBar.getClose() - bidBar.getLow();

        double[] atr1 = indicators.atr(instrument, selectedPeriod, OfferSide.BID, 13, indicatorFilter, 12,
                prevBar.getTime(), 1);

        // SMA crossed previous green candle

        if (co > base * atr1[5]) {

            submitOrder(OrderCommand.BUY);

        }

        // SMA crossed previous red candle

        if (oc > base * atr1[5]) {

            submitOrder(OrderCommand.SELL);

        }

    }

    private IOrder submitOrder(OrderCommand orderCmd) throws JFException {

        double stopLossPrice = 0, takeProfitPrice = 0;

        // Calculating stop loss and take profit prices

        if (orderCmd == OrderCommand.BUY) {

            if (stopLossPips > 0) {
                stopLossPrice = history.getLastTick(this.instrument).getBid() - getPipPrice(this.stopLossPips);
            }
            if (takeProfitPips > 0) {
                takeProfitPrice = history.getLastTick(this.instrument).getBid() + getPipPrice(this.takeProfitPips);
            }

        } else if (orderCmd == OrderCommand.SELL) {
            if (stopLossPips > 0) {
                stopLossPrice = history.getLastTick(this.instrument).getAsk() + getPipPrice(this.stopLossPips);
            }
            if (takeProfitPips > 0) {
                takeProfitPrice = history.getLastTick(this.instrument).getAsk() - getPipPrice(this.takeProfitPips);
            }

        }

        // Submitting an order for the specified instrument at the current market price

        return engine.submitOrder(getLabel(instrument), this.instrument, orderCmd, this.amount, 0, 20, stopLossPrice,
                takeProfitPrice);

    }

    protected String getLabel(Instrument instrument) {

        String label = instrument.name();

        label = label + (counter++);

        label = label.toUpperCase();

        return label;

    }

    private double getPipPrice(int pips) {

        return pips * this.instrument.getPipValue();

    }

}
