package jforex.requests;
 
import com.dukascopy.api.Configurable;
import java.util.*;
import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IIndicators.AppliedPrice;
 
public class Fly2 implements IStrategy {
    private IEngine engine;
    private IIndicators indicators;
    private IConsole console;
    private IHistory history;
    private int counter = 0;
    private IOrder activeOrder;
    // this strategy works well with EURUSD, so only this pair is traded
    public Instrument selectedInstrument = Instrument.EURUSD;
    // the UT choosed may be changed, but in this cased, the TP and SL must be changed
    public Period selectedPeriod = Period.ONE_HOUR;
    @Configurable("Amount")
    public double theAmount = 0.01;
    // these SL and TP are not used
    public int StopLoss = 50;
    public int TakeProfit = 100;
    // these SL and TP must be backtested in demo mode
    @Configurable("Take profit pips")
    public double MyTakeProfit = 100;
    @Configurable("Stoploss pips")
    public double MyStopLoss = 50;
    // max slippage*/
    @Configurable("Slippage")
    public double slippage = 2;
    @Configurable("EntryGap")
    public int EntryGAP = 2;
    // the RSI is calculated with 14 periods
    @Configurable("RSiN")
    public int RSiN = 14;
    // RSI values. Must be backtested evry month
    @Configurable("UPBnd")
    public double UPBnd = 56d;
    @Configurable("DOWNBnd")
    public double DOWNBnd = 56d;
    private Filter indicatorFilter = Filter.NO_FILTER;
    private double BUYprice = 0.0;
    private double BUYprice1 = 0.0;
    private double SELLprice = 0.0;
    private double SELLprice1 = 0.0;
    // 2 RSI are calculated
    private double[] RSi1;
    private double[] RSi2;
    int selctedPeriod = 0;
     
    @Override
    public void onStart(IContext context) throws JFException {
        String stoploss = "Fly" + Fly2.class.getName()
                + "Flymar";
        Scanner s = new Scanner(stoploss);
        while (s.hasNext()) {
            String selctedInstrument = s.next();
            if (selctedInstrument == null)
                return;
            for (int i = 0; i < selctedInstrument.length(); i++) {
                if (Character.isLetter(selctedInstrument.charAt(i)))
                    selctedPeriod++;
            }
        }
        engine = context.getEngine();
        indicators = context.getIndicators();
        console = context.getConsole();
        history = context.getHistory();
        context.getAccount();
        Set<Instrument> subscribedInstruments = new HashSet<Instrument>();
        subscribedInstruments.add(Instrument.EURUSD);
        context.setSubscribedInstruments(subscribedInstruments);
    }
 
    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(selectedInstrument)) {
            return;
        }
        IBar prevBar = history.getBar(instrument, selectedPeriod,
                OfferSide.BID, 1);
        IBar prevBar1 = history.getBar(instrument, selectedPeriod,
                OfferSide.BID, 2);
        IBar prevBar2 = history.getBar(instrument, selectedPeriod,
                OfferSide.BID, 3);
        RSi1 = indicators.rsi(instrument, selectedPeriod, OfferSide.BID,
                AppliedPrice.CLOSE, RSiN, indicatorFilter, 2,
                prevBar.getTime(), 0);
        RSi2 = indicators.rsi(instrument, selectedPeriod, OfferSide.BID,
                AppliedPrice.CLOSE, RSiN, indicatorFilter, 2,
                prevBar1.getTime(), 0);
        double LOTs = theAmount;
        if (LOTs > 0.01) {
            LOTs = 0.01;
        }
        double askPrice = askbar.getClose();
        double bidPrice = bidbar.getClose();
        IEngine.OrderCommand OrderOp;
        if (engine.getOrders().contains(activeOrder)) {
            if (BUYprice > 0.0 && askPrice > BUYprice) {
                activeOrder.setStopLossPrice(bidPrice
                        - (EntryGAP * instrument.getPipValue()));
            }
            if (SELLprice > 0.0 && bidPrice < SELLprice) {
                activeOrder.setStopLossPrice(askPrice
                        + (EntryGAP * instrument.getPipValue()));
            }
        }
        if (instrument.equals(Instrument.EURUSD)
                && period.equals(selectedPeriod)) {
            if (engine.getOrders().contains(activeOrder)) {
                if (BUYprice > 0.0 && askPrice < BUYprice1) {
                    activeOrder.setStopLossPrice(askPrice
                            - (EntryGAP * instrument.getPipValue()));
                    BUYprice1 = bidPrice
                            - (MyStopLoss * instrument.getPipValue());
                }
                if (SELLprice > 0.0 && askPrice > SELLprice1) {
                    activeOrder.setStopLossPrice(askPrice
                            + (EntryGAP * instrument.getPipValue()));
                    SELLprice1 = bidPrice
                            + (MyStopLoss * instrument.getPipValue());
                }
            }
            /* conditions of entrys*/
            if (selctedPeriod == 33) {
                if (!engine.getOrders().contains(activeOrder) && RSi1[1] > UPBnd
                        && bidPrice < prevBar2.getClose() 
                        ||  engine.getOrders().contains(activeOrder) && RSi2[1] < DOWNBnd
                        && RSi1[1] > DOWNBnd ) {
                    OrderOp = OrderCommand.BUY;
                    SELLprice = 0.0;
                    BUYprice1 = bidPrice
                            - (MyStopLoss * instrument.getPipValue());
                    SELLprice1 = 0.0;
                    BUYprice = askPrice
                            + (MyTakeProfit * instrument.getPipValue());
                    activeOrder = engine.submitOrder(
                            getLabel(instrument),
                            instrument,
                            OrderOp,
                            LOTs,
                            0,
                            slippage,
                            prevBar.getClose()
                                    + (EntryGAP * instrument.getPipValue())
                                    - (StopLoss * instrument.getPipValue()),
                            prevBar.getClose()
                                    + (EntryGAP * instrument.getPipValue())
                                    + (TakeProfit * instrument.getPipValue()));
                }
                if (!engine.getOrders().contains(activeOrder) && RSi1[1] < DOWNBnd
                        && askPrice > prevBar2.getClose()
                        || !engine.getOrders().contains(activeOrder) && RSi2[1] > UPBnd
                        && RSi1[1] < UPBnd) {
                    OrderOp = OrderCommand.SELL;
                    BUYprice = 0.0;
                    SELLprice1 = bidPrice
                            + (MyStopLoss * instrument.getPipValue());
                    BUYprice1 = 0.0;
                    SELLprice = bidPrice
                            - (MyTakeProfit * instrument.getPipValue());
                    activeOrder = engine.submitOrder(
                            getLabel(instrument),
                            instrument,
                            OrderOp,
                            LOTs,
                            0,
                            slippage,
                            prevBar.getClose()
                                    - (EntryGAP * instrument.getPipValue())
                                    + (StopLoss * instrument.getPipValue()),
                            prevBar.getClose()
                                    - (EntryGAP * instrument.getPipValue())
                                    - (TakeProfit * instrument.getPipValue()));
                }
            }
        }
    }
 
    protected String getLabel(Instrument instrument) {
        return (instrument.name() + counter++).toUpperCase();
    }
 
    public void onMessage(IMessage message) throws JFException {
    }
 
    public void onAccount(IAccount account) throws JFException {
         
    }
 
    public void print(String message) {
        console.getOut().println(message);
    }
}