Orders Execution

Placing and Checking Intra-Day orders

Order Checks

Executing an Order is the main workflow of Pre-Trade - it is how the client checks individual assets across both their system and ours.

In simple terms, a client places an order (equivalent of a Post-Trade asset), and we check that order against the previous Post-Trade data and current Pre-Trade data we have to give the most accurate picture we can of their regulatory requirements.

❓ What Is An Order?

An Order is the execution of a single trade (or transaction) of an Asset (within a Portfolio)

A 'Buy' Order is an increase of position, A 'Sell' order is a decrease of position.

For each order we provide as accurate as possible compliance information (required disclosures) given the data available to the time the order was placed.

How Does It Work?

A client will place an order by executing a request to POST /order/execute with the appropriate properties as laid out

Key Characteristics

🕧When does it happen?: When a client places an order

⏱️How long does it take?: We aim for under a second, but this largely depends on how large the dataset they are using is (Large order request, big aggregation structure, large number of results etc.). All requests should be less than 30s, 90% should be under 10 seconds in all scenarious.

🤖 How does it interact with the Baseline Roll?: Aggregation, Rule Results, Assets & Market Data (RegData etc.)

📞 Order Requests & Response

The Request

Here is an overview of the request model used for executing an Order

{
   "Instruments": [
        {
            "Properties": {
                "InstrumentId": "1",
                "AssetClass": "Swap",
                ...
            },
            "Components": [
                {
                    "InstrumentId": "2",
                    "Weighting": 0.05
                }
            ]
        },
        {
            "Properties": {
                "Isin": "GB00BLGZ9862",
                "InstrumentId": "2",
                "AssetClass": "Equity"
                ...
            }
        }
    ],
    "Asset": {
        "Properties": {
            "Quantity": 375000,
            "SFTType": "Normal",
            "HoldingType": "Direct",
            "AssetId": "Test_Swap",
            "AssetName": "Test Swap > Index > Equity",
            "InstrumentId": "1",
            "MarketValueInInstrumentCurrency": 10000000,
            "MarketValue": 10000000,
            "IncludeInShortAU":"false"
        }
    },
    "PortfolioId": "11",
    "OrderType": "Sell",
    "Timestamp": "2023-08-09T10:30:00Z"
}

Let's break that down!

  • Instruments: In this block each object gives an instrument (financial security). Each instrument must contain a Properties block with the InstrumentId and AssetClass, along with other instrument properties required by the service documentation. If the instrument has underlying components, this is signalled with a Components block for which the InstrumentId provides the pointer to the component and Weighting if the component is weighted
  • Asset: In this block is defined the Asset for which the order is placed. The Properties block in this should contain all of the required Asset Properties as in the service documentation.

On top of the Asset data, we also require a couple of fields to tell us about the Order (what & when).

Required:

  • PortfolioId - This will be the Portfolio that is buying or selling the Asset.
  • OrderType - Signifies whether the Order is buying or selling from their current position. Must be Buy or Sell
  • Timestamp - Demarkates the time (in UTC format) the order was made. Only orders between the last Baseline Roll and this timestamp will be included in the check.

Optional:

  • IncludeNonDiscloseable - This includes non-discloseable results in the Pre-Trade response.

The Response

Take the following response

{
    "orderId": "320b0025-951a-499f-9bf1-40967a9e4e21",
    "passed": false,
    "rulesFailed": [
        {
            "ruleName": "Major: Ghana",
            "ruleId": 1265,
            "ruleVersionId": "67cd0720-af4c-4748-990a-bae24af97452",
            "results": [
                {
                    "passed": false,
                    "groupKey": "549300C116EOWV835768#US0079031078",
                    "resultType": "Disclosure",
                    "explanation": "Crossed upper threshold: 10.00",
                    "portfolioId": "FAAM",
                    "value": 1009.000,
                    "disclosureThreshold": 10.0,
                    "directionCrossed": "Upwards"
                }
            ]
        },
        {
            "ruleName": "Major: Ghana",
            "ruleId": 1265,
            "ruleVersionId": "67cd0720-af4c-4748-990a-bae24af97452",
            "results": [
                {
                    "passed": false,
                    "groupKey": "549300C116EOWV835768#US0079031078",
                    "resultType": "Disclosure",
                    "explanation": "Crossed upper threshold: 10.00",
                    "portfolioId": "11",
                    "value": 1009.000,
                    "disclosureThreshold": 10.0,
                    "directionCrossed": "Upwards"
                }
            ]
        }
    ],
    "totalRulesChecked": [
        {
            "portfolioId": "FAAM",
            "totalRulesChecked": 301
        },
        {
            "portfolioId": "11",
            "totalRulesChecked": 144
        }
    ],
    "unknownSummary": {
        "summaries": [
            {
                "ruleName": "Hart-Scott-Rodino Act - United States - Value Limits",
                "ruleId": 19010,
                "ruleVersionId": "af05e96c-1d4d-4b00-bd0b-c0e98aa0672e",
                "results": [
                    {
                        "passed": false,
                        "groupKey": "549300C116EOWV835768",
                        "resultType": "Unknown",
                        "explanation": "Assets in this group have missing data: PriceForHSR",
                        "portfolioId": "FAAM",
                        "value": null
                    }
                ]
            }
        ],
        "totalUnknowns": 1
    }
}

