Order Management

One can get access to existing orders by using a number of methods provided by the IEngine interface. The IEngine works with all active orders of the given account, regardless if they were created manually, by the current strategy or another strategy. Methods getOrder and getOrderById retrieve existing order by label or by id respectively. For example:

IEngine engine = context.getEngine();
IOrder orderByLabel = engine.getOrder("label");
IOrder orderById = engine.getOrderById("id");

Method getOrders returns the list of active orders (i.e. orders in IOrder.State CREATED, OPENED and FILLED. One can print all active orders in the following way:

console.getOut().println("Active orders: " + engine.getOrders())

Also one can retrieve the list of active orders (i.e. orders in IOrder.State CREATED, OPENED and FILLED for the specified instrument.

List<IOrder> instrumentOrders = engine.getOrders(Instrument.EURUSD);

Get all profitable/losing orders

Consider selecting in a list all profitable active orders:

List<IOrder> orders = new ArrayList<IOrder>();
for(IOrder o : engine.getOrders()){
    if(o.getProfitLossInUSD() >= 0){
        orders.add(o);
    }
}

Get all pending orders

Consider selecting in a list all pending orders:

List<IOrder> orders = new ArrayList<IOrder>();
for(IOrder o : engine.getOrders()){
    if(o.getState() == IOrder.State.OPENED){
        orders.add(o);
    }
}

For more on order states, see Order State.

Print and/or close orders by group

Consider the previous two examples. Now consider that we want to print all orders from a certain group and/or close those orders, depending on strategy settings. More in particular the following example strategy in every 10 seconds prints lists of:

  • active orders,
  • pending orders,
  • profitable orders,
  • losing orders.

Depending on strategy parameters the strategy closes the orders of a certain group.

public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
    if(instrument != EURUSD || period != Period.TEN_SECS){
        return;
    }
    console.getOut().println("Active orders: " + engine.getOrders());
    console.getOut().println("Pending orders: " + getPendingOrders());
    console.getOut().println("Orders in profit: " + getProfitOrders());
    console.getOut().println("Orders in loss: " + getLossOrders()); 

    if(closeAllActive) closeOrders(engine.getOrders());
    if(closeAllPending) closeOrders(getPendingOrders());
    if(closeAllProfit) closeOrders(getProfitOrders());
    if(closeAllLoss) closeOrders(getLossOrders());
}

private void closeOrders(List<IOrder> orders) throws JFException{
    for(IOrder o: orders){
        if(o.getState() == IOrder.State.FILLED || o.getState() == IOrder.State.OPENED){
            o.close();
        }
    }
}

OrderManagementPL.java

Position aggregated profit/loss

Consider a strategy which in every 10 seconds prints the aggregated profit loss of the filled positions:

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

    double profitLoss = 0;
    for (IOrder order : engine.getOrders()) {
        if (order.getState() == IOrder.State.FILLED){
             profitLoss += order.getProfitLossInUSD();
        }
    }        
    print(String.format("%s PL in USD =%.5f ",
        sdf.format(askBar.getTime() + period.getInterval()),profitLoss));
}

LogProfitLoss.java

Position aggregated P/L and amount for each instrument

Consider a strategy which prints aggregated position profit/loss and amount for each instrument:

@Override
public void onStart(IContext context) throws JFException {
    this.engine = context.getEngine();
    this.console = context.getConsole();
    for(Instrument instrument : context.getSubscribedInstruments()){
        double profitLoss = 0;
        double amount = 0;
        int filledOrders = 0;
        for (IOrder order : engine.getOrders(instrument)) {
            if (order.getState() == IOrder.State.FILLED){
                profitLoss += order.getProfitLossInUSD();
                amount += order.isLong() ? order.getAmount() : -order.getAmount();
                filledOrders++;
            }
        }
        if(filledOrders > 0){
            console.getOut().println(String.format("%s aggregated PL in USD =%.5f, amount=%.5f", instrument ,profitLoss, amount));
        }
    }
    context.stop(); //stop the strategy
}

PositionPLandAmount.java

Maintain order list

In many strategies the strategy itself identifies its own orders by label prefix or by comment, a convenient alternative is keeping all strategy orders in a list. Consider adding every newly created order to a List myOrders and on order close or cancel - removing the order from the list:

private List<IOrder> myOrders = new ArrayList<IOrder>();
@Override
public void onStart(IContext context) throws JFException {
    engine = context.getEngine();
    console = context.getConsole();
    IOrder order = engine.submitOrder("myOrder", Instrument.EURUSD, OrderCommand.BUY, 0.001);
    myOrders.add(order);
}

@Override
public void onMessage(IMessage message) throws JFException {
    IOrder order = message.getOrder();
    if(order == null){
        return;
    }
    if(!myOrders.contains(order)){
        //casual log messages for non-this-strategy order changes
        console.getOut().println(message);
        List<IOrder> otherOrders = new ArrayList<IOrder>(engine.getOrders());
        otherOrders.removeAll(myOrders);
        console.getOut().println("all other orders: " + otherOrders);
    } else {
        //warning log messages for this-strategy order changes
        console.getWarn().println(message);
        console.getWarn().println("all this strategy orders: " + myOrders);
        if(order.getState() == IOrder.State.CLOSED || order.getState() == IOrder.State.CANCELED){
            myOrders.remove(order);
        }
    }     
}

MaintainOrderList.java

Manage order commands

Consider a strategy which on its start creates an order for every OrderCommand and thereafter prints the info about the created orders depending on their OrderCommand:

package jforex.test;

import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;
# import static com.dukascopy.api.IEngine.OrderCommand.*;
/**
 * The strategy on its start creates an order for every order type
 * and thereafter prints the info about the created orders depending on their type
 *
 */
public class SwitchOrderCommand implements IStrategy {

    private IEngine engine;
    private IConsole console;
    private IHistory history;

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

        //price used for conditional orders - just the last bid price
        double price = history.getLastTick(Instrument.EURUSD).getBid();

        //make an order for every order command
        OrderCommand[] orderCommands = OrderCommand.values();
        for (int i = 0; i < orderCommands.length; i++){
            try{
                //market orders
                if (orderCommands[i] == BUY || orderCommands[i] == SELL){
                    engine.submitOrder("order"+i, Instrument.EURUSD, orderCommands[i], 0.001);
                //conditional orders - for conditional orders we need to assign a >0 price
                } else { 
                    engine.submitOrder("order"+i, Instrument.EURUSD, orderCommands[i], 0.001, price);
                }
            } catch (JFException e) {
                console.getErr().println(orderCommands[i] + " " + e);
            }
        }

        //iterate through all active orders
        for (IOrder order : engine.getOrders()) {
            switch (order.getOrderCommand()) {
            case BUY:
                print(order.getLabel() + " is a LONG market order");
                break;
            case SELL:
                print(order.getLabel() + " is a SHORT market order");
                break;
            default:
                print(order.getLabel() + " is a " + (order.isLong() ? "LONG" : "SHORT") + " " + order.getOrderCommand()
                        + " conditional order");
            }
        }

    }

    //close all active orders on startegy stop
    @Override
    public void onStop() throws JFException {
        for (IOrder o : engine.getOrders()){
            o.close();
        }
    }

    private void print(Object o){
        console.getOut().println(o);
    }

    @Override
    public void onTick(Instrument instrument, ITick tick) throws JFException {}
    @Override
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {}
    @Override
    public void onMessage(IMessage message) throws JFException {}
    @Override
    public void onAccount(IAccount account) throws JFException {}

}

SwitchOrderCommand.java

The information on this web site is provided only as general information, which may be incomplete or outdated. Click here for full disclaimer.