package jforex;

import java.util.concurrent.TimeUnit;

import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IIndicators.AppliedPrice;
import com.dukascopy.api.IIndicators.MaType;

public class TradingByMa implements IStrategy {
	@Configurable("Instrument") public Instrument instrument = Instrument.EURUSD;
	@Configurable("Amount") public double amount = 0.25;
	@Configurable("Slippage") public double slippage = 5;
	@Configurable("Time frame") public Period timeFrame = Period.TEN_MINS;	
	@Configurable("MA1 type") public MaType ma1Type = MaType.SMA;
	@Configurable("MA1 time period") public int ma1TimePeriod = 5;	
	@Configurable("MA2 type") public MaType ma2Type = MaType.SMA;
	@Configurable("MA2 time period") public int ma2TimePeriod = 30;	
	@Configurable("MA filter") public Filter maFilter = Filter.WEEKENDS;
	@Configurable("Offer side") public OfferSide offerSide = OfferSide.ASK;
	@Configurable("Applied price") public AppliedPrice appliedPrice  = AppliedPrice.CLOSE;
	
	private IEngine engine;
	private IConsole console;
	private IHistory history;
	private IContext context;
	private IIndicators indicators;
	private IUserInterface userInterface;
	
	private IOrder order = null;
	
	public void onStart(IContext context) throws JFException {
		this.engine = context.getEngine();
		this.console = context.getConsole();
		this.history = context.getHistory();
		this.context = context;
		this.indicators = context.getIndicators();
		this.userInterface = context.getUserInterface();
	}

	public void onAccount(IAccount account) throws JFException {
	}

	public void onMessage(IMessage message) throws JFException {		
	}

	public void onStop() throws JFException {
	}

	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(this.instrument) || period != this.timeFrame) return;
		
    	long time = history.getPreviousBarStart(period, history.getLastTick(instrument).getTime());
		double ma1 = indicators.ma(instrument, this.timeFrame, this.offerSide, this.appliedPrice, this.ma1TimePeriod, this.ma1Type, this.maFilter, 1, time, 0)[0];
		double ma2 = indicators.ma(instrument, this.timeFrame, this.offerSide, this.appliedPrice, this.ma2TimePeriod, this.ma2Type, this.maFilter, 1, time, 0)[0];
				
		if (ma1 - ma2 < 0){
			if (this.order != null && order.isLong()){				
				closeOrder();									
			}
			if (this.order == null)
				submitOrder("Sell", OrderCommand.SELL, bidBar.getOpen());				
		}	
		else if(ma1 - ma2 > 0){
			if (this.order != null && !order.isLong()){				
				closeOrder();												
			}
			if (this.order == null)
				submitOrder("Buy", OrderCommand.BUY, askBar.getOpen());				
		}		
    }       
    
    private void submitOrder(String label, OrderCommand orderCmd, double price) throws JFException{
    	this.order = engine.submitOrder(label, this.instrument, orderCmd, this.amount, price, this.slippage);
    	while (this.order.getState() == IOrder.State.CREATED || this.order.getState() == IOrder.State.OPENED){
			order.waitForUpdate(2, TimeUnit.SECONDS);
		}
    	if (order.getState() == IOrder.State.CANCELED){	    				    	    		    	    	
			this.order = null;
		}
    }
    
    private void closeOrder() throws JFException{
    	if (this.order.getState() == IOrder.State.FILLED){
    		this.order.close();
    		this.order = null;
    	}
    }
}


























