All Downloads are FREE. Search and download functionalities are using the official Maven repository.

.cdm-java.6.0.0-dev.72.source-code.product-qualification-func.rosetta Maven / Gradle / Ivy

namespace cdm.product.qualification
version "${project.version}"

import cdm.base.datetime.*
import cdm.base.staticdata.asset.common.*
import cdm.base.staticdata.asset.rates.*
import cdm.mapping.config.*
import cdm.product.template.*
import cdm.product.common.settlement.*
import cdm.observable.asset.*

isProduct root EconomicTerms;

func UnderlierQualification: <"Identifies whether the underlier(s) have either the specified securityType or assetClass.">
    inputs:
        underlier Underlier (1..1)  <"An Underlier is an Observable (eg Asset, Basket or Index) or a Product.">
        securityType SecurityTypeEnum (0..1)
        assetClass AssetClassEnum (0..1)
    output:
        qualifies boolean (1..1)

    set qualifies:
        ObservableQualification(underlier -> Observable, securityType, assetClass)
        or underlier -> Product -> TransferableProduct -> Instrument -> Security -> securityType = securityType
        // The EconomicTerms of any TransferableProduct or a NonTransferableProduct should be checked outside this function.

func ObservableQualification: <"Identifies whether the observable(s) have either the specified securityType or assetClass.">
    inputs:
        observable Observable (0..1)  <"An Observable is an Asset, Basket or Index.">
        securityType SecurityTypeEnum (0..1)
        assetClass AssetClassEnum (0..1)
    output:
        qualifies boolean (1..1)

    set qualifies:
        observable -> Asset -> Instrument -> Security -> securityType = securityType
        or observable -> Index ->> assetClass = assetClass
        or 
            if observable -> Basket exists
            then observable -> Basket -> basketConstituent extract [ ObservableQualification(item, securityType, assetClass) ] all = True
            else False

/*
 * COMPOSABLE PRODUCT QUALIFICATION based on ISDA Taxonomy v2
 * AssetClass - BaseProduct - SubProduct - TransactionType

 * Level 1 - ASSETCLASS:
 *  - InterestRate : Qualify_AssetClass_InsterestRate
 *  - ForeignExchange: Qualify_AssetClass_ForeignExchange
 *  - Credit: Qualify_AssetClass_Credit
 *  - Equity: Qualify_AssetClass_Equity
 *  - Commodity: Qualify_AssetClass_Commodity
 */
func Qualify_AssetClass_InterestRate: <"Qualifies a product as having the Asset Class classification Interest Rate.">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    alias optionUnderlier:
        economicTerms -> payout -> optionPayout only-element -> underlier
    alias settlementUnderlier:
        economicTerms -> payout -> settlementPayout only-element -> underlier

    set is_product:
        economicTerms -> payout -> interestRatePayout only exists
            or (economicTerms -> payout -> optionPayout only exists
                and (ObservableQualification(optionUnderlier -> Observable, SecurityTypeEnum -> Debt, AssetClassEnum -> InterestRate) 
                    or optionUnderlier -> Product -> TransferableProduct -> Instrument -> Security -> securityType = SecurityTypeEnum -> Debt
                    or if optionUnderlier -> Product exists
                        then Qualify_AssetClass_InterestRate(optionUnderlier -> Product ->> economicTerms) = True
                        else False
                ))
            or (economicTerms -> payout -> settlementPayout only exists
                and (UnderlierQualification(settlementUnderlier, SecurityTypeEnum -> Debt, AssetClassEnum -> InterestRate) 
                    or if settlementUnderlier -> Product ->> economicTerms exists
                        then Qualify_AssetClass_InterestRate(settlementUnderlier -> Product ->> economicTerms) = True
                        else False
                ))

func Qualify_AssetClass_Credit: <"Qualifies a product as having the Asset Class classification Credit Default.">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    alias optionUnderlier: economicTerms -> payout -> optionPayout only-element -> underlier
    alias settlementUnderlier:
        economicTerms -> payout -> settlementPayout only-element -> underlier
    alias performanceUnderlier:
        economicTerms -> payout -> performancePayout only-element -> underlier

    set is_product:
        economicTerms -> payout -> creditDefaultPayout only exists
            or (economicTerms -> payout -> creditDefaultPayout, economicTerms -> payout -> interestRatePayout) only exists
            or (economicTerms -> payout -> optionPayout only exists
                and (ObservableQualification(optionUnderlier -> Observable, empty, AssetClassEnum -> Credit) 
                    or if optionUnderlier -> Product exists
                        then Qualify_AssetClass_Credit(optionUnderlier -> Product ->> economicTerms) = True
                        else False
                ))
            or (economicTerms -> payout -> settlementPayout only exists
                and (UnderlierQualification(settlementUnderlier, empty, AssetClassEnum -> Credit) 
                    or if settlementUnderlier -> Product ->> economicTerms exists
                        then Qualify_AssetClass_Credit(settlementUnderlier -> Product ->> economicTerms) = True
                        else False
                ))
                    // Interest Rate Payout + Performance Payout (Total Return Swap with a debt instrument as underlier)
            or ((economicTerms -> payout -> interestRatePayout, economicTerms -> payout -> performancePayout) only exists
                and if performanceUnderlier exists
                    then (performanceUnderlier -> Observable -> Asset -> Instrument -> Loan exists or performanceUnderlier -> Observable -> Asset -> Instrument -> Security -> securityType = SecurityTypeEnum -> Debt))

func Qualify_AssetClass_ForeignExchange: <"Qualifies a product as having the Asset Class classification Foreign Exchange">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    alias optionUnderlier: economicTerms -> payout -> optionPayout only-element -> underlier
    alias settlementUnderlier:
        economicTerms -> payout -> settlementPayout only-element -> underlier

    set is_product:
        (economicTerms -> payout -> settlementPayout only exists
            and (   economicTerms -> payout -> settlementPayout -> underlier -> Observable -> Asset -> Cash exists
                or  UnderlierQualification(settlementUnderlier, empty, AssetClassEnum -> ForeignExchange))
            )
            or economicTerms -> payout -> performancePayout -> underlier -> Observable -> Index -> ForeignExchangeRateIndex exists
            or (economicTerms -> payout -> optionPayout only exists
                and (optionUnderlier -> Observable -> Asset -> Cash exists
                    or if optionUnderlier -> Product exists
                    then Qualify_AssetClass_ForeignExchange(optionUnderlier -> Product ->> economicTerms) = True
                    else False
            ))

func Qualify_AssetClass_Equity:
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    alias optionUnderlier: economicTerms -> payout -> optionPayout only-element -> underlier
    alias settlementUnderlier:
        economicTerms -> payout -> settlementPayout only-element -> underlier

    set is_product:
        (economicTerms -> payout -> performancePayout -> underlier -> Observable
            extract Qualify_UnderlierObservable_Equity
            then all = True
                    and ( // Interest Rate Payout + Performance Payout (Price Return Swap, Total Return Swap)
                    (economicTerms -> payout -> interestRatePayout, economicTerms -> payout -> performancePayout) only exists
                        // Performance Payout + Fixed Price Payout (Dividend Swap)
                        or (economicTerms -> payout -> performancePayout, economicTerms -> payout -> fixedPricePayout) only exists
                            // Performance Payout only (Variance, Volatility and Correlation Swap)
                or economicTerms -> payout -> performancePayout only exists))
            or (economicTerms -> payout -> optionPayout only exists
                and (Qualify_UnderlierObservable_Equity(optionUnderlier -> Observable) 
                    or if optionUnderlier -> Product exists
                        then Qualify_AssetClass_Equity(optionUnderlier -> Product ->> economicTerms) = True
                        else False
                ))
            or (economicTerms -> payout -> settlementPayout only exists
                and (Qualify_UnderlierObservable_Equity(settlementUnderlier -> Observable) 
                    or if settlementUnderlier -> Product ->> economicTerms exists
                        then Qualify_AssetClass_Equity(
									settlementUnderlier -> Product ->> economicTerms) = True
                        else False
                ))

func Qualify_AssetClass_Commodity: <"Qualifies a product as having the Asset Class classification Commodity">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    alias optionUnderlier:
        economicTerms -> payout -> optionPayout only-element -> underlier

    alias settlementUnderlier:
        economicTerms -> payout -> settlementPayout only-element -> underlier

    set is_product:
        // Regular Commodity Swap
        ( economicTerms -> payout -> commodityPayout, economicTerms -> payout -> fixedPricePayout) only exists
        // Commodity Basis Swap
            or (economicTerms -> payout -> commodityPayout only exists
            and economicTerms -> payout -> commodityPayout count = 2)
        // Commodity Option
            or (economicTerms -> payout -> optionPayout only exists
                and (optionUnderlier -> Observable -> Asset -> Commodity exists
                    or optionUnderlier -> Product -> TransferableProduct -> Commodity exists
                    or if optionUnderlier -> Product exists
                    then Qualify_AssetClass_Commodity(optionUnderlier -> Product ->> economicTerms) = True
                    else False
                ))          
        // Commodity Spot or Forward
            or (((economicTerms -> payout -> settlementPayout, economicTerms -> payout -> fixedPricePayout) only exists
                    or (economicTerms -> payout -> settlementPayout, economicTerms -> payout -> commodityPayout) only exists)
                and (economicTerms -> payout -> settlementPayout -> underlier -> Observable -> Asset -> Commodity exists
                    or settlementUnderlier -> Product -> TransferableProduct -> Commodity exists
                    or if settlementUnderlier -> Product ->> economicTerms exists
                        then Qualify_AssetClass_Commodity(
						settlementUnderlier -> Product ->> economicTerms) = True
                    else False
            ))        

/*
 * ENDOF Qualification of ISDA Taxonomy V2 Level 1 - ASSETCLASS:
 */
func Qualify_CreditDefaultSwap_SingleName: <"Qualifies a product as a Credit Default Swap which provides protection relative to defaults of a reference entity that could be a corporate, municipal, sovererign, or special purpose vehicle issuer of publically traded debt.  The determination of the qualification is based on the economic terms and the following criteria: 1) A product with one credit default leg and one interest leg, 2) the reference entity is corporate, municipal, or sovereign issuer of debt, 3) the reference obligation is not a loan, and 4) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        Qualify_AssetClass_Credit(economicTerms) = True
                // qualifies the Credit Default Swap as having a single name underlyer that is not a loan
            and economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists
            and economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referenceObligation -> loan is absent

