Lesson 06 · 5 min

Trades, Parties & TradeState

A Trade is a tradable product with names, dates, and identifiers. TradeState wraps it for the lifecycle.

From product to trade

Here is one of this model version's most elegant facts: Trade extends TradableProduct. A trade is not a record that points at a product; it is the tradable product, with the product terms, its payouts, and its lots all inherited, plus the facts that make it a real transaction: identifiers, dates, and the actual parties.

TradableProductproduct · lots · rolesTrade+ tradeIdentifier · tradeDateextends: a Trade ISa tradable productParty1roleParty2rolePershing SquareGoldman Sachsparty[] binds each roleto a real entitysame product terms, now with identifiers, dates, and people
Key ideas
  • Trade = TradableProduct + identity

    Inherited: product, tradeLot, counterparty. Added: tradeIdentifier, tradeDate, party, and execution details.

  • Roles get real names

    party lists the legal entities on the trade. counterparty binds each abstract role (Party1, Party2) to one of them by reference. The product stays reusable; the trade is specific.

  • TradeState wraps the trade for the lifecycle

    TradeState holds the trade plus a state (executed, terminated…) and histories of resets, transfers, and valuations. It is the unit the lifecycle engine passes around.

A trade, trimmed to its skeleton

{} trade, identity layer only
{  "tradeIdentifier": [    {      "assignedIdentifier": [        {          "identifier": {            "value": "W22LROWP2IHZNBB6K528SW77QGFM2A41"          }        }      ],      "identifierType": "UniqueTransactionIdentifier"    }  ],  "tradeDate": {    "value": "2026-06-12"  },  "party": [    {      "partyId": [        {          "identifier": {            "value": "QW46WU5Y2RDY41BTIO66"          },          "identifierType": "LEI"        }      ],      "name": {        "value": "Pershing Square, L.P."      }    },    {      "partyId": [        {          "identifier": {            "value": "W22LROWP2IHZNBB6K528"          },          "identifierType": "LEI"        }      ],      "name": {        "value": "Goldman Sachs International"      }    }  ],  "counterparty": [    {      "role": "Party1",      "partyReference": {        "name": {          "value": "Pershing Square, L.P."        }      }    },    {      "role": "Party2",      "partyReference": {        "name": {          "value": "Goldman Sachs International"        }      }    }  ],  "product": "… NonTransferableProduct, the economic terms …",  "tradeLot": [    "… lots: quantity and price …"  ]}
The product's abstract roles finally meet the legal entities. Every payout that said "Party1 pays" now has a name attached, without the product itself ever changing.

That identifier deserves a note: the UTI is what lets two firms and a regulator agree they are even talking about the same trade.

TradeState: the lifecycle's unit of work

The lifecycle engine never passes a bare trade around. It passes TradeState: the trade, its current state, and the histories that accumulate as life happens (resetHistory, transferHistory, observationHistory, valuationHistory). Think of it as the trade plus its diary. The next lesson shows how events write new pages.

Try itOpen Trade and look at the top of the schema: the inherited block from TradableProduct is rendered first, then Trade's own fields. The inheritance from this lesson is visible right in the explorer.
◆ Checkpoint

01How does Trade relate to TradableProduct in this model version?

1 / 3