// modified strategy from Dukascopy JStore - Global Equity Closure
// by JP7 - persinaru@gmail.com

import com.dukascopy.api.*;
import java.text.DecimalFormat;

public class TakeTotalProfit_Entry_and_Reversal implements IStrategy {

    private IEngine engine;
    private IConsole console;
    
    @Configurable("Buy")
    public boolean buy = true;
    @Configurable("Sell")
    public boolean sell = false;

    @Configurable("Amount")
    public double amount = 0.1;

    @Configurable("Total take profit (% of account)")
    public double tpPercent = 1;
    @Configurable("Total stop loss (% of account)")
    public double slPct = 10;

    private double balance;

    public void onStart(IContext context) throws JFException {
        this.engine = context.getEngine();
        this.console = context.getConsole();

        double totalPL = 0;
        for (IOrder ord : engine.getOrders()) {
            totalPL += ord.getProfitLossInAccountCurrency();
        }

        // set current balance level to equity without current orders profit/loss
        balance = context.getAccount().getEquity() - totalPL;
        console.getOut().println("initial balance " + (new DecimalFormat("#.#######")).format(balance));

    }
    public void onTick(Instrument instrument, ITick tick) throws JFException {
        if (buy) {
        if (tradesTotalBUY() == 0) {
            engine.submitOrder("BUY", Instrument.EURUSD, IEngine.OrderCommand.BUY, amount);
        }}
        if(sell){
        if (tradesTotalSELL() == 0) {
            engine.submitOrder("SELL", Instrument.EURUSD, IEngine.OrderCommand.SELL, amount);
        }}
    }

    public void onAccount(IAccount account) throws JFException {
        double totalPL = 0;
        for (IOrder ord : engine.getOrders()) {
            totalPL += ord.getProfitLossInAccountCurrency();
        }

        if (totalPL > balance * 0.01 * tpPercent) {buy=false; sell=false;
            for (IOrder order : engine.getOrders()) {
                if (order.getState() != IOrder.State.CLOSED && order.getState() != IOrder.State.CANCELED) {
                    if (tradesTotalBUY()  == 1) {buy=false; sell=true;order.close();}
                    if (tradesTotalSELL() == 1) {sell=false; buy=true;order.close();}
                }

                balance = account.getEquity();
                console.getOut().println("UP balance " + (new DecimalFormat("#.#######")).format(balance));
            }
        }
        if ((totalPL < -balance * 0.01 * slPct)) {buy=false; sell=false;
            for (IOrder order : engine.getOrders()) {
                if (order.getState() != IOrder.State.CLOSED && order.getState() != IOrder.State.CANCELED) {
                    if (tradesTotalBUY()  == 1) {buy=false; sell=true;order.close();}
                    if (tradesTotalSELL() == 1) {sell=false; buy=true;order.close();}
                    
                }
            }

            balance = account.getEquity();
            console.getOut().println("DOWN balance " + (new DecimalFormat("#.#######")).format(balance));
        }

    }

    public void onMessage(IMessage message) throws JFException {
    }

    public void onStop() throws JFException {
    }


    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
    }

    public int tradesTotalBUY() throws JFException {
        int counter1 = 0;
        for (IOrder ORD : engine.getOrders()) {
            if (ORD.getState() == IOrder.State.FILLED && ORD.isLong()) {
                counter1++;
            }
        }
        return counter1;
    }

    public int tradesTotalSELL() throws JFException {
        int counter2 = 0;
        for (IOrder ORD : engine.getOrders()) {
            if (ORD.getState() == IOrder.State.FILLED && !ORD.isLong()) {
                counter2++;
            }
        }
        return counter2;
    }

}