func Qualify_CreditDefaultSwap_Index: <"Qualifies a product as a Credit Default Swap which provides protection relative to the performance of an index. The determination of the qualification is based on the economic terms and the following criteria: 1) A product with one credit default leg and one interest leg, 2) the reference entity is an index, and 3) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        Qualify_AssetClass_Credit(economicTerms) = True
                // qualifies the Credit Default Swap as having a single name underlyer that is not a loan
            and economicTerms -> payout -> creditDefaultPayout -> generalTerms -> indexReferenceInformation exists
            and economicTerms -> payout -> creditDefaultPayout -> generalTerms -> indexReferenceInformation -> tranche is absent

func Qualify_CreditDefaultSwap_IndexTranche: <"Qualifies a product as a Credit Default Swap which provides protection relative to the performance of an index. The determination of the qualification is based on the economic terms and the following criteria: 1) A product with one credit default leg and one interest leg, 2) the reference entity is an index, and 3) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        Qualify_AssetClass_Credit(economicTerms) = True
                // qualifies the Credit Default Swap as having a single name underlyer that is not a loan
            and economicTerms -> payout -> creditDefaultPayout -> generalTerms -> indexReferenceInformation exists
            and economicTerms -> payout -> creditDefaultPayout -> generalTerms -> indexReferenceInformation -> tranche exists

func Qualify_CreditDefaultSwap_Loan: <"Qualifies a product as a Credit Default Swap which provides protection relative to defaults of a reference entity that is a loan. The determination of the qualification is based on the economic terms and the following criteria: 1) A product with one credit default leg and one interest leg, 2) the reference entity is a loan, and there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        Qualify_AssetClass_Credit(economicTerms) = True
                // qualifies the Credit Default Swap as having a single name underlyer that is not a loan
            and economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists
            and economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referenceObligation -> loan exists

func Qualify_CreditDefaultSwap_Basket: <"Qualifies a product as a Credit Default Swap which provides protection relative to defaults of a reference entity that is a loan. The determination of the qualification is based on the economic terms and the following criteria: 1) A product with one credit default leg and one interest leg, 2) the reference entity is a loan, and there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        Qualify_AssetClass_Credit(economicTerms) = True
                // qualifies the Credit Default Swap as having a single name underlyer that is not a loan
            and economicTerms -> payout -> creditDefaultPayout -> generalTerms -> basketReferenceInformation exists

func Qualify_CreditDefaultSwaption: <"This product qualification is temporary until such time that the ISDA Credit Group specifies a proper taxonomy for credit derivatives that is based upon economic terms.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        economicTerms -> payout -> optionPayout only exists
            and Qualify_AssetClass_Credit(
                    economicTerms -> payout -> optionPayout only-element -> underlier -> Product ->> economicTerms
                ) = True

func Qualify_UnderlierObservable_Equity: <"Qualifies an Observable as having the Asset Class classification Equity.">
    inputs:
        observable Observable (1..1)
    output:
        is_product boolean (1..1)

    set is_product:
        Qualify_SecurityTypeEquity(observable -> Asset -> Instrument -> Security)
            or observable -> Index ->> assetClass = AssetClassEnum -> Equity
                // Qualifies that the underlier is a basket composed of equity products only
            or (observable -> Basket exists
                and observable -> Basket -> basketConstituent extract [ Qualify_UnderlierObservable_Equity ] any = True)

func Qualify_SecurityTypeEquity: <"Qualifies that the security type, for all of the provided securities, is Equity-related.">
    inputs:
        security Security (1..1)
    output:
        is_equity boolean (1..1)

    set is_equity:
        security -> securityType = SecurityTypeEnum -> Equity
            or (security -> securityType = SecurityTypeEnum -> Fund
                and security -> fundType = FundProductTypeEnum -> ExchangeTradedFund)
            or (security -> securityType = SecurityTypeEnum -> Fund
                and security -> fundType = FundProductTypeEnum -> MutualFund)
            or security -> securityType = SecurityTypeEnum -> Warrant 

func Qualify_BaseProduct_EquitySwap: <"Qualifies a product as having the Asset Class classification Equity and Base Product Classification Swap.">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    set is_product:
        // all underliers must be equity asset class
        Qualify_AssetClass_Equity(economicTerms) = True
            and ( // Interest Rate Payout + Performance Payout (Price Return Swap, Total Return Swap)
            (economicTerms -> payout -> interestRatePayout, economicTerms -> payout -> performancePayout) only exists
                // Performance Payout + Fixed Price Payout (Dividend Swap)
                or (economicTerms -> payout -> performancePayout, economicTerms -> payout -> fixedPricePayout) only exists
                    // Performance Payout only (Variance, Volatility and Correlation Swap)
                or economicTerms -> payout -> performancePayout only exists)

func Qualify_EquitySwap_PriceReturnBasicPerformance_SingleName: <"Qualifies a product as an Equity Swap for which the performance is based on the price change on a single stock.  The determination of the qualification is based on the economic terms and the following criteria: 1) An equity product with one performance leg and one interest leg 2) with the former featuring priceReturnTerms, 3) the underlier is an equity security, a fund, an exchange traded fund, mutual fund, or warrant, and 4) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquitySwap_PriceReturnBasicPerformance_SingleName"]
            [synonym ISDA_Taxonomy_v2 value "EquitySwap_PriceReturnBasicPerformance_SingleName"]

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that there is exactly one performance leg, one interest rate leg and no legs of other types
            (economicTerms -> payout -> interestRatePayout, economicTerms -> payout -> performancePayout) only exists
            and economicTerms -> payout -> interestRatePayout count = 1
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the performance leg has priceReturnTerms
            performancePayout -> returnTerms -> priceReturnTerms only exists
            and // qualifies that underlier is a security (single name)
            performancePayout -> underlier -> Observable -> Asset -> Instrument -> Security exists

func Qualify_EquitySwap_TotalReturnBasicPerformance_SingleName: <"Qualifies a product as an Equity Swap for which the performance is based on the price changes and dividend returns on a single stock.  The determination of the qualification is based on the economic terms and the following criteria: 1) An equity product with one performance leg and one interest leg 2) with the former featuring priceReturnTerms and dividendReturnTerms, 3) the underlier is an equity security, a fund, an exchange traded fund, mutual fund, or warrant, and 4) there are no option features">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that underlier is a security (single name)
            economicTerms -> payout -> performancePayout -> underlier -> Observable -> Asset -> Instrument -> Security exists
            and ( // Intended final payout structure
            // qualifies that there is exactly two performance legs, one interest rate leg and no legs of other types
            ((economicTerms -> payout -> interestRatePayout, economicTerms -> payout -> performancePayout) only exists
                    and economicTerms -> payout -> interestRatePayout count = 1
                    and economicTerms -> payout -> performancePayout count = 2)
                or // Provisional payout structure
                // qualifies that there is 1 performance leg, 1 interest rate leg and no legs of other types
                ((economicTerms -> payout -> interestRatePayout, economicTerms -> payout -> performancePayout) only exists
                    and economicTerms -> payout -> interestRatePayout count = 1
                    and economicTerms -> payout -> performancePayout count = 1))
            and // qualifies that there is a performancePayout with dividendReturnTerms and another with priceReturnTerms
            economicTerms -> payout -> performancePayout -> returnTerms -> priceReturnTerms exists
            and economicTerms -> payout -> performancePayout -> returnTerms -> dividendReturnTerms exists

func Qualify_EquitySwap_PriceReturnBasicPerformance_Index: <"Qualifies a product as an Equity Swap for which the performance is based on the price change on an index.  The determination of the qualification is based on the economic terms and the following criteria: 1) An equity product with one performance leg and one interest leg 2) with the former featuring priceReturnTerms, 3) the underlier is an index, and 4) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquitySwap_PriceReturnBasicPerformance_SingleIndex"]
            [synonym ISDA_Taxonomy_v2 value "EquitySwap_PriceReturnBasicPerformance_SingleIndex"]

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that there is exactly one performance leg, one interest rate leg and no legs of other types
            (economicTerms -> payout -> interestRatePayout, economicTerms -> payout -> performancePayout) only exists
            and economicTerms -> payout -> interestRatePayout count = 1
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the performance leg has priceReturnTerms
            performancePayout -> returnTerms -> priceReturnTerms only exists
            and // qualifies that underlier is an index
            performancePayout -> underlier -> Observable -> Index exists

func Qualify_EquitySwap_TotalReturnBasicPerformance_Index: <"Qualifies a product as an Equity Swap for which the performance is based on the price changes and dividend returns on an index.  The determination of the qualification is based on the economic terms and the following criteria: 1) An equity product with one performance leg and one interest leg 2) with the former featuring priceReturnTerms and dividendReturnTerms, 3) the underlier is an index, and 4) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that underlier is an index
            economicTerms -> payout -> performancePayout -> underlier -> Observable -> Index exists
            and ( // Intended final payout structure
            // qualifies that there is exactly two performance legs, one interest rate leg and no legs of other types
            ((economicTerms -> payout -> interestRatePayout, economicTerms -> payout -> performancePayout) only exists
                    and economicTerms -> payout -> interestRatePayout count = 1
                    and economicTerms -> payout -> performancePayout count = 2)
                or // Provisional payout structure
                // qualifies that there is 1 performance leg, 1 interest rate leg and no legs of other types
                ((economicTerms -> payout -> interestRatePayout, economicTerms -> payout -> performancePayout) only exists
                    and economicTerms -> payout -> interestRatePayout count = 1
                    and economicTerms -> payout -> performancePayout count = 1))
            and // qualifies that there is a performancePayout with dividendReturnTerms and another with priceReturnTerms
            economicTerms -> payout -> performancePayout -> returnTerms -> priceReturnTerms exists
            and economicTerms -> payout -> performancePayout -> returnTerms -> dividendReturnTerms exists

func Qualify_EquitySwap_PriceReturnBasicPerformance_Basket: <"Qualifies a product as an Equity Swap for which the performance is based on the price change on a basket.  The determination of the qualification is based on the economic terms and the following criteria: 1) An equity product with one performance leg and one interest leg 2) with the former featuring priceReturnTerms, 3) the underlier is a basket and 4) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquitySwap_PriceReturnBasicPerformance_Basket"]
            [synonym ISDA_Taxonomy_v2 value "EquitySwap_PriceReturnBasicPerformance_Basket"]

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that there is exactly one performance leg, one interest rate leg and no legs of other types
            (economicTerms -> payout -> interestRatePayout, economicTerms -> payout -> performancePayout) only exists
            and economicTerms -> payout -> interestRatePayout count = 1
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that underlier is a basket
            performancePayout -> underlier -> Observable -> Basket exists
            and // qualifies that the performance leg has priceReturnTerms
            performancePayout -> returnTerms -> priceReturnTerms only exists