Let's break down the constituent parts:

  • OrderId: This is the GUID that marks the order, which can be used for
  • Passed: This boolean flags marks whether the order has triggered any Disclosure or
  • TotalRulesChecked: This gives you the total number of rules checked for audit reasons.
  • RulesFailed: This field contains all rules which have triggered an alert to be considered failed (Disclosure, Breach, Unknown). These are analagous to Post-Trade results.
  • UnknownSummary: Information for rules that trigger Unknown results.

For each Pre-Trade result (in rulesFailed, unknownSummary or otherwise), the elements of that include:

  • passed: Indicates whether or not the rule has passed the check (usually false)
  • groupKey: The groupkey of the Rule Result (usually RefIssuerId)
  • resultType: The alert type of the result.
  • explanation: The cause of the failure
  • portfolioId: portfolio the rule failed for
  • value: The value of the result
  • (failed rules only) disclosureThreshold: What disclosure threshold was crossed
  • (failed rules only) directionCrossed: From what direction it was crossed (upwards/downards)

In the example above, the Order has triggered two failed rule results (the same rule) at both the Portfolio and Entity level. There is also one unknown due to a missing property: PriceForHSR.

📬 Translating Pre-Trade Orders From Post-Trade

So how does that process match to our Post-Trade offerings? In short, it is very easy to map an asset and instrument between how a client constructs position files for Post-Trade and Pre-trade. We use the same properties that you find in the positions file.

Let's take a simple positions file (Post-Trade):

<Snapshot Date="2017-12-29">
  <Instruments>
    <Equity InstrumentId="88579Y101" ISIN="US0079031078" CUSIP="88579Y101" InstrumentCurrency="USD" Price="217.82" InstrumentName="3MCO" >
  </Instruments>
  <Portfolios>
    <Portfolio PortfolioId="17">
      <Asset InstrumentId="88579Y101" AssetId="ABC" SFTType="Normal" Quantity="99000" AssetName="3M CO" />
    </Portfolio>
  </Portfolios>
</Snapshot>

This contains a single Equity instrument, for which a single asset holds a quantity of 99000 within portfolio 17.

If a client wanted to, for example, place an order that increases the quantity by 50

{
   "Instruments":[
        {
            "Properties": {
                "Isin":"US0079031078",
                "InstrumentId":"88579Y101",
                "InstrumentName":"3MCO",
                "AssetClass":"Equity", // Maps to the <Equity> tag in instruments
                "CUSIP":"88579Y101",
                "InstrumentCurrency": "USD",
                "Price": 217.82
            }
        }
    ],
    "Asset":{
        "Properties":{
            "Quantity": 50,
            "SFTType":"Normal",
            "AssetId":"ABC",
            "AssetName":"Ghana Bank",
            "InstrumentId":"88579Y101",
        }
    },
    "PortfolioId":"17", // The portfolio which holds the assets.
    "OrderType":"Buy", // Buy or sell (think of this as increase or decrease)
    "Timestamp":"2023-09-08T12:00:00Z" // The UTC time the order was placed (cannot be before last baseline roll)
}

Here is an example of the same Order payload in XML which we also support

<ExecuteOrder>
    <PortfolioId>17</PortfolioId>
    <OrderType>Buy</OrderType>
    <Timestamp>2023-09-08T12:00:00Z</Timestamp>
    <Instruments>
        <Equity InstrumentId=""88579Y101"" ISIN=""US0079031078"" InstrumentName=""3MCO"" CountryOfIncorporation=""GB"" CountryOfIssue=""GB"" VotesPerShare=""1"" />
    </Instruments>
    <Asset SFTType=""Normal"" AssetId=""ABC"" AssetName=""Ghana Bank"" InstrumentId=""88579Y101"" Quantity=""50"" />
