OTO trigger OMO

Imported from previous forum

I want to send a NewOrderList message that has one order that if traded triggers two other orders, the trading of either one will cause the other order to be cancelled. I can’t figure out how to do this in FIX. Any help would be greatly appreciated.

Hi Robert.
Here is a propose approach:

My assumption are

  1. Partial execution of order A activates both orders B and order C.
  2. Partial execution of order B cancels order C.
  3. Partial execution of order C cancels order B.

Accordingly:

  1. On the list order level: ContingencyType(1385) = One Triggers the Other(2)
    And if you are very conservative, you may use a new value for ContingencyType(1385)(i.e. 1385=100) to indicate: ‘First order triggers all other orders’

  2. On order B:
    TriggerType(1100) = partialExecution(1);
    TriggerAction(1101) = Cancel(3);
    TriggerScope(1628) = Other order(1)
    RefOrderID(1080) = C

  3. On order C:
    TriggerType(1100) = partialExecution(1);
    TriggerAction(1101) = Cancel(3);
    TriggerScope(1628) = Other order(1)
    RefOrderID(1080) = B

Clearly, this needs to be well documented in the rules & engagements.

I hope it helps
Yuval

Thank you Yuval, that is helpful.

I think it is a little more complex. The contingency types work for two orders of a list (one and the other) but not for three, especially if they have different semantics. Defining an ordering of repeating group elements (first one trigeers the others) should be avoided if possible.

Here is my suggestion:

  1. Submit orders B and C with NewOrderList having ListID(66) = X and ListExecInstType(463) set to 2=”Wait for execution instruction”. The partial execution of A is to be defined as the execution instruction for X. B and C themselves should have trigger instructions as shown by Yuval above.

  2. Submit A with NewOrderSingle and
    TriggerType(1100) = partialExecution(1);
    TriggerAction(1101) = Activate (1);
    TriggerScope(1628) = Other order(1)
    RefOrderID(1080) = X

The issue is that you can only one specific orders or a group of orders adhering to a filter criteria. Specifying two specific orders is not possible in the trigger instruction. Hence the “workaround” of triggering a list order. There is a small semantic gap in FIX due to TriggerScope(1628) being intended for cancel only: “Defines the scope of TriggerAction(1101) when it is set to “cancel” (3).”. I do see the above as a use case to extend the semantics for an activation, i.e. “Defines the scope of TriggerAction(1101) when it is set to “cancel” (3) or activate (1).”

Thanks Hanno!

Shouldn’t it be ClOrdLinkID rather than RefOrderID though?

No, I do not think so. ClOrdLinkID statically groups orders without a purpose for pre-trading, rather one for post-trading, i.e. to be able to group trades resulting from these orders. NewOrderList allows an atomic submission whereas ClOrdLinkID requires two independent NewOrderSingle messages that the recipient has to group together. It is a technical possibility but semantically I would still suggest to use RefOrderID. It is the intended usage when triggering a specific order.

Hi Hanno, I have done something more like what Yuval has suggested but with the an “implicit” OCO relationship between the contingent orders (documented in the ROE). This isn’t “complete” as you point out but is compact for our specific use case. This has worked so far for us and in our cases we only needed to consider complete fills. We reply to the list order with 3 execution reports, one for each order and use the “WorkingIndicator” to convey the fact that the contingent orders are not yet triggered. Each order is assigned an OrderID. We Now will need to support partial fills. This presents a puzzle for the order identities. The partial fill results in an order transitioning to working with a size corresponding to the partial fill. The remaining portion of the contingent order - in our implementation - is not working and in fact we expect a subsequent fill or partial fill of the primary order to result in the remaining size being “triggered”. We can see that the triggered orders for partial fills need to have their own lifecycle. What I am thinking is that the (partial) triggered order should be a new order with a new OrderID and a RelatedOrderGrp entry referring to the original contingent order with an OrderRelationship of type “Order Split”. The remaining contingent order would retain its identity, remain “not working” and be restated with a reduced size. It seems sensible that the same should be done with ClOrdID, to avoid having 2 orders extant with different OrderIDs but the same ClOrdID. Does this a reasonable use of “Order Split” ?

@davidgibbsthat sounds like quite a complex scenario. Splitting an order should result in two separate orders that may refer to one another as you describe. They should have their own identifiers, i.e. ClOrdID(11) and OrderID(37). However, ClOrdID(11) should always come from the submitter, not from you. One option is not to use ClOrdID(11) for orders generated by your system, i.e. require the submitter to use OrderID(37), at least for the first request affecting that new order.

An alternative may be to ask for SecondaryClOrdID(526) on the initial order and use that for the new order. That only works for the first split. If you want to be able to repeat the process for every partial fill (reduce primary, create a new working order with the qty from the partial fill), the first option is better. The user could send in a dummy modification request to establish a new ClOrdID(11) for the new order.

Thanks Hanno, I agree that this complex! let’s just think of an order with one contingent order, say a contingent “stop losses” stop order. The contingent order would be “new, not working”. A partial fill of the “primary order” would result in a bet split. A new working stop order with size corresponding to the partial fill would be created. It would have a system assigned Order ID, and no Client Order Id. It would refer to the “original”, remaining, new, not working contingent stop order using the RelatedOrderGrp. The “original” contingent order would remain “new, not working” with reduced size. If another partial fill occurs the process is repeated. If the order is eventually filled the “original” “new, not working” order becomes “working”. This should make it possible to find the “original” order using the client order id, the split orders can be identified by traversing the relationships. The relationship between “primary” and contingent order can also be tracked. N.B. ideas like volume weighted averaging of the fill prices are deliberately left aside here, for this derivative type the fill price is a quality of the position, there a discrete “position” for each partial fill.

@hanno.klein Does that look abominable ?

@davidgibbs sorry for dropping the ball on this. Indeed a complex flow diagram but looks ok to me. We use a different representation that is easier to read I believe. It has the actors exchanging messages as vertical bars and messages as boxes between them with arrows and the key fields. Check out Chapter 4 of EP118 for examples.

Thanks for your reply, yes I like the diagram that’s more like an interaction diagram.