func Qualify_EquitySwap_TotalReturnBasicPerformance_Basket: <"Qualifies a product as an Equity Swap for which the performance is based on the price changes and dividend returns on a basket.  The determination of the qualification is based on the economic terms and the following criteria: 1) An equity product with one performance leg and one interest leg 2) with the former featuring priceReturnTerms and dividendReturnTerms, 3) the underlier is a basket and 4) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that underlier is a basket
            economicTerms -> payout -> performancePayout -> underlier -> Observable -> Basket exists
            and ( // Intended final payout structure
            // qualifies that there is exactly two performance legs, one interest rate leg and no legs of other types
            ((economicTerms -> payout -> interestRatePayout, economicTerms -> payout -> performancePayout) only exists
                    and economicTerms -> payout -> interestRatePayout count = 1
                    and economicTerms -> payout -> performancePayout count = 2)
                or // Provisional payout structure
                // qualifies that there is 1 performance leg, 1 interest rate leg and no legs of other types
                ((economicTerms -> payout -> interestRatePayout, economicTerms -> payout -> performancePayout) only exists
                    and economicTerms -> payout -> interestRatePayout count = 1
                    and economicTerms -> payout -> performancePayout count = 1))
            and // qualifies that there is a performancePayout with dividendReturnTerms and another with priceReturnTerms
            economicTerms -> payout -> performancePayout -> returnTerms -> priceReturnTerms exists
            and economicTerms -> payout -> performancePayout -> returnTerms -> dividendReturnTerms exists

func Qualify_EquitySwap_ParameterReturnVariance_SingleName: <"Qualifies a product as an Equity Swap for which the performance is based on the variance changes on a single stock.  The determination of the qualification is based on the economic terms and the following criteria: 1) Is an equity product 2) of swap type, 3) with a single performance leg, 4) which has variance return terms, 4) the underlier is a single stock, and 5) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquitySwap_ParameterReturnVariance_SingleName"]
            [synonym ISDA_Taxonomy_v2 value "EquitySwap_ParameterReturnVariance_SingleName"]

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that there is a single leg of performance type
            economicTerms -> payout -> performancePayout only exists
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the only leg has varianceReturnTerms
            performancePayout -> returnTerms -> varianceReturnTerms only exists
            and // qualifies that underlier is a security (single name)
            performancePayout -> underlier -> Observable -> Asset -> Instrument -> Security exists

func Qualify_EquitySwap_ParameterReturnVariance_Index: <"Qualifies a product as an Equity Swap for which the performance is based on the variance changes on an index.  The determination of the qualification is based on the economic terms and the following criteria: 1) Is an equity product 2) of swap type, 3) with a single performance leg, 4) which has variance return terms, 5) the underlier is an index, and 6) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquitySwap_ParameterReturnVariance_SingleIndex"]
            [synonym ISDA_Taxonomy_v2 value "EquitySwap_ParameterReturnVariance_SingleIndex"]

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that there is a single leg of performance type
            economicTerms -> payout -> performancePayout only exists
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the only leg has varianceReturnTerms
            performancePayout -> returnTerms -> varianceReturnTerms only exists
            and // qualifies that underlier is an index
            performancePayout -> underlier -> Observable -> Index exists

func Qualify_EquitySwap_ParameterReturnVariance_Basket: <"Qualifies a product as an Equity Swap for which the performance is based on the variance changes on a basket.  The determination of the qualification is based on the economic terms and the following criteria: 1) Is an equity product 2) of swap type, 3) with a single performance leg, 4) which has variance return terms, 5) the underlier is a basket, and 6) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquitySwap_ParameterReturnVariance_Basket"]
            [synonym ISDA_Taxonomy_v2 value "EquitySwap_ParameterReturnVariance_Basket"]

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that there is a single leg of performance type
            economicTerms -> payout -> performancePayout only exists
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the only leg has varianceReturnTerms
            performancePayout -> returnTerms -> varianceReturnTerms only exists
            and // qualifies that underlier is a basket
            performancePayout -> underlier -> Observable -> Basket exists

func Qualify_EquitySwap_ParameterReturnDispersion: <"Qualifies a product as an Equity Swap for which the performance is based on the variance changes in several legs.  The determination of the qualification is based on the economic terms and the following criteria: 1) Is an equity product 2) of swap type, 3) more than one performance leg, 4) all of which have variance return terms, and 5) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that there is more than one leg of performance type
            economicTerms -> payout -> performancePayout only exists
            and economicTerms -> payout -> performancePayout count > 1
            and // qualifies that all legs have varianceReturnTerms
            economicTerms -> payout -> performancePayout -> returnTerms -> varianceReturnTerms count > 1
            and economicTerms -> payout -> performancePayout -> returnTerms -> volatilityReturnTerms is absent
            and economicTerms -> payout -> performancePayout -> returnTerms -> correlationReturnTerms is absent
            and economicTerms -> payout -> performancePayout -> returnTerms -> priceReturnTerms is absent
            and economicTerms -> payout -> performancePayout -> returnTerms -> dividendReturnTerms is absent

func Qualify_EquitySwap_ParameterReturnVolatility_SingleName: <"Qualifies a product as an Equity Swap for which the performance is based on the volatility changes on a single stock.  The determination of the qualification is based on the economic terms and the following criteria: 1) Is an equity product 2) of swap type, 3) with a single performance leg, 4) which has volatility return terms, 5) the underlier is a single stock, and 6) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquitySwap_ParameterReturnVolatility_SingleName"]
            [synonym ISDA_Taxonomy_v2 value "EquitySwap_ParameterReturnVolatility_SingleName"]

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that there is a single leg of performance type
            economicTerms -> payout -> performancePayout only exists
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the only leg has volatilityReturnTerms
            performancePayout -> returnTerms -> volatilityReturnTerms only exists
            and // qualifies that underlier is a security (single name)
            performancePayout -> underlier -> Observable -> Asset -> Instrument -> Security exists

func Qualify_EquitySwap_ParameterReturnVolatility_Index: <"Qualifies a product as an Equity Swap for which the performance is based on the volatility changes on an index.  The determination of the qualification is based on the economic terms and the following criteria: 1) Is an equity product 2) of swap type, 3) with a single performance leg, 4) which has volatility return terms, 5) the underlier is an index, and 6) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquitySwap_ParameterReturnVolatility_SingleIndex"]
            [synonym ISDA_Taxonomy_v2 value "EquitySwap_ParameterReturnVolatility_SingleIndex"]

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that there is a single leg of performance type
            economicTerms -> payout -> performancePayout only exists
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the only leg has volatilityReturnTerms
            performancePayout -> returnTerms -> volatilityReturnTerms only exists
            and // qualifies that underlier is an index
            performancePayout -> underlier -> Observable -> Index exists

func Qualify_EquitySwap_ParameterReturnVolatility_Basket: <"Qualifies a product as an Equity Swap for which the performance is based on the volatility changes on a basket.  The determination of the qualification is based on the economic terms and the following criteria: 1) Is an equity product 2) of swap type, 3) with a single performance leg, 4) which has volatility return terms, 5) the underlier is a basket, and 6) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquitySwap_ParameterReturnVolatility_Basket"]
            [synonym ISDA_Taxonomy_v2 value "EquitySwap_ParameterReturnVolatility_Basket"]

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that there is a single leg of performance type
            economicTerms -> payout -> performancePayout only exists
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the only leg has varianceReturnTerms
            performancePayout -> returnTerms -> volatilityReturnTerms only exists
            and // qualifies that underlier is a basket
            performancePayout -> underlier -> Observable -> Basket exists

func Qualify_EquitySwap_ParameterReturnCorrelation_Basket: <"Qualifies a product as an Equity Swap for which the performance is based on changes in the correlation between the constituents of a basket.  The determination of the qualification is based on the economic terms and the following criteria: 1) Is an equity product 2) of swap type, 3) with a single performance leg, 4) which has correlation return terms, 5) the underlier is a basket, and 6) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that there is a single leg of performance type
            economicTerms -> payout -> performancePayout only exists
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the only leg has varianceReturnTerms
            performancePayout -> returnTerms -> correlationReturnTerms only exists
            and // qualifies that underlier is a basket
            performancePayout -> underlier -> Observable -> Basket exists

func Qualify_EquitySwap_ParameterReturnDividend_SingleName: <"Qualifies a product as an Equity Swap for which the performance is based on the dividend returns of a single stock.  The determination of the qualification is based on the economic terms and the following criteria: 1) Is an equity product 2) of swap type, 3) with one fixed price leg and one performance leg 4) which has dividend return terms, 5) the underlier is a single stock, and 6) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquitySwap_ParameterReturnDividend_SingleName"]
            [synonym ISDA_Taxonomy_v2 value "EquitySwap_ParameterReturnDividend_SingleName"]

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that there is one fixed price and one performance payout
            (economicTerms -> payout -> performancePayout, economicTerms -> payout -> fixedPricePayout) only exists
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the performance Payout has dividendReturnTerms
            performancePayout -> returnTerms -> dividendReturnTerms only exists
            and // qualifies that underlier is a security (single name)
            performancePayout -> underlier -> Observable -> Asset -> Instrument -> Security exists

func Qualify_EquitySwap_ParameterReturnDividend_Index: <"Qualifies a product as an Equity Swap for which the performance is based on the dividend returns of an index.  The determination of the qualification is based on the economic terms and the following criteria: 1) Is an equity product 2) of swap type, 3) with one fixed price leg and one performance leg 4) which has dividend return terms, 5) the underlier is an index, and 6) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquitySwap_ParameterReturnDividend_SingleIndex"]
            [synonym ISDA_Taxonomy_v2 value "EquitySwap_ParameterReturnDividend_SingleIndex"]

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that there is one fixed price and one performance payout
            (economicTerms -> payout -> performancePayout, economicTerms -> payout -> fixedPricePayout) only exists
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the performance Payout has dividendReturnTerms
            performancePayout -> returnTerms -> dividendReturnTerms only exists
            and // qualifies that underlier is an index
            performancePayout -> underlier -> Observable -> Index exists

