Views:

The order lifecycle within LUSID is represented via a domain model of related entities and functions, which allows the client the freedom to model any bespoke relationship required. At a very high level, the model allows use cases such as the following:

  • Fund managers give verbal instructions to brokers to execute transactions.
  • Electronic RFQs are generated via eTrading platforms.
  • A large futures order is placed directly on an exchange, resulting in hundreds of small fills
  • An allocation process examines the participation and apportions the fills across multiple accounts
  • Transactions are matched back to the original orders and the remainder held over to be re-submitted at the next session

Different organisations use processes of varying complexity over different instruments, and typically interchange terms from a mostly common set to describe the entities involved. To support such a range of related systems, LUSID uses an extensible model that can be mapped onto any particular client use case.

In the diagram below, we show an example order workflow and how it interacts with the LUSID domain model. This is by no means representative of all use cases, and our intention is to ensure clients can consume as much or little of the model as needed.

Once an order in LUSID has been blocked and placed with executing brokers or intermediaries in accordance with its participation, the allocation process distributes returned executions to allocations in line with its ruleset and the originating order's participation. Transactions are then created and booked from the allocations.

An orders and allocations book of record

Support exists via API endpoint (see orders and allocations) and examples of the implementation in code can be found in the SDK and in Jupyter Notebooks.

Orders and allocations in LUSID support a small core of common properties, to which a client can add bespoke properties as appropriate. Both can be filtered on retrieval by any of the properties, the LusidInstrumentId (LUID), Quantity, OrderId or Portfolio.

Support also exists via API endpoint for related entities such as order books, blocks, executions, participations and placements. We are also working on a blended position view which includes pending orders across portfolios.

Mapping FIX messages

The most direct points of integration with the market would be via receipt of FIX New Order Single messages (which map to the LUSID placement entity) and FIX Execution Report messages (which map to the LUSID execution entity), both via FIX drop copy, although LUSID also supports the bulk upload of order, allocation or other entity data directly to appropriate endpoints.

Currently, LUSID has some facility for processing FIX. In the full domain model, a FIX Execution Report message, for example, would get mapped to a LUSID execution. However, as an example, it's possible to demonstrate its mapping to a LUSID allocation, mimicking the direct-allocation process a smaller investment concern might want to use.

Say the market produces an Execution Report for sale of 25 gold futures contracts:

8=FIX.4.2|9=266|35=8|49=ABC|56=XYZ|50=AZ12|57=NA|34=833|52=20200130-08:00:51.992|55=GLD|48=PL11YA|167=FUT|207=LIFFE|1=AA1|37=ORD000001234|17=ACBDFE|58=Fill|200=202009|205=13|32=25|151=0|14=25|54=2|40=2|77=O|59=0|150=2|20=0|39=2|442=1|44=99.06|38=25|31=99.06|6=99.06|60=20100130-08:00:52|10=136|

This would get mapped onto an allocation with:

Allocation
  OrderId = ORD000001234
  Quantity = 25
  Instrument Identifiers = {
    "Instrument/default/ZYX", "Something Here"
  }
  Portfolio = "ClientScope/AA1",
  Properties = {
    "Order/ClientScope/ExecId", "ACBDFE",
    "Order/ClientScope/Symbol", "GLD",
    "Order/ClientScope/SecurityId", "PL11YA",
    "Order/ClientScope/SecurityType", "FUT",
    "Order/ClientScope/SecurityExchange", "LIFFE",
    "Order/ClientScope/MaturityMonthYear", "202009",
    "Order/ClientScope/MaturityDay", "23",
    "Order/ClientScope/LeavesQty", "0",
    "Order/ClientScope/Side", "Sell",                 // mapped from 2
    "Order/ClientScope/TimeInForce", "Day",           // mapped from 0
    "Order/ClientScope/Price", "99.06",
    "Order/ClientScope/AvgPx", "99.06",
    "Order/ClientScope/LastPx", "99.06",
    "Order/ClientScope/TransactTime", "20200130-08:00:51.992",
    ...
  }