</ExecuteOrder>

Asset And Instrument Properties

The input message outlines the instrument being traded, market data related to that instrument [Properties] and then Asset properties related to the instrument e.g Quantity being traded.

All properties match up to properties which are already part of the Shareholding Disclosure data spec and descriptions of properties can be found here: https://docs.fundapps.co/PropertiesSD.html

For instruments which have components (e.g a basket/index or a derivative) the components would be created inside the component tag.

The Portfolio the trade is assigned to may not be known exactly pre-execution but it will be needed in the input.

Bonus Complicated Composite example

While the above example is simple, it's worth understanding what this looks like for a composite. Take for example this Swap on an Index of an Equity.

Post-Trade Position File:

<Snapshot Date="2023-08-09">
  <Instruments>
		<Swap CUSIP="NONE" Delta="1" ISIN="UNKNOWN" InstrumentId="1" InstrumentName="Test Swap > Index > Equity" IsCashSettled="true" MarketsListedIn="XXXX" MaturityDate="2025-07-29">
			<Component InstrumentId="2"/>
		</Swap>
		<Index InstrumentCurrency="GBP" InstrumentId="2" InstrumentName="Test Index > Equity" IssuerId="4" Price="1000">
			<Component InstrumentId="3" Weighting="0.005"/>
		</Index>
		<Equity AssetClassCustomer="Test Equity" CUSIP="NONE" ClassSharesOutstanding="100000000.0000" CountryOfIncorporation="GB" CountryOfIssue="GB" GICSIndustries="252010" HasAlternateUSSection12Registration="false" ISIN="GB00BLGZ9862" InstrumentCurrency="GBP" InstrumentId="3" InstrumentName="Test Equity" IsREIT="false" IsWhenIssued="false" IssuerId="5" IssuerName="Test equity PLC" LocalTicker="TST" Market="XLON" MarketsListedIn="XLON,AQXE,BATE,BLOX,BOTC,CAPA,CHIX,ECEU,HOTC,LEUE,LIQU,LSSI,SGMX,TREA,TREU,TRNL,TRQX,TWEM,XAPA,XBRN,XBUD" ParValue="1.000000000" Price="2.000" TotalIssuedNominalCapital="100000000.0000" TotalSharesInTreasury="0" TotalSharesOutstanding="100000000.0000" TotalVotingRights="100000000.0000" TotalVotingRightsInTreasury="0" TotalVotingShares="100000000.0000" TotalVotingSharesInTreasury="0" VotesPerShare="1.0"/>
    </Instruments>
  <Portfolios>
    <Portfolio PortfolioId="11">
      <Asset AssetId="Test_Swap" AssetName="Test Swap > Index > Equity" IncludeInShortAU="false" InstrumentId="1" MarketValue="10000000" MarketValueInInstrumentCurrency="10000000" Quantity="-150000" SFTType="Normal"/>
    </Portfolio>
  </Portfolios>
</Snapshot>

Pre-Trade Order

