Apama Capital Markets Foundation 10.7 | Capital Markets Foundation | Samples | Adapter Support Bundle samples | Multi-Leg Order Manager sample
 
Multi-Leg Order Manager sample
The Multi-Leg Order Manager sample lets you submit a single order that is actually a container for multiple orders. Each of the contained orders is referred to as a leg.
Description
This sample demonstrates the use of multi-leg order management functionality. It allows the user or application to do the following:
*Submit one or more orders to market service provider monitors that are loaded in the correlator. Each order can contain any number of legs.
*Receive acknowledgment of the orders and/or legs.
*Amend or cancel the orders and/or legs.
About Multi-Leg Order Manager market service provider monitors
Market service provider monitors are outside this sample. The Multi-leg Order Manager sample communicates with EPL from the Legacy Finance Support bundle by using the events defined in the com.apama.mlom package. For information about these events, see the ApamaDoc. All events are in the com.apama.mlom package.
Event structures
This sample provides the events listed below in the com.apama.mlom.user package.
OrderParams
This contains the input values for placement, modification, or cancellation of an order.
Field
Description
orderId
A unique identifier to perform operations on the order.
serviceId
The name of the market service provider monitor to use, or an empty string to use any market service provider monitor.
tradeId
The name of the trader.
traderSubId
Additional identification information for the trader.
marketId
The name of the market to send the order to. To determine whether you need to specify this field, and obtain more information about the meaning of this field, see the documentation for the adapter you are using. If the documentation does not mention this field, you do not need to specify it.
marketSubId
Additional identification information about the market to send the order to. To determine whether you need to specify this field, and obtain more information about the meaning of this field, see the documentation for the adapter you are using. If the documentation does not mention this field, you do not need to specify it.
legId
A unique identifier to perform operations on the leg.
symbol
The instrument to trade for the leg identified by the current legId.
price
The price to trade at, or 0 for a market order, for the leg identified by the current legId.
quantity
The amount to trade for the leg identified by the current legId. For example, the number of shares to buy or sell.
side
BUY or SELL. Applies to the leg identified by the current legId. Some services also support other values such as BUY MINUS or SELLSHORT.
type
MARKET or LIMIT. Some services also support other values such as STOPMARKET or STOPLIMIT. If left blank, the order is placed as a LIMIT if a price is specified or a MARKET order if no price is specified (or is 0). This field applies to each leg in the order.
extraParams(dictionary)
Any extra parameters for the service. Applies to each leg in the order.
OrderStatus
The Multi-Leg Order Manager sample updates the order status output as an acknowledgment upon placement, modification, or cancellation of an order. This reports all information about each order, including averages or totals for all legs in a particular order. Each time there is a change in the order (such as a state or status change for any leg), the order status feed provides an update as a callback.
Field
Description
order_identifier
A unique identifier to perform operations on the order.
market_order_identifier
An identifier supplied by the market, typically unique across all orders in that market.
symbol
If all legs in the order are trading the same instrument, this field contains the identifier for the instrument being traded. If all legs are not trading the same instrument, this field is empty.
price
The volume weighted average price of all legs in the order. Takes into account any changes to any legs.
quantity
The total number of units, such as shares, to trade for all legs in the order. Includes any changes to any legs.
state
The order's state indicated by an integer from 0-9. See Order states and status fields for a description of what each integer signifies.
money_executed
The sum of price * quantity for all fills of all legs in this order, or 0.0 if no fills have occurred.
average_price_executed
The volume-weighted average price over all fills for all legs, or 0.0 if no fills have occurred.
last_price_executed
The price obtained per item for the last fill, or 0.0 if no fills of any legs in this order have occurred.
quantity_executed
The number of items traded so far, or 0.0 if no fills of any legs in this order have occurred.
quantity_remaining
The number of items left to trade in the market for all legs in this order, or 0.0 if all items have been traded.
in_market
Number of legs in the order that are known to the market.
visible
Number of legs in the order that are visible in the market. Some markets consider orders to be invisible until a certain condition has been met, for example, stop orders are invisible until the trigger price is hit.
modifiable
Number of legs in the order that can be modified immediately.
cancelled
Number of legs in the order that have been rejected or cancelled, possibly before being entered into the market. A cancelled leg might have had some quantity traded.
change_rejected
Number of legs in the order for which the most recent modification or cancellation was rejected by the market. An explanation might be available in the status message field.
externally_modified
Number of legs in the order that have been modified by anything other than the current sample, for example, the market or a third party.
final
Number of legs in the order that have entered the final state. This means the leg was completed, cancelled, or rejected. Note that a leg in the final state can still be updated. A leg that is settled can no longer be updated.
status_message
A message from either the market service provider monitor or the market explaining what has happened. The format and meaning of the message varies from service to service and market to market.
numLegs
Number of legs in the order.
numSettled
Number of settled legs in the order. A settled leg cannot be updated.
last_quantity_executed
The number of items traded in the last fill, or 0.0 if no fills of any legs in this order have occurred.
type
The type of the order — MARKET, LIMIT, or some other type supported by the market.
side
The side of the order — BUY, SELL, or some other side supported by the market.
extraParams
Dictionary that specifies additional parameters in a key,value format.
OrderLegStatus
The Multi-Leg Order Manager sample updates the leg status output as an acknowledgment upon placement, modification, or cancellation of a leg. Each time there is a change in a leg (such as a state or status change), the leg status feed provides output.
Field
Description
leg_identifier
A unique identifier to perform operations on the order leg.
market_order_identifier
An identifier supplied by the market, typically unique across all orders in that market.
symbol
Identifier for the instrument this leg is trading.
price
The price requested either when the leg was submitted or the latest modification to the leg. A price of 0.0 signifies a market order.
quantity
The total number of units, such as shares, to trade, or the number the leg has been amended to.
side
The side of the leg — BUY, SELL, or some other side supported by the market.
type
The type of the leg — MARKET, LIMIT, or some other type supported by the market.
state
The order’s state indicated by 0-9. See Order states and status fields.
money_executed
The sum of price * quantity for all fills of this leg, or 0.0 if no fills have occurred.
average_price_executed
The volume-weighted average price over all fills of this leg, or 0.0 if no fills have occurred. For example, suppose you submit a leg to buy 100 shares of IBM at up to $10.00 per share. You bought 20 shares at $9.95 and 20 shares at $9.97. The average price executed is $9.96.
last_price_executed
The price obtained per item for the last fill for this leg, or 0.0 if no fills have occurred.
last_quantity_executed
The number of items traded in the last fill for this leg, or 0.0 if no fills of this leg have occurred.
quantity_executed
The number of items traded so far, or 0.0 if no fills of this leg have occurred.
quantity_remaining
The number of items left to trade in the market as part of this leg.
in_market
true if the leg is known to the market.
visible
true if the leg is visible in the market. Some markets consider legs to be invisible until a certain condition has been met, for example, stop orders are invisible until the trigger price is hit.
modifiable
true if the leg can be modified immediately.
cancelled
true if the leg has been rejected or cancelled, possibly before being entered into the market. A cancelled leg might have had some quantity traded.
change_rejected
true if the most recent modification or cancellation of the leg was rejected by the market. An explanation might be available in the status message field.
externally_modified
true if the leg has been modified by anything other than the sample, such as the market or a third party.
final
true if the quantity specified for the leg has been traded, or if the leg was cancelled or rejected. A final leg can still be updated.
status_message
A message from either the market service provider monitor or the market explaining what has happened. The format and meaning of the message varies from service to service and market to market.
settled
true if this leg is final and can no longer be updated.
extraParams
Dictionary that specifies additional parameters, which contain more information about the instrument being traded.
MultilegOrderManagerInterface
The Multi-Leg Order Manager sample provides this interface for different order operations.
Action/Operation
Description
action< OrderParams /*params*/ > StartMultilegOrder
Start submission of a new order. See Submitting multi-leg orders.
action< OrderParams /*params*/ > AddLeg
Add a leg to the current order’s set of legs.
action< OrderParams /*params*/ > SubmitMultilegOrder
Send the order to the market. The order automatically enters state 1, waiting for acknowledgment.
action <string /*orderId*/ > StartModifyMultilegOrder
Open order for modifications. See Modifying multi-leg orders.
action< OrderParams /*params*/ > RemoveLeg
Remove the leg identified by the current legId from the order identified by the current orderId.
action< OrderParams /*params*/ > AmendLeg
For the leg identified by the current legId, modify the price, quantity, side, type, or extraParams parameter.
action< OrderParams /*params*/ > ModifyMultilegOrder
Send modified order to the market. The order automatically enters state 5, pending change, unless the order is not modifiable at this time. See Modifying multi-leg orders.
action< OrderParams /*params*/ > CancelMultilegOrder
Cancel the order in the market. The order automatically enters state 6, pending cancel, unless the order is not modifiable at this time. The market can reject a cancellation. Consequently, after an order is in the pending cancel state, it can become cancelled, completed, or, if the cancellation is rejected, working.
action< OrderParams /*params*/ > CancelLeg
Cancel the leg in the market. The leg automatically enters state 6, pending cancel, unless the leg is not modifiable at this time. The market can reject a cancellation. Consequently, after a leg is in the pending cancel state, it can become cancelled, completed, or, if the cancellation is rejected, working.
action< OrderStatus /*update*/ > onOrderStatusAcknowledgement
This is a callback on order state updates.
action< OrderLegStatus /*legUpdate*/ > onLegStatusAcknowledgement
This is a callback on leg state updates.
Submitting multi-leg orders
In a multi-leg order, there is data that is common to all legs in the order and there is data that is relevant to each of the legs. To submit an order, you must define the legs of the order.
To submit an order:
1. Set the order’s identifier by specifying a value for the orderId field of the OrderParams event.
2. Call the StartMultilegOrder operation.
3. For one leg, add the corresponding value to the field of the OrderParams event.
4. Invoke the AddLeg operation.
5. Repeat Step 3 and Step 4 for each leg.
6. Invoke the StartModifyMultilegOrder operation for the same orderId.
After invoking the StartModifyMultilegOrder operation, the sample will acknowledge the order status and/or leg status (as a callback) for each order/leg update.
Modifying multi-leg orders
To add a new leg, modify an existing leg, or remove a leg:
1. Set the orderId field to the identifier of the order you want to modify.
2. Invoke the StartModifyMultilegOrder operation.
3. Follow the appropriate steps for modifying, adding or removing a leg:
To modify a leg:
a. Set the legId field to the identifier of the leg you want to modify.
b. Assign updated values to the fields of the OrderParams event.
c. Invoke the AmendLeg operation.
To add a leg:
a. Specify a unique value for the legId field of the OrderParams event and specify the appropriate values for the other fields.
b. Invoke the AddLeg operation.
To remove a leg:
a. Set the legId field to the identifier of the leg you want to remove.
b. Invoke the RemoveLeg operation.
4. Repeat all substeps in Step 3 for each leg you want to modify, add, or remove.
5. Invoke the ModifyMultilegOrder operation.
Working with multi-leg orders
Order identifiers and leg identifiers must be unique in the scope of the Multi-Leg Order Manager sample.
At any one point in time, each order has one status and one state. Likewise, each leg has one status and one state. The status is a text description of where the order or leg is in the order process. The state is a number, from 0 through 9, that indicates more precisely the location of the order or leg in the order process. See Order states and status fields for further information. All information in that topic applies to legs as well as orders.
When the legs in an order are in different states, the state of the order is unknown (9). When the legs in an order are all in the same state, the state of the order is the same as the state of the legs.
The Multi-Leg Order Manager sample maintains an order book that contains information about each of the orders it has submitted. The order book indicates the state and status of each order placed. In the order book, an order identifier distinguishes each order from every other order placed from that sample. You always specify the order identifier as a parameter when you amend, cancel, retrieve, or clear an order.
The Multi-Leg Order Manager sample also maintains a leg book for each order. The leg book contains information about each of the legs submitted as part of the order. In the leg book, a leg identifier distinguishes each leg from every other leg in that order. You always specify the leg identifier as a parameter when you amend, cancel, retrieve, or clear a leg.
Updating final orders
When a leg is final, it has been completed, cancelled, or rejected. Sometimes, it is necessary to update a leg that is final. The Multi-Leg Order Manager sample continues to listen for update events for final legs. If an update event occurs, it performs the update.
If you do not want to allow updates to a final leg, you must specify that the leg is settled. To do this, your client must send a LegUpdate event to the Multi-Leg Order Manager sample and specify true for the settled field. LegUpdate events are defined in the com.apama.mlom package. For additional information, see the ApamaDoc.
Sample code for a multi-leg order operation
using com.apama.mlom.user.MultilegOrderManagerFactory;
using com.apama.mlom.user.MultilegOrderManagerInterface;
using com.apama.mlom.user.OrderStatus;
using com.apama.mlom.user.OrderLegStatus;
using com.apama.mlom.user.OrderParams;
 