func Qualify_EquitySwap_ParameterReturnDividend_Basket: <"Qualifies a product as an Equity Swap for which the performance is based on the dividend returns of a basket.  The determination of the qualification is based on the economic terms and the following criteria: 1) Is an equity product 2) of swap type, 3) with one fixed price leg and one performance leg 4) which has dividend return terms, 5) the underlier is a basket, and 6) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquitySwap_ParameterReturnDividend_Basket"]
            [synonym ISDA_Taxonomy_v2 value "EquitySwap_ParameterReturnDividend_Basket"]

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        // qualifies that the Base Product is an Equity Swap (i.e.: only performance, interest rate or fixed price payouts)
        Qualify_BaseProduct_EquitySwap(economicTerms) = True
            and // qualifies that there is one fixed price and one performance payout
            (economicTerms -> payout -> performancePayout, economicTerms -> payout -> fixedPricePayout) only exists
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the performance Payout has dividendReturnTerms
            performancePayout -> returnTerms -> dividendReturnTerms only exists
            and // qualifies that underlier is a security (single name)
            performancePayout -> underlier -> Observable -> Basket exists

func Qualify_BaseProduct_EquityForward: <"Qualifies a product as having the Asset Class classification Equity and Base Product Classification Forward.">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        Qualify_AssetClass_Equity(economicTerms) = True
            and economicTerms -> payout -> settlementPayout only exists

func Qualify_EquityOption_PriceReturnBasicPerformance_SingleName: <"Qualifies a product as a plain vanilla Equity Option.  The determination of the qualification is based on the economic terms and the following criteria: 1) An option product  for which the underlier is a single stock and 2) No special option feature exists other than option averaging."> //
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquityOption_PriceReturnBasicPerformance_SingleName"]
            [synonym ISDA_Taxonomy_v2 value "EquityOption_PriceReturnBasicPerformance_SingleName"]
    alias optionUnderlier: economicTerms -> payout -> optionPayout only-element -> underlier
    set is_product:
        Qualify_AssetClass_Equity(economicTerms) = True
                // qualifies that only the option payout exist and all other payouts are absent
            and economicTerms -> payout -> optionPayout only exists
                // qualifies that the underlier is an asset
            and economicTerms -> payout -> optionPayout only-element -> underlier -> Observable -> Asset exists
                // qualifies that the underlier is a security (already verified as equity)
            and optionUnderlier -> Observable -> Asset -> Instrument -> Security only exists 
                    // qualifies that no feature other than averaging exists
            and (economicTerms -> payout -> optionPayout -> feature is absent
                or economicTerms -> payout -> optionPayout -> feature -> averagingFeature only exists)

func Qualify_EquityOption_PriceReturnBasicPerformance_Index: <"Qualifies a product as an Equity Option with an index as underlier.  The determination of the qualification is based on the economic terms and the following criteria: 1) An option product  for which the underlier is an index and 2) No special option feature exists other than option averaging.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquityOption_PriceReturnBasicPerformance_SingleIndex"]
            [synonym ISDA_Taxonomy_v2 value "EquityOption_PriceReturnBasicPerformance_SingleIndex"]
    set is_product:
        Qualify_AssetClass_Equity(economicTerms) = True
                // qualifies that only the option payout exist and all other payouts are absent
            and economicTerms -> payout -> optionPayout only exists
                // qualifies that the underlier is an equity index
            and economicTerms -> payout -> optionPayout only-element -> underlier -> Observable -> Index -> EquityIndex exists
                // qualifies that no feature other than averaging exists
            and (economicTerms -> payout -> optionPayout -> feature is absent
                or economicTerms -> payout -> optionPayout -> feature -> averagingFeature only exists)

func Qualify_EquityOption_PriceReturnBasicPerformance_Basket: <"Qualifies a product as an Equity Option with a basket underlier.  The determination of the qualification is based on the economic terms and the following criteria: 1) An option product  for which the underlier is a basket and 2) No special option feature exists other than option averaging.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquityOption_PriceReturnBasicPerformance_Basket"]
            [synonym ISDA_Taxonomy_v2 value "EquityOption_PriceReturnBasicPerformance_Basket"]
    set is_product:
        Qualify_AssetClass_Equity(economicTerms) = True
                // qualifies that only the option payout exist and all other payouts are absent
            and economicTerms -> payout -> optionPayout only exists
                // qualifies that the underlier is an equity basket
            and economicTerms -> payout -> optionPayout only-element -> underlier -> Observable -> Basket exists
                // qualifies that no feature other than averaging exists
            and (economicTerms -> payout -> optionPayout -> feature is absent
                or economicTerms -> payout -> optionPayout -> feature -> averagingFeature only exists)

func Qualify_EquityOption_ParameterReturnVariance_SingleName: <"Qualifies a product as an Equity Variance Single Name Option.  The determination of the qualification is based on the economic terms and the following criteria: 1) The product contains a single option payout and 2) the underlying product is a Single Name Equity Variance Swap">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquityOption_ParameterReturnVariance_SingleName"]
            [synonym ISDA_Taxonomy_v2 value "EquityOption_ParameterReturnVariance_SingleName"]

    alias underlierEconomicTerms:
        economicTerms -> payout -> optionPayout -> underlier -> Product ->> economicTerms only-element
    set is_product:
        // qualifies that only the option payout exist and all other payouts are absent
        economicTerms -> payout -> optionPayout only exists
            // qualifies that the underlier is a single name variance swap
            and Qualify_EquitySwap_ParameterReturnVariance_SingleName(
                    underlierEconomicTerms
                ) = True

func Qualify_EquityOption_ParameterReturnVariance_Index: <"Qualifies a product as an Equity Variance Index Option.  The determination of the qualification is based on the economic terms and the following criteria: 1) The product contains a single option payout and 2) the underlying product is aan Index Equity Variance Swap">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquityOption_ParameterReturnVariance_SingleIndex"]
            [synonym ISDA_Taxonomy_v2 value "EquityOption_ParameterReturnVariance_SingleIndex"]

    alias underlierEconomicTerms:
        economicTerms -> payout -> optionPayout -> underlier -> Product ->> economicTerms only-element
    set is_product:
        // qualifies that only the option payout exist and all other payouts are absent
        economicTerms -> payout -> optionPayout only exists
            // qualifies that the underlier is an index variance swap
            and Qualify_EquitySwap_ParameterReturnVariance_Index(underlierEconomicTerms) = True

// and Qualify_EquitySwap_ParameterReturnVariance_Index (economicTerms -> payout -> optionPayout -> underlier -> contractualProduct -> economicTerms only-element) = True
func Qualify_EquityOption_ParameterReturnVariance_Basket: <"Qualifies a product as an Equity Variance Basket Option.  The determination of the qualification is based on the economic terms and the following criteria: 1) The product contains a single option payout and 2) the underlying product is a Basket Equity Variance Swap">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "Qualify_EquityOption_ParameterReturnVariance_Basket"]
            [synonym ISDA_Taxonomy_v2 value "Qualify_EquityOption_ParameterReturnVariance_Basket"]

    alias underlierEconomicTerms:
        economicTerms -> payout -> optionPayout -> underlier -> Product ->> economicTerms only-element
    set is_product:
        // qualifies that only the option payout exist and all other payouts are absent
        economicTerms -> payout -> optionPayout only exists
            // qualifies that the underlier is a basket variance swap
            and Qualify_EquitySwap_ParameterReturnVariance_Basket(underlierEconomicTerms) = True

func Qualify_EquityOption_ParameterReturnVolatility_SingleName: <"Qualifies a product as an Equity Volatility Single Name Option.  The determination of the qualification is based on the economic terms and the following criteria: 1) The product contains a single option payout and 2) the underlying product is a Single Name Equity Volatility Swap">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquityOption_ParameterReturnVolatility_SingleName"]
            [synonym ISDA_Taxonomy_v2 value "EquityOption_ParameterReturnVolatility_SingleName"]

    alias underlierEconomicTerms:
        economicTerms -> payout -> optionPayout -> underlier -> Product ->> economicTerms only-element
    set is_product:
        // qualifies that only the option payout exist and all other payouts are absent
        economicTerms -> payout -> optionPayout only exists
            // qualifies that the underlier is a single name volatility swap
            and Qualify_EquitySwap_ParameterReturnVolatility_SingleName(
                    underlierEconomicTerms
                ) = True

func Qualify_EquityOption_ParameterReturnVolatility_Index: <"Qualifies a product as an Equity Volatility Index Option.  The determination of the qualification is based on the economic terms and the following criteria: 1) The product contains a single option payout and 2) the underlying product is aan Index Equity Volatility Swap">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "EquityOption_ParameterReturnVolatility_SingleIndex"]
            [synonym ISDA_Taxonomy_v2 value "EquityOption_ParameterReturnVolatility_SingleIndex"]

    alias underlierEconomicTerms:
        economicTerms -> payout -> optionPayout -> underlier -> Product ->> economicTerms only-element
    set is_product:
        // qualifies that only the option payout exist and all other payouts are absent
        economicTerms -> payout -> optionPayout only exists
            // qualifies that the underlier is an index volatility swap
            and Qualify_EquitySwap_ParameterReturnVolatility_Index(underlierEconomicTerms) = True

func Qualify_EquityOption_ParameterReturnVolatility_Basket: <"Qualifies a product as an Equity Volatility Basket Option.  The determination of the qualification is based on the economic terms and the following criteria: 1) The product contains a single option payout and 2) the underlying product is a Basket Equity Volatility Swap">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "Qualify_EquityOption_ParameterReturnVolatility_Basket"]
            [synonym ISDA_Taxonomy_v2 value "Qualify_EquityOption_ParameterReturnVaolatility_Basket"]

    alias underlierEconomicTerms:
        economicTerms -> payout -> optionPayout -> underlier -> Product ->> economicTerms only-element
    set is_product:
        // qualifies that only the option payout exist and all other payouts are absent
        economicTerms -> payout -> optionPayout only exists
            // qualifies that the underlier is a basket volatility swap
            and Qualify_EquitySwap_ParameterReturnVolatility_Basket(underlierEconomicTerms) = True

