package jforex.strategies.oneorder;

import java.text.SimpleDateFormat;
import java.util.TimeZone;

import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;

/**
 * The strategy creates 10 market orders with SL and TP on its start.
 * In case if the order does not get closed by SL or TP within 40 seconds after
 * its fill, the order expires -> it gets closed.
 *
 */
@RequiresFullAccess
public class MarketOrderExpire implements IStrategy {

	private IConsole console;
	private IEngine engine;
	private IHistory history;

	@Configurable("")
	public Period period = Period.TEN_SECS;
	@Configurable("")
	public Instrument instrument = Instrument.EURUSD;
	@Configurable("Order expire time (in bars)")
	public int expireTimeInBars = 4;
	@Configurable("Order count")
	public int orderCount = 10;
	
	private final String label = "order";
	private SimpleDateFormat sdf;

	@Override
	public void onStart(IContext context) throws JFException {
		engine = context.getEngine();
		console = context.getConsole();
		history = context.getHistory();

		sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		sdf.setTimeZone(TimeZone.getTimeZone("GMT"));

		double price = history.getLastTick(instrument).getBid();
		print("Start");

		for (int i = 1; i < orderCount + 1; i++){
			engine.submitOrder(label + i, instrument, OrderCommand.BUY, 0.001, 0, 20, 
					price - i *instrument.getPipValue(), //SL
					price + i *instrument.getPipValue()); //TP
		}
	}

	@Override
	public void onTick(Instrument instrument, ITick tick) throws JFException {}

	@Override
	public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
		if(instrument != this.instrument || period != this.period){
			return;
		}
		//iterate through all active orders
		for(IOrder order : engine.getOrders()){
			if(order.getState() != IOrder.State.FILLED){
				continue;
			}
			long orderExpireTime = order.getFillTime() + period.getInterval() * expireTimeInBars;
			long lastBarEndTime = bidBar.getTime() + period.getInterval();
			//if order expired within the period of the last bar, then close it
			if(orderExpireTime < lastBarEndTime){
				print(order.getLabel() + " expired: " + sdf.format(orderExpireTime) + " < "+ sdf.format(lastBarEndTime));
				order.close();
			}
		}
		

	}

	@Override
	public void onMessage(IMessage message) throws JFException {}

	@Override
	public void onAccount(IAccount account) throws JFException {}

	@Override
	public void onStop() throws JFException {
		for (IOrder o : engine.getOrders())
			o.close();
	}

	private void print(Object o) {
		console.getOut().println(o);
	}

}