monitor MultilegOrderManagerHelperExample {
 
context mainContext := context.current();
 
action onload() {
 
MultilegOrderManagerInterface iface :=
(new MultilegOrderManagerFactory).create(mainContext, OrderStatusCb,
OrderLegStatusCb);
 
/****** To place an order with Order_1 identifier ******/
 
//start multi-leg operation
OrderParams param := OrderParams("Order_1","MarketSimulator",
"","","","","","",0.0,0.0,"","","",new dictionary<string,string>);
iface.StartMultilegOrder(param);
 
//add leg
param := OrderParams("Order_1","MarketSimulator",
"","","","","Leg_1","INSTRUMENT_1",1.23,700.0,"SELL","MARKET","",
new dictionary<string,string>);
iface.AddLeg(param);
 
//place an order
param := com.apama.mlom.user.OrderParams("Order_1","MarketSimulator",
"","","","","","",0.0,0.0,"","","",new dictionary<string,string>);
iface.SubmitMultilegOrder(param);
 
/****** END ******/
 
/****** To modify the order ******/
 
param := OrderParams("Order_1","MarketSimulator",
"","","","","","",0.0,0.0,"","","",new dictionary<string,string>);
 
//Start modify operation -> for Order_1 identifier
iface.StartModifyMultilegOrder("Order_1");
 
//Modify leg -> changed type and quantity
param := com.apama.mlom.user.OrderParams("Order_1","MarketSimulator",
"","","","","Leg_1","INSTRUMENT_1",1.23,900.0,"SELL","LIMIT","",
new dictionary<string,string>);
iface.AmendLeg(param);
 
//Submit modify
param:= com.apama.mlom.user.OrderParams("Order_1","MarketSimulator",
"","","","","","",0.0,0.0,"","","",new dictionary<string,string>);
iface.SubmitMultilegOrder(param);
 
/****** END ******/
 
/****** To cancel the order leg ******/
 
param:= com.apama.mlom.user.OrderParams("Order_1","MarketSimulator",
"","","","","Leg_1","",0.0,0.0,"","","",
new dictionary<string,string>);
iface.CancelLeg(param);
 
/****** END ******/
 
/****** To cancel the order ******/
 
param:= com.apama.mlom.user.OrderParams("Order_1","MarketSimulator",
"","","","","","",0.0,0.0,"","","",new dictionary<string,string>);
iface.CancelMultilegOrder(param);
 
/****** END ******/
 
}
 
action OrderStatusCb(OrderStatus orderStatus) {
log "Received order status for order ID = "
+ orderStatus.order_identifier +" status = "
+ orderStatus.status_message at INFO;
}
 
action OrderLegStatusCb(OrderLegStatus legStatus) {
log "Received leg status for leg ID = "+ legStatus.leg_identifier
+" status = " + legStatus.status_message at INFO;
}
 
}