func Qualify_EquityOption_ParameterReturnCorrelation_Basket: <"Qualifies a product as an Equity Correlation Basket Option.  The determination of the qualification is based on the economic terms and the following criteria: 1) The product contains a single option payout and 2) the underlying product is a Basket Equity Correlation Swap">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    alias underlierEconomicTerms:
        economicTerms -> payout -> optionPayout -> underlier -> Product ->> economicTerms only-element
    set is_product:
        // qualifies that only the option payout exist and all other payouts are absent
        economicTerms -> payout -> optionPayout only exists
            // qualifies that the underlier is a basket correlation swap
            and Qualify_EquitySwap_ParameterReturnCorrelation_Basket(underlierEconomicTerms) = True

func Qualify_EquityOption_ParameterReturnDividend_SingleName: <"Qualifies a product as an Equity Dividend Single Name Option.  The determination of the qualification is based on the economic terms and the following criteria: 1) The product contains a single option payout and 2) the underlying product is a Single Name Equity Dividend Swap">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "Qualify_EquityOption_ParameterReturnDividend_SingleName"]
            [synonym ISDA_Taxonomy_v2 value "Qualify_EquityOption_ParameterReturnDividend_SingleName"]

    alias underlierEconomicTerms:
        economicTerms -> payout -> optionPayout -> underlier -> Product ->> economicTerms only-element
    set is_product:
        // qualifies that only the option payout exist and all other payouts are absent
        economicTerms -> payout -> optionPayout only exists
            // qualifies that the underlier is a single name dividend swap
            and Qualify_EquitySwap_ParameterReturnDividend_SingleName(
                    underlierEconomicTerms
                ) = True

func Qualify_EquityOption_ParameterReturnDividend_Index: <"Qualifies a product as an Equity Dividend Index Option.  The determination of the qualification is based on the economic terms and the following criteria: 1) The product contains a single option payout and 2) the underlying product is an Index Equity Dividend Swap">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "Qualify_EquityOption_ParameterReturnDividend_SingleIndex"]
            [synonym ISDA_Taxonomy_v2 value "Qualify_EquityOption_ParameterReturnDividend_SingleIndex"]

    alias underlierEconomicTerms:
        economicTerms -> payout -> optionPayout -> underlier -> Product ->> economicTerms only-element
    set is_product:
        // qualifies that only the option payout exist and all other payouts are absent
        economicTerms -> payout -> optionPayout only exists
            // qualifies that the underlier is a single name dividend swap
            and Qualify_EquitySwap_ParameterReturnDividend_Index(underlierEconomicTerms) = True

func Qualify_EquityOption_ParameterReturnDividend_Basket: <"Qualifies a product as an Equity Dividend Basket Option.  The determination of the qualification is based on the economic terms and the following criteria: 1) The product contains a single option payout and 2) the underlying product is a Basket Equity Dividend Swap">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "Qualify_EquityOption_ParameterReturnDividend_Basket"]
            [synonym ISDA_Taxonomy_v2 value "Qualify_EquityOption_ParameterReturnDividend_Basket"]

    alias underlierEconomicTerms:
        economicTerms -> payout -> optionPayout -> underlier -> Product ->> economicTerms only-element
    set is_product:
        // qualifies that only the option payout exist and all other payouts are absent
        economicTerms -> payout -> optionPayout only exists
            // qualifies that the underlier is a single name dividend swap
            and Qualify_EquitySwap_ParameterReturnDividend_Basket(underlierEconomicTerms) = True

func Qualify_BaseProduct_IRSwap: <"Qualifies a product as having the Base Product classification Interest Rate Swap.">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    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

func Qualify_BaseProduct_CrossCurrency: <"Qualifies a product as having the Base Product classification Cross Currency.">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        Qualify_AssetClass_InterestRate(economicTerms) = True
            and economicTerms -> payout -> interestRatePayout count = 2
            and (economicTerms -> payout -> interestRatePayout -> priceQuantity -> quantitySchedule -> unit -> currency
                    distinct
                    count = 2
                or (economicTerms -> payout -> interestRatePayout -> priceQuantity -> quantitySchedule -> unit -> currency exists
                    and economicTerms -> payout -> interestRatePayout -> priceQuantity -> quantityMultiplier -> fxLinkedNotionalSchedule -> varyingNotionalCurrency exists
                    and economicTerms -> payout -> interestRatePayout -> priceQuantity -> quantitySchedule -> unit -> currency <> economicTerms -> payout -> interestRatePayout -> priceQuantity -> quantityMultiplier -> fxLinkedNotionalSchedule -> varyingNotionalCurrency))

func Qualify_BaseProduct_Fra: <"Qualifies a product as having the Base Product classification Forward Rate Agreement">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    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

func Qualify_BaseProduct_Inflation: <"Qualifies a product as having the Base Product classification Inflation Swap">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        Qualify_AssetClass_InterestRate(economicTerms) = True
            and economicTerms -> payout -> interestRatePayout count = 2
            and economicTerms -> payout -> interestRatePayout -> paymentDates count = 2
            and economicTerms -> payout -> interestRatePayout -> rateSpecification -> InflationRateSpecification exists

func Qualify_SubProduct_FixedFloat: <"Qualifies a product as having the Sub Product classification Fixed Float">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    set is_product:
        (economicTerms -> payout -> interestRatePayout -> rateSpecification -> FixedRateSpecification count = 1
                and economicTerms -> payout -> interestRatePayout -> rateSpecification -> FloatingRateSpecification count = 1)
            or (economicTerms -> payout -> interestRatePayout -> rateSpecification -> FixedRateSpecification count = 1
                and economicTerms -> payout -> interestRatePayout -> rateSpecification -> InflationRateSpecification count = 1)
            or ((economicTerms -> payout -> interestRatePayout -> rateSpecification -> FloatingRateSpecification count = 1
                    or economicTerms -> payout -> interestRatePayout -> rateSpecification -> InflationRateSpecification count = 1)
                and (economicTerms -> payout -> interestRatePayout
                    filter rateSpecification is absent and priceQuantity exists
                    then count = 1
                    ))

func Qualify_SubProduct_FixedFixed: <"Qualifies a product as having the Sub Product classification Fixed Fixed">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        economicTerms -> payout -> interestRatePayout -> rateSpecification -> FixedRateSpecification count = 2

func Qualify_SubProduct_Basis: <"Qualifies a product as having the Sub Product classification Basis">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        economicTerms -> payout -> interestRatePayout -> rateSpecification -> FloatingRateSpecification count = 2
            or (economicTerms -> payout -> interestRatePayout -> rateSpecification -> InflationRateSpecification count = 1
                and economicTerms -> payout -> interestRatePayout -> rateSpecification -> FloatingRateSpecification count = 1)
            or economicTerms -> payout -> interestRatePayout -> rateSpecification -> InflationRateSpecification count = 2

func Qualify_Transaction_ZeroCoupon: <"Qualifies a product as having the Transaction classification Zero Coupon">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        economicTerms -> payout -> interestRatePayout -> paymentDates -> paymentFrequency
            filter item -> periodMultiplier = 1 and item -> period = PeriodExtendedEnum -> T
            then exists

func Qualify_Transaction_ZeroCoupon_KnownAmount: <"Qualifies a product as having the Transaction classification Zero Coupon with a Known Amount. This category applies to a Zero Coupon Swap in which the fixed leg pays a known amount at maturity.">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        Qualify_SubProduct_FixedFloat(economicTerms) = True
            and Qualify_Transaction_ZeroCoupon(economicTerms) = True
            and (economicTerms -> payout -> interestRatePayout
                filter
                    item -> priceQuantity exists
                        and rateSpecification is absent
                        and paymentDates -> paymentFrequency -> periodMultiplier = 1
                        and paymentDates -> paymentFrequency -> period = PeriodExtendedEnum -> T
                then exists
                )

func Qualify_Transaction_YoY: <"Qualifies a product as having the Transaction classification Year on Year">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        economicTerms -> payout -> interestRatePayout -> paymentDates -> paymentFrequency -> periodMultiplier all = 1
            and economicTerms -> payout -> interestRatePayout -> paymentDates -> paymentFrequency -> period all = PeriodExtendedEnum -> Y

