import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IIndicators.AppliedPrice;
import java.util.List;
import com.dukascopy.api.util.*;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

import com.dukascopy.api.indicators.IIndicator;
import java.math.BigDecimal;
import java.math.RoundingMode;

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.IHistory;
import com.dukascopy.api.IMessage;
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;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IMessage.Type;

public class SMASimpleStrategymodify3 implements IStrategy {
        private IEngine engine;
        private IHistory history;
        private IConsole console;
        private IIndicators indicators;
        private int counter = 0;
        private IOrder order;

        @Configurable("Instrument")
        public Instrument instrument = Instrument.EURUSD;
        @Configurable("Period")
        public Period selectedPeriod = Period.FIFTEEN_MINS;
        @Configurable("SMA filter")
        public Filter indicatorFilter = Filter.NO_FILTER;
        @Configurable("Amount")
        public double amount = 0.02;
        @Configurable("Stop loss")
        public int stopLossPips = 10;
        @Configurable("Take profit")
        public int takeProfitPips = 90;

        public void onStart(IContext context) throws JFException {
                this.engine = context.getEngine();
                this.history = context.getHistory();
                this.console = context.getConsole(); 
                this.indicators = context.getIndicators();
        }

        public void onAccount(IAccount account) throws JFException {
        }

         public void onMessage(IMessage message) throws JFException {
        if (message.getType() == IMessage.Type.ORDER_CLOSE_OK)
        {
        IOrder lastorderclosed = message.getOrder();
    }
    }

        public void onStop() throws JFException {
            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.EURUSD) || !period.equals(Period.FIFTEEN_MINS))
                        return;

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

                int smaTimePeriod = 50;
                int candlesBefore = 2;
                int candlesAfter = 0;

                double sma = indicators.sma(instrument, selectedPeriod, OfferSide.BID, AppliedPrice.CLOSE, smaTimePeriod, indicatorFilter,
                                candlesBefore, prevBar.getTime(), candlesAfter)[0];
                
                ITick tick1 = history.getLastTick(instrument);     
        
        if (lastorderclosed.getOrderCommand() == OrderCommand.BUY && tick1.getBid() > lastorderclosed.getOpenPrice() && prevBar.getOpen() < sma && prevBar.getClose() > sma && order == null){
                order = submitOrder(OrderCommand.BUY);
                }
    
        if (lastorderclosed.getOrderCommand() == OrderCommand.SELL && tick1.getBid() < lastorderclosed.getOpenPrice() && prevBar.getOpen() > sma && prevBar.getClose() < sma && order == null){
                order = submitOrder(OrderCommand.SELL);
                }
              
        if (prevBar.getOpen() < sma && prevBar.getClose() > sma) {
                        submitOrder(OrderCommand.BUY);
                }

        if (prevBar.getOpen() > sma && prevBar.getClose() < sma) {
                        submitOrder(OrderCommand.SELL);
                }  
                                 
        }

        private IOrder submitOrder(OrderCommand orderCmd) throws JFException {

                double stopLossPrice, takeProfitPrice;

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

                return engine.submitOrder(getLabel(instrument), this.instrument, orderCmd, this.amount, 0, 20, stopLossPrice, takeProfitPrice);
        }
        
        private void closeOrder(IOrder order) throws JFException {
        if (order != null && isActive(order)) {
            order.close();
        }
    }
    
    private boolean isActive(IOrder order) throws JFException {
        if (order != null && order.getState() != IOrder.State.CLOSED && order.getState() != IOrder.State.CANCELED) {
            return true;
        }
        return false;
    }
        
        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();
        }
}