AI-Native Financial Data Foundation (20) — Product Qualification: The Product Is What Its Structure Says It Is

AI-Native Financial Data Foundation (20) — Product Qualification: The Product Is What Its Structure Says It Is

The previous articles traced the eight payout types and how they compose into products. An IRS is two InterestRatePayouts. A CDS is an InterestRatePayout plus a CreditDefaultPayout. A commodity swap is a FixedPricePayout plus a CommodityPayout.

But if the product type is expressed only through composition, how does a system know what to call it? How does the model answer the question: is this an IRS, a cross-currency swap, or an inflation swap?

The CDM’s answer: qualification. The product type is not stored. It is inferred from the payout structure.

How Qualification Works in ISDA CDM

Qualification is a set of boolean functions that inspect the economic terms and determine whether the product matches a given classification. Each function is annotated [qualification Product] and returns True or False.

An OIS is qualified by Qualify_InterestRate_IRSwap_FixedFloat_OIS. It is the canonical example because it reaches all four taxonomy levels:

func Qualify_InterestRate_IRSwap_FixedFloat_OIS:
[qualification Product]
inputs: economicTerms EconomicTerms (1..1)
output: is_product boolean (1..1)
set is_product:
Qualify_BaseProduct_IRSwap(economicTerms) = True
and Qualify_SubProduct_FixedFloat(economicTerms) = True
and Qualify_Transaction_OIS(economicTerms) = True

Three calls. Each calls the level below it. Here is the full chain from the top:

Qualify_InterestRate_IRSwap_FixedFloat_OIS
← Level 4: Transaction
├── Qualify_BaseProduct_IRSwap
← Level 2: "this is an IRS"
│ │
│ └── Qualify_AssetClass_InterestRate
← Level 1: "this is Interest Rate"
│ │
│ └── Reads: all payouts are IRPs, or the underlier is Debt/IR
├── Qualify_SubProduct_FixedFloat
← Level 3: "one fixed, one floating"
│ │
│ └── Reads: one IRP has FixedRateSpecification,
│ the other has FloatingRateSpecification
└── Qualify_Transaction_OIS
← Level 4: "overnight index swap"
└── Reads: floating leg has compoundingMethod,
resetFrequency is daily

The chain is additive. Each level narrows the classification by adding one condition.

Level 1: AssetClass → InterestRate, Credit, Equity, FX, Commodity
Level 2: BaseProduct → IRSwap, CrossCurrency, FRA, Inflation, CDS, EquitySwap, ...
Level 3: SubProduct → FixedFloat, FixedFixed, Basis, ...
Level 4: Transaction → ZeroCoupon, OIS, YoY, KnownAmount, ...
  • Level 1: is this an interest rate product?
  • Level 2: is the structure an IRS (two IRPs, recurring payments, same currency, no inflation)?
  • Level 3: is one fixed and one floating?
  • Level 4: is the floating leg an overnight compounded rate?

Not every product uses all four levels. A plain IRS stops at Level 3 — there is no Transaction distinction. An FRA stops at Level 2 — there is no SubProduct or Transaction. The taxonomy is as deep as the product family requires:

The tree starts at the payout level — not a product label. It counts IRPs. It checks the payment schedule. It checks for inflation. It checks for cross-currency. Each split is a structural condition, and each condition maps to a qualification function.

How the Functions Read the Payout Structure

The qualification functions do not read a productType field. They read the payout structure directly. Here is how Qualify_BaseProduct_IRSwap works:

func Qualify_BaseProduct_IRSwap:
set is_product:
Qualify_AssetClass_InterestRate(economicTerms) = True
and economicTerms -> payout -> InterestRatePayout count = 2
and economicTerms -> payout -> InterestRatePayout -> paymentDates count = 2
and Qualify_BaseProduct_CrossCurrency(economicTerms) = False
and economicTerms -> payout -> InterestRatePayout
-> rateSpecification -> InflationRateSpecification is absent

An IRS is: all payouts are InterestRatePayouts, exactly two of them, both have recurring payment dates, same currency, no inflation. The function reads countpaymentDatesrateSpecification, and priceQuantity.currency — all attributes we traced in the F-PAL analysis.