func Qualify_Transaction_OIS: <"Qualifies a product as having the Transaction classification OIS">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    alias floatingRateIndex:
        economicTerms -> payout -> interestRatePayout -> rateSpecification -> FloatingRateSpecification -> rateOption -> InterestRateIndex -> floatingRateIndex

    set is_product:
        floatingRateIndex any = FloatingRateIndexEnum -> AUD_AONIA_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> AUD_AONIA_OIS_Compound_1
            or floatingRateIndex any = FloatingRateIndexEnum -> AUD_AONIA_OIS_COMPOUND_SwapMarker
            or floatingRateIndex any = FloatingRateIndexEnum -> CAD_CORRA_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> CAD_CORRA_OIS_Compound_1
            or floatingRateIndex any = FloatingRateIndexEnum -> CHF_OIS_11_00_ICAP
            or floatingRateIndex any = FloatingRateIndexEnum -> CHF_SARON_OIS_Compound_1
            or floatingRateIndex any = FloatingRateIndexEnum -> CHF_SARON_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> CHF_TOIS_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> CNY_SHIBOR_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> CNY_Shibor_OIS_Compounding
            or floatingRateIndex any = FloatingRateIndexEnum -> COP_IBR_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> COP_IBR_OIS_Compound_1
            or floatingRateIndex any = FloatingRateIndexEnum -> CZK_CZEONIA_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> DKK_DESTR_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> DKK_DKKOIS_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> DKK_Tom_Next_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> EUR_EONIA_OIS_10_00_BGCANTOR
            or floatingRateIndex any = FloatingRateIndexEnum -> EUR_EONIA_OIS_10_00_ICAP
            or floatingRateIndex any = FloatingRateIndexEnum -> EUR_EONIA_OIS_10_00_TRADITION
            or floatingRateIndex any = FloatingRateIndexEnum -> EUR_EONIA_OIS_11_00_ICAP
            or floatingRateIndex any = FloatingRateIndexEnum -> EUR_EONIA_OIS_4_15_TRADITION
            or floatingRateIndex any = FloatingRateIndexEnum -> EUR_EONIA_OIS_Compound_1
            or floatingRateIndex any = FloatingRateIndexEnum -> EUR_EONIA_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> EUR_EONIA_OIS_COMPOUND_Bloomberg
            or floatingRateIndex any = FloatingRateIndexEnum -> EUR_EURONIA_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> EUR_EURONIA_OIS_Compound_1
            or floatingRateIndex any = FloatingRateIndexEnum -> EUR_EuroSTR_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> GBP_RONIA_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> GBP_SONIA_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> GBP_SONIA_OIS_11_00_ICAP
            or floatingRateIndex any = FloatingRateIndexEnum -> GBP_SONIA_OIS_11_00_TRADITION
            or floatingRateIndex any = FloatingRateIndexEnum -> GBP_SONIA_OIS_4_15_TRADITION
            or floatingRateIndex any = FloatingRateIndexEnum -> GBP_SONIA_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> GBP_WMBA_RONIA_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> GBP_WMBA_SONIA_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> HKD_HONIA_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> HKD_HONIX_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> HUF_HUFONIA_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> ILS_SHIR_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> INR_FBIL_MIBOR_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> INR_MIBOR_OIS_Compound_1
            or floatingRateIndex any = FloatingRateIndexEnum -> INR_MIBOR_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> INR_MIOIS
            or floatingRateIndex any = FloatingRateIndexEnum -> INR_MITOR_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> JPY_OIS_11_00_ICAP
            or floatingRateIndex any = FloatingRateIndexEnum -> JPY_OIS_11_00_TRADITION
            or floatingRateIndex any = FloatingRateIndexEnum -> JPY_OIS_3_00_TRADITION
            or floatingRateIndex any = FloatingRateIndexEnum -> JPY_TONA_OIS_Compound_1
            or floatingRateIndex any = FloatingRateIndexEnum -> JPY_TONA_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> KRW_KOFR_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> MXN_TIIE_ON_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> MYR_MYOR_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> NOK_NOWA_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> NZD_NZIONA_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> NZD_NZIONA_OIS_Compound_1
            or floatingRateIndex any = FloatingRateIndexEnum -> PLN_POLONIA_OIS_Compound_1
            or floatingRateIndex any = FloatingRateIndexEnum -> PLN_POLONIA_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> PLN_WIRON_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> REPOFUNDS_RATE_FRANCE_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> REPOFUNDS_RATE_GERMANY_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> REPOFUNDS_RATE_ITALY_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> RUB_RUONIA_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> RUB_RUONIA_OIS_Compound_1
            or floatingRateIndex any = FloatingRateIndexEnum -> SEK_SIOR_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> SEK_STIBOR_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> SEK_SWESTR_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> SGD_SONAR_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> SGD_SONAR_OIS_VWAP_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> SGD_SORA_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> SGD_SORA_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> THB_THOR_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> THB_THOR_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> TRY_TLREF_OIS_Compound_1
            or floatingRateIndex any = FloatingRateIndexEnum -> TRY_TLREF_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> USD_Federal_Funds_H_15_OIS_COMPOUND
            or floatingRateIndex any = FloatingRateIndexEnum -> USD_Federal_Funds_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> USD_OIS_11_00_BGCANTOR
            or floatingRateIndex any = FloatingRateIndexEnum -> USD_OIS_11_00_LON_ICAP
            or floatingRateIndex any = FloatingRateIndexEnum -> USD_OIS_11_00_NY_ICAP
            or floatingRateIndex any = FloatingRateIndexEnum -> USD_OIS_11_00_TRADITION
            or floatingRateIndex any = FloatingRateIndexEnum -> USD_OIS_3_00_BGCANTOR
            or floatingRateIndex any = FloatingRateIndexEnum -> USD_OIS_3_00_NY_ICAP
            or floatingRateIndex any = FloatingRateIndexEnum -> USD_OIS_4_00_TRADITION
            or floatingRateIndex any = FloatingRateIndexEnum -> USD_SOFR_OIS_Compound
            or floatingRateIndex any = FloatingRateIndexEnum -> ZAR_ZARONIA_OIS_Compound

func Qualify_InterestRate_IRSwap_FixedFloat: <"Qualifies a product as a Fixed-Float Interest Rate Swap based on the economic terms and the following criteria: 1) An interest rate product with one fixed and one floating leg and more than one payment, 2) without inflation features or cross-currency features or 'zero coupon' features, and 3) where the floating leg is not based on an OIS index.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "InterestRate_IRSwap_FixedFloat"]
            [synonym ISDA_Taxonomy_v2 value "InterestRate_IRSwap_FixedFloat"]

    set is_product:
        Qualify_BaseProduct_IRSwap(economicTerms) = True
            and Qualify_SubProduct_FixedFloat(economicTerms) = True
            and Qualify_Transaction_ZeroCoupon(economicTerms) = False
            and Qualify_Transaction_OIS(economicTerms) = False

func Qualify_InterestRate_IRSwap_FixedFixed: <"Qualifies a product as a Fixed-Fixed Interest Rate Swap based on the economic terms and the following criteria: 1) An interest rate product with two fixed legs and more than one payment and 2) without inflation features or cross-currency features but could have 'zero coupon' features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "InterestRate_IRSwap_FixedFixed"]
            [synonym ISDA_Taxonomy_v2 value "InterestRate_IRSwap_FixedFixed"]
    set is_product:
        Qualify_BaseProduct_IRSwap(economicTerms) = True
            and Qualify_SubProduct_FixedFixed(economicTerms) = True

func Qualify_InterestRate_IRSwap_Basis: <"Qualifies a product as a Basis (Float-Float) Interest Rate Swap based on the economic terms and the following criteria: 1) An interest rate product with two floating legs and more than one payment, 2) without inflation features or cross-currency features but could have 'zero coupon' features, and 3) where neither floating leg is  based on an OIS index.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "InterestRate_IRSwap_Basis"]
            [synonym ISDA_Taxonomy_v2 value "InterestRate_IRSwap_Basis"]

    set is_product:
        Qualify_BaseProduct_IRSwap(economicTerms) = True
            and Qualify_SubProduct_Basis(economicTerms) = True
            and Qualify_Transaction_OIS(economicTerms) = False

func Qualify_InterestRate_IRSwap_FixedFloat_ZeroCoupon: <"Qualifies a product as a Fixed-Float Zero Coupon Interest Rate Swap based on the economic terms and the following criteria: 1) An interest rate product with one fixed and one floating leg, 2) where the fixed leg represents one singular payment agreed upon execution and to be made at maturity, 3) where the floating leg is not based on an OIS index and 4) without any inflation features or cross-currency features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v2 value "InterestRate_IRSwap_FixedFloat_ZeroCoupon"]

    set is_product:
        Qualify_BaseProduct_IRSwap(economicTerms) = True
            and Qualify_SubProduct_FixedFloat(economicTerms) = True
            and Qualify_Transaction_ZeroCoupon(economicTerms) = True
            and Qualify_Transaction_OIS(economicTerms) = False

func Qualify_InterestRate_IRSwap_FixedFloat_OIS: <"Qualifies a product as a Fixed-Float OIS Interest Rate Swap based on the economic terms and the following criteria: 1) An interest rate product with one fixed and one floating leg and more than one payment and where the floating leg is based on an OIS index, 2) without inflation features or cross-currency features, and 3) could include 'zero coupon' features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v2 value "InterestRate_IRSwap_FixedFloat_OIS"]

    set is_product:
        Qualify_BaseProduct_IRSwap(economicTerms) = True
            and Qualify_SubProduct_FixedFloat(economicTerms) = True
            and Qualify_Transaction_OIS(economicTerms) = True

func Qualify_InterestRate_IRSwap_Basis_OIS: <"Qualifies a product as a Basis (Fixed-Float) OIS Interest Rate Swap based on the economic terms and the following criteria: 1) An interest rate product with two floating legs and more than one payment and where one or both the floating leg is based on an OIS index, 2) without inflation features or cross-currency features, and 3) could include 'zero coupon' features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v2 value "InterestRate_IRSwap_Basis"]

    set is_product:
        Qualify_BaseProduct_IRSwap(economicTerms) = True
            and Qualify_SubProduct_Basis(economicTerms) = True
            and Qualify_Transaction_OIS(economicTerms) = True

func Qualify_InterestRate_CrossCurrency_FixedFloat: <"Qualifies a product as a Fixed-Float Cross-Currency Interest Rate Swap based on the economic terms and the following criteria: 1) An interest rate product with one fixed and one floating leg and a cross-currency feature and more than one payment, 2) without inflation features and 3) could be a 'zero coupon' and the floating leg index could be OIS or non-OIS.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "InterestRate_CrossCurrency_FixedFloat"]

    set is_product:
        Qualify_BaseProduct_CrossCurrency(economicTerms) = True
            and Qualify_SubProduct_FixedFloat(economicTerms) = True

func Qualify_InterestRate_CrossCurrency_Basis: <"Qualifies a product as a Basis (Float-Float) Cross Currency Interest Rate Swap based on the economic terms and the following criteria: 1) An interest rate product with two floating legs, a cross-currency feature in one or both legs, and more than one payment, 2) but without inflation features, and 3) could be a 'zero coupon' and floating leg index could be OIS or non-OIS.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "InterestRate_CrossCurrency_Basis"]
            [synonym ISDA_Taxonomy_v2 value "InterestRate_CrossCurrency_Basis"]

    set is_product:
        Qualify_BaseProduct_CrossCurrency(economicTerms) = True
            and Qualify_SubProduct_Basis(economicTerms) = True

func Qualify_InterestRate_CrossCurrency_FixedFixed: <"Qualifies a product as a Fixed-Fixed Cross-Currency Interest Rate Swap based on the economic terms and the following criteria: 1) An interest rate product with two fixed legs and a cross-currency feature and more than one payment, 2) without inflation features and 3) could be a 'zero coupon'">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "InterestRate_CrossCurrency_FixedFixed"]
            [synonym ISDA_Taxonomy_v2 value "InterestRate_CrossCurrency_FixedFixed"]

    set is_product:
        Qualify_BaseProduct_CrossCurrency(economicTerms) = True
            and Qualify_SubProduct_FixedFixed(economicTerms) = True

func Qualify_InterestRate_InflationSwap_FixedFloat_YearOn_Year: <"Qualifies a product as a Fixed-Float Annual Reset Inflation Swap based on the economic terms and the following criteria: 1) An interest rate product with one fixed and one inflation rate leg and more than one payment, and 2) without cross-currency features or 'zero coupon' features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v2 value "InterestRate_IRSwap_Inflation"]

    set is_product:
        Qualify_BaseProduct_Inflation(economicTerms) = True
            and Qualify_BaseProduct_CrossCurrency(economicTerms) = False
            and Qualify_SubProduct_FixedFloat(economicTerms) = True
            and Qualify_Transaction_YoY(economicTerms) = True

