AlgoTraderAlgoTrader Documentation

Chapter 17. Order Management

17.1. Place Order
17.1.1. Order Preferences
17.1.2. Trade Suggestions
17.1.3. Order Properties
17.2. Receive Fills
17.3. Handling of Fees and Commissions
17.4. Internal Order Id Format
17.5. Symbology

Before sending an Order, it is advised to call the validate method on the order. This will validate the order regarding limits, amount, quantity, etc. In case validation fails an Exception will be thrown and the order can be modified.

The method sendOrder of the OrderService is responsible for placing Orders. This method takes an Order Entity or Order Value Object as parameter.

Sending an order using and Order Entity looks like this:

MarketOrder order = MarketOrder.Factory.newInstance();

order.setStrategy(strategy);
order.setAccount(account);
order.setSecurity(security);
order.setQuantity(orderQuantity);
order.setSide(Side.BUY);
getOrderService().sendOrder(order);

The associated Entities (i.e. strategy, account and security) can be retrieved via the LookupService.

Sending an order using Order Value Objects looks like this:

MarketOrderVO order = MarketOrderVOBuilder.create()

.setStrategyId(strategyId)
.setAccountId(accountId)
.setSecurityId(securityId)
.setQuantity(orderQuantity)
.setSide(Side.BUY)
.build();
getOrderService().sendOrder(order);

Sending of AlgoTrader orders is currently only supported via Order Entities. Creating and sending an AlgoOrder looks like this:

SlicingOrder order = new SlicingOrder();

order.setStrategy(strategy);
order.setAccount(account);
order.setSecurity(security);
order.setQuantity(orderQuantity);
order.setSide(Side.BUY);
order.setMinQuantity(BigDecimal.valueOf(10));
order.setMaxQuantity(BigDecimal.valueOf(100));
order.setMinVolPct(0.01);
order.setMaxVolPct(0.1);
order.setMinDuration(1);
order.setMaxDuration(5);
order.setMinDelay(1);
order.setMaxDelay(5);
getOrderService().sendOrder(order);

The broker / exchange specific SimpleOrderExecService will create the broker / exchange specific order, assign an intId if none has been assigned yet and send the order to the broker / exchange.

After sending the Order to the broker / exchange, the order object is propagated to the AlgoTrader Server Esper service instance (running inside the AlgoTrader Server) as well as to the Esper service instance of the corresponding strategy (where potential actions like cancel order or modify order can be executed).

Open orders are kept in an internal order book until their full execution or cancellation. Completed orders remain in the book and are accessible through OrderService until evicted. Algotrader evicts completed orders at 24:00 local time daily by default. One can also manually evict orders by calling OrderService#evictExecutedOrders() method.

The actual exchange an Order is sent to will be retrieved from the associated Security/SecurityFamily. Alternatively it is possible to assign an Exchange to an Order Entity or Order Value Object directly.

Even though the Order Entity already contains commonly used properties like side, quantity, time-in-force, etc. it is possible to attach additional arbitrary properties to an Order. Order properties have a name, a value and a type.

Order properties of type INTERNAL are kept inside the system and are not propagated to external brokers.

If the type of an Order property is FIX it is assigned to an outgoing Fix order as an additional fix tag. It is therefore mandatory that the name of the order property is a number (representing the fix tag).

If the type of an Order property is IB the system will try to find an IB order field corresponding to the IB order property name. In case no matching field is found the order property is added as an AlgoParams)

An internal order property can be attached to an order as follows:

order.addProperty("test", "XYZ", OrderPropertyType.INTERNAL);

An Fix order property can be attached to an order as follows:

order.addProperty("4000", "XYZ", OrderPropertyType.FIX);

An IB order property can be attached to an order as follows:

order.addProperty("faGroup", "group1", OrderPropertyType.IB);

Note

OrderProperties are only supported on Order Entities but not on Order value objects.

Whenever order status events and fills are received back from the broker / exchange, OrderStatus and Fill objects / events are created and propagated to the AlgoTrader Server Esper service Instance.

The Fill events trigger the creation of a Transaction object (a persistent Record in the database). In addition the Fill and corresponding Transactions are also propagated to the strategy, where actions can be taken upon.

Like Fills and Transactions the OrderStatus event will also be propagated to the corresponding strategy.

If an order does not receive either an Acknowledgment or Fill within a configurable time period (default: 1 sec) after sending the Order, an Exception is thrown, as there might be a problem with the broker / exchange connection. This is enforced by the NOTIFY_MISSING_ORDER_REPLY statement which can be turned of by changing the following property inside conf-core.properties. Alternatively the properties can be changed via Section 2.3, “VM Arguments”

# notify in case there is no reply on an order
statement.notifyMissingOrderReply = false

Once all fills corresponding to an Order are fully persisted an OrderCompletionVO event is generated and propagated to the Strategy. By the time an OrderStatus event is received by the strategy, corresponding database activity might not have been completed yet. However by the time an OrderCompletionVO event is received, it is guaranteed that all database activity has been completed. It is therefore save to invoke any sort of the database lookup at this time. For further details see Section 8.4.8, “Callbacks”.

AlgoTrader supports handling of the following three types of fees and commissions:

All three types are available in the database table transaction. As most adapter do not provide fee information on execution messages AlgoTrader does not currently import and fee or commission information provided by the broker or exchange at the time of execution. Instead AlgoTrader uses the internal Execution Model (see Section 5.1, “Exchange Simulator”) to assign fees and commissions based on configuration (e.g. commission-per-contract).

intId is the internally assigned order identifier whereas extId is the id assigned by the external broker / exchange.

In general the internal order identifier has the following format:

Example: lmax1.1

By default AlgoTrader automatically assigns an IntId value to all outgoing orders. Open and executed orders can be identified and looked up by their IntId.

Especially when using a Section 8.4.8.2, “Trade callback” it is necessary to generate and assign an IntId value to the order prior to submitting it to the order service. The OrderService#getNextOrderId() method can be used to generate a unique IntId value per session associated with an Account record.

String orderId = getOrderService().getNextOrderId(order.getClass(), accountId);


order.setIntId(orderId);
engine.addTradeCallback(Collections.singleton(orderId), (strategyName, orderStati) -> {
    ...
});
getOrderService().sendOrders(orders);

Note

Please note that care must be taken when using OrderService#getNextOrderId() with the IB order service. The IB native interface expects orders to be sent with their order ids in ascending order. The Class IBOrderIdSynchronizer is responsible to make sure order ids are actually in ascending order. In case an order id is skipped the IBOrderIdSynchronizer will wait for up to maxOrderSyncTime milliseconds for the order with the correct order id to arrive.

In the electronic trading domain there are different ways to identify a security, some of which are:

Different Brokers employ different types of Symbology to identify a security. For this purpose AlgoTrader provides the notion of SymbologyResolver which is responsible for assigning appropriate information to outgoing broker communication. These SymbologyResolvers can be extended on a per broker basis.