Here is how cross-currency is distinguished:

func Qualify_BaseProduct_CrossCurrency:
set is_product:
Qualify_AssetClass_InterestRate(economicTerms) = True
and economicTerms -> payout -> InterestRatePayout count = 2
and (payout -> priceQuantity -> quantitySchedule -> unit -> currency distinct count = 2
or (payout -> priceQuantity -> quantityMultiplier
-> fxLinkedNotionalSchedule -> varyingNotionalCurrency exists
and ...))

Cross-currency is an IRS where the two IRPs have different currencies in their quantitySchedule.

Here is how FRA is distinguished from IRS:

func Qualify_BaseProduct_Fra:
set is_product:
Qualify_AssetClass_InterestRate(economicTerms) = True
and economicTerms -> payout -> InterestRatePayout count = 2
and economicTerms -> payout -> InterestRatePayout -> paymentDate count = 2
and economicTerms -> payout -> InterestRatePayout
-> rateSpecification -> InflationRateSpecification is absent

An FRA is: two IRPs, both with single paymentDate (not recurring paymentDates), no inflation. The choice between paymentDates and paymentDate — which we analysed in previous articles as a deliberate structural distinction — is the exact attribute that separates an IRS from an FRA in the qualification logic.

The Taxonomy Infrastructure

The qualification result is stored in ProductTaxonomy, which lives on the product definition:

type ProductTaxonomy extends Taxonomy:
primaryAssetClass AssetClassEnum (0..1)
secondaryAssetClass AssetClassEnum (0..*)
productQualifier string (0..1)

productQualifier is the string output of the qualification chain. For our OIS example, it is "InterestRate_IRSwap_FixedFloat_OIS"primaryAssetClass is INTEREST_RATE. Both are populated by running the qualification functions against the payout structure.

The CDM also supports external taxonomies alongside its own. A Taxonomy type carries a source (ISDA, FpML, DTCC, CME) and a TaxonomyValue, which can be a simple string or a hierarchical classification:

type TaxonomyValue:
name string (0..1)
classification TaxonomyClassification (0..*)

A product can carry multiple taxonomy entries simultaneously:

"productTaxonomy": [
{ "primaryAssetClass": "INTEREST_RATE" },
{
"taxonomySource": "ISDA",
"productQualifier": "InterestRate_IRSwap_FixedFloat_OIS"
},
{
"taxonomySource": "FpML",
"taxonomyValue": { "value": "InterestRate:IRSwap:FixedFloat:OIS" }
}
]

The CDM-derived qualifier (InterestRate_IRSwap_FixedFloat_OIS) sits alongside the FpML-derived type from the original message. The OIS qualifies as both an IRS (two IRPs, fixed-float) and an OIS (overnight floating leg) — the qualifier captures both. The FpML entry may use a different naming convention. Both are present. Neither replaces the other.

Why Qualification Matters for AI-Native Data

Product qualification is the CDM’s answer to a fundamental data modelling question: how do you classify a financial product?

The traditional approach stores a productType field. This works until two systems disagree on the label, or a product sits at a boundary, or a new product type appears that no enum covers. The label is an assertion. It cannot be verified from the data itself.

The CDM’s approach is: the product is what its payout structure says it is. The qualification function is the proof. If someone calls a product an IRS but Qualify_BaseProduct_IRSwap returns False, the AI can explain why — there is only one InterestRatePayout, or one leg uses paymentDate instead of paymentDates, or the currencies differ. The classification is auditable because it is derived, not asserted.

For AI agents, this means:

  • A product label can be verified. Run the qualification function. Does the structure match?
  • A product can be reclassified. If a trade amendment changes a payout from floating to inflation-linked, the qualification changes automatically — no one needs to update a productType field.
  • A product at a boundary can be understood. A trade that looks like an IRS but has an FX-linked notional is a cross-currency swap, not an IRS. The qualification logic catches the structural difference.
  • An AI agent can explain the classification. “This is an IRS because it has exactly two InterestRatePayouts, both with recurring payment dates, same currency, and no inflation.” That explanation comes from the qualification function’s conditions, not from a memorised label.

Leave a comment