//TH Review -> This product exists at ISDA Taxonomy V2 but has no match in CDM yet. The proposal needs to be completed adding the composable utility functions to improve qualification for IR inflation products
/*func Qualify_InterestRate_Inflation: <"Qualifies a product as a Fixed-Float Inflation Swap with a single accrual period based on the economic terms and the following criteria: 1) An interest rate product with one fixed and one inflation rate leg and more than one payment, and 2) without cross-currency features.">
 *     [qualification Product]

 *     inputs: economicTerms EconomicTerms (1..1)
 *     output: is_product boolean (1..1)
 *         [synonym ISDA_Taxonomy_v2 value "InterestRate_Inflation"]
 * 
 *     set is_product:
 *         Qualify_BaseProduct_Inflation(economicTerms) = True
 *         and Qualify_InterestRate_InflationSwap_FixedFloat_ZeroCoupon (economicTerms) = False
 *         and Qualify_InterestRate_InflationSwap_FixedFloat_YearOn_Year (economicTerms) = False
 *         and Qualify_InterestRate_InflationSwap_Basis_ZeroCoupon (economicTerms) = False
 *         and Qualify_InterestRate_InflationSwap_Basis_YearOn_Year (economicTerms) = False
 */
func Qualify_InterestRate_InflationSwap_FixedFloat_ZeroCoupon: <"Qualifies a product as a Fixed-Float Inflation Swap based on the economic terms and the following criteria: 1) An interest rate product with one fixed and one inflation rate leg, 2) where the fixed leg represents one singular payment agreed upon execution and to be made at maturity, 3) where the inflation leg features an inflation floating rate and 4) without cross-currency features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v2 value "InterestRate_IRSwap_Inflation"]

    set is_product:
        Qualify_BaseProduct_Inflation(economicTerms) = True
            and Qualify_BaseProduct_CrossCurrency(economicTerms) = False
            and Qualify_SubProduct_FixedFloat(economicTerms) = True
            and Qualify_Transaction_ZeroCoupon(economicTerms) = True

func Qualify_InterestRate_InflationSwap_Basis_YearOn_Year: <"Qualifies a product as a Basis (Float-Float) Annual Reset Inflation Swap based on the economic terms and the following criteria: 1) An interest rate product with one floating interest rate leg and one inflation rate leg and more than one payment, and 2) without cross-currency features or 'zero coupon' features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "InterestRate_IRSwap_Inflation"]

    set is_product:
        Qualify_BaseProduct_Inflation(economicTerms) = True
            and Qualify_BaseProduct_CrossCurrency(economicTerms) = False
            and Qualify_SubProduct_Basis(economicTerms) = True
            and Qualify_Transaction_YoY(economicTerms) = True

func Qualify_InterestRate_InflationSwap_Basis_ZeroCoupon: <"Qualifies a product as a Basis (Float-Float) Inflation Swap based on the economic terms and the following criteria: 1) An interest rate product with one floating interest rate leg and one inflation interest rate leg, 2) where the floating leg is not based on an OIS index, 3) where the inflation leg features an inflation floating rate, 4) where an interest rate payout is made at maturity into a singular payment and 5) without cross-currency features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "InterestRate_IRSwap_Inflation"]

    set is_product:
        Qualify_BaseProduct_Inflation(economicTerms) = True
            and Qualify_BaseProduct_CrossCurrency(economicTerms) = False
            and Qualify_SubProduct_Basis(economicTerms) = True
            and Qualify_Transaction_ZeroCoupon(economicTerms) = True

func Qualify_InterestRate_Fra: <"Qualifies the product as a Floating Rate Agreement based on the economic terms and the following criteria: 1) An interest rate product with one fixed and one floating leg, each of which has a single payment, and 2) could include a cross-currency feature, and the floating rate leg could be based OIS index.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "InterestRate_Fra"]
            [synonym ISDA_Taxonomy_v1 value "InterestRate_Fra"]

    set is_product:
        Qualify_AssetClass_InterestRate(economicTerms) = True
            and economicTerms -> payout -> interestRatePayout -> rateSpecification -> FixedRateSpecification count = 1
            and economicTerms -> payout -> interestRatePayout -> rateSpecification -> FloatingRateSpecification count = 1
            and economicTerms -> payout -> interestRatePayout -> paymentDate count = 2

func Qualify_InterestRate_CapFloor: <"Qualifies a product as an interest rate cap, interest rate floor, or an interest rate collar based on the economic terms and the following criteria: 1) An interest rate product with one one leg that includes a cap and/or a floor.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "InterestRate_CapFloor"]
            [synonym ISDA_Taxonomy_v2 value "InterestRate_CapFloor"]

    set is_product:
        Qualify_AssetClass_InterestRate(economicTerms) = True
                and economicTerms -> payout -> interestRatePayout count = 1
                    // qualifies the product as having a cap and/or floor in the interestRatePayout
                and economicTerms -> payout -> interestRatePayout -> rateSpecification -> FloatingRateSpecification -> capRateSchedule exists
            or economicTerms -> payout -> interestRatePayout -> rateSpecification -> FloatingRateSpecification -> floorRateSchedule exists

func Qualify_InterestRate_Option_Swaption: <"Qualifies a product as a Swaption that can be exercised into an Interest Rate Swap, which could be any type of interest rate product with two legs based on the economic terms.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "InterestRate_Option_Swaption"]
            [synonym ISDA_Taxonomy_v2 value "InterestRate_Option_Swaption"]
    set is_product:
        Qualify_AssetClass_InterestRate(economicTerms) = True
                // qualifies that only the option payout exists and all other payouts are absent
            and economicTerms -> payout -> optionPayout only exists
            and Qualify_AssetClass_InterestRate(
                    economicTerms -> payout -> optionPayout -> underlier -> Product ->> economicTerms only-element
                ) = True

func Qualify_InterestRate_Option_DebtOption: <"Qualifies a product as a Option that can be exercised into an Debt Product based on the economic terms.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "InterestRate_Option_DebtOption"]
            [synonym ISDA_Taxonomy_v2 value "InterestRate_Option_DebtOption"]
    alias optionPayout: economicTerms -> payout -> optionPayout
    set is_product:
        Qualify_AssetClass_InterestRate(economicTerms) = True
                // qualifies that only the option payout exists and all other payouts are absent
            and economicTerms -> payout -> optionPayout only exists
                // qualifies the underlyer of the option as a debt security
            and optionPayout -> underlier -> Observable extract [ ObservableQualification(item, SecurityTypeEnum -> Debt, empty) ] all = True 

func Qualify_InterestRate_Forward_Debt: <"Qualifies a product as Interest Rate Bond Forward based on economic terms, which is defined as a transaction in which one party agrees to pay an agreed price for a specified amount of a bond of an issuer or a basket of bonds of several issuers at a future date and the other party agrees to pay a price for the same amount of the same bond to be set on a specified date in the future.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "InterestRate_Forward_Debt"]
            [synonym ISDA_Taxonomy_v2 value "InterestRate_Forward_Debt"]
    alias forwardPayout: economicTerms -> payout -> settlementPayout only-element
    set is_product:
        Qualify_AssetClass_InterestRate(economicTerms) = True
            and (forwardPayout -> underlier -> Observable -> Asset -> Instrument -> Security exists
                or forwardPayout -> underlier -> Product -> TransferableProduct -> Instrument -> Security exists)

func Qualify_ForeignExchange_Spot_Forward: <"Qualifies a product as Foreign Exchange based on economic terms, which is defined as an agreement to buy one currency against the delivery of another currency at a rate set on the trade date for settlement on a specified date in the future.  Dependent on conventions specific to local markets the product could be considered either Spot or Forward.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "ForeignExchange_Forward"]
            [synonym ISDA_Taxonomy_v1 value "ForeignExchange_Spot"]
            [synonym ISDA_Taxonomy_v2 value "ForeignExchange_Forward"]
            [synonym ISDA_Taxonomy_v2 value "ForeignExchange_Spot"]
    set is_product:
        Qualify_AssetClass_ForeignExchange(economicTerms) = True
                // only FX transactions result in the buyer receiving only cash
                // other products result in a cash receipt, but not in as a single SettlementPayout
            and economicTerms -> payout -> settlementPayout only exists
            and economicTerms -> payout -> settlementPayout count = 1
            and economicTerms -> payout -> settlementPayout -> settlementTerms -> cashSettlementTerms is absent

func Qualify_ForeignExchange_Swap: <"Qualifies a product as Foreign Exchange Swap based on economic terms, which is defined as a contract in which one party borrows one currency from, and simultaneously lends another to, the second party. Each party uses the repayment obligation to its counterparty as collateral and the amount of repayment is fixed at the FX forward rate as of the start of the contract.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        Qualify_AssetClass_ForeignExchange(economicTerms) = True
            and economicTerms -> payout -> settlementPayout only exists
            and economicTerms -> payout -> settlementPayout count = 2
            and economicTerms -> payout -> settlementPayout -> settlementTerms -> cashSettlementTerms is absent

func Qualify_ForeignExchange_NDF: <"Qualifies a product as Foreign Exchange Non-Deliverable Forward based on economic terms, which is defined as a Forward transaction where the notional amount of one of the currencies (the reference currency) is converted into the other currency (the settlement currency) at a spot foreign exchange rate that is observed on a valuation date prior to the settlement date, and a single net payment in the settlement currency is made on the settlement date. No payment or account transfer takes place in the reference currency.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "ForeignExchange_NDF"]
            [synonym ISDA_Taxonomy_v2 value "ForeignExchange_NDF"]
    set is_product:
        Qualify_AssetClass_ForeignExchange(economicTerms) = True
                // only FX transactions result in the buyer receiving only cash
                // other products result in a cash receipt, but not in as a single SettlementPayout
            and economicTerms -> payout -> settlementPayout only exists
            and economicTerms -> payout -> settlementPayout count = 1
            and economicTerms -> payout -> settlementPayout -> settlementTerms -> cashSettlementTerms exists

func Qualify_ForeignExchange_NDS: <"Qualifies a product as Foreign Exchange NDS based on economic terms, which is defined as a contract in which one party borrows one currency from, and simultaneously lends another to, the second party. Each party uses the repayment obligation to its counterparty as collateral and the amount of repayment is fixed at the FX forward rate as of the start of the contract.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        Qualify_AssetClass_ForeignExchange(economicTerms) = True
            and economicTerms -> payout -> settlementPayout only exists
            and economicTerms -> payout -> settlementPayout count = 2
            and economicTerms -> payout -> settlementPayout -> settlementTerms -> cashSettlementTerms exists