{
  "Instruments": [
    {
      "Properties": {
        "InstrumentId": "1",
        "InstrumentName": "Test Swap > Index > Equity",
        "AssetClass": "Swap",
        "IsCashSettled": true,
        "Delta": 1,
        "ContractSize": 1,
        "MaturityDate":"2025-07-29",
        "MarketsListedIn": "XXXX"
      },
      "Components": [
        {
          "InstrumentId": "2" // Instrument below is a single weighted component of this
        }
      ]
    },
    {
      "Properties": {
        "InstrumentId": "2",
        "InstrumentName": "Test Index > Equity",
        "AssetClass": "Index",
        "IssuerId": "4",
        "InstrumentCurrency": "GBP",
        "Price": 1000
      },
      "Components": [
        {
          "InstrumentId": "3",  // Instrument below is a single weighted component
          "Weighting": "0.005"
        }
      ]
    },
    {
      "Properties": {
        "Isin": "GB00BLGZ9862",
        "InstrumentId": "3",
        "InstrumentName": "Test Equity",
        "AssetClass": "Equity",
        "IssuerId": "5",
        "IssuerName": "Test equity PLC",
        "InstrumentCurrency": "GBP",
        "CountryOfIncorporation": "GB",
        "CountryOfIssue": "GB",
        "Market": "XLON",
        "MarketsListedIn": "XLON,AQXE,BATE,BLOX,BOTC,CAPA,CHIX,ECEU,HOTC,LEUE,LIQU,LSSI,SGMX,TREA,TREU,TRNL,TRQX,TWEM,XAPA,XBRN,XBUD",
        "Price": 2,
        "VotesPerShare": 1,
        "ClassSharesOutstanding": 100000000.0000,
        "TotalSharesOutstanding": 100000000.0000,
        "TotalSharesInTreasury": 0,
        "TotalVotingShares": 100000000.0000,
        "TotalVotingSharesInTreasury": 0,
        "TotalVotingRights": 100000000.0000,
        "TotalVotingRightsInTreasury": 0,
        "IsWhenIssued": false
      }
    }
  ],
  "Asset": {
    "Properties": {
        "Quantity": 375000,
        "SFTType": "Normal",
        "HoldingType": "Direct",
        "AssetId": "Test_Swap",
        "AssetName": "Test Swap > Index > Equity",
        "InstrumentId": "1",
        "MarketValueInInstrumentCurrency": 10000000,
        "MarketValue": 10000000,
        "IncludeInShortAU":"false"
    }
  },
  "PortfolioId": "11",
  "OrderType": "Sell",
  "Timestamp": "2023-08-09T10:30:00Z"
}

🎸 Baseline Roll Behaviour

The central theme is this: All orders placed after are aggregated against the last Baseline Roll.
To explore this, let's use some cumulative examples. Assume all orders are for an Asset with the same GroupKey (i.e. for the same issuer).

In order of the Orders being placed (the time represents the included Timestamp of the order)

  1. Baseline Roll 1 (Day 1, 7am) & Order 1 (Day 1, 7:15am): Baselines from Baseline Roll 1 and Order 1 used to calculate results.
  2. Baseline Roll 1 (Day 1, 7am) & Order 2 (Day 1, 10:15am): Baselines from Baseline Roll 1 and Orders 1 & 2 used to calculate results.
  3. Baseline Roll 1 (Day 1, 7am) & Order 3 (Day 2, 8:45am): Baselines from Baseline Roll 1 and Orders 1, 2 & 3 used to calculate results.
  4. Baseline Roll 1 (Day 1, 7am) & Order 4 (Day 2, 6:00am): Baselines from Baseline Roll 1 and Orders 1, 2, 3 & 4 used to calculate results.
  5. Baseline Roll 2 (Day 2, 7am) & Order 5 (Day 2, 8:00am): Baselines from Baseline Roll 2 and Orders 3 & 5 used to calculate results.
  6. Baseline Roll 2 (Day 2, 7am) & Order 6 (Day 2, 8:00am): Baselines from Baseline Roll 2 and Orders 3, 5 & 6 used to calculate results.

Editing & Viewing Orders

❓ How Editing Orders Work

After placing orders, a client may wish to:

See their Orders (and effects)
Cancel (but not change) an Order

For this we offer solutions to integrate as part of their workflow

Checking Orders Placed

Many Orders will be placed during a day. To have visibility over which orders are currently "open", which is to say they will be aggregated on all subsequent checks where the timestamp exceeds the last order placed, clients can see their open orders with a call to GET /order/openorders. This will contain the information for Orders placed since the last Baseline Roll.

Checking Current Positions

Similarly, clients may wish to check their current positions for each rule.

For this, we offer the GET /order/openpositions endpoint, which displays their open positions for each rule.

Checking Rules In Effect

To view the rules currently in effect within Pre-Trade, we offer the GET /rules endpoint

Cancelling Orders

Let's say one of the following things has happened:

  • The client placed an order which triggered a disclosure they want to avoid
  • The client placed an order and decided against the order for a different reason
  • The client spilled a drink on their keyboard and accidentally placed an order for no reason

In this case the client can cancel a specific order!

In the response for an executed Order, an OrderId is returned

{
    "orderId": "320b0025-951a-499f-9bf1-40967a9e4e21"
    ...
}

To cancel that order, request OrderId

PATCH /order/cancel/320b0025-951a-499f-9bf1-40967a9e4e21

Note: Technically an order can be undone by placing an order of the opposite type (Buy -> Sell, Sell -> Buy).