package jforex;
/* I would like to change this strategy this way : 

1° I want to take an order a week on Monday 4am at the same "BUY" and "SELL" conditions. 

2° I want that if the previous order is still opened, that the strategy take a second order on the next Monday at 4am at the same "BUY" and "SELL" conditions

Thanks for helping.

*/
import com.dukascopy.api.*;
import java.util.*;
import com.dukascopy.api.IIndicators;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IIndicators.AppliedPrice;
import com.dukascopy.api.indicators.IIndicator;
import com.dukascopy.api.IIndicators.MaType;

public class EMA_STRATEGY_Modified implements IStrategy {
    
    private IContext context = null;
    private IEngine engine = null;
    private IChart chart = null;
    private IHistory history = null;
    private IIndicators indicators = null;
    private IConsole console = null;
    private IOrder order;
    private int counter = 0;
     
    private double amount = 0.0;
    public int takeProfitPips = 70;
    public int stopLossPips = 35;
    
    public Instrument instrument = Instrument.EURUSD;    
    public Period selectedPeriod = Period.THIRTY_MINS;   
    public Period selectedPeriodma = Period.THIRTY_MINS;  
    public OfferSide offerSide = OfferSide.BID;
    public AppliedPrice appliedPrice = AppliedPrice.CLOSE;
    public int ma1TimePeriod = 120; 
    public MaType ma1Type = MaType.EMA;
        
  
    public void onStart(IContext context) throws JFException {
         Set subscribedInstruments = new HashSet();
         subscribedInstruments.add(Instrument.EURUSD);
         context.setSubscribedInstruments(subscribedInstruments);
        this.context = context;  
        engine = context.getEngine();
        indicators = context.getIndicators();
        history = context.getHistory();
        console = context.getConsole();
        indicators = context.getIndicators();     
    }

    public void onStop() throws JFException {
    }

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

 
  // indicators                
        double emaprev = indicators.ma(this.instrument,this.selectedPeriodma,this.offerSide,this.appliedPrice,this.ma1TimePeriod,this.ma1Type,4);
        double ema = indicators.ma(this.instrument,this.selectedPeriodma,this.offerSide,this.appliedPrice,this.ma1TimePeriod,this.ma1Type,2);
        double emanext = indicators.ma(this.instrument,this.selectedPeriodma,this.offerSide,this.appliedPrice,this.ma1TimePeriod,this.ma1Type,0);
        

           
         //size lots
   
       amount = 0.02;

        //========================================================================================================================
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));        //time GMT
        calendar.setTimeInMillis(tick.getTime());                                        
        Date datetime = calendar.getTime();            
        
       
        //------------------------------------------------------------------------
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);        //1 is Sunday
        int hour = calendar.get(Calendar.HOUR_OF_DAY);             //from 0 to 23
        int minute = calendar.get(Calendar.MINUTE);

                
        boolean timeToEntry = dayOfWeek == 2 && hour == 4 && minute ==0 ;
        //========================================================================================================================

                                    
        if (positionsTotal(instrument) == 0) {
            if (emaprev < ema && ema < emanext && timeToEntry) {
                closeOrder(order);
                order = submitOrder(OrderCommand.BUY);
            }
            if (emaprev > ema && ema > emanext && timeToEntry) {
                closeOrder(order);
                order = submitOrder(OrderCommand.SELL);
            }
        }
                 

    }

    // counted opened positions 
    protected int positionsTotal(Instrument instrument) throws JFException {
        int counter = 0;
        for (IOrder order : engine.getOrders(instrument)) {
            if (order.getState() == IOrder.State.FILLED) {
                counter++;
            }
        }
        return counter;
    }



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

 
  // indicators                
        double emaprev = indicators.ma(this.instrument,this.selectedPeriodma,this.offerSide,this.appliedPrice,this.ma1TimePeriod,this.ma1Type,4);
        double ema = indicators.ma(this.instrument,this.selectedPeriodma,this.offerSide,this.appliedPrice,this.ma1TimePeriod,this.ma1Type,2);
        double emanext = indicators.ma(this.instrument,this.selectedPeriodma,this.offerSide,this.appliedPrice,this.ma1TimePeriod,this.ma1Type,0);
        

           
         //size lots
   
       amount = 0.02;

        //========================================================================================================================
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));        //time GMT
        calendar.setTimeInMillis(bidBar.getTime());                                        
        Date datetime = calendar.getTime();            
        
       
        //------------------------------------------------------------------------
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);        //1 is Sunday
        int hour = calendar.get(Calendar.HOUR_OF_DAY);             //from 0 to 23
        int minute = calendar.get(Calendar.MINUTE);


        boolean timeToEntry = dayOfWeek == 1 && hour == 4 && minute ==0 ;
        //========================================================================================================================

                                    
        if (positionsTotal(instrument) == 0) {
//        if (emaprev < ema && ema < emanext && timeToEntry) {
            if (timeToEntry) {

                closeOrder(order);
                order = submitOrder(OrderCommand.BUY);
            }
            if (emaprev > ema && ema > emanext && timeToEntry) {

                closeOrder(order);
                order = submitOrder(OrderCommand.SELL);
            }
        }
*/  
  
  }
    

  public void onMessage(IMessage message) throws JFException {
        
        if (message != null && message.getType() == IMessage.Type.ORDER_CLOSE_OK) {
            
            IOrder lastOne = message.getOrder();
            
            double profitsLoss = lastOne.getProfitLossInPips();
            
            console.getOut().println("Order : "+lastOne.getLabel()+ " "+ lastOne.getOrderCommand()+ " Pips: "+profitsLoss);
            
           
        }
}
 
     public void onAccount(IAccount account) throws JFException {


   }

      private IOrder submitOrder(OrderCommand orderCmd) throws JFException {

        double stopLossPrice, takeProfitPrice;

        // Calculating order price, stop loss and take profit prices
        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), instrument, orderCmd, amount, 0, 20, stopLossPrice, takeProfitPrice);
    }

    private void closeOrder(IOrder order) throws JFException {
        if (order == null) {
            return;
        }
        if (order.getState() != IOrder.State.CLOSED && order.getState() != IOrder.State.CREATED && order.getState() != IOrder.State.CANCELED) {
            order.close();
            order = null;
        }
    }

    private double getPipPrice(int pips) {
        return pips * this.instrument.getPipValue();
    }

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