func Qualify_ForeignExchange_ParameterReturnVariance: <"Qualifies a product as Foreign Exchange Swap for which the performance is based on the variance of a foreign exhange underlier.  The determination of the qualification is based on the economic terms and the following criteria: 1) Is a Foreign Exchange product (the underlier is foreign exchange) 2) with only one performance leg 3) which has variance return terms, 4) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "ForeignExchange_SimpleExotic_Vol/Var"]
            [synonym ISDA_Taxonomy_v2 value "ForeignExchange_SimpleExotic_Vol/Var"]

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        Qualify_AssetClass_ForeignExchange(economicTerms) = True
                // qualifies that the product is FX (i.e.: has only foreign Exchange underliers)
            and performancePayout -> underlier -> Observable -> Index -> ForeignExchangeRateIndex exists
            and // qualifies that there is a single leg of performance type
            economicTerms -> payout -> performancePayout only exists
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the performance leg has varianceReturnTerms
            performancePayout -> returnTerms -> varianceReturnTerms only exists

func Qualify_ForeignExchange_ParameterReturnVolatility: <"Qualifies a product as Foreign Exchange Swap for which the performance is based on the volatility of a foreign exchange underlier.  The determination of the qualification is based on the economic terms and the following criteria: 1) Is a Foreign Exchange product (the underlier is foreign exchange) 2) with only one performance leg 3) which has volatility return terms, 4) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "ForeignExchange_SimpleExotic_Vol/Var"]
            [synonym ISDA_Taxonomy_v2 value "ForeignExchange_SimpleExotic_Vol/Var"]

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        Qualify_AssetClass_ForeignExchange(economicTerms) = True
                // qualifies that the product is FX (i.e.: has only foreign Exchange underliers)
            and performancePayout -> underlier -> Observable -> Index -> ForeignExchangeRateIndex exists
            and // qualifies that there is a single leg of performance type
            economicTerms -> payout -> performancePayout only exists
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the performance leg has volatilityReturnTerms
            performancePayout -> returnTerms -> volatilityReturnTerms only exists

func Qualify_ForeignExchange_ParameterReturnCorrelation: <"Qualifies a product as Foreign Exchange Swap for which the performance is based on the correlation changes between the constituents of a basket.  The determination of the qualification is based on the economic terms and the following criteria: 1) Is a product with with only one performance leg 2) which has correlation return terms, 3) with a basket underlier 4) which is exclusively constituted by foreign exchange constituents and 5) there are no option features.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)

    alias performancePayout: economicTerms -> payout -> performancePayout only-element
    set is_product:
        Qualify_AssetClass_ForeignExchange(economicTerms) = True
                // qualifies that there is a single leg of performance type
            and economicTerms -> payout -> performancePayout only exists
            and economicTerms -> payout -> performancePayout count = 1
            and // qualifies that the performance leg has correlationReturnTerms
            performancePayout -> returnTerms -> correlationReturnTerms only exists
            and // qualifies that the underlier is a basket
            performancePayout -> underlier -> Observable -> Basket exists
            and // qualifies that the product is FX (i.e.: the basket is constituted by foreign exchange constituents)
            performancePayout -> underlier -> Observable -> Basket -> basketConstituent extract [ Index -> ForeignExchangeRateIndex exists ] all = True

func Qualify_ForeignExchange_VanillaOption: <"Qualifies a product as FX Plain Vanilla Option based on economic terms, which is defined as one where 1) exercise style is American or European style only, and 2) does not contain any feature like Forward Starting Strike or Performance payout.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "ForeignExchange_VanillaOption"]
            [synonym ISDA_Taxonomy_v2 value "ForeignExchange_VanillaOption"]
    set is_product:
        Qualify_AssetClass_ForeignExchange(economicTerms) = True
            and economicTerms -> payout -> optionPayout only exists
            and (economicTerms -> payout -> optionPayout -> exerciseTerms -> style any <> OptionExerciseStyleEnum -> Bermuda)
            and (economicTerms -> payout -> optionPayout -> feature is absent
                or economicTerms -> payout -> optionPayout -> feature -> averagingFeature only exists)

func Qualify_RepurchaseAgreement: <"Qualifies a product as a Repurchase Agreement based on the repo trate of the trade (ie the interest charges) being defined in an InterestRatePayout and the asset that is bought and sold being defined in an AssetPayout in a CollateralPosition.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        economicTerms -> payout -> interestRatePayout only exists
            and economicTerms -> payout -> interestRatePayout count = 1
            and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product ->> economicTerms -> payout -> assetPayout exists
            and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product ->> economicTerms -> payout -> assetPayout -> repoType all <> RepoTypeEnum -> BuySellBack

func Qualify_BuySellBack: <"Qualifies a product as a Buy/Sell Back based on the repo trate of the trade (ie the interest charges) being defined in an InterestRatePayout and the asset that is bought and sold being defined in an AssetPayout in a CollateralPosition, along with an enumerator to distinguish ths product type from a traditional repurchase ageement.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        economicTerms -> payout -> interestRatePayout only exists
            and economicTerms -> payout -> interestRatePayout count = 1
            and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product ->> economicTerms -> payout -> assetPayout exists
            and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product ->> economicTerms -> payout -> assetPayout -> repoType any = RepoTypeEnum -> BuySellBack

func Qualify_SecurityLending: <"Qualifies a product as Securities Lending based on the asset to be lent (usually a security) being defined in a singular AssetPayout, with the collateral, which can be an asset (usually cash or securities), defined in a CollateralPosition.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
    set is_product:
        economicTerms -> payout -> assetPayout only exists
            and economicTerms -> payout -> assetPayout count = 1
            and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> TransferableProduct exists

func Qualify_Commodity_Swap_FixedFloat: <"Qualifies a product as a Fixed Float Commodity Swap.  The determination of the qualification is based on the economic terms and the following criteria: 1) One Floating Leg represented by the CommodityPayout, with an underlier that is a commodity, 2) One Fixed Leg represented by the FixedPricePayout, and 3) there are no other payout types.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "Commodity_Swap_FixedFloat"]
            [synonym ISDA_Taxonomy_v2 value "Commodity_Swap_FixedFloat"]
    set is_product:
        Qualify_AssetClass_Commodity(economicTerms) = True
            and (economicTerms -> payout -> commodityPayout, economicTerms -> payout -> fixedPricePayout) only exists

func Qualify_Commodity_Swap_Basis: <"Qualifies a product as a Basis Commodity Swap.  The determination of the qualification is based on the economic terms and the following criteria: 1) Two Floating Legs represented by the CommodityPayout, with an underlier that is a commodity, and 2) there are no other payout types.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "Commodity_Swap_Basis"]
            [synonym ISDA_Taxonomy_v2 value "Commodity_Swap_Basis"]
    set is_product:
        Qualify_AssetClass_Commodity(economicTerms) = True
            and economicTerms -> payout -> commodityPayout only exists
            and economicTerms -> payout -> commodityPayout count = 2

func Qualify_Commodity_Option: <"Qualifies a product as a Option that can be exercised into an Commodity.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "Commodity_Option"]
            [synonym ISDA_Taxonomy_v2 value "Commodity_Option"]
    set is_product:
        Qualify_AssetClass_Commodity(economicTerms) = True
            and economicTerms -> payout -> optionPayout only exists
            and  ( economicTerms -> payout -> optionPayout -> underlier -> Observable -> Asset -> Commodity exists
                or economicTerms -> payout -> optionPayout -> underlier -> Product -> TransferableProduct -> Commodity exists )

func Qualify_Commodity_Option_Cash: <"Qualifies a product as a Option that can be exercised into an Commodity.">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "Commodity_Option_Cash"]
            [synonym ISDA_Taxonomy_v2 value "Commodity_Option_Cash"]
    set is_product:
        Qualify_Commodity_Option(economicTerms) = True
            and economicTerms -> payout -> optionPayout only-element -> settlementTerms -> settlementType = SettlementTypeEnum -> Cash

func Qualify_Commodity_Option_Physical: <"Qualifies a product as a Option that can be exercised into an Commodity.">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "Commodity_Option_Physical"]
            [synonym ISDA_Taxonomy_v2 value "Commodity_Option_Physical"]
    set is_product:
        Qualify_Commodity_Option(economicTerms) = True
            and economicTerms -> payout -> optionPayout only-element -> settlementTerms -> settlementType = SettlementTypeEnum -> Physical

func Qualify_Commodity_Swaption: <"Qualifies a product as a Swaption that can be exercised into a Commodity Swap, which could be any type of interest rate product with two legs based on the economic terms.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "Commodity_Swaption"]
            [synonym ISDA_Taxonomy_v2 value "Commodity_Swaption"]
    set is_product:
        economicTerms -> payout -> optionPayout only exists
            and (Qualify_Commodity_Swap_Basis(
                        economicTerms -> payout -> optionPayout only-element -> underlier -> Product ->> economicTerms
                    ) = True
                or Qualify_Commodity_Swap_FixedFloat(
                        economicTerms -> payout -> optionPayout only-element -> underlier -> Product ->> economicTerms
                    ) = True)

func Qualify_Commodity_Forward: <"Qualifies a product as a Forward that will be settled with the physical delivery of a Commodity. The determination of the qualification is based on the economic terms and the following criteria: 1) One pricing Leg represented by either the FixedPricePayout or the CommodityPayout, 2) One physical Leg represented by the ForwardPayout, with an underlier that is a commodity, and 3) there are no other payout types.">
    [qualification Product]
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_product boolean (1..1)
            [synonym ISDA_Taxonomy_v1 value "Commodity_Spot_Fwd"]
            [synonym ISDA_Taxonomy_v2 value "Commodity_Forward"]
    set is_product:
        Qualify_AssetClass_Commodity(economicTerms) = True
            and ((economicTerms -> payout -> settlementPayout, economicTerms -> payout -> fixedPricePayout) only exists
                or // Fixed Price Forward
                (economicTerms -> payout -> settlementPayout, economicTerms -> payout -> commodityPayout) only exists) // Floating Price Forward




© 2015 - 2025 Weber Informatics LLC | Privacy Policy