From 348f4306dd65e77ca710fc7680ee30f615b4844a Mon Sep 17 00:00:00 2001 From: Lionel Smith-Gordon Date: Fri, 19 Jul 2024 16:45:56 +0000 Subject: [PATCH 1/5] 3 - ART Phase 3 Initial commit (includes P2 changes) --- .../base-staticdata-asset-common-enum.rosetta | 2 +- .../base-staticdata-asset-common-type.rosetta | 95 ++--- .../main/rosetta/event-common-func.rosetta | 397 ++++++++++-------- .../main/rosetta/event-common-type.rosetta | 236 +++++------ .../main/rosetta/event-position-func.rosetta | 10 +- .../main/rosetta/event-position-type.rosetta | 2 +- .../rosetta/event-qualification-func.rosetta | 40 +- ...ml-confirmation-tradestate-synonym.rosetta | 73 ++-- .../main/rosetta/mapping-ore-synonym.rosetta | 6 +- .../rosetta/observable-asset-enum.rosetta | 6 +- .../rosetta/observable-asset-type.rosetta | 85 ++-- .../rosetta/observable-common-func.rosetta | 2 +- .../rosetta/observable-event-func.rosetta | 2 +- .../main/rosetta/product-asset-type.rosetta | 17 +- .../rosetta/product-collateral-type.rosetta | 6 +- .../product-common-schedule-type.rosetta | 10 +- .../product-common-settlement-func.rosetta | 13 + .../product-common-settlement-type.rosetta | 22 +- .../product-qualification-func.rosetta | 372 +++++++++------- .../rosetta/product-template-enum.rosetta | 11 + .../rosetta/product-template-type.rosetta | 175 ++++---- 21 files changed, 859 insertions(+), 723 deletions(-) diff --git a/rosetta-source/src/main/rosetta/base-staticdata-asset-common-enum.rosetta b/rosetta-source/src/main/rosetta/base-staticdata-asset-common-enum.rosetta index 1d46f41f2c..b99e5b4bc8 100755 --- a/rosetta-source/src/main/rosetta/base-staticdata-asset-common-enum.rosetta +++ b/rosetta-source/src/main/rosetta/base-staticdata-asset-common-enum.rosetta @@ -34,7 +34,7 @@ enum ProductIdTypeEnum: <"Provides the enumerated values to specify the product enum TaxonomySourceEnum: <"Represents the enumerated values to specify taxonomy sources."> CFI <"Represents the ISO 10962 Classification of Financial Instruments code."> ISDA <"Represents the ISDA product taxonomy."> - ICAD <"Represents the ISDA Collateral Asset Definition Idenifier code."> + ICAD <"Represents the ISDA Collateral Asset Definition Identifier code."> EMIR <"Represents the EMIR Article 9 Asset Definition Identifier code."> EU_EMIR_EligibleCollateralAssetClass <"Identifies European Union Eligible Collateral Assets classification categories based on EMIR Uncleared Margin Rules."> UK_EMIR_EligibleCollateralAssetClass <"Identifies United Kingdom Eligible Collateral Assets classification categories based on UK Onshored EMIR Uncleared Margin Rules Eligible Collateral asset classes for both initial margin (IM) and variation margin (VM) posted and collected between specified entities.Please note: UK EMIR regulation will detail which eligible collateral assets classes apply to each type of entity pairing (counterparty) and which apply to posting of IM and VM."> diff --git a/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta b/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta index 0bee4d882c..dce6827bd8 100755 --- a/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta +++ b/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta @@ -6,35 +6,35 @@ import cdm.base.datetime.* import cdm.base.math.* import cdm.base.staticdata.party.* import cdm.observable.asset.* -import cdm.product.template.* -choice Asset: <"An Asset is defined as something that can be owned and transferred in the financial markets. As a choice data type, one and only one of the attributes must be used."> +choice Asset: <"An Asset is defined as something that can be owned and transferred in the financial markets. As a choice data type, one and only one of the attributes must be used."> Cash <"An Asset that consists solely of a monetary holding in a currency."> Commodity <"An Asset comprised of raw or refined materials or agricultural products, eg gold, oil or wheat."> DigitalAsset <"An Asset that exists only in digital form, eg Bitcoin or Ethereum; excludes the digital representation of other Assets."> Instrument <"An asset that is issued by one party to one or more others; Instrument is also a choice data type."> type AssetBase: <"The base data type to specify common attributes for all Assets."> - identifier AssetIdentifier (0..*) <"Asset Identifiers are used to uniquely identify an Asset, using a specified Asset Identifier Type."> + identifier AssetIdentifier (1..*) <"Asset Identifiers are used to uniquely identify an Asset, using a specified Asset Identifier Type."> taxonomy Taxonomy (0..1) <"Defines the taxonomy of an object by combining a taxonomy source (i.e. the rules to classify the object) and a value (i.e. the output of those rules on the object."> + isExchangeListed boolean (0..1) <"Defines whether the Asset is listed on a public exchange."> + exchange LegalEntity (0..1) <"If the Asset is listed, defines the public exchange of the listing."> + [metadata scheme] + relatedExchange LegalEntity (0..*) <"Provides the related Exchanges, if applicable."> + + condition ExchangeListed: <"If Exchange is specified, it must be an exchange-listed Instrument."> + if exchange exists + then isExchangeListed type AssetIdentifier: <"The unique identifier for an Asset, specified using an Asset Identifier Type enumerator."> identifier string (1..1) <"The identifier value."> - [metadata scheme] identifierType AssetIdTypeEnum (1..1) <"Defines the symbology source of the Asset Identifier, eg CUSIP, ISIN, etc."> type InstrumentBase extends AssetBase: <"Defines the common attributes for all Instrument data types."> - isExchangeListed boolean (0..1) <"Defines whether the Instrument is listed on a public exchange."> - exchange LegalEntity (0..*) <"If the Instrument is listed, defines the public exchange(s) of the listing."> - - condition ExchangeListed: <"If Exchange is specified, it must be an exchange-listed Instrument."> - if exchange exists - then isExchangeListed -choice Instrument: <"A type of Asset that is issued by one party to one or more others. ListedDerivative: A securitized derivative on another asset that is created by an exchange. Loan: An Asset that represents a loan or borrow obligation. Security: An Asset that is issued by a party to be held by or transferred to others."> - ListedDerivative - Loan - Security +choice Instrument: <"A type of Asset that is issued by one party to one or more others."> + ListedDerivative <"A securitized derivative on another asset that is created by an exchange."> + Loan <"An Asset that represents a loan or borrow obligation."> + Security <"An Asset that is issued by a party to be held by or transferred to others."> type ProductIdentifier: <"Comprises an identifier and a source. The associated metadata key denotes the ability to associate a hash value to the ProductIdentifier instantiations for the purpose of model cross-referencing, in support of functionality such as the event effect and the lineage."> [metadata key] @@ -42,11 +42,6 @@ type ProductIdentifier: <"Comprises an identifier and a source. The associated m [metadata scheme] source ProductIdTypeEnum (1..1) <"Defines the source of the identifier."> -type ProductBase: <"Serves as an abstract class to specify a product using a productIdentifier."> - productTaxonomy ProductTaxonomy (0..*) <"Specifies the product taxonomy, which is composed of a taxonomy value and a taxonomy source."> - productIdentifier ProductIdentifier (0..*) <"Comprises an identifier and a source. The associated metadata key denotes the ability to associate a hash value to the ProductIdentifier instantiations for the purpose of model cross-referencing, in support of functionality such as the event effect and the lineage."> - [metadata address "pointsTo"=Observable->productIdentifier] - type TaxonomyValue: <"Defines a taxonomy value as either a simple string or a more granular expression with class names and values for each class."> name string (0..1) <"Specifies the taxonomy value as a simple string, which may be associated to an external scheme."> @@ -102,41 +97,45 @@ type IndexReferenceInformation: <"A class defining information related to Index" condition IndexAttributes: <"A required choice condition for either a floating rate or inflation rate index."> indexName exists or indexId exists -type IndexBase extends AssetIdentifier: <"Identifies an index by referencing an identifier."> +type IndexBase extends AssetBase: <"Identifies an index by referencing an identifier."> name string (0..1) <"A description of the Index."> - provider string (0..1) <"The organisation that creates or maintains the Index."> + provider LegalEntity (0..1) <"The organisation that creates or maintains the Index."> assetClass AssetClassEnum (0..1) <"The Asset Class of the Index."> - exchange string (0..*) <"If the Index is listed, defines the public exchange(s) of the listing."> - [metadata scheme] - relatedExchange string (0..*) <"Provides the related Exchanges, if applicable."> -//choice Index: <"Defines the different types of Index."> -// CreditIndex -// EquityIndex -// FloatingIndex -// InflationIndex -// OtherIndex +choice Index: <"An Index is an Observable which is computed based on the prices, rates or valuations of a number of assets that are tracked in a standardized way. Examples include equity market indices as well as indices on interest rates, inflation and credit instruments."> + CreditIndex <"An index based on credit risk, typically composed using corporate debt instruments in a region or industry sector, e.g. the iTraxx indices."> + EquityIndex <"An index based on equity securities, e.g. the S&P 500."> + FloatingRateIndex <"An interest rate index which can change over time, e.g. the SONIA (Sterling Overnight Index Average) in the UK."> + ForeignExchangeRate <"A rate based on the exchange of a pair of cash assets in specific currencies, e.g. USD versus GBP."> + InflationIndex <"An index that measures inflation in a specific market, e.g. the US Consumer Price Index."> + OtherIndex <"An index created by a market participant which doesn't align with the other index types."> + +type Cash extends AssetBase: <"An Asset that consists solely of a monetary holding in a currency. The currency of the Cash asset is held in the string Identifier (from AssetBase) and the AssetIdTypeEnum must be set to define that a CurrencyCode is set. The function SetCashCurrency can be used to create (or update) a Cash object and the function GetCashCurrency can be used to retrieve the currency of a Cash object."> -type Index extends ProductBase: <"Identifies an index by referencing a product identifier."> + condition CurrencyExists: <"There must be one and only one currency code and it must be valid (ie in the enumerated list)."> + AssetIdentifierByType(identifier, AssetIdTypeEnum -> CurrencyCode) count = 1 + and + AssetIdentifierByType(identifier, AssetIdTypeEnum -> CurrencyCode) -> identifier first to-enum CurrencyCodeEnum exists -type Cash extends AssetBase: <"An Asset that consists solely of a monetary holding in a currency. The currency of the Cash asset is held in the string Identifier (from AssetBase) and the AssetIdTypeEnum must be set to define that a CurrencyCode is set."> + condition NoTaxonomy: <"Taxonomy is not applicable for a Cash asset."> + taxonomy is absent - condition IdentifierIsCurrencyCode: <"The identifier of a Cash Asset is used to identify the Currency."> - identifier -> identifierType any = AssetIdTypeEnum -> CurrencyCode + condition NoExchange: <"Cash cannot be a listed Asset."> + exchange is absent -type Commodity extends ProductBase: <"Identifies a specific commodity by referencing a product identifier or by a product definition."> +type Commodity extends AssetBase: <"Identifies a specific commodity by referencing a product identifier or by a product definition."> commodityProductDefinition CommodityProductDefinition (0..1) <"Specifies the commodity underlier in the event that no ISDA Commodity Reference Benchmark exists."> priceQuoteType QuotationSideEnum (1..1) <"Describes the required quote type of the underlying price that will be observed. Example values include 'Bid, 'Ask', 'Settlement' (for a futures contract) and 'WeightedAverage' (for some published prices and indices)."> deliveryDateReference DeliveryDateParameters (0..1) <"Specifies the parameters for identifying the relevant contract date when the commodity reference price is a futures contract."> description string (0..1) <"Provides additional information about the commodity underlier."> condition OrdinalExists: <"Requires that, if multiple classification elements are present, they contain an ordinal so that they can be sorted."> - if productTaxonomy -> value -> classification count > 1 - then productTaxonomy -> value -> classification -> ordinal exists + if taxonomy -> value -> classification count > 1 + then taxonomy -> value -> classification -> ordinal exists condition ValueSource: <"Requires that value and source are present when product taxonomy is present"> - if productTaxonomy exists - then (productTaxonomy -> source exists and productTaxonomy -> value exists) + if taxonomy exists + then (taxonomy -> source exists and taxonomy -> value exists) type CommodityProductDefinition: <"Specifies the commodity underlier in the event that no ISDA Commodity Reference Price exists."> referenceFramework CommodityReferenceFramework (1..1) <"Specifies the type of commodity."> @@ -171,19 +170,16 @@ type CommodityReferenceFramework: <"Specifies the type of commodity."> type DigitalAsset extends AssetBase: <"An Asset that exists only in digital form, eg Bitcoin or Ethereum, that is not backed by other Assets; excludes the digital representation of other Assets, eg coins or Tokenised assets."> type ListedDerivative extends InstrumentBase: <"A securitized derivative on another asset."> - expiration string (1..1) <"The Expiration Date of the contract, expressed using the same symbology as the contract identifier."> - optionType OptionTypeEnum (0..1) <"The type of option, ie Put or Call. Left empty if it is a Future, also following the identifier symbology."> - strike string (0..1) <"Specifies the strike of the option, using the identifier symbology."> + deliveryTerm string (0..1) <"Also called contract month or delivery month. However, it's not always a month. It is usually expressed using a code, e.g. Z23 would be the Dec 2023 contract, (Z = December). For crude oil, the corresponding contract might be called CLZ23. Optional as this can be uniquely identified in the identifier."> + optionType PutCallEnum (0..1) <"The type of option, ie Put or Call. Left empty if it is a Future."> + strike number (0..1) <"Specifies the strike of the option."> condition Options: <"Options must have a strike price."> if optionType exists then strike exists else strike is absent -enum OptionTypeEnum: <"The enumerated values to specify the type of the option. In FpML, OptionTypeEnum is a union with PutCallEnum, which specifies whether the option is a put or a call."> +enum PutCallEnum: <"The enumerated values to specify the types of listed derivative options."> Put <"A put option gives the holder the right to sell the underlying asset by a certain date for a certain price."> Call <"A call option gives the holder the right to buy the underlying asset by a certain date for a certain price."> - Payer <"A 'payer' option: If you buy a 'payer' option you have the right but not the obligation to enter into the underlying swap transaction as the 'fixed' rate/price payer and receive float."> - Receiver <"A 'receiver' option: If you buy a 'receiver' option you have the right but not the obligation to enter into the underlying swap transaction as the 'fixed' rate/price receiver and pay float."> - Straddle <"A straddle strategy, which involves the simultaneous buying of a put and a call of the same underlier, at the same strike and same expiration date"> type Loan extends InstrumentBase: <"Identifies a loan by referencing an asset identifier and through an optional set of attributes."> borrower LegalEntity (0..*) <"Specifies the borrower. There can be more than one borrower. It is meant to be used in the event that there is no Bloomberg Id or the Secured List isn't applicable."> @@ -227,14 +223,13 @@ type CollateralTaxonomyValue: <"Specifies the collateral taxonomy value, either condition: one-of -type Security extends ProductBase: <"Identifies a security by referencing a product identifier and by specifying the sector."> +type Security extends InstrumentBase: <"Identifies a security by referencing an identifier and by specifying the sector."> [docReference ICMA GMRA namingConvention "Purchased Security" provision "As defined in GMRA paragraph 2(oo) The Purchased Securities are the Securities sold or to be sold and any New Purchased Securities transferred by Seller to Buyer under paragraph 8 (Substitution)."] securityType SecurityTypeEnum (1..1) <"Identifies the type of security using an enumerated list."> debtType DebtType (0..1) <"Identifies the type of debt and selected debt economics."> equityType EquityTypeEnum (0..1) <"Identifies the type of equity."> fundType FundProductTypeEnum (0..1) <"Identifies the type of fund."> - economicTerms EconomicTerms (0..1) <"The economic terms associated with a contractual product, i.e. the set of features that are price-forming."> condition DebtSubType: if securityType <> SecurityTypeEnum -> Debt @@ -248,10 +243,6 @@ type Security extends ProductBase: <"Identifies a security by referencing a prod if securityType <> SecurityTypeEnum -> Fund then fundType is absent - condition BondEconomicTerms: - if economicTerms exists - then securityType = SecurityTypeEnum -> Debt - type DebtType: <"Specifies the type of debt instrument."> debtClass DebtClassEnum (0..1) <"Specifies the characteristics of a debt instrument."> debtEconomics DebtEconomics (0..*) <"Specifies selected financial terms of a debt instrument."> diff --git a/rosetta-source/src/main/rosetta/event-common-func.rosetta b/rosetta-source/src/main/rosetta/event-common-func.rosetta index 07b39df60a..efa88c5bf3 100644 --- a/rosetta-source/src/main/rosetta/event-common-func.rosetta +++ b/rosetta-source/src/main/rosetta/event-common-func.rosetta @@ -33,9 +33,9 @@ func QuantityIncreased: after extract [ CompareTradeLot( - item -> trade -> tradableProduct -> tradeLot only-element, + item -> trade -> tradeLot only-element, CompareOp -> GreaterThan, - before -> trade -> tradableProduct -> tradeLot only-element + before -> trade -> tradeLot only-element ) = True ] all = True @@ -51,13 +51,13 @@ func QuantityDecreased: extract [ // check each after (item) is less than before (input) CompareTradeLot( - item -> trade -> tradableProduct -> tradeLot only-element, + item -> trade -> tradeLot only-element, CompareOp -> LessThan, - before -> trade -> tradableProduct -> tradeLot only-element + before -> trade -> tradeLot only-element ) = True and // check each after (item) is greater than zero CompareTradeLotToAmount( - item -> trade -> tradableProduct -> tradeLot only-element, + item -> trade -> tradeLot only-element, CompareOp -> GreaterThan, 0.0 ) = True @@ -72,7 +72,7 @@ func QuantityDecreasedToZero: set result: CompareTradeLotToAmount( - before -> trade -> tradableProduct -> tradeLot only-element, + before -> trade -> tradeLot only-element, CompareOp -> GreaterThanOrEquals, 0.0 ) = True @@ -90,7 +90,7 @@ func CompareTradeStatesToAmount: <"For each TradeState, compare the Quantity amo tradeStates extract [ CompareTradeLotToAmount( - item -> trade -> tradableProduct -> tradeLot only-element, + item -> trade -> tradeLot only-element, op, amount ) @@ -176,12 +176,12 @@ func InterestCashSettlementAmount: <"Defines the performance calculations releve ) alias payer: ExtractCounterpartyByRole( - tradeState -> trade -> tradableProduct -> counterparty, + tradeState -> trade -> counterparty, interestRatePayout -> payerReceiver -> payer ) -> partyReference alias receiver: ExtractCounterpartyByRole( - tradeState -> trade -> tradableProduct -> counterparty, + tradeState -> trade -> counterparty, interestRatePayout -> payerReceiver -> receiver ) -> partyReference set interestCashSettlementAmount -> quantity -> value: performance @@ -219,8 +219,9 @@ func ResolvePerformanceObservationIdentifiers: <"Defines which attributes on the if adjustedDate < adjustedFinalValuationDate then payout -> valuationDates -> interimValuationDate else payout -> valuationDates -> finalValuationDate - add identifiers -> observable -> productIdentifier: <"Represents the identifer for the equity underlier."> - payout -> underlier -> security -> productIdentifier + + set identifiers -> observable: <"Represents the identifer for the equity underlier."> + payout -> underlier set identifiers -> observationDate: <"Specifies the date for which to retrieve the market data value(s). Selects the most recent valuation date."> AdjustedValuationDates(payout -> valuationDates) filter item <= adjustedDate @@ -229,9 +230,11 @@ func ResolvePerformanceObservationIdentifiers: <"Defines which attributes on the ResolvePerformanceValuationTime( valuationDates -> valuationTime, valuationDates -> valuationTimeType, - identifiers -> observable -> productIdentifier only-element, + identifiers -> observable -> asset ->> identifier only-element, valuationDates -> determinationMethod ) + set identifiers -> informationSource: + payout -> observationTerms -> informationSource -> primarySource set identifiers -> determinationMethodology -> determinationMethod: <"Identifies a more specific price should multiple prices for the underlier be available at the given date time, for example bid or ask prices."> valuationDates -> determinationMethod @@ -253,7 +256,7 @@ func ResolvePerformanceValuationTime: <"Defines how to resolve the observation t inputs: valuationTime BusinessCenterTime (0..1) <"Represents the Equity Valuation terms from the Equity product definition."> valuationTimeType TimeTypeEnum (0..1) <"The time of day at which the calculation agent values the underlying, for example the official closing time of the exchange."> - productIdentifier ProductIdentifier (1..1) <"Specifies the product identifier, along with the source, which should be used to determine the correct valuation time i.e. close times are different across exchanges."> + assetIdentifier AssetIdentifier (1..1) <"Specifies the asset identifier, along with the source, which should be used to determine the correct valuation time i.e. close times are different across exchanges."> determinationMethod DeterminationMethodEnum (1..1) <"Specifies the method according to which an amount or a date is determined."> output: time TimeZone (1..1) @@ -263,7 +266,7 @@ func ResolvePerformanceValuationTime: <"Defines how to resolve the observation t set time: if valuationTimeType exists then ResolveTimeZoneFromTimeType( - productIdentifier, + assetIdentifier, valuationTimeType, determinationMethod ) @@ -289,7 +292,7 @@ func EquityCashSettlementAmount: <"Represents Part 1 Section 12 of the 2018 ISDA equityCashSettlementAmount Transfer (1..1) alias equityPerformancePayout: - tradeState -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> performancePayout only-element + tradeState -> trade -> product -> economicTerms -> payout -> performancePayout only-element alias equityPerformance: EquityPerformance( tradeState -> trade, @@ -298,12 +301,12 @@ func EquityCashSettlementAmount: <"Represents Part 1 Section 12 of the 2018 ISDA ) alias payer: ExtractCounterpartyByRole( - tradeState -> trade -> tradableProduct -> counterparty, + tradeState -> trade -> counterparty, equityPerformancePayout -> payerReceiver -> payer ) -> partyReference alias receiver: ExtractCounterpartyByRole( - tradeState -> trade -> tradableProduct -> counterparty, + tradeState -> trade -> counterparty, equityPerformancePayout -> payerReceiver -> receiver ) -> partyReference @@ -311,7 +314,7 @@ func EquityCashSettlementAmount: <"Represents Part 1 Section 12 of the 2018 ISDA Abs(equityPerformance) set equityCashSettlementAmount -> quantity -> unit -> currency: <"Does not handle the cross currency case. Only works in the case of a single trade lot."> ResolveEquityInitialPrice( - tradeState -> trade -> tradableProduct -> tradeLot only-element -> priceQuantity -> price + tradeState -> trade -> tradeLot only-element -> priceQuantity -> price ) -> unit -> currency set equityCashSettlementAmount -> payerReceiver -> payerPartyReference: if equityPerformance >= 0 then payer else receiver @@ -331,12 +334,12 @@ func EquityPerformance: <"Part 1 Section 12 of the 2018 ISDA CDM Equity Confirma equityPerformance number (1..1) alias performancePayout: - trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> performancePayout only-element + trade -> product -> economicTerms -> payout -> performancePayout only-element alias periodStartPrice: <"Only works in the case of a single trade lot."> ResolvePerformancePeriodStartPrice( performancePayout, - trade -> tradableProduct -> tradeLot only-element -> priceQuantity -> price, - trade -> tradableProduct -> tradeLot -> priceQuantity -> observable only-element, + trade -> tradeLot only-element -> priceQuantity -> price, + trade -> tradeLot -> priceQuantity -> observable only-element, date ) alias periodEndPrice: observation @@ -346,7 +349,7 @@ func EquityPerformance: <"Part 1 Section 12 of the 2018 ISDA CDM Equity Confirma alias notionalAmount: EquityNotionalAmount(numberOfSecurities, periodEndPrice) condition PriceReturnTermsExists: - trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> performancePayout -> returnTerms -> priceReturnTerms exists + trade -> product -> economicTerms -> payout -> performancePayout -> returnTerms -> priceReturnTerms exists set equityPerformance: rateOfReturn * notionalAmount @@ -381,7 +384,7 @@ func Create_StockSplit: <"Function specification to create the fully-formed busi alias preSplitNumberOfShares: <"Only works in the case of a single trade lot."> FilterQuantityByFinancialUnit( - before -> trade -> tradableProduct -> tradeLot only-element -> priceQuantity -> quantity, + before -> trade -> tradeLot only-element -> priceQuantity -> quantity, FinancialUnitEnum -> Share ) only-element -> value @@ -395,7 +398,7 @@ func Create_StockSplit: <"Function specification to create the fully-formed busi ... } alias preSplitPrice: - before -> trade -> tradableProduct -> tradeLot -> priceQuantity -> price + before -> trade -> tradeLot -> priceQuantity -> price filter perUnitOf -> financialUnit = FinancialUnitEnum -> Share then only-element alias postSplitPrice: <"The pre-split price is divided by the adjustment ratio to determine the post-split price."> @@ -434,17 +437,17 @@ func Create_Execution: <"Specifies the function to compose an execution based on instruction ExecutionInstruction (1..1) <"Instructions to be used as an input to the function"> output: execution TradeState (1..1) <"Execution primitive event with absent before state and an after state containing the tradable product, parties, associated party roles and the known settlement terms."> - set execution -> trade -> tradableProduct -> product: <"Assign the product input to the tradable product of the execution object."> + set execution -> trade -> product: <"Assign the product input to the tradable product of the execution object."> instruction -> product - add execution -> trade -> tradableProduct -> tradeLot: <"Assign the prices and quantities and lot identifier input to the tradable product of the execution object."> + add execution -> trade -> tradeLot: <"Assign the prices and quantities and lot identifier input to the tradable product of the execution object."> TradeLot { priceQuantity: instruction -> priceQuantity, lotIdentifier: instruction -> lotIdentifier } - add execution -> trade -> tradableProduct -> counterparty: <"Assign the counterparty input to the tradable product of the execution object."> + add execution -> trade -> counterparty: <"Assign the counterparty input to the tradable product of the execution object."> instruction -> counterparty - add execution -> trade -> tradableProduct -> ancillaryParty: <"Assign the ancillaryRole input to the tradable product of the execution object."> + add execution -> trade -> ancillaryParty: <"Assign the ancillaryRole input to the tradable product of the execution object."> instruction -> ancillaryParty add execution -> trade -> party: <"Assign the parties input to the execution object."> instruction -> parties @@ -493,20 +496,25 @@ func Create_Exercise: <"Defines the process of putting into effect the rights sp exercise TradeState (1..*) alias tradableProduct: <"Extracts the originally traded product."> - originalTrade -> trade -> tradableProduct + originalTrade -> trade alias optionPayout: <"Extracts the optionPayout from exerciseInstruction if provided or from the original trade if absent"> if exerciseInstruction -> exerciseOption exists then exerciseInstruction -> exerciseOption - else tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> optionPayout only-element + else tradableProduct -> product -> economicTerms -> payout -> optionPayout only-element alias underlier: <"Extracts the underlying financial product, upon which the option decision is contingent. Requires that the original contract contains an option payout."> - optionPayout -> underlier + optionPayout -> productUnderlier + + alias nonTransferableProduct: + if underlier -> NonTransferableProduct exists + then underlier -> NonTransferableProduct + else Create_NonTransferableProduct(underlier -> TransferableProduct, optionPayout -> payerReceiver) alias execution: <"Creates the execution primitive describing the exchange of the underlying product, either as a cash transfer or as the formation of a new contractual product between parties."> Create_Execution( ExecutionInstruction { - product: underlier, + product: nonTransferableProduct, priceQuantity: tradableProduct -> tradeLot only-element -> priceQuantity, counterparty: tradableProduct -> counterparty, ancillaryParty: tradableProduct -> ancillaryParty, @@ -528,6 +536,16 @@ func Create_Exercise: <"Defines the process of putting into effect the rights sp add exercise: <"Adds the replacement trade"> execution +func Create_NonTransferableProduct: <"Creates a NonTransferableProduct (ie EconomicTerms) from an underlier."> + inputs: + underlier TransferableProduct (1..1) + payerReceiver PayerReceiver (1..1) + output: + newProduct NonTransferableProduct (1..1) + + set newProduct -> economicTerms -> payout -> settlementPayout -> underlier -> TransferableProduct: underlier + set newProduct -> economicTerms -> payout -> settlementPayout -> payerReceiver: payerReceiver + func Create_Reset: <"Defines how a Reset should be constructed."> inputs: instruction ResetInstruction (1..1) <"Specifies the reset instructions."> @@ -623,11 +641,11 @@ func Create_AssetTransfer: <"Defines how Transfer that represents an exchange of transfer Transfer (1..1) alias assetPayout: - instruction -> tradeState -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> contractualProduct -> economicTerms -> payout -> assetPayout only-element + instruction -> tradeState -> trade -> product -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> economicTerms -> payout -> assetPayout only-element alias tradeQuantity: <"Security quantity obtained by filtering on the trade quantity"> FilterQuantityByFinancialUnit( - instruction -> tradeState -> trade -> tradableProduct -> tradeLot -> priceQuantity -> quantity, + instruction -> tradeState -> trade -> tradeLot -> priceQuantity -> quantity, FinancialUnitEnum -> Share ) only-element @@ -643,7 +661,7 @@ func Create_AssetTransfer: <"Defines how Transfer that represents an exchange of alias securityPrice: FilterPrice( - instruction -> tradeState -> trade -> tradableProduct -> tradeLot -> priceQuantity -> price, + instruction -> tradeState -> trade -> tradeLot -> priceQuantity -> price, PriceTypeEnum -> AssetPrice, empty, empty @@ -660,38 +678,38 @@ func Create_AssetTransfer: <"Defines how Transfer that represents an exchange of ... } - add transfer -> asset -> Instrument -> Security -> productIdentifier: - assetPayout -> securityInformation -> security -> productIdentifier + add transfer -> asset -> Instrument -> Security -> identifier: + assetPayout -> securityInformation -> security -> identifier set transfer -> payerReceiver -> payerPartyReference: if instruction -> payerReceiver -> payer exists then ExtractCounterpartyByRole( - instruction -> tradeState -> trade -> tradableProduct -> counterparty, + instruction -> tradeState -> trade -> counterparty, instruction -> payerReceiver -> payer ) -> partyReference else if assetPayout -> payerReceiver -> payer exists then ExtractCounterpartyByRole( - instruction -> tradeState -> trade -> tradableProduct -> counterparty, + instruction -> tradeState -> trade -> counterparty, assetPayout -> payerReceiver -> payer ) -> partyReference set transfer -> payerReceiver -> receiverPartyReference: if instruction -> payerReceiver -> payer exists then ExtractCounterpartyByRole( - instruction -> tradeState -> trade -> tradableProduct -> counterparty, + instruction -> tradeState -> trade -> counterparty, instruction -> payerReceiver -> receiver ) -> partyReference else if assetPayout -> payerReceiver -> receiver exists then ExtractCounterpartyByRole( - instruction -> tradeState -> trade -> tradableProduct -> counterparty, + instruction -> tradeState -> trade -> counterparty, assetPayout -> payerReceiver -> receiver ) -> partyReference set transfer -> settlementDate -> adjustedDate: instruction -> date set transfer -> settlementOrigin -> assetPayout: - if instruction -> tradeState -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> contractualProduct -> economicTerms -> payout -> assetPayout exists - then instruction -> tradeState -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> contractualProduct -> economicTerms -> payout -> assetPayout only-element + if instruction -> tradeState -> trade -> product -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> economicTerms -> payout -> assetPayout exists + then instruction -> tradeState -> trade -> product -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> economicTerms -> payout -> assetPayout only-element as-key func ResolveTransfer: <"Defines how to calculate the amount due to be transferred after a Reset Event."> @@ -740,22 +758,22 @@ func SecurityFinanceCashSettlementAmount: cashSettlementAmount Transfer (1..1) alias assetPayout: - tradeState -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> contractualProduct -> economicTerms -> payout -> assetPayout only-element + tradeState -> trade -> product -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> economicTerms -> payout -> assetPayout only-element alias collateral: - tradeState -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> collateral + tradeState -> trade -> product -> economicTerms -> collateral alias securityQuantity: <"Specifies the number of securities."> if quantity exists then quantity else FilterQuantityByFinancialUnit( - tradeState -> trade -> tradableProduct -> tradeLot -> priceQuantity -> quantity, + tradeState -> trade -> tradeLot -> priceQuantity -> quantity, FinancialUnitEnum -> Share ) alias securityPrice: <"Specifies the price per security."> FilterPrice( - tradeState -> trade -> tradableProduct -> tradeLot -> priceQuantity -> price, + tradeState -> trade -> tradeLot -> priceQuantity -> price, PriceTypeEnum -> AssetPrice, empty, empty @@ -772,8 +790,8 @@ func SecurityFinanceCashSettlementAmount: if quantity exists then quantity -> unit -> financialUnit = FinancialUnitEnum -> Share - condition ProductIdentifiersMatch: - tradeState -> trade -> tradableProduct -> tradeLot -> priceQuantity -> observable -> productIdentifier = assetPayout -> securityInformation -> security -> productIdentifier + condition IdentifiersMatch: + tradeState -> trade -> tradeLot -> priceQuantity -> observable -> asset ->> identifier = assetPayout -> securityInformation -> security -> identifier set cashSettlementAmount -> quantity -> value: securityPrice -> value * securityQuantity -> value * marginRatio @@ -784,24 +802,24 @@ func SecurityFinanceCashSettlementAmount: set cashSettlementAmount -> payerReceiver -> payerPartyReference: if payerReceiver exists then ExtractCounterpartyByRole( - tradeState -> trade -> tradableProduct -> counterparty, + tradeState -> trade -> counterparty, payerReceiver -> receiver ) -> partyReference else if assetPayout -> payerReceiver -> receiver exists then ExtractCounterpartyByRole( - tradeState -> trade -> tradableProduct -> counterparty, + tradeState -> trade -> counterparty, assetPayout -> payerReceiver -> receiver ) -> partyReference set cashSettlementAmount -> payerReceiver -> receiverPartyReference: if payerReceiver exists then ExtractCounterpartyByRole( - tradeState -> trade -> tradableProduct -> counterparty, + tradeState -> trade -> counterparty, payerReceiver -> payer ) -> partyReference else if assetPayout -> payerReceiver -> payer exists then ExtractCounterpartyByRole( - tradeState -> trade -> tradableProduct -> counterparty, + tradeState -> trade -> counterparty, assetPayout -> payerReceiver -> payer ) -> partyReference @@ -836,7 +854,7 @@ func Create_PartyChange: <"Defines the logic for changing one of the counterpart role: counterparty -> role } else ExtractCounterpartyByRole( - originalTrade -> trade -> tradableProduct -> counterparty, + originalTrade -> trade -> counterparty, CounterpartyRoleEnum -> Party1 ) alias counterparty2: @@ -846,18 +864,18 @@ func Create_PartyChange: <"Defines the logic for changing one of the counterpart role: counterparty -> role } else ExtractCounterpartyByRole( - originalTrade -> trade -> tradableProduct -> counterparty, + originalTrade -> trade -> counterparty, CounterpartyRoleEnum -> Party2 ) alias partyToRemove: ExtractCounterpartyByRole( - originalTrade -> trade -> tradableProduct -> counterparty, + originalTrade -> trade -> counterparty, counterparty -> role ) -> partyReference set newTrade: <"Copy the original trade."> originalTrade - set newTrade -> trade -> tradableProduct -> counterparty: <"Assigns the new counterparties."> + set newTrade -> trade -> counterparty: <"Assigns the new counterparties."> [counterparty1, counterparty2] set newTrade -> trade -> party: <"Removes the existing party, and adds the new party."> ReplaceParty( @@ -869,7 +887,7 @@ func Create_PartyChange: <"Defines the logic for changing one of the counterpart tradeId add newTrade -> trade -> party: <"Add ancillary party as an additional party"> ancillaryParty -> partyReference - add newTrade -> trade -> tradableProduct -> ancillaryParty: <"Add ancillary party role"> + add newTrade -> trade -> ancillaryParty: <"Add ancillary party role"> ancillaryParty add newTrade -> trade -> party: <"Add party role party reference as an additional party"> partyRole -> partyReference @@ -890,7 +908,7 @@ func Create_QuantityChange: <"A specification of the inputs, outputs and constra quantityChange TradeState (1..1) alias tradableProduct: <"TradableProduct from the input TradeState"> - tradeState -> trade -> tradableProduct + tradeState -> trade alias tradeLotExists: <"The quantity change instruction applies to an existing tradeLot"> FilterTradeLot(tradableProduct -> tradeLot, instruction -> lotIdentifier) exists @@ -935,14 +953,12 @@ func Create_QuantityChange: <"A specification of the inputs, outputs and constra set quantityChange: tradeState - set quantityChange -> trade -> tradableProduct: <"Update trade with new TradableProduct."> - TradableProduct { - product: tradableProduct -> product, - tradeLot: newTradeLots, - counterparty: tradableProduct -> counterparty, - ancillaryParty: tradableProduct -> ancillaryParty, - adjustment: tradableProduct -> adjustment - } + // Update trade with new TradableProduct. + set quantityChange -> trade -> product: tradableProduct -> product + set quantityChange -> trade -> tradeLot: newTradeLots + set quantityChange -> trade -> counterparty: tradableProduct -> counterparty + set quantityChange -> trade -> ancillaryParty: tradableProduct -> ancillaryParty + set quantityChange -> trade -> adjustment: tradableProduct -> adjustment set quantityChange -> state -> positionState: if newTradeLots -> priceQuantity -> quantity -> value all = 0 @@ -958,28 +974,26 @@ func Create_TermsChange: <"A specification of the inputs, outputs and constraint alias newProduct: if termsChange -> product exists then termsChange -> product - else before -> trade -> tradableProduct -> product + else before -> trade -> product alias newAncillaryParty: if termsChange -> ancillaryParty exists then termsChange -> ancillaryParty - else before -> trade -> tradableProduct -> ancillaryParty + else before -> trade -> ancillaryParty alias newAdjustment: if termsChange -> adjustment exists then termsChange -> adjustment - else before -> trade -> tradableProduct -> adjustment + else before -> trade -> adjustment set tradeState: before - set tradeState -> trade -> tradableProduct: <"Contract to be updated based on the new terms change inputs."> - TradableProduct { - product: newProduct, - tradeLot: tradeState -> trade -> tradableProduct -> tradeLot, - counterparty: tradeState -> trade -> tradableProduct -> counterparty, - ancillaryParty: newAncillaryParty, - adjustment: newAdjustment - } + // Contract to be updated based on the new terms change inputs. + set tradeState -> trade -> product: newProduct + set tradeState -> trade -> tradeLot: tradeState -> trade -> tradeLot + set tradeState -> trade -> counterparty: tradeState -> trade -> counterparty + set tradeState -> trade -> ancillaryParty: newAncillaryParty + set tradeState -> trade -> adjustment: newAdjustment func FilterOpenTradeStates: <"Filter to only 'open' TradeState - where both the closedState and positionState are not set."> inputs: @@ -1109,8 +1123,8 @@ func UpdateSpreadAdjustmentAndRateOptions: <"For each of the trade state's price set updatedTradeState: tradeState - set updatedTradeState -> trade -> tradableProduct -> tradeLot -> priceQuantity: - tradeState -> trade -> tradableProduct -> tradeLot only-element -> priceQuantity + set updatedTradeState -> trade -> tradeLot -> priceQuantity: + tradeState -> trade -> tradeLot only-element -> priceQuantity extract UpdateIndexTransitionPriceAndRateOption( item, @@ -1220,18 +1234,18 @@ func ResolveSecurityFinanceBillingAmount: <"Calculates the billing amount for a alias securityQuantity: <"Specifies the number of securities."> FilterQuantityByFinancialUnit( - tradeState -> trade -> tradableProduct -> tradeLot -> priceQuantity -> quantity, + tradeState -> trade -> tradeLot -> priceQuantity -> quantity, FinancialUnitEnum -> Share ) alias interestRatePayout: <"The interest payout that represents the lending fee."> - tradeState -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> interestRatePayout only-element + tradeState -> trade -> product -> economicTerms -> payout -> interestRatePayout only-element alias assetPayout: <"The security finance payout that represents the securities lent."> - tradeState -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> contractualProduct -> economicTerms -> payout -> assetPayout only-element + tradeState -> trade -> product -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> economicTerms -> payout -> assetPayout only-element alias collateral: - tradeState -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> collateral + tradeState -> trade -> product -> economicTerms -> collateral alias haircutPercentage: (1.0 - collateral -> collateralProvisions -> eligibleCollateral only-element -> treatment -> valuationTreatment -> haircutPercentage) @@ -1270,13 +1284,13 @@ func ResolveSecurityFinanceBillingAmount: <"Calculates the billing amount for a alias payerPartyReference: ExtractCounterpartyByRole( - tradeState -> trade -> tradableProduct -> counterparty, + tradeState -> trade -> counterparty, interestRatePayout -> payerReceiver -> payer ) -> partyReference alias receiverPartyReference: ExtractCounterpartyByRole( - tradeState -> trade -> tradableProduct -> counterparty, + tradeState -> trade -> counterparty, interestRatePayout -> payerReceiver -> receiver ) -> partyReference @@ -1323,8 +1337,6 @@ func Create_Return: <"Defines the process of partially or fully returning a Secu output: returnEvent BusinessEvent (1..1) <"Produces the business event composed of primitive events describing the transfer and termination, as a result of the input return instruction."> - alias tradableProduct: tradeState -> trade -> tradableProduct - alias quantitySchedule: returnInstruction -> quantity extract @@ -1360,7 +1372,7 @@ func Qualify_Repurchase: <"The qualification of a repurchase event from the fact is_event boolean (1..1) set is_event: businessEvent -> intent = EventIntentEnum -> Repurchase - and businessEvent -> after -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> contractualProduct -> economicTerms -> payout -> assetPayout exists + and businessEvent -> after -> trade -> product -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> economicTerms -> payout -> assetPayout exists and (businessEvent -> instruction count = 1 and (businessEvent -> instruction -> primitiveInstruction -> quantityChange, businessEvent -> instruction -> primitiveInstruction -> transfer) only exists) and QuantityDecreasedToZero( @@ -1377,7 +1389,7 @@ func ResolveRepurchaseTransferInstruction: <"Resolves an instruction for settlem repurchaseInstruction EventInstruction (1..1) alias changeQuantity: <"Create distinct list of Quantity with value set to zero."> - tradeState -> trade -> tradableProduct -> tradeLot -> priceQuantity -> quantity + tradeState -> trade -> tradeLot -> priceQuantity -> quantity extract NonNegativeQuantitySchedule { value: 0.0, @@ -1403,6 +1415,27 @@ func ResolveRepurchaseTransferInstruction: <"Resolves an instruction for settlem lotIdentifier: empty } +func CheckTransferableProduct: <"Identifies whether a product is transferable, that is, it has only an Asset or a Transferable Product in a single Settlement Payout."> + inputs: + economicTerms EconomicTerms (1..1) + output: + isTransferableProduct boolean (1..1) + + set isTransferableProduct: + if economicTerms -> payout -> settlementPayout only exists + and economicTerms -> payout -> settlementPayout -> underlier exists + then True + +func CheckTradeNotTransferableProduct: <"Identifies whether the product inside a TradeState is not transferable, that is, it has only an Asset or a Transferable Product in a single Settlement Payout."> + inputs: + tradeState TradeState (1..1) + output: + isNotTransferableProduct boolean (1..1) + + set isNotTransferableProduct: + if CheckTradeNotTransferableProduct(tradeState) + then False + func Create_RollPrimitiveInstruction: <"Creates the primitive instructions for a trade roll. A trade roll consists in closing an existing trade and entering into a new one which has the same characteristics as the old one, except with an extended termination date and (possibly) a different price."> inputs: tradeState TradeState (1..1) <"The original trade to be rolled."> @@ -1413,7 +1446,7 @@ func Create_RollPrimitiveInstruction: <"Creates the primitive instructions for a instruction PrimitiveInstruction (1..1) condition ContractualProduct: <"Only a contractual product can be rolled."> - tradeState -> trade -> tradableProduct -> product -> contractualProduct exists + CheckTradeNotTransferableProduct(tradeState) set instruction -> split -> breakdown: <"Sets the first part of the split to be a termination instruction for the existing trade."> [Create_TerminationInstruction(tradeState)] @@ -1427,7 +1460,7 @@ func Create_RollPrimitiveInstruction: <"Creates the primitive instructions for a lotIdentifier: empty }, termsChange: Create_RollTermChangeInstruction( - tradeState -> trade -> tradableProduct -> product -> contractualProduct, + tradeState -> trade -> product, effectiveRollDate, terminationDate ), @@ -1437,7 +1470,7 @@ func Create_RollPrimitiveInstruction: <"Creates the primitive instructions for a func Create_EffectiveOrTerminationDateTermChangeInstruction: <"Creates the relevant terms change primitive instruction object for rolling a contractual product, which consists in the same terms as the original contractual product but with different effective and termination dates."> inputs: - contractualProduct ContractualProduct (1..1) <"The original contractual product to be rolled."> + product NonTransferableProduct (1..1) <"The original contractual product to be rolled."> effectiveRollDate AdjustableOrRelativeDate (0..1) <"The date to close and open a new position."> terminationDate AdjustableOrRelativeDate (0..1) <"The new termination date."> output: @@ -1446,30 +1479,30 @@ func Create_EffectiveOrTerminationDateTermChangeInstruction: <"Creates the relev condition DateExists: effectiveRollDate exists or terminationDate exists - set termsChangeInstruction -> product -> contractualProduct: contractualProduct + set termsChangeInstruction -> product: product - set termsChangeInstruction -> product -> contractualProduct -> economicTerms -> effectiveDate: + set termsChangeInstruction -> product -> economicTerms -> effectiveDate: if effectiveRollDate exists then effectiveRollDate - else contractualProduct -> economicTerms -> effectiveDate + else product -> economicTerms -> effectiveDate - set termsChangeInstruction -> product -> contractualProduct -> economicTerms -> terminationDate: + set termsChangeInstruction -> product -> economicTerms -> terminationDate: if terminationDate exists then terminationDate - else contractualProduct -> economicTerms -> terminationDate + else product -> economicTerms -> terminationDate func Create_RollTermChangeInstruction: <"Creates the relevant terms change primitive instruction object for rolling a contractual product, which consists in the same terms as the original contractual product but with different effective and termination dates."> inputs: - contractualProduct ContractualProduct (1..1) <"The original contractual product to be rolled."> + product NonTransferableProduct (1..1) <"The original contractual product to be rolled."> effectiveRollDate AdjustableOrRelativeDate (1..1) <"The date to close and open a new position."> terminationDate AdjustableOrRelativeDate (1..1) <"The new termination date."> output: termsChangeInstruction TermsChangeInstruction (1..1) <"The relevant primitive instruction for the roll, which is a terms change."> - set termsChangeInstruction -> product -> contractualProduct: contractualProduct - set termsChangeInstruction -> product -> contractualProduct -> economicTerms -> effectiveDate: + set termsChangeInstruction -> product: product + set termsChangeInstruction -> product -> economicTerms -> effectiveDate: effectiveRollDate - set termsChangeInstruction -> product -> contractualProduct -> economicTerms -> terminationDate: + set termsChangeInstruction -> product -> economicTerms -> terminationDate: terminationDate func Qualify_Roll: <"Qualification of a roll event based on: (i) terminating a single existing trade, (ii) entering into a new trade with the same details as the old trade, except for the effective and termination date where the effective date. The roll qualification does not make any assumption on the resulting quantity which may change compared to the original trade (it may only be partially rolled). The price is also likely different as market conditions may have evolved."> @@ -1480,9 +1513,9 @@ func Qualify_Roll: <"Qualification of a roll event based on: (i) terminating a s is_event boolean (1..1) alias beforeEconomicterms: - businessEvent -> instruction only-element -> before -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms + businessEvent -> instruction only-element -> before -> trade -> product -> economicTerms alias openEconomicTerms: - FilterOpenTradeStates(businessEvent -> after) only-element -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms + FilterOpenTradeStates(businessEvent -> after) only-element -> trade -> product -> economicTerms alias closedTradeState: FilterClosedTradeStates(businessEvent -> after) set is_event: @@ -1504,9 +1537,10 @@ func Create_OnDemandRateChangePrimitiveInstruction: <"Creates a full primitive i instruction PrimitiveInstruction (1..1) condition ContractualProduct: <"Only a contractual product can have a rate change."> - tradeState -> trade -> tradableProduct -> product -> contractualProduct exists + CheckTradeNotTransferableProduct(tradeState) + condition SingleTradeLot: <"Rate change only works for a trade with a single trade lot."> - tradeState -> trade -> tradableProduct -> tradeLot count = 1 + tradeState -> trade -> tradeLot count = 1 set instruction -> split -> breakdown: <"Sets the first part of the split to be a termination instruction for the existing trade."> [Create_TerminationInstruction(tradeState)] @@ -1515,11 +1549,11 @@ func Create_OnDemandRateChangePrimitiveInstruction: <"Creates a full primitive i [ PrimitiveInstruction { quantityChange: Create_OnDemandRateChangePriceChangeInstruction( - tradeState -> trade -> tradableProduct -> tradeLot only-element -> priceQuantity, + tradeState -> trade -> tradeLot only-element -> priceQuantity, agreedRate ), termsChange: Create_OnDemandRateChangeTermsChangeInstruction( - tradeState -> trade -> tradableProduct -> product -> contractualProduct, + tradeState -> trade -> product, effectiveDate ), ... @@ -1569,14 +1603,14 @@ func Create_OnDemandRateChangePriceChangeInstruction: <"Creates a price change i func Create_OnDemandRateChangeTermsChangeInstruction: <"Creates a terms change instruction for an on-demand rate change, based on a new rate provided as a single number. This instruction only updates the effective date but keeps other details of the trade unchanged."> inputs: - contractualProduct ContractualProduct (1..1) <"The original contractual product whose rate is changed."> + product NonTransferableProduct (1..1) <"The original contractual product whose rate is changed."> effectiveDate AdjustableOrRelativeDate (1..1) <"The date to open the new position."> output: termsChangeInstruction TermsChangeInstruction (1..1) - set termsChangeInstruction -> product -> contractualProduct: <"Keep the same contractual product as the original trade"> - contractualProduct - set termsChangeInstruction -> product -> contractualProduct -> economicTerms -> effectiveDate: <"Updates the contractual product's effective date to be the new effective date."> + set termsChangeInstruction -> product: <"Keep the same contractual product as the original trade"> + product + set termsChangeInstruction -> product -> economicTerms -> effectiveDate: <"Updates the contractual product's effective date to be the new effective date."> effectiveDate func Qualify_OnDemandRateChange: <"The qualification of on an-demand rate change event from the fact that the only primitive is the reset."> @@ -1586,32 +1620,36 @@ func Qualify_OnDemandRateChange: <"The qualification of on an-demand rate change output: is_event boolean (1..1) - alias beforeTradableProduct: - businessEvent -> instruction only-element -> before -> trade -> tradableProduct + alias beforeTrade: + businessEvent -> instruction only-element -> before -> trade + alias beforeProduct: + beforeTrade -> product alias beforeEconomicterms: - beforeTradableProduct -> product -> contractualProduct -> economicTerms - alias openTradableProduct: - FilterOpenTradeStates(businessEvent -> after) only-element -> trade -> tradableProduct + beforeProduct -> economicTerms + alias openTrade: + FilterOpenTradeStates(businessEvent -> after) only-element -> trade + alias openProduct: + openTrade -> product alias openEconomicTerms: - openTradableProduct -> product -> contractualProduct -> economicTerms + openProduct -> economicTerms alias closedTradeState: FilterClosedTradeStates(businessEvent -> after) alias beforePriceQuantityRateOnly: <"The rate value before. There must be 1 and only 1."> - beforeTradableProduct -> tradeLot only-element -> priceQuantity + beforeTrade -> tradeLot only-element -> priceQuantity extract price then flatten then filter priceType = PriceTypeEnum -> InterestRate then extract value alias openPriceQuantityRateOnly: <"The rate value after. There must be 1 and only 1, and it must be different from the rate before."> - openTradableProduct -> tradeLot only-element -> priceQuantity + openTrade -> tradeLot only-element -> priceQuantity extract price then flatten then filter priceType = PriceTypeEnum -> InterestRate then extract value alias beforePriceQuantityNoRate: <"The price and quantity attributes before, excluding any rate price."> - beforeTradableProduct -> tradeLot only-element -> priceQuantity + beforeTrade -> tradeLot only-element -> priceQuantity extract PriceQuantity { price: price @@ -1622,7 +1660,7 @@ func Qualify_OnDemandRateChange: <"The qualification of on an-demand rate change } alias openPriceQuantityNoRate: <"The price and quantity attributes after, excluding any rate price. They must be equal to the price and quantity before, excluding any rate price"> - openTradableProduct -> tradeLot only-element -> priceQuantity + openTrade -> tradeLot only-element -> priceQuantity extract PriceQuantity { price: price @@ -1653,8 +1691,8 @@ func Create_CancellationPrimitiveInstruction: <"Creates a primitive instruction output: instruction PrimitiveInstruction (1..1) - condition ContractualProduct: <"If a contratual product can be cancelled."> - tradeState -> trade -> tradableProduct -> product -> contractualProduct exists + condition ContractualProduct: <"Only a contractual product can be cancelled."> + CheckTradeNotTransferableProduct(tradeState) set instruction -> split -> breakdown: <"Sets the first part of the split to be a termination instruction for the existing trade."> [Create_TerminationInstruction(tradeState)] @@ -1663,12 +1701,12 @@ func Create_CancellationPrimitiveInstruction: <"Creates a primitive instruction [ PrimitiveInstruction { quantityChange: QuantityChangeInstruction { - change: tradeState -> trade -> tradableProduct -> tradeLot -> priceQuantity, + change: tradeState -> trade -> tradeLot -> priceQuantity, direction: QuantityChangeDirectionEnum -> Replace, lotIdentifier: empty }, termsChange: Create_CancellationTermChangeInstruction( - tradeState -> trade -> tradableProduct -> product -> contractualProduct, + tradeState -> trade -> product, cancellationDate ), ... @@ -1677,13 +1715,13 @@ func Create_CancellationPrimitiveInstruction: <"Creates a primitive instruction func Create_CancellationTermChangeInstruction: <"Create a terms change instruction for a cancellation that consists in bringing the termination date forward."> inputs: - contractualProduct ContractualProduct (1..1) <"Contractual product of original trade"> + product NonTransferableProduct (1..1) <"Contractual product of original trade"> cancellationDate AdjustableOrRelativeDate (1..1) <"The new termination date."> output: termsChangeInstruction TermsChangeInstruction (1..1) - set termsChangeInstruction -> product -> contractualProduct: contractualProduct - set termsChangeInstruction -> product -> contractualProduct -> economicTerms -> terminationDate: + set termsChangeInstruction -> product: product + set termsChangeInstruction -> product -> economicTerms -> terminationDate: cancellationDate func Qualify_Cancellation: <"Qualification of an cancellation event."> @@ -1694,9 +1732,9 @@ func Qualify_Cancellation: <"Qualification of an cancellation event."> is_event boolean (1..1) alias closedEconomicTerms: - FilterClosedTradeStates(businessEvent -> after) only-element -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms + FilterClosedTradeStates(businessEvent -> after) only-element -> trade -> product -> economicTerms alias openEconomicTerms: - FilterOpenTradeStates(businessEvent -> after) only-element -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms + FilterOpenTradeStates(businessEvent -> after) only-element -> trade -> product -> economicTerms set is_event: businessEvent -> instruction -> before count = 1 @@ -1730,10 +1768,10 @@ func Create_PairOffInstruction: <"Creates a set of instructions to pair-off a se item -> trade -> contractDetails -> documentation ), execution: ExecutionInstruction { - product: item -> trade -> tradableProduct -> product, - priceQuantity: item -> trade -> tradableProduct -> tradeLot only-element -> priceQuantity, - counterparty: item -> trade -> tradableProduct -> counterparty, - ancillaryParty: item -> trade -> tradableProduct -> ancillaryParty, + product: item -> trade -> product, + priceQuantity: item -> trade -> tradeLot only-element -> priceQuantity, + counterparty: item -> trade -> counterparty, + ancillaryParty: item -> trade -> ancillaryParty, parties: item -> trade -> party, partyRoles: item -> trade -> partyRole, executionDetails: Create_PackageExecutionDetails( @@ -1770,7 +1808,11 @@ func Qualify_PairOff: <"Qualifies an event as a pair-off when all the details of newTradeInstruction count = businessEvent -> instruction count // All the trade details (except the execution instructions) are unchanged // and openTradeNoExecutionDetails = beforeTradeNoExecutionDetails - and openTradeState -> trade -> tradableProduct = newTradeInstruction -> before -> trade -> tradableProduct + and openTradeState -> trade -> product = newTradeInstruction -> before -> trade -> product + and openTradeState -> trade -> tradeLot = newTradeInstruction -> before -> trade -> tradeLot + and openTradeState -> trade -> counterparty = newTradeInstruction -> before -> trade -> counterparty + and openTradeState -> trade -> ancillaryParty = newTradeInstruction -> before -> trade -> ancillaryParty + and openTradeState -> trade -> adjustment = newTradeInstruction -> before -> trade -> adjustment // All open trades are associated to a package, and that package is the same across all trades and packageRef count = openTradeState count and packageRef distinct count = 1 @@ -1799,10 +1841,10 @@ func Create_ShapingInstruction: <"Creates a set of instructions to shape a trade tradeState -> trade -> contractDetails -> documentation ), execution: ExecutionInstruction { - product: tradeState -> trade -> tradableProduct -> product, - priceQuantity: tradeState -> trade -> tradableProduct -> tradeLot only-element -> priceQuantity, - counterparty: tradeState -> trade -> tradableProduct -> counterparty, - ancillaryParty: tradeState -> trade -> tradableProduct -> ancillaryParty, + product: tradeState -> trade -> product, + priceQuantity: tradeState -> trade -> tradeLot only-element -> priceQuantity, + counterparty: tradeState -> trade -> counterparty, + ancillaryParty: tradeState -> trade -> ancillaryParty, parties: tradeState -> trade -> party, partyRoles: tradeState -> trade -> partyRole, executionDetails: Create_PackageExecutionDetails( @@ -1847,7 +1889,7 @@ func Qualify_Shaping: <"The qualification of a shaping event from the fact that // Open trade counterparties should match before trade counterparties and openTradeStates extract [ - item -> trade -> tradableProduct -> counterparty -> partyReference = beforeTradeState -> trade -> tradableProduct -> counterparty -> partyReference + item -> trade -> counterparty -> partyReference = beforeTradeState -> trade -> counterparty -> partyReference ] all = True // All open trades are associated to a package, and that package is the same across all trades and packageRef count = openTradeNoExecutionDetails count @@ -1861,7 +1903,7 @@ func Create_PartialDeliveryPrimitiveInstruction: <"Creates the primitive instruc instruction PrimitiveInstruction (1..1) condition ContractualProduct: <"This function applies to contractual products only."> - tradeState -> trade -> tradableProduct -> product -> contractualProduct exists + CheckTradeNotTransferableProduct(tradeState) set instruction -> split -> breakdown: <"Sets the first part of the split to be a termination instruction for the existing trade."> [Create_TerminationInstruction(tradeState)] @@ -1872,7 +1914,7 @@ func Create_PartialDeliveryPrimitiveInstruction: <"Creates the primitive instruc quantityChange: QuantityChangeInstruction { change: deliveredPriceQuantity, direction: QuantityChangeDirectionEnum -> Replace, - lotIdentifier: tradeState -> trade -> tradableProduct -> tradeLot -> lotIdentifier + lotIdentifier: tradeState -> trade -> tradeLot -> lotIdentifier }, ... } @@ -1922,7 +1964,7 @@ func Create_RepricePrimitiveInstruction: <"Creates the primitive instructions fo instruction PrimitiveInstruction (1..1) alias oldPriceQuantity: - tradeState -> trade -> tradableProduct -> tradeLot -> priceQuantity + tradeState -> trade -> tradeLot -> priceQuantity alias currentAssetPrice: <"Filter interest rate price and make it into a single element"> oldPriceQuantity @@ -1945,7 +1987,7 @@ func Create_RepricePrimitiveInstruction: <"Creates the primitive instructions fo } alias changeCashQuantity: <"Create distinct list of Quantity with value set to newAssetQuantity"> - tradeState -> trade -> tradableProduct -> tradeLot only-element -> priceQuantity -> quantity + tradeState -> trade -> tradeLot only-element -> priceQuantity -> quantity extract NonNegativeQuantitySchedule { value: newCashValue, @@ -1972,7 +2014,7 @@ func Create_RepricePrimitiveInstruction: <"Creates the primitive instructions fo lotIdentifier: empty }, termsChange: Create_EffectiveOrTerminationDateTermChangeInstruction( - tradeState -> trade -> tradableProduct -> product -> contractualProduct, + tradeState -> trade -> product, effectiveRepriceDate, empty ), @@ -1990,7 +2032,7 @@ func Create_AdjustmentPrimitiveInstruction: <"Creates the primitive instructions instruction PrimitiveInstruction (1..1) alias oldPriceQuantity: - tradeState -> trade -> tradableProduct -> tradeLot -> priceQuantity + tradeState -> trade -> tradeLot -> priceQuantity alias currentAssetPrice: <"Filter interest rate price and make it into a single element"> oldPriceQuantity @@ -2013,7 +2055,7 @@ func Create_AdjustmentPrimitiveInstruction: <"Creates the primitive instructions } alias changeQuantity: <"Create distinct list of Quantity with value set to newAssetQuantity"> - tradeState -> trade -> tradableProduct -> tradeLot only-element -> priceQuantity -> quantity + tradeState -> trade -> tradeLot only-element -> priceQuantity -> quantity extract NonNegativeQuantitySchedule { value: newAssetQuantity, @@ -2030,10 +2072,10 @@ func Create_AdjustmentPrimitiveInstruction: <"Creates the primitive instructions } condition ContractualProduct: <"This repricing function applies only to contractual products."> - tradeState -> trade -> tradableProduct -> product -> contractualProduct exists + CheckTradeNotTransferableProduct(tradeState) condition SingleTradeLot: <"This repricing function applies only to trades with a single lot."> - tradeState -> trade -> tradableProduct -> tradeLot count = 1 + tradeState -> trade -> tradeLot count = 1 set instruction -> split -> breakdown: [Create_TerminationInstruction(tradeState)] @@ -2046,7 +2088,7 @@ func Create_AdjustmentPrimitiveInstruction: <"Creates the primitive instructions lotIdentifier: empty }, termsChange: Create_EffectiveOrTerminationDateTermChangeInstruction( - tradeState -> trade -> tradableProduct -> product -> contractualProduct, + tradeState -> trade -> product, effectiveRepriceDate, empty ), @@ -2086,7 +2128,7 @@ func Qualify_Reprice: <"This qualification function is used to qualify repricing alias openEconomicTerms: ExtractOpenEconomicTerms(businessEvent) set is_event: - businessEvent -> after -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> interestRatePayout exists + businessEvent -> after -> trade -> product -> economicTerms -> payout -> interestRatePayout exists and openTrades count = 1 and closedTradeState count = 1 and beforeTradePurchasePrice exists @@ -2127,7 +2169,7 @@ func Qualify_Adjustment: <"This qualification function is used to qualify adjust alias openEconomicTerms: ExtractOpenEconomicTerms(businessEvent) set is_event: - businessEvent -> after -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> interestRatePayout exists + businessEvent -> after -> trade -> product -> economicTerms -> payout -> interestRatePayout exists and openEconomicTerms -> payout = beforeEconomicterms -> payout and beforeTradePurchasePrice exists and afterTradePurchasePrice exists @@ -2149,7 +2191,7 @@ func Create_SubstitutionPrimitiveInstruction: <"Creates the primitive instructio instruction PrimitiveInstruction (1..1) condition ContractualProduct: <"Only a security finance contractual product can substitute collateral."> - tradeState -> trade -> tradableProduct -> product -> contractualProduct exists + tradeState -> trade -> product -> economicTerms -> payout -> assetPayout exists set instruction: <"Sets the second part of the split to be a new contract with a new asset payout."> PrimitiveInstruction { @@ -2159,7 +2201,7 @@ func Create_SubstitutionPrimitiveInstruction: <"Creates the primitive instructio lotIdentifier: empty }, termsChange: Create_SubstitutionInstruction( - tradeState -> trade -> tradableProduct -> product -> contractualProduct, + tradeState -> trade -> product, effectiveDate, newCollateralPortfolio ), @@ -2168,7 +2210,7 @@ func Create_SubstitutionPrimitiveInstruction: <"Creates the primitive instructio func Create_SubstitutionInstruction: <"Creates the terms change instruction that updates the payout with the new substitution payout."> inputs: - contractualProduct ContractualProduct (1..1) <"The original contractual product to be used as the basis of the new trade."> + product NonTransferableProduct (1..1) <"The original contractual product to be used as the basis of the new trade."> effectiveDate AdjustableOrRelativeDate (1..1) <"The effective date of the substitution."> newCollateralPortfolio CollateralPortfolio (1..1) <"New collateral portfolio to substitute for the original collateral."> output: @@ -2176,12 +2218,12 @@ func Create_SubstitutionInstruction: <"Creates the terms change instruction that set termsChangeInstruction: Create_EffectiveOrTerminationDateTermChangeInstruction( - contractualProduct, + product, effectiveDate, empty ) - set termsChangeInstruction -> product -> contractualProduct -> economicTerms -> collateral -> collateralPortfolio: + set termsChangeInstruction -> product -> economicTerms -> collateral -> collateralPortfolio: newCollateralPortfolio func Qualify_Substitution: <"Qualification of a collateral substitution event."> @@ -2247,7 +2289,7 @@ func Create_OnDemandInterestPaymentPrimitiveInstruction: <"An instruction to mak instruction PrimitiveInstruction (1..1) <"Result is a Terms Change Instruction."> alias interestRatePayout: - tradeState -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> interestRatePayout only-element + tradeState -> trade -> product -> economicTerms -> payout -> interestRatePayout only-element alias cashflow: <"A fully structured CashFlow or the following need to be provided to create a cashflow."> Create_Cashflow( @@ -2271,7 +2313,7 @@ func Create_OnDemandInterestPaymentPrimitiveInstruction: <"An instruction to mak set instruction: PrimitiveInstruction { termsChange: Create_CashflowTermsChangeInstruction( - tradeState -> trade -> tradableProduct -> product -> contractualProduct, + tradeState -> trade -> product, cashflow ), ... @@ -2287,9 +2329,9 @@ func Qualify_OnDemandPayment: <"Qualification of a on-demand payment."> alias afterTradeStates: FilterOpenTradeStates(businessEvent -> after) alias beforeCashFlow: - FilterClosedTradeStates(businessEvent -> after) only-element -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> cashflow + FilterClosedTradeStates(businessEvent -> after) only-element -> trade -> product -> economicTerms -> payout -> cashflow alias afterCashFlow: - FilterOpenTradeStates(businessEvent -> after) only-element -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> cashflow + FilterOpenTradeStates(businessEvent -> after) only-element -> trade -> product -> economicTerms -> payout -> cashflow set is_event: businessEvent -> instruction -> before count = 1 @@ -2301,13 +2343,13 @@ func Qualify_OnDemandPayment: <"Qualification of a on-demand payment."> func Create_CashflowTermsChangeInstruction: inputs: - contractualProduct ContractualProduct (1..1) + product NonTransferableProduct (1..1) cashFlow Cashflow (1..1) output: termsChangeInstruction TermsChangeInstruction (1..1) - set termsChangeInstruction -> product -> contractualProduct: contractualProduct - add termsChangeInstruction -> product -> contractualProduct -> economicTerms -> payout -> cashflow: + set termsChangeInstruction -> product: product + add termsChangeInstruction -> product -> economicTerms -> payout -> cashflow: cashFlow func Create_Cashflow: @@ -2347,7 +2389,7 @@ func Create_TerminationInstruction: <"Creates the relevant primitive instruction instruction PrimitiveInstruction (1..1) alias changeQuantity: <"Create distinct list of Quantity with value set to zero."> - tradeState -> trade -> tradableProduct -> tradeLot only-element -> priceQuantity -> quantity + tradeState -> trade -> tradeLot only-element -> priceQuantity -> quantity extract NonNegativeQuantitySchedule { value: 0.0, @@ -2512,7 +2554,7 @@ func ExtractBeforeEconomicTerms: economicTerms EconomicTerms (0..1) set economicTerms: - businessEvent -> instruction only-element -> before -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms + businessEvent -> instruction only-element -> before -> trade -> product -> economicTerms func ExtractOpenEconomicTerms: inputs: @@ -2521,7 +2563,22 @@ func ExtractOpenEconomicTerms: economicTerms EconomicTerms (0..1) set economicTerms: - FilterOpenTradeStates(businessEvent -> after) only-element -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms + FilterOpenTradeStates(businessEvent -> after) only-element -> trade -> product -> economicTerms + +func CreateTradableProduct: + inputs: + trade Trade (1..1) + output: + tradableProduct TradableProduct (1..1) + + set tradableProduct: + TradableProduct { + product: trade -> product, + tradeLot: trade -> tradeLot, + counterparty: trade -> counterparty, + ancillaryParty: trade -> ancillaryParty, + adjustment: trade -> adjustment + } func ExtractBeforeTradableProduct: inputs: @@ -2530,7 +2587,7 @@ func ExtractBeforeTradableProduct: tradableProduct TradableProduct (0..1) set tradableProduct: - businessEvent -> instruction only-element -> before -> trade -> tradableProduct + CreateTradableProduct(businessEvent -> instruction only-element -> before -> trade) func ExtractAfterTradableProduct: inputs: @@ -2539,7 +2596,7 @@ func ExtractAfterTradableProduct: tradableProduct TradableProduct (0..1) set tradableProduct: - FilterOpenTradeStates(businessEvent -> after) only-element -> trade -> tradableProduct + CreateTradableProduct(FilterOpenTradeStates(businessEvent -> after) only-element -> trade) func ExtractTradePurchasePrice: inputs: diff --git a/rosetta-source/src/main/rosetta/event-common-type.rosetta b/rosetta-source/src/main/rosetta/event-common-type.rosetta index d2f58b9fc1..917e82352c 100644 --- a/rosetta-source/src/main/rosetta/event-common-type.rosetta +++ b/rosetta-source/src/main/rosetta/event-common-type.rosetta @@ -24,32 +24,6 @@ import cdm.product.collateral.* import cdm.event.workflow.* import cdm.event.position.* -type Confirmation: <"A class to specify a trade confirmation."> - - identifier Identifier (1..*) <"The identifier(s) associated with the trade and resulting confirmation."> - party Party (1..*) <"The parties associated with the trade."> - partyRole PartyRole (1..*) <"The role(s) that party(ies) may have in relation to the trade"> - lineage Lineage (0..1) <"The lineage attribute provides a linkage to previous lifecycle events and associated data."> - status ConfirmationStatusEnum (1..1) - - condition BothBuyerAndSellerPartyRolesMustExist: <"For an security confirmation, both buyer and seller party roles must exist."> - if lineage -> tradeReference -> tradableProduct -> product -> security exists - then partyRole -> role contains PartyRoleEnum -> Buyer - or partyRole -> role contains PartyRoleEnum -> Seller - -type Affirmation: <"A class to specify a trade affirmation."> - - identifier Identifier (1..*) <"The identifier(s) associated with the trade and resulting confirmation."> - party Party (1..*) <"The parties associated with the trade."> - partyRole PartyRole (1..*) <"The role(s) that party(ies) may have in relation to the trade"> - lineage Lineage (0..1) <"The lineage attribute provides a linkage to previous lifecycle events and associated data."> - status AffirmationStatusEnum (1..1) - - condition BothBuyerAndSellerPartyRolesMustExist: <"For an security affirmation, both buyer and seller party roles must exist."> - if lineage -> tradeReference -> tradableProduct -> product -> security exists - then partyRole -> role contains PartyRoleEnum -> Buyer - or partyRole -> role contains PartyRoleEnum -> Seller - type ContractFormationInstruction: <"Specifies instructions to create a fully formed contract, with optional legal agreements."> legalAgreement LegalAgreement (0..*) <"Optional legal agreements associated to the contract being formed, for instance a master agreement."> condition ExecutedAgreements: <"The full formation of a contract can only be completed with executed legal agreements."> @@ -111,7 +85,7 @@ type ValuationInstruction: <"Specifies inputs needed to process a valuation."> replace boolean (1..1) <"Specifies whether the previous valuation tracks in the valuation history are removed (True) or kept (False)."> type ExecutionInstruction: <"Specifies instructions for execution of a transaction, consisting of a product, price, quantity, parties, trade identifier, execution details, and settlement terms."> - product Product (1..1) <"Defines the financial product to be executed and contract formed."> + product NonTransferableProduct (1..1) <"Defines the financial product to be executed and contract formed."> priceQuantity PriceQuantity (1..*) <"Defines the prices (e.g. spread, equity price, FX rate), quantities (e.g. currency amount, no. shares) and settlement terms (e.g. initial fee, broker fee, up-front cds payment or option premium settlement) associated with the constituents of the transacted product."> counterparty Counterparty (2..2) <"Maps two defined parties to counterparty enums for the transacted product."> ancillaryParty AncillaryParty (0..*) <"Maps any ancillary parties, e.g. parties involved in the transaction that are not one of the two principal parties."> @@ -169,7 +143,7 @@ type IndexTransitionInstruction: <"Defines the information needed to create a In and priceQuantity -> quantity is absent type TermsChangeInstruction: <"Specifies instructions for terms change consisting of the new transaction terms, and the renegotiation fee."> - product Product (0..1) <"product to be changed"> + product NonTransferableProduct (0..1) <"product to be changed"> ancillaryParty AncillaryParty (0..*) <"ancillary party to be changed"> adjustment NotionalAdjustmentEnum (0..1) @@ -299,7 +273,7 @@ type Valuation: <"Defines the value of an investment, asset, or security"> condition ValuationType: <"The below condition ensures one and only one of the two attributes: 'Valuation Method' or 'Valuation Source' is allowed. Valuation of a trade or a portfolio is either internally calculated (via M2Market or M2Model methods) or supplied from an external source (e.g Central Counterparty's Valuation). Valuation cannot be based upon internal calculations and external source at the same time."> required choice method, source -type Trade: <"Defines the output of a financial transaction between parties - a Business Event. A Trade impacts the financial position (i.e. the balance sheet) of involved parties."> +type Trade extends TradableProduct: <"Defines the output of a financial transaction between parties - a Business Event. A Trade impacts the financial position (i.e. the balance sheet) of involved parties."> [metadata key] [docReference ICMA GMRA namingConvention "Transaction" provision "As defined in the GMRA, paragraph 1(a) and 1(b) Referring to the agreement between Buyer and Seller in which a Seller agrees to sell Securities against the payment of the purchase price by Buyer to Seller, with a simultaneous agreement by Buyer to sell to Seller Equivalent Securities at a future date. May be a Repurchase Transaction or Buy/Sell Back Transaction."] @@ -308,7 +282,6 @@ type Trade: <"Defines the output of a financial transaction between parties - a [metadata id] tradeTime TimeZone (0..1) <"Denotes the trade time and timezone as agreed by the parties to the trade."> [metadata id] - tradableProduct TradableProduct (1..1) <"Represents the financial instrument The corresponding FpML construct is the product abstract element and the associated substitution group."> party Party (0..*) <"Represents the parties to the trade. The cardinality is optional to address the case where the trade is defined within a BusinessEvent data type, in which case the party is specified in BusinessEvent."> partyRole PartyRole (0..*) <"Represents the role each specified party takes in the trade. further to the principal roles, payer and receiver."> executionDetails ExecutionDetails (0..1) <"Represents information specific to trades that arose from executions."> @@ -323,17 +296,17 @@ type Trade: <"Defines the output of a financial transaction between parties - a // if tradableProduct -> product -> security exists // then partyRole -> role contains PartyRoleEnum -> ExecutingEntity and partyRole -> role contains PartyRoleEnum -> Counterparty condition SecurityPartyRoleBuyerSeller: <"When the executed product is a security, both buyer and seller party roles must exist."> - if tradableProduct -> product -> security exists + if product -> economicTerms -> payout -> settlementPayout only exists then partyRole -> role contains PartyRoleEnum -> Buyer and partyRole -> role contains PartyRoleEnum -> Seller - + condition SecurityPrice: <"When the executed product is a security, the price must be specified."> - if tradableProduct -> product -> security exists - then tradableProduct -> tradeLot -> priceQuantity -> price exists + if product -> economicTerms -> payout -> settlementPayout only exists + then tradeLot -> priceQuantity -> price exists - condition SettlementTerms: <"When the executed product is a security, the settlement terms must be specified."> - if tradableProduct -> product -> security exists - then tradableProduct -> tradeLot only-element -> priceQuantity -> settlementTerms exists + condition SettlementTerms: <"When the executed product is a security, the settlement terms must be specified on the settlementPayout."> + if product -> economicTerms -> payout -> settlementPayout only exists + then product -> economicTerms -> payout -> settlementPayout -> settlementTerms exists condition PackageTrade: <"When the trade is part of a package as specified in the execution details, the trade identifier must be found as one of the package components."> if executionDetails -> packageReference exists @@ -342,80 +315,80 @@ type Trade: <"Defines the output of a financial transaction between parties - a condition DeliverableObligationsPhysicalSettlementMatrix: <"The below set of credit deliverable obligation provisions are specified as optional boolean in FpML and the CDM because they would be specified as part of the Physical Settlement Matrix when such document governs the contract terms. As a result, this data rule specifies that those provisions cannot be omitted if the Credit Derivatives Physical Settlement Matrix doesn't governs the terms of the contract."> if (contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix -> matrixType all <> MatrixTypeEnum -> CreditDerivativesPhysicalSettlementMatrix or contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix -> matrixType is absent) - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations exists - then (tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> notSubordinated exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> specifiedCurrency exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> notSovereignLender exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> notDomesticCurrency exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> notDomesticLaw exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> notContingent exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> notDomesticIssuance exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> assignableLoan exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> consentRequiredLoan exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> transferable exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> maximumMaturity exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> notBearer exists) - and (tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> fullFaithAndCreditObLiability exists - or tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> generalFundObligationLiability exists - or tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> revenueObligationLiability exists) + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations exists + then (product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> notSubordinated exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> specifiedCurrency exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> notSovereignLender exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> notDomesticCurrency exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> notDomesticLaw exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> notContingent exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> notDomesticIssuance exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> assignableLoan exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> consentRequiredLoan exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> transferable exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> maximumMaturity exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> notBearer exists) + and (product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> fullFaithAndCreditObLiability exists + or product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> generalFundObligationLiability exists + or product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> revenueObligationLiability exists) condition ObligationsPhysicalSettlementMatrix: <"The below set of obligation of the reference entity are specified as optional boolean in FpML and the CDM because they would be specified as part of the Physical Settlement Matrix when such document governs the contract terms. As a result, this data rule specifies that those provisions cannot be omitted if the Physical Settlement Matrix governs the terms of the contract. This data rule also applies to cash settled contracts because those could still end-up being physically settled, in case the case where an auction could not take place because of, say, liquidity considerations."> if (contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix -> matrixType all <> MatrixTypeEnum -> CreditDerivativesPhysicalSettlementMatrix or contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix -> matrixType is absent) - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations exists - then (tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> notSubordinated exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> notSovereignLender exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> notDomesticLaw exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> notDomesticIssuance exists) - and (tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> fullFaithAndCreditObLiability exists - or tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> generalFundObligationLiability exists - or tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> revenueObligationLiability exists) + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations exists + then (product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> notSubordinated exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> notSovereignLender exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> notDomesticLaw exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> notDomesticIssuance exists) + and (product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> fullFaithAndCreditObLiability exists + or product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> generalFundObligationLiability exists + or product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> revenueObligationLiability exists) condition CreditEventsPhysicalSettlementMatrix: <"The below set of credit events are specified as optional boolean in FpML and the CDM because they would be specified as part of the Physical Settlement Matrix when such document governs the contract terms. As a result, this data rule specifies that those provisions can only be omitted if the Physical Settlement Matrix governs the terms of the contract. This data rule also applies to cash settled contracts because those could still end-up being physically settled, in the case where an auction could not take place because of, say, liquidity considerations."> if (contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix -> matrixType all <> MatrixTypeEnum -> CreditDerivativesPhysicalSettlementMatrix or contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix -> matrixType is absent) - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents exists - then (tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> bankruptcy exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> obligationDefault exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> obligationAcceleration exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> repudiationMoratorium exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> governmentalIntervention exists) + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents exists + then (product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> bankruptcy exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> obligationDefault exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> obligationAcceleration exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> repudiationMoratorium exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> governmentalIntervention exists) condition RestructuringPhysicalSettlementMatrix: <"The below multiple holder obligation restructuring provisions is specified as optional boolean in FpML and the CDM because they would be specified as part of the Physical Settlement Matrix when such document governs the contract terms. As a result, this data rule specifies that this provision can only be omitted if the Physical Settlement Matrix governs the terms of the contract. This data rule also applies to cash settled contracts because those could still end-up being physically settled, in the case where an auction could not take place because of, say, liquidity considerations."> if (contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix -> matrixType all <> MatrixTypeEnum -> CreditDerivativesPhysicalSettlementMatrix or contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix -> matrixType is absent) - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> restructuring exists - then tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> restructuring -> multipleHolderObligation exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> restructuring exists + then product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> restructuring -> multipleHolderObligation exists condition AdditionalFixedPaymentsMortgages: <"The below set of additional fixed payment provisions are specified as optional boolean in FpML and the CDM because they only apply to mortgage credit default swaps. As a result, this data rule specifies that those provisions are required if the contract corresponds to a mortgage credit default swap. The provision related to the existence of the Contractual Term Supplement is meant to address the case where the underlier is a mortgage index."> - if ((tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referenceObligation -> security -> securityType any = SecurityTypeEnum -> Debt - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referenceObligation -> security -> debtType -> debtClass any = DebtClassEnum -> AssetBacked) + if ((product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referenceObligation -> security -> securityType any = SecurityTypeEnum -> Debt + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referenceObligation -> security -> debtType -> debtClass any = DebtClassEnum -> AssetBacked) or contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualTermsSupplement -> contractualTermsSupplementType contains ContractualSupplementTypeEnum -> CDSonMBS) - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents exists - then (tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents -> additionalFixedPayments -> interestShortfallReimbursement exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents -> additionalFixedPayments -> principalShortfallReimbursement exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents -> additionalFixedPayments -> writedownReimbursement exists) + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents exists + then (product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents -> additionalFixedPayments -> interestShortfallReimbursement exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents -> additionalFixedPayments -> principalShortfallReimbursement exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents -> additionalFixedPayments -> writedownReimbursement exists) condition FloatingAmountEventsMortgages: <"The below set of floating amount events provisions are specified as optional boolean in FpML and the CDM because they only apply to mortgage credit default swaps. As a result, this data rule specifies that those provisions are required if the contract corresponds to a mortgage credit default swap. The provision related to the existence of the Contractual Term Supplement is meant to address the case where the underlier is a mortgage index."> - if ((tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referenceObligation -> security -> securityType any = SecurityTypeEnum -> Debt - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referenceObligation -> security -> debtType -> debtClass any = DebtClassEnum -> AssetBacked) + if ((product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referenceObligation -> security -> securityType any = SecurityTypeEnum -> Debt + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referenceObligation -> security -> debtType -> debtClass any = DebtClassEnum -> AssetBacked) or contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualTermsSupplement -> contractualTermsSupplementType contains ContractualSupplementTypeEnum -> CDSonMBS) - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents exists - then (tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents -> failureToPayPrincipal exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents -> writedown exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents -> impliedWritedown exists) + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents exists + then (product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents -> failureToPayPrincipal exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents -> writedown exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> floatingAmountEvents -> impliedWritedown exists) condition CreditEventsMortgages: <"The below set of credit events provisions are specified as optional boolean in FpML and the CDM because they only apply to mortgage credit default swaps. As a result, this data rule specifies that those provisions are required if the contract corresponds to a mortgage credit default swap. The provision related to the existence of the Contractual Term Supplement is meant to address the case where the underlier is a mortgage index."> - if ((tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referenceObligation -> security -> securityType any = SecurityTypeEnum -> Debt - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referenceObligation -> security -> debtType -> debtClass any = DebtClassEnum -> AssetBacked) + if ((product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referenceObligation -> security -> securityType any = SecurityTypeEnum -> Debt + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referenceObligation -> security -> debtType -> debtClass any = DebtClassEnum -> AssetBacked) or contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualTermsSupplement -> contractualTermsSupplementType contains ContractualSupplementTypeEnum -> CDSonMBS) - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents exists - then (tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> failureToPayPrincipal exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> failureToPayInterest exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> distressedRatingsDowngrade exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> maturityExtension exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> writedown exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> impliedWritedown exists) + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents exists + then (product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> failureToPayPrincipal exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> failureToPayInterest exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> distressedRatingsDowngrade exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> maturityExtension exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> writedown exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> impliedWritedown exists) condition HedgingParty: <"FpML specifies that there cannot be more than 2 hedging parties."> if partyRole -> role contains PartyRoleEnum -> HedgingParty @@ -433,88 +406,90 @@ type Trade: <"Defines the output of a financial transaction between parties - a if clearedDate exists then clearedDate >= tradeDate condition FpML_cd_1: <"FpML validation rule cd-1 - If referenceInformation exists, tradeDate must be before effectiveDate/unadjustedDate."> - if tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists - then tradeDate < tradableProduct -> product -> contractualProduct -> economicTerms -> effectiveDate -> adjustableDate -> unadjustedDate or tradeDate < tradableProduct -> product -> contractualProduct -> economicTerms -> effectiveDate -> adjustableDate -> adjustedDate + if product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists + then tradeDate < product -> economicTerms -> effectiveDate -> adjustableDate -> unadjustedDate or tradeDate < product -> economicTerms -> effectiveDate -> adjustableDate -> adjustedDate condition FpML_cd_7: <"FpML validation rule cd-7 - If condition LongForm is true, then effectiveDate/dateAdjustments exists."> if contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> masterConfirmationType is absent and contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix is absent - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists - then tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> interestRatePayout -> calculationPeriodDates -> effectiveDate -> adjustableDate -> dateAdjustments exists or tradeDate < tradableProduct -> product -> contractualProduct -> economicTerms -> effectiveDate -> adjustableDate -> adjustedDate + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists + then product -> economicTerms -> payout -> interestRatePayout -> calculationPeriodDates -> effectiveDate -> adjustableDate -> dateAdjustments exists or tradeDate < product -> economicTerms -> effectiveDate -> adjustableDate -> adjustedDate condition FpML_cd_8: <"FpML validation rule cd-8 - If condition LongForm is true, and if scheduledTerminationDate exists then scheduledTerminationDate/dateAdjustments exists."> if contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> masterConfirmationType is absent and contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix is absent - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists - then tradableProduct -> product -> contractualProduct -> economicTerms -> terminationDate -> adjustableDate -> dateAdjustments exists + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists + then product -> economicTerms -> terminationDate -> adjustableDate -> dateAdjustments exists condition FpML_cd_11: <"FpML validation rule cd-11 - If condition LongForm is true, and if condition ISDA2003 is true, then allGuarantees must exist."> if contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> masterConfirmationType is absent and contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix is absent - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists and contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualDefinitionsType any = ContractualDefinitionsEnum -> ISDA2003CreditDerivatives - then tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> allGuarantees exists + then product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> allGuarantees exists condition FpML_cd_19: <"FpML validation rule cd-19 - If the condition ISDA1999Credit is true, then the following elements must not exist: protectionTerms/creditEvents/creditEventNotice/businessCenter, protectionTerms/creditEvents/restructuring/multipleHolderObligation, protectionTerms/creditEvents/restructuring/multipleCreditEventNotices, generalTerms/referenceInformation/allGuarantees, generalTerms/indexReferenceInformation, generalTerms/substitution, generalTerms/modifiedEquityDelivery."> if contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualDefinitionsType any = ContractualDefinitionsEnum -> ISDA1999CreditDerivatives - then tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> creditEventNotice -> businessCenter is absent - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> restructuring -> multipleHolderObligation is absent - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> restructuring -> multipleCreditEventNotices is absent - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> allGuarantees is absent - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> indexReferenceInformation is absent - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> substitution is absent - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> modifiedEquityDelivery is absent + then product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> creditEventNotice -> businessCenter is absent + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> restructuring -> multipleHolderObligation is absent + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> restructuring -> multipleCreditEventNotices is absent + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> allGuarantees is absent + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> indexReferenceInformation is absent + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> substitution is absent + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> modifiedEquityDelivery is absent condition FpML_cd_20: <"FpML validation rule cd-20 - If the condition ISDA2003 is true, then protectionTerms/obligations/notContingent must not exist."> if contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualDefinitionsType any = ContractualDefinitionsEnum -> ISDA2003CreditDerivatives - then tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> notContingent is absent + then product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations -> notContingent is absent condition FpML_cd_23: <"FpML validation rule cd-23 - If the condition LongForm is true, then cashSettlementTerms or physicalSettlementTerms must exist."> if contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> masterConfirmationType is absent and contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix is absent - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists - then tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> cashSettlementTerms exists - or tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms exists + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists + then product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> cashSettlementTerms exists + or product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms exists condition FpML_cd_24: <"FpML validation rule cd-24 - If the condition LongForm is true, then the following elements must exist: protectionTerms/creditEvents/creditEventNotice, protectionTerms/obligations, generalTerms/referenceInformation/referencePrice."> if contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> masterConfirmationType is absent and contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix is absent - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists - then tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> creditEventNotice exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referencePrice exists + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists + then product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> creditEvents -> creditEventNotice exists + and product -> economicTerms -> payout -> creditDefaultPayout -> protectionTerms -> obligations exists + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation -> referencePrice exists condition FpML_cd_25: <"FpML validation rule cd-25 - If the condition LongForm is true, and if physicalSettlementTerms exists, then physicalSettlementTerms must contain settlementCurrency, physicalSettlementPeriod, escrow and deliverableObligations/accruedInterest."> if contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> masterConfirmationType is absent and contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix is absent - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms exists - then tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> settlementCurrency exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> physicalSettlementPeriod exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> escrow exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> accruedInterest exists + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms exists + then product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> settlementCurrency exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> physicalSettlementPeriod exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> escrow exists + and product -> economicTerms -> payout -> creditDefaultPayout -> settlementTerms -> physicalSettlementTerms -> deliverableObligations -> accruedInterest exists condition FpML_cd_32: <"FpML validation rule cd-32 - If condition LongForm is true, and if fixedAmountCalculation/calculationAmount exists, then fixedAmountCalculation/dayCountFraction must exist."> if contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> masterConfirmationType is absent and contractDetails -> documentation -> legalAgreementIdentification -> agreementName -> contractualMatrix is absent - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists - and tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> interestRatePayout -> priceQuantity exists - and tradableProduct -> tradeLot -> priceQuantity -> quantity -> value exists - then tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> interestRatePayout -> dayCountFraction exists + and product -> economicTerms -> payout -> creditDefaultPayout -> generalTerms -> referenceInformation exists + and product -> economicTerms -> payout -> interestRatePayout -> priceQuantity exists + and tradeLot -> priceQuantity -> quantity -> value exists + then product -> economicTerms -> payout -> interestRatePayout -> dayCountFraction exists condition FpML_ird_8: <"FpML validation rule ird-8 - If the same party is specified as the payer and receiver, then different accounts must be specified."> - if tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> interestRatePayout exists - then FpmlIrd8(tradableProduct, account) = True + if product -> economicTerms -> payout -> interestRatePayout exists + then FpmlIrd8(CreateTradableProduct(item),account) = True condition ExtraordinaryEvents: <"Extraordinary events provisions must be associated with an equity payout."> if contractDetails -> documentation -> agreementTerms -> agreement -> transactionAdditionalTerms -> equityAdditionalTerms -> extraordinaryEvents exists - then tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> performancePayout -> returnTerms -> priceReturnTerms exists // and performancePayout underlier must be security - or tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> optionPayout -> underlier -> security exists + then ( product -> economicTerms -> payout -> performancePayout -> returnTerms -> priceReturnTerms exists + and product -> economicTerms -> payout -> performancePayout -> underlier -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Equity ) + or product -> economicTerms -> payout -> optionPayout -> productUnderlier -> Asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Equity + or product -> economicTerms -> payout -> optionPayout -> productUnderlier -> TransferableProduct -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Equity condition DisruptionEventsDeterminingParty: if contractDetails -> documentation -> agreementTerms -> agreement -> transactionAdditionalTerms -> equityAdditionalTerms -> extraordinaryEvents -> additionalDisruptionEvents -> determiningParty exists - then tradableProduct -> ancillaryParty -> role contains AncillaryRoleEnum -> DisruptionEventsDeterminingParty - and if tradableProduct -> ancillaryParty -> role contains AncillaryRoleEnum -> DisruptionEventsDeterminingParty + then ancillaryParty -> role contains AncillaryRoleEnum -> DisruptionEventsDeterminingParty + and if ancillaryParty -> role contains AncillaryRoleEnum -> DisruptionEventsDeterminingParty then contractDetails -> documentation -> agreementTerms -> agreement -> transactionAdditionalTerms -> equityAdditionalTerms -> extraordinaryEvents -> additionalDisruptionEvents -> determiningParty exists type ExecutionDetails: <"Defines specific attributes that relate to trade executions."> @@ -733,6 +708,9 @@ type CollateralPosition extends Position: <"Specifies the individual components then collateralPositionStatus = CollateralStatusEnum -> SettledAmount or collateralPositionStatus = CollateralStatusEnum -> InTransitAmount + condition CollateralMustBeTransferableAsset: <"Collateral can only be a Transferable Product or Asset, not a NonTransferableProduct."> + product -> AssetUnderlier exists + type MarginCallIssuance extends MarginCallBase: <"Represents common attributes required for a Margin Call Issuance under a legal agreement such as a credit support document or equivalent."> callAmountInBaseCurrency Money (1..1) <"Specifies the amount of margin being called for which accounts for margin calculation inclusive of exposure, independent amount,threshold,collateral balance, MTA, rounding increments (in base currency detailed in supporting collateral agreement)."> recallNonCashCollateralDescription EligibleCollateralCriteria (0..*) <"Specifies the details to describe or identify non-cash collateral eligible assets for recall purposes."> diff --git a/rosetta-source/src/main/rosetta/event-position-func.rosetta b/rosetta-source/src/main/rosetta/event-position-func.rosetta index 970f0fbeec..e79ec16e25 100644 --- a/rosetta-source/src/main/rosetta/event-position-func.rosetta +++ b/rosetta-source/src/main/rosetta/event-position-func.rosetta @@ -13,20 +13,20 @@ func FxMarkToMarket: <"Representation of sample mark to market calculation provi value number (1..1) alias forwardPayout: <"Alias to the forward pay out."> - trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> forwardPayout only-element + trade -> product -> economicTerms -> payout -> forwardPayout only-element alias quotedCurrency: <"The quoted currency."> - trade -> tradableProduct -> tradeLot -> priceQuantity -> price -> unit -> currency + trade -> tradeLot -> priceQuantity -> price -> unit -> currency distinct only-element alias baseCurrency: <"The base currency."> - trade -> tradableProduct -> tradeLot -> priceQuantity -> price -> perUnitOf -> currency + trade -> tradeLot -> priceQuantity -> price -> perUnitOf -> currency distinct only-element alias quantities: <"Quantity list. Only works in the case of a single trade lot."> - trade -> tradableProduct -> tradeLot only-element -> priceQuantity -> quantity + trade -> tradeLot only-element -> priceQuantity -> quantity alias quotedQuantity: <"Quoted quantity amount."> FilterQuantityByCurrency(quantities, quotedCurrency) only-element -> value @@ -37,7 +37,7 @@ func FxMarkToMarket: <"Representation of sample mark to market calculation provi alias interpolatedRate: InterpolateForwardRate(forwardPayout) condition ForwardPayoutExists: <"The forwardPayout on the contract must exist."> - trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> payout -> forwardPayout exists + trade -> product -> economicTerms -> payout -> forwardPayout exists set value: (quotedQuantity / interpolatedRate - baseQuantity) * interpolatedRate diff --git a/rosetta-source/src/main/rosetta/event-position-type.rosetta b/rosetta-source/src/main/rosetta/event-position-type.rosetta index 67737858aa..33e40ab9c9 100644 --- a/rosetta-source/src/main/rosetta/event-position-type.rosetta +++ b/rosetta-source/src/main/rosetta/event-position-type.rosetta @@ -32,7 +32,7 @@ type CounterpartyPosition extends ContractBase: <"A Position describes the accum type Position: <"A Position describes how much of a given Product is being held and constitutes the atomic element of a Portfolio."> priceQuantity PriceQuantity (1..*) <"Position with many price quantities."> - product Product (1..1) <"The product underlying the position."> + product Underlier (1..1) <"The product underlying the position."> cashBalance Money (0..1) <"The aggregate cost of proceeds"> tradeReference TradeState (0..1) <"Reference to the Contract, in case product is contractual and the contract has been formed"> [metadata reference] diff --git a/rosetta-source/src/main/rosetta/event-qualification-func.rosetta b/rosetta-source/src/main/rosetta/event-qualification-func.rosetta index c0ba58fae1..541a260e50 100644 --- a/rosetta-source/src/main/rosetta/event-qualification-func.rosetta +++ b/rosetta-source/src/main/rosetta/event-qualification-func.rosetta @@ -25,11 +25,11 @@ func Qualify_Allocation: <"The qualification of allocation event from the fact t and openTradeStates count >= 1 and businessEvent -> instruction -> primitiveInstruction -> split exists // before trade counterparties should match closed after trade counterparties - and beforeTradeState -> trade -> tradableProduct -> counterparty -> partyReference = closedTradeStates only-element -> trade -> tradableProduct -> counterparty -> partyReference + and beforeTradeState -> trade -> counterparty -> partyReference = closedTradeStates only-element -> trade -> counterparty -> partyReference // before trade counterparties should not match open after trade counterparties and openTradeStates extract [ - item -> trade -> tradableProduct -> counterparty -> partyReference <> beforeTradeState -> trade -> tradableProduct -> counterparty -> partyReference + item -> trade -> counterparty -> partyReference <> beforeTradeState -> trade -> counterparty -> partyReference ] all = True func Qualify_CashTransfer: <"The qualification of a cash transfer from the fact that the only component is a cashTransfer."> @@ -78,10 +78,10 @@ func Qualify_ClearedTrade: and closedTradeStates count = 1 and openTradeStates count = 2 and businessEvent -> instruction -> primitiveInstruction -> split exists - and beforeTradeState -> trade -> tradableProduct -> counterparty -> partyReference = closedTradeStates only-element -> trade -> tradableProduct -> counterparty -> partyReference + and beforeTradeState -> trade -> counterparty -> partyReference = closedTradeStates only-element -> trade -> counterparty -> partyReference and openTradeStates extract [ - item -> trade -> tradableProduct -> counterparty -> partyReference <> beforeTradeState -> trade -> tradableProduct -> counterparty -> partyReference + item -> trade -> counterparty -> partyReference <> beforeTradeState -> trade -> counterparty -> partyReference and item -> trade -> tradeIdentifier <> beforeTradeState -> trade -> tradeIdentifier and item -> trade -> partyRole -> role contains PartyRoleEnum -> ClearingOrganization ] all = True @@ -101,7 +101,7 @@ func Qualify_OpenOfferClearedTrade: and (businessEvent -> instruction -> primitiveInstruction -> execution, businessEvent -> instruction -> primitiveInstruction -> contractFormation) only exists and openTradeStates extract [ - item -> trade -> tradableProduct -> counterparty -> partyReference <> beforeTradeState -> trade -> tradableProduct -> counterparty -> partyReference + item -> trade -> counterparty -> partyReference <> beforeTradeState -> trade -> counterparty -> partyReference and item -> trade -> tradeIdentifier <> beforeTradeState -> trade -> tradeIdentifier and item -> trade -> partyRole -> role contains PartyRoleEnum -> ClearingOrganization ] all = True @@ -163,7 +163,7 @@ func Qualify_Increase: <"The qualification of a increase event from the fact tha and (QuantityIncreased( businessEvent -> instruction -> before only-element, businessEvent -> after - ) = True or businessEvent -> instruction -> before -> trade -> tradableProduct -> tradeLot count < businessEvent -> after -> trade -> tradableProduct -> tradeLot count)) + ) = True or businessEvent -> instruction -> before -> trade -> tradeLot count < businessEvent -> after -> trade -> tradeLot count)) func Qualify_Novation: <"The qualification of a novation event from the fact that (i) the intent is Novation when specified, (ii) the primitives quantityChange and a contract formation exist, (iii) the remaining quantity = 0, (iv) the closedState of the contract is Novated, (v) the stepped-in contract has a different contract identifier than the novated contract, (vi) the stepped-in contract has the novation event date and the novation event effective date, and (vii) the contract counterparties have changed."> [qualification BusinessEvent] @@ -180,8 +180,8 @@ func Qualify_Novation: <"The qualification of a novation event from the fact tha and closedTradeStates count = 1 and openTradeStates count = 1 and businessEvent -> instruction -> primitiveInstruction -> split exists - and beforeTradeState -> trade -> tradableProduct -> counterparty -> partyReference = closedTradeStates only-element -> trade -> tradableProduct -> counterparty -> partyReference - and beforeTradeState -> trade -> tradableProduct -> counterparty -> partyReference <> openTradeStates only-element -> trade -> tradableProduct -> counterparty -> partyReference + and beforeTradeState -> trade -> counterparty -> partyReference = closedTradeStates only-element -> trade -> counterparty -> partyReference + and beforeTradeState -> trade -> counterparty -> partyReference <> openTradeStates only-element -> trade -> counterparty -> partyReference and beforeTradeState -> trade -> tradeIdentifier <> openTradeStates -> trade -> tradeIdentifier func Qualify_PartialNovation: <"The qualification of a novation event from the fact that (i) the intent is Novation when specified, (ii) the primitives quantityChange and contractFormation exist, (iii) the contract quantity/notional has decreased as part of the quantityChange primitive, while (iv) there is a remaining quantity/notional, (v) the stepped-in contract has a different contract identifier than the original contract, (vi) the stepped-in contract has the novation event date and the novation event effective date, and (vii) the contract counterparties have changed."> @@ -202,10 +202,10 @@ func Qualify_PartialNovation: <"The qualification of a novation event from the f and openTradeStates extract [ // before trade counterparties should not match open after trade counterparties, and neither should trade identifiers - (item -> trade -> tradableProduct -> counterparty -> partyReference <> beforeTradeState -> trade -> tradableProduct -> counterparty -> partyReference + (item -> trade -> counterparty -> partyReference <> beforeTradeState -> trade -> counterparty -> partyReference and item -> trade -> tradeIdentifier <> beforeTradeState -> trade -> tradeIdentifier) or // before trade counterparties match open after trade counterparties, and match trade identifiers, but with decreased quantity - (item -> trade -> tradableProduct -> counterparty -> partyReference = beforeTradeState -> trade -> tradableProduct -> counterparty -> partyReference + (item -> trade -> counterparty -> partyReference = beforeTradeState -> trade -> counterparty -> partyReference and item -> trade -> tradeIdentifier = beforeTradeState -> trade -> tradeIdentifier and QuantityDecreased(beforeTradeState, [item])) ] all = True @@ -274,7 +274,7 @@ func Qualify_SecurityTransfer: <"The qualification of a security transfer from t ) only-element set is_event: - transfer -> asset -> Instrument -> Security -> productIdentifier exists + transfer -> asset -> Instrument -> Security exists and transfer -> quantity -> unit -> financialUnit only exists func Qualify_SecuritySettlement: <"The qualification of a security settlement from the fact that (i) it is composed of a cashTransfer component and a securityTransfer component, and (ii) the cash and security move in opposite directions."> @@ -357,14 +357,14 @@ func Qualify_StockSplit: <"The qualification of StockSplit business event based alias afterTradeState: businessEvent -> after only-element alias beforeQuantities: - beforeTradeState -> trade -> tradableProduct -> tradeLot only-element -> priceQuantity -> quantity + beforeTradeState -> trade -> tradeLot only-element -> priceQuantity -> quantity alias beforeNoOfUnits: FilterQuantityByFinancialUnit(beforeQuantities, FinancialUnitEnum -> Share) only-element -> value alias afterQuantities: - afterTradeState -> trade -> tradableProduct -> tradeLot -> priceQuantity -> quantity + afterTradeState -> trade -> tradeLot -> priceQuantity -> quantity alias afterNoOfUnits: FilterQuantityByFinancialUnit(afterQuantities, FinancialUnitEnum -> Share) @@ -377,13 +377,13 @@ func Qualify_StockSplit: <"The qualification of StockSplit business event based FilterQuantityByCurrencyExists(afterQuantities) -> value distinct only-element alias beforePrice: <"Only works in the case of a single trade lot and price."> - beforeTradeState -> trade -> tradableProduct -> tradeLot only-element -> priceQuantity -> price + beforeTradeState -> trade -> tradeLot only-element -> priceQuantity -> price filter perUnitOf -> financialUnit = FinancialUnitEnum -> Share then extract value then only-element alias afterPrice: <"Only works in the case of a single trade lot and price."> - afterTradeState -> trade -> tradableProduct -> tradeLot only-element -> priceQuantity -> price + afterTradeState -> trade -> tradeLot only-element -> priceQuantity -> price filter perUnitOf -> financialUnit = FinancialUnitEnum -> Share then extract value then only-element @@ -425,9 +425,9 @@ func Qualify_IndexTransition: <"The qualification of an index transition event b output: is_event boolean (1..1) - alias after: businessEvent -> after only-element -> trade -> tradableProduct + alias after: businessEvent -> after only-element -> trade - alias before: businessEvent -> instruction -> before -> trade -> tradableProduct + alias before: businessEvent -> instruction -> before -> trade alias floatingRateIndexChanged: before -> tradeLot -> priceQuantity -> observable -> rateOption -> floatingRateIndex exists @@ -463,7 +463,7 @@ func Qualify_FullReturn: <"The qualification of a full return event from the fac only-element set is_event: (businessEvent -> intent is absent) - and businessEvent -> after -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> contractualProduct -> economicTerms -> payout -> assetPayout exists + and businessEvent -> after -> trade -> product -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> economicTerms -> payout -> assetPayout exists and (businessEvent -> instruction count = 1 and businessEvent -> instruction -> primitiveInstruction -> quantityChange exists or (businessEvent -> instruction -> primitiveInstruction -> quantityChange exists and transfer exists)) @@ -491,10 +491,10 @@ func Qualify_Reallocation: <"The qualification of a reallocation event from the and openTradeStates extract [ // before trade counterparties should not match open after trade counterparties, and neither should trade identifiers - (item -> trade -> tradableProduct -> counterparty -> partyReference <> beforeTradeState -> trade -> tradableProduct -> counterparty -> partyReference + (item -> trade -> counterparty -> partyReference <> beforeTradeState -> trade -> counterparty -> partyReference and item -> trade -> tradeIdentifier <> beforeTradeState -> trade -> tradeIdentifier) or // before trade counterparties match open after trade counterparties, and match trade identifiers, but with decreased quantity - (item -> trade -> tradableProduct -> counterparty -> partyReference = beforeTradeState -> trade -> tradableProduct -> counterparty -> partyReference + (item -> trade -> counterparty -> partyReference = beforeTradeState -> trade -> counterparty -> partyReference and item -> trade -> tradeIdentifier = beforeTradeState -> trade -> tradeIdentifier and QuantityDecreased(beforeTradeState, [item])) ] all = True diff --git a/rosetta-source/src/main/rosetta/mapping-fpml-confirmation-tradestate-synonym.rosetta b/rosetta-source/src/main/rosetta/mapping-fpml-confirmation-tradestate-synonym.rosetta index a7d5bb1c87..37287f9f03 100644 --- a/rosetta-source/src/main/rosetta/mapping-fpml-confirmation-tradestate-synonym.rosetta +++ b/rosetta-source/src/main/rosetta/mapping-fpml-confirmation-tradestate-synonym.rosetta @@ -661,15 +661,15 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML [hint "commodityClassification"] // Other [value "underlyer"] - + settlementTerms - [hint "settlementType"] - [hint "paymentDelay"] - [hint "paymentDate"] - [hint "adjustablePaymentDate"] - [hint "adjustedPaymentDate"] - + buyerSeller - [hint "payerPartyReference"] - [hint "receiverPartyReference"] + // + settlementTerms + // [hint "settlementType"] + // [hint "paymentDelay"] + // [hint "paymentDate"] + // [hint "adjustablePaymentDate"] + // [hint "adjustedPaymentDate"] + // + buyerSeller + // [hint "payerPartyReference"] + // [hint "receiverPartyReference"] + effectiveDate [value "ignore"] // Do not map, until a canonical representation of effective date is built in the CDM and existing effective date attributes can be re-directed here @@ -987,12 +987,12 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML [value "averagingPeriodOut"] ObservationTerms: - + pricingTime + + observationTime [value "pricingDates"] [value "fixingTime"] [value "fixingTime" path "fixingInformationSource"] [value "valuationTime"] - + pricingTimeType + + observationTimeType [value "pricingDates"] + calculationPeriodDates [hint "calculationPeriodsSchedule"] @@ -1717,13 +1717,6 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML [value "description" path "index" maps 2 mapper "ProductIdentifierSource"] ProductBase: - + productIdentifier - [hint "productId"] - [hint "commoditySwaption"] - [hint "fra"] - [hint "creditDefaultSwapOption"] - [hint "bondOption"] - [value "genericProduct"] + productTaxonomy [hint "primaryAssetClass"] [hint "secondaryAssetClass"] @@ -1781,7 +1774,7 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML [set to 3 when "code->commodityClassificationScheme" = "http://www.fpml.org/coding-scheme/isda-layer-3-commodity-classification"] Security: - + productIdentifier + + identifier [value "bond" meta "instrumentId" mapper "BasketConstituent"] [value "convertibleBond" meta "instrumentId" mapper "BasketConstituent"] [value "mortgage" meta "instrumentId" mapper "BasketConstituent"] @@ -1959,18 +1952,18 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML [value "notionalAmountReference" meta "href"] Observable: - + commodity - [hint "commodity"] - [hint "commodityClassification"] +// + commodity //**ART** needs to be mapped to Asset +// [hint "commodity"] +// [hint "commodityClassification"] + productIdentifier [hint "equity"] [hint "bond"] [hint "convertibleBond"] [hint "index"] [hint "exchangeTradedContractNearest"] - + currencyPair - [value "quotedCurrencyPair"] - [hint "features" , "putCurrencyAmount" , "callCurrencyAmount"] + // + currencyPair //**ART** Needs to be mapped to Index/ForeignExchangeRate + // [value "quotedCurrencyPair"] + // [hint "features" , "putCurrencyAmount" , "callCurrencyAmount"] Cashflow: [meta "id"] @@ -2297,7 +2290,7 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML [hint "strikePricePerUnit"] [hint "strikePricePerUnitSchedule"] [hint "spotRate"] - + underlier + + productUnderlier [value "singleUnderlyer" path "underlyer" , "underlyer"] [hint "bond" , "equity" , "mortgage" , "convertibleBond" , "index"] [hint "swap"] @@ -2556,7 +2549,7 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML [value "fxVarianceSwap"] [value "fxVolatilitySwap"] [value "returnLeg"] - + settlementCommitment + + settlementPayout [value "ignore"] Product: @@ -2632,18 +2625,18 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML + basket [value "basket"] - Index: - + productIdentifier - [value "index" meta "instrumentId" mapper "BasketConstituent"] - [value "index" meta "description"] - [hint "index"] +// Index: +// + identifier +// [value "index" meta "instrumentId" mapper "BasketConstituent"] +// [value "index" meta "description"] +// [hint "index"] Basket: + basketConstituent [value "basketConstituent"] Commodity: - + productIdentifier + + identifier [hint "commodity"] + priceQuoteType [value "specifiedPrice" path "commodity" maps 2] @@ -3653,20 +3646,6 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML [hint "callCurrencyAmount"] + tenorPeriod [value "tenorPeriod"] - + exchangeRate - [value "exchangeRate"] - - ExchangeRate: - + crossRate - [value "crossRate"] - - CrossRate: - + rate - [value "rate"] - + spotRate - [value "spotRate"] - + forwardPoints - [value "forwardPoints"] FxRateSourceFixing: + settlementRateSource diff --git a/rosetta-source/src/main/rosetta/mapping-ore-synonym.rosetta b/rosetta-source/src/main/rosetta/mapping-ore-synonym.rosetta index b7e3bad313..33e2fb8acc 100644 --- a/rosetta-source/src/main/rosetta/mapping-ore-synonym.rosetta +++ b/rosetta-source/src/main/rosetta/mapping-ore-synonym.rosetta @@ -27,8 +27,8 @@ synonym source ORE_1_0_39 extends ORE + tradeIdentifier + party [value "Envelope" path "Trade"] - + tradableProduct - [value "Trade" mapper "ORECounterparty"] + // + tradableProduct + // [value "Trade" mapper "ORECounterparty"] + party [value "Envelope" path "Trade"] @@ -40,7 +40,7 @@ synonym source ORE_1_0_39 extends ORE + partyReference [value "Envelope"] + role - [set to CounterpartyRoleEnum -> Party2 when rosettaPath = TradeState -> trade -> tradableProduct -> counterparty] + [set to CounterpartyRoleEnum -> Party2 when rosettaPath = TradeState -> trade -> counterparty] PriceSchedule: + value diff --git a/rosetta-source/src/main/rosetta/observable-asset-enum.rosetta b/rosetta-source/src/main/rosetta/observable-asset-enum.rosetta index f3187b122f..405c7ad3d2 100644 --- a/rosetta-source/src/main/rosetta/observable-asset-enum.rosetta +++ b/rosetta-source/src/main/rosetta/observable-asset-enum.rosetta @@ -321,8 +321,4 @@ enum PriceOperandEnum: enum CsaTypeEnum: <"How is the Creadit Support Annex defined for this transaction as defined in the 2021 ISDA Definitions, section 18.2.1 "> NoCSA displayName "NoCSA" <"There is no CSA applicable"> ExistingCSA displayName "ExistingCSA" <"Thre is an existing Credit Support Annex"> - ReferenceVMCSA displayName "ReferenceVMCSA" <"There is a bilateral Credit Support Annex specific to the transaction"> - -enum OptionReferenceTypeEnum: <"The enumeration values to specify the reference source that determines the final settlement price of the option."> - Future <"Reference from the price of a future contract."> - Spot <"Reference from an underlyer spot price."> + ReferenceVMCSA displayName "ReferenceVMCSA" <"There is a bilateral Credit Support Annex specific to the transaction"> \ No newline at end of file diff --git a/rosetta-source/src/main/rosetta/observable-asset-type.rosetta b/rosetta-source/src/main/rosetta/observable-asset-type.rosetta index 56966704e2..24c5358378 100644 --- a/rosetta-source/src/main/rosetta/observable-asset-type.rosetta +++ b/rosetta-source/src/main/rosetta/observable-asset-type.rosetta @@ -11,22 +11,33 @@ import cdm.observable.common.* import cdm.product.asset.* import cdm.mapping.config.* -type FloatingIndex extends IndexBase: <"Specification of the floating rate index details."> +//**ART** Needed to support PriceQuantity in BasketConstituent, which will be refactored +import cdm.product.common.settlement.* + +type FloatingRateIndex extends IndexBase: <"Specification of an interest rate index which can change over time, e.g. the SONIA (Sterling Overnight Index Average) in the UK."> floatingRateIndex FloatingRateIndexEnum (1..1) <"The reference index that is used to specify the floating interest rate."> [metadata scheme] indexTenor Period (0..1) <"The ISDA Designated Maturity, i.e. the floating rate tenor."> - condition InterestRateAssetClass: + condition InterestRateAssetClass: <"The asset class must be Interest Rate."> assetClass = AssetClassEnum -> InterestRate -type InflationIndex extends IndexBase: <"Specification of the inflation index details."> +type ForeignExchangeRate extends IndexBase: <"Specification of a rate based on the exchange of a pair of cash assets in specific currencies, e.g. USD versus GBP."> + quotedCurrencyPair QuotedCurrencyPair (1..1) <"Describes the composition of a rate that has been quoted or is to be quoted."> + primaryFxSpotRateSource InformationSource (1..1) <"Specifies the primary source from which a rate should be observed."> + secondaryFxSpotRateSource InformationSource (0..1) <"Specifies an alternative, or secondary, source from which a rate should be observed."> + + condition FXAssetClass: <"The asset class must be Foreign Exchange."> + assetClass = AssetClassEnum -> ForeignExchange + +type InflationIndex extends IndexBase: <"Specification of an index that measures inflation in a specific market, e.g. the US Consumer Price Index."> inflationRateIndex InflationRateIndexEnum (1..1) <"The reference index that is used to specify the inflation interest rate."> [metadata scheme] - condition InterestRateAssetClass: + condition InterestRateAssetClass: <"The asset class must be Interest Rate."> assetClass = AssetClassEnum -> InterestRate -type CreditIndex extends IndexBase: <"A class defining a Credit Default Swap Index ."> +type CreditIndex extends IndexBase: <"Specification of an index based on credit risk, typically composed using corporate debt instruments in a region or industry sector, e.g. the iTraxx indices."> [metadata key] indexSeries int (0..1) <"A CDS index series identifier, e.g. 1, 2, 3 etc."> indexAnnexVersion int (0..1) <"A CDS index series version identifier, e.g. 1, 2, 3 etc."> @@ -49,18 +60,18 @@ type CreditIndex extends IndexBase: <"A class defining a Credit Default Swap Ind if indexFactor exists then indexFactor >= 0 and indexFactor <= 1 - condition CreditAssetClass: + condition CreditAssetClass: <"The asset class must be Credit."> assetClass = AssetClassEnum -> Credit -type EquityIndex extends IndexBase: <"Specification of the equity market index details."> +type EquityIndex extends IndexBase: <"Specification of an index based on equity securities, e.g. the S&P 500.."> - condition EquityAssetClass: + condition EquityAssetClass: <"The asset class must be Equity."> assetClass = AssetClassEnum -> Equity type OtherIndex extends IndexBase: <"Specification of a user-defined index that does not meet the criteria of other Index data types."> description string (0..1) <"A description that defines the OtherIndex."> - condition AssetClassRequired: + condition AssetClassRequired: <"The asset class must be explicitly set."> assetClass exists type PremiumExpression: <"This class corresponds to the FpML Premium.model group for representing the option premium when expressed in a way other than an amount."> @@ -153,22 +164,33 @@ type Price extends PriceSchedule: <"Specifies a price as a single value to be as value exists and datedValue is absent type Observable: <"Specifies the object to be observed for a price, it could be an asset or a reference."> - [metadata key] + //**ART** Wil make this a choice in P3; currently not supported with annotation - rateOption FloatingRateOption (0..1) <"Specifies a floating rate index and tenor."> - [metadata location] - commodity Commodity (0..1) <"Identifies a commodity by referencing a product identifier."> - [metadata location] - productIdentifier ProductIdentifier (0..*) <"Comprises of an identifier and a source. The associated metadata key denotes the ability to associate a hash value to the ProductIdentifier instantiations for the purpose of model cross-referencing, in support of functionality such as the event effect and the lineage."> + asset Asset (0..1) <"The object to be observed is an Asset, ie something that can be owned and transferred in the financial markets."> + basket Basket (0..1) <"The object to be observed is a Basket, ie a collection of Observables with an identifier and optional weightings."> + index Index (0..1) <"The object to be observed is an Index, ie an observable computed on the prices, rates or valuations of a number of assets."> + + //**ART** Will remove ProductIdentifier and map to Asset in Phase 3 + productIdentifier ProductIdentifier (0..*) <"Comprises an identifier and a source of a Product."> [metadata location] - identifier AssetIdentifier (0..*) <"Comprises of an identifier and a symbology source. The associated metadata key denotes the ability to associate a hash value to the AssetIdentifier instantiations for the purpose of model cross-referencing, in support of functionality such as the event effect and the lineage. This attribute will replace ProductIdentifier in the full release."> - [metadata location] - currencyPair QuotedCurrencyPair (0..1) <"Describes the composition of a rate that has been quoted or is to be quoted, including the two currencies and the quotation relationship between the two currencies."> + //**ART** Will remove rateOption and map to Index in Phase 3 + rateOption FloatingRateOption (0..1) <"Specifies a floating rate index and tenor."> [metadata location] - optionReferenceType OptionReferenceTypeEnum (0..1) <"The underlying contract which is referenced when determining the final settlement price of the instrument. Eg. Rolling Front Month Future; Spot etc."> - - condition ObservableChoice: <"An observable can only be composed of one type any time."> - required choice rateOption, commodity, productIdentifier, currencyPair + + condition: one-of + +type Basket extends AssetBase: <"Defines a custom basket by referencing an identifier and its constituents."> + basketConstituent BasketConstituent (1..*) <"Identifies the constituents of the basket"> + +type BasketConstituent extends Observable: <"Identifies the constituents of the basket"> + quantity NonNegativeQuantitySchedule (0..*) <"Specifies a quantity schedule to be associated to an individual underlier that is a basket constituent. The multiple cardinality is aligned to the one of the PriceQuantity->quantity that this quantity is referencing."> + [metadata address "pointsTo"=PriceQuantity->quantity] + initialValuationPrice PriceSchedule (0..*) <"Specifies an initial price schedule to be associated to an individual underlier that is a basket constituent. The multiple cardinality is aligned to the one of the PriceQuantity->price that this price is referencing."> + [metadata address "pointsTo"=PriceQuantity->price] + interimValuationPrice PriceSchedule (0..*) <"Specifies an interim price schedule to be associated to an individual underlier that is a basket constituent. The multiple cardinality is aligned to the one of the PriceQuantity->price that this price is referencing."> + [metadata address "pointsTo"=PriceQuantity->price] + finalValuationPrice PriceSchedule (0..*) <"Specifies a final price schedule to be associated to an individual underlier that is a basket constituent. The multiple cardinality is aligned to the one of the PriceQuantity->price that this price is referencing."> + [metadata address "pointsTo"=PriceQuantity->price] type InformationSource: <"A class defining the source for a piece of information (e.g. a rate fix or an FX fixing). The attribute names have been adjusted from FpML to address the fact that the information is not limited to rates."> @@ -185,15 +207,9 @@ type Money extends Quantity: <"Defines a monetary amount in a specified currency condition CurrencyUnitExists: unit -> currency exists -type ExchangeRate: <"A class that is used for describing the exchange rate for a particular transaction."> - [deprecated] - - crossRate CrossRate (0..*) <"An optional element that allow for definition of the currency exchange rates used to cross between the traded currencies for non-base currency FX contracts."> - type FxRateObservable: <"Defines foreign exchange (FX) asset class specific parameters for market observations."> - + [deprecated] quotedCurrencyPair QuotedCurrencyPair (1..1) <"Describes the composition of a rate that has been quoted or is to be quoted."> - [metadata address "pointsTo"=Observable->currencyPair] primaryFxSpotRateSource InformationSource (1..1) <"Specifies the primary source from which a rate should be observed."> secondaryFxSpotRateSource InformationSource (0..1) <"Specifies an alternative, or secondary, source from which a rate should be observed."> @@ -205,16 +221,6 @@ type QuotedCurrencyPair: <"A class that describes the composition of a rate that [metadata scheme] quoteBasis QuoteBasisEnum (1..1) <"The method by which the exchange rate is quoted."> -type CrossRate extends QuotedCurrencyPair: <"A class that is used for including the currency exchange rates used to cross between the traded currencies for non-base currency FX contracts."> - [deprecated] - - rate number (1..1) <"The exchange rate used to cross between the traded currencies."> - spotRate number (0..1) <"An optional element used for FX forwards and certain types of FX OTC options. For deals consummated in the FX Forwards Market, this represents the current market rate for a particular currency pair."> - forwardPoints number (0..1) <"An optional element used for deals consummated in the FX Forwards market. Forward points represent the interest rate differential between the two currencies traded and are quoted as a premium or a discount. Forward points are added to, or subtracted from, the spot rate to create the rate of the forward trade."> - - condition CrossRate: - if forwardPoints exists then spotRate exists - type Curve: interestRateCurve InterestRateCurve (0..1) @@ -427,7 +433,6 @@ type SingleValuationDate: <"A class to specify the number of business days after type ValuationSource: <"A class describing the method for obtaining a settlement rate, specified through either an information source (page), a settlement rate option (fixing) or by using quotes from reference banks."> quotedCurrencyPair QuotedCurrencyPair (0..1) <"Defines the two currencies for an FX trade and the quotation relationship between the two currencies. This attribute was formerly part of 'fxSettlementTerms', which is now being harmonised into a common 'CashSettlementTerms' that includes a 'ValuationDate'."> - [metadata address "pointsTo"=Observable->currencyPair] informationSource FxSpotRateSource (0..1) <"The information source where a published or displayed market rate will be obtained, e.g. Telerate Page 3750."> settlementRateOption SettlementRateOption (0..1) <"The rate option to use for the fixing. Currently only applicable to foreign exchange fixing in case of cross-currency settlement."> referenceBanks ReferenceBanks (0..1) <"A container for a set of reference institutions that may be called upon to provide rate quotations as part of the method to determine the applicable cash settlement amount. If institutions are not specified, it is assumed that reference institutions will be agreed between the parties on the exercise date, or in the case of swap transaction to which mandatory early termination is applicable, the cash settlement valuation date."> diff --git a/rosetta-source/src/main/rosetta/observable-common-func.rosetta b/rosetta-source/src/main/rosetta/observable-common-func.rosetta index 3d454b4efa..b3849766fd 100644 --- a/rosetta-source/src/main/rosetta/observable-common-func.rosetta +++ b/rosetta-source/src/main/rosetta/observable-common-func.rosetta @@ -9,7 +9,7 @@ import cdm.observable.asset.* func ResolveTimeZoneFromTimeType: <"Defines inputs and outputs needed to derive the time and time-zone for a product identifier"> inputs: - productIdentifier ProductIdentifier (1..1) + assetIdentifier AssetIdentifier (1..1) timeType TimeTypeEnum (1..1) determinationMethod DeterminationMethodEnum (1..1) output: diff --git a/rosetta-source/src/main/rosetta/observable-event-func.rosetta b/rosetta-source/src/main/rosetta/observable-event-func.rosetta index 7c782b57e8..f7c9aa7235 100644 --- a/rosetta-source/src/main/rosetta/observable-event-func.rosetta +++ b/rosetta-source/src/main/rosetta/observable-event-func.rosetta @@ -14,7 +14,7 @@ func Create_AssetPayoutTradeStateWithObservations: <"Attaches a set of Observati tradeState TradeState (1..1) alias assetPayout: - billingInstruction -> tradeState -> trade -> tradableProduct -> product -> contractualProduct -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> contractualProduct -> economicTerms -> payout -> assetPayout only-element + billingInstruction -> tradeState -> trade -> product -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> economicTerms -> payout -> assetPayout only-element alias date: billingInstruction -> recordEndDate diff --git a/rosetta-source/src/main/rosetta/product-asset-type.rosetta b/rosetta-source/src/main/rosetta/product-asset-type.rosetta index 8477f82d75..e8b0743ab2 100644 --- a/rosetta-source/src/main/rosetta/product-asset-type.rosetta +++ b/rosetta-source/src/main/rosetta/product-asset-type.rosetta @@ -338,6 +338,7 @@ type ReferenceInformation: <"A class specifying the Credit Default Swap Referenc required choice referenceObligation, noReferenceObligation , unknownReferenceObligation type ReferenceObligation: <"A class to specify the reference obligation that is associated with a credit derivative instrument."> + //**ART3** security Security (0..1) <"Identifies the underlying asset when it is a security, such as a bond or convertible bond. The security data type requires one or more productIdentifiers, specificaiton of the security type (e.g. debt), and includes optional attributes to specify a debt class, such as asset-backed, as well as seniority."> loan Loan (0..1) <"Identifies the underlying asset when it is a loan."> primaryObligor LegalEntity (0..1) <"The entity primarily responsible for repaying debt to a creditor as a result of borrowing or issuing bonds. ISDA 2003 Term: Primary Obligor."> @@ -516,9 +517,9 @@ type VarianceReturnTerms extends ReturnTermsBase: if vegaNotionalAmount -> value exists then vegaNotionalAmount -> value > 0 - condition UnderlierMustBeSecurity: <"If an exchange traded contract nearest is specified, it must have a security as underlier."> + condition UnderlierMustBeListedDerivative: <"If an exchange traded contract nearest is specified, it must have a listed derivative as underlier."> if exchangeTradedContractNearest exists - then exchangeTradedContractNearest -> productIdentifier exists + then exchangeTradedContractNearest -> asset -> Instrument -> ListedDerivative exists condition ReferenceContract: <"If futurePriceValuation is true, an exchange traded contract is used as a reference, therefore such contract must be specified in exchangeTradedContractNearest"> if valuationTerms -> futuresPriceValuation = True @@ -536,12 +537,11 @@ type VolatilityReturnTerms extends ReturnTermsBase: volatilityStrikePrice Price (1..1) <"Volatility Strike Price in accordance with the ISDA 2011 Equity Derivatives Definitions."> volatilityCapFloor VolatilityCapFloor (0..1) <"Contains volatility-based barriers"> - // vegaNotionalAmount NonNegativeQuantitySchedule (0..1) <"Vega Notional represents the approximate gain/loss at maturity for a 1% difference between RVol (realised vol) and KVol (strike vol). It does not necessarily represent the Vega Risk of the trade."> exchangeTradedContractNearest Observable (0..1) <"Specification of the exchange traded contract nearest."> condition UnderlierMustBeSecurity: <"If an exchange traded contract nearest is specified, it must have a security as underlier."> if exchangeTradedContractNearest exists - then exchangeTradedContractNearest -> productIdentifier exists + then exchangeTradedContractNearest -> asset -> Instrument -> Security exists type CorrelationReturnTerms extends ReturnTermsBase: @@ -627,20 +627,21 @@ type BoundedCorrelation: <"Describes correlation bounds, which form a cap and a maximumBoundaryPercent number (0..1) <"Maximum Boundary as a percentage of the Strike Price."> type ForeignExchange: <"From FpML: A type defining either a spot or forward FX transactions."> - + [deprecated] exchangedCurrency1 Cashflow (1..1) <"This is the first of the two currency flows that define a single leg of a standard foreign exchange transaction."> exchangedCurrency2 Cashflow (1..1) <"This is the second of the two currency flows that define a single leg of a standard foreign exchange transaction."> tenorPeriod Period (0..1) <"A tenor expressed as a period type and multiplier (e.g. 1D, 1Y, etc.)"> - exchangeRate ExchangeRate (0..1) <"The rate of exchange between the two currencies."> - [deprecated] type BondReference: <"Reference to a bond underlier to represent an asset swap or Condition Precedent Bond."> - bond ProductIdentifier (1..1) <"Reference to a bond underlier."> + bond Asset (1..1) <"Reference to a bond underlier."> conditionPrecedentBond boolean (1..1) <"To indicate whether the Condition Precedent Bond is applicable. The swap contract is only valid if the bond is issued and if there is any dispute over the terms of fixed stream then the bond terms would be used."> discrepancyClause boolean (0..1) <"To indicate whether the Discrepancy Clause is applicable."> couponRate FixedRateSpecification (0..1) <"Specifies the coupon rate (expressed in percentage) of a fixed income security or convertible bond."> + condition BondUnderlier: <"The underlier should be a security."> + bond -> Instrument -> Security exists + type CashflowRepresentation: <"A data defining: the cashflow representation of a swap trade."> cashflowsMatchParameters boolean (1..1) <"A true/false flag to indicate whether the cashflows match the parametric definition of the stream, i.e. whether the cashflows could be regenerated from the parameters without loss of information."> diff --git a/rosetta-source/src/main/rosetta/product-collateral-type.rosetta b/rosetta-source/src/main/rosetta/product-collateral-type.rosetta index 37b9f7cdc9..2de13e80c5 100644 --- a/rosetta-source/src/main/rosetta/product-collateral-type.rosetta +++ b/rosetta-source/src/main/rosetta/product-collateral-type.rosetta @@ -181,13 +181,13 @@ type AssetCriteria: <"Represents a set of criteria used to specify eligible coll agencyRating AgencyRatingCriteria (0..*) <"Represents an agency rating based on default risk and creditors claim in event of default associated with specific instrument."> maturityType MaturityTypeEnum (0..1) <"Specifies whether the maturity range is the remaining or original maturity."> maturityRange PeriodRange (0..1) <"Represents a filter based on the underlying asset maturity."> - productIdentifier ProductIdentifier (0..*) <"Represents a filter based on specific instrument identifiers (e.g. specific ISINs, CUSIPs etc)."> + asset Asset (0..*) <"Represents a filter based on specific instrument identifiers (e.g. specific ISINs, CUSIPs etc)."> collateralTaxonomy CollateralTaxonomy (0..*) <"Specifies the collateral taxonomy,which is composed of a taxonomy value and a taxonomy source."> domesticCurrencyIssued boolean (0..1) <"Identifies that the Security must be denominated in the domestic currency of the issuer."> listing ListingType (0..1) <"Specifies the exchange, index or sector specific to listing of a security."> - condition AssetCriteriaChoice: <"If any are specified, only one of AssetType, ProductTaxonomy or ProductIdentifer should exist."> - optional choice collateralAssetType, collateralTaxonomy, productIdentifier + condition AssetCriteriaChoice: <"If any are specified, only one of AssetType, CollateralTaxonomy or Asset should exist."> + optional choice collateralAssetType, collateralTaxonomy, asset type ListingType: <"Specifies a filter based on an underlying corporate financial official listing defined at a stock exchange."> exchange string (0..1) <"Represents a filter based on the Primary Stock Exchange facilitating the listing of companies, exchange of Stocks, Exchange traded Derivatives, Bonds, and other Securities expressed in ISO standard 10383."> diff --git a/rosetta-source/src/main/rosetta/product-common-schedule-type.rosetta b/rosetta-source/src/main/rosetta/product-common-schedule-type.rosetta index 438f87164d..08b5883b9a 100644 --- a/rosetta-source/src/main/rosetta/product-common-schedule-type.rosetta +++ b/rosetta-source/src/main/rosetta/product-common-schedule-type.rosetta @@ -175,8 +175,8 @@ type ObservationDate: <"Specifies a single date on which market observations tak type ObservationTerms: <"Class containing terms that are associated with observing a price/benchmark/index across either single or multiple observations. "> - pricingTime BusinessCenterTime (0..1) <"Defines time in respect to a business calendar location that the price/benchmark/index is observed"> - pricingTimeType TimeTypeEnum (0..1) <"The enumerated values to specify points in the day when option exercise and valuation can occur."> + observationTime BusinessCenterTime (0..1) <"Defines time in respect to a business calendar location that the price/benchmark/index is observed"> + observationTimeType TimeTypeEnum (0..1) <"The enumerated values to specify points in the day when option exercise and valuation can occur."> informationSource FxSpotRateSource (0..1) <"The information source where a published or displayed market rate will be obtained, e.g. Telerate Page 3750."> precision Rounding (0..1) <"Defines rounding rules and precision to be used in the rounding of observations."> calculationPeriodDates CalculationPeriodDates (0..1) <"Defines parameters used to generate the calculation period dates schedule, including the specification of any initial or final stub calculation periods. A calculation period schedule consists of an optional initial stub calculation period, one or more regular calculation periods and an optional final stub calculation period. In the absence of any initial or final stub calculation periods, the regular part of the calculation period schedule is assumed to be between the effective date and the termination date. No implicit stubs are allowed, i.e. stubs must be explicitly specified using an appropriate combination of firstPeriodStartDate, firstRegularPeriodStartDate and lastRegularPeriodEndDate."> @@ -184,9 +184,9 @@ type ObservationTerms: <"Class containing terms that are associated with observi observationDates ObservationDates (1..1) <"Describes date details for a set of observation dates in parametric or non-parametric form."> numberOfObservationDates int (0..1) <"The number of observation dates between observation start date and observation end date."> - condition PricingTime: <"Checks that a pricing time is specified either explicitly (through the pricing time) or implicitly (through a pricing time type different to Specific Time). If Specific Time is defined as pricing time type (i.e. no implicit time value), the condition checks that an explicit pricing time is provided."> - if pricingTimeType = TimeTypeEnum -> SpecificTime - then pricingTime exists + condition ObservationTime: <"Checks that an observation time is specified either explicitly (through the observation time) or implicitly (through a observation time type different to Specific Time). If Specific Time is defined as observation time type (i.e. no implicit time value), the condition checks that an explicit observation time is provided."> + if observationTimeType = TimeTypeEnum -> SpecificTime + then observationTime exists type ParametricDates: <"Defines rules for the dates on which the price will be determined."> dayType DayTypeEnum (1..1) <"Denotes the enumerated values to specify the day type classification used in counting the number of days between two dates."> diff --git a/rosetta-source/src/main/rosetta/product-common-settlement-func.rosetta b/rosetta-source/src/main/rosetta/product-common-settlement-func.rosetta index 4a4ff50524..01d803d661 100644 --- a/rosetta-source/src/main/rosetta/product-common-settlement-func.rosetta +++ b/rosetta-source/src/main/rosetta/product-common-settlement-func.rosetta @@ -32,3 +32,16 @@ func RateOptionObservableCondition: <"Implementation for PriceQuantity.RateOptio extract [ priceType = PriceTypeEnum -> InterestRate and arithmeticOperator exists ] all = True + +func InterestRateObservableCondition: <"Implementation for PriceQuantity.InterestRateObservable condition."> + inputs: + pq PriceQuantity (1..1) + output: + valid boolean (0..1) + + set valid: + if pq -> observable -> index -> FloatingRateIndex exists and pq -> price exists + then pq -> price + extract [ + priceType = PriceTypeEnum -> InterestRate and arithmeticOperator exists + ] all = True diff --git a/rosetta-source/src/main/rosetta/product-common-settlement-type.rosetta b/rosetta-source/src/main/rosetta/product-common-settlement-type.rosetta index 1964295b76..ddbb668659 100644 --- a/rosetta-source/src/main/rosetta/product-common-settlement-type.rosetta +++ b/rosetta-source/src/main/rosetta/product-common-settlement-type.rosetta @@ -62,7 +62,7 @@ type ResolvablePriceQuantity: <"Generic class to specify the quantity for differ if quantityMultiplier exists then quantityReference -> reference exists -type PayoutBase: <" Base class that all payout types should extend. Use case is that some validation rules may need to apply across all payout types, for which the data rule can be written at the base class level"> +type PayoutBase: <"A data type that contains the common attributes (e.g. payer and receiver parties) and validation conditions that apply across all payout types"> payerReceiver PayerReceiver (1..1) <"Canonical representation of the payer and receiver parties applicable to each payout leg."> priceQuantity ResolvablePriceQuantity (0..1) <"Each payout leg must implement the quantity concept as a 'resolvable' type, which allows for different payout legs to be linked to each other (e.g. in the case of cross-curreny products)."> @@ -307,18 +307,26 @@ type PriceQuantity: <"Defines a settlement as an exchange between two parties of quantity NonNegativeQuantitySchedule (0..*) <"Specifies a quantity to be associated with an event, for example a trade amount."> [metadata location] observable Observable (0..1) <"Specifies the object to be observed for a price, it could be an asset or a reference. The cardinality is optional as some quantity / price cases have no observable (e.g. a notional and a fixed rate in a given currency)."> - buyerSeller BuyerSeller (0..1) <"Defines the direction of the exchange. The convention is that the buyer receives the quantity / pays the price, whereas the seller receives the price / pays the quantity. Attribute is optional in case the price/quantity settlement is defined as part of the product mechanics."> - settlementTerms SettlementTerms (0..1) <"Whether the settlement is cash or physical and the corresponding terms. Attribute is optional in case the price/quantity settlement is defined as part of the product mechanics."> + // buyerSeller BuyerSeller (0..1) <"Defines the direction of the exchange. The convention is that the buyer receives the quantity / pays the price, whereas the seller receives the price / pays the quantity. Attribute is optional in case the price/quantity settlement is defined as part of the product mechanics."> + // settlementTerms SettlementTerms (0..1) <"Whether the settlement is cash or physical and the corresponding terms. Attribute is optional in case the price/quantity settlement is defined as part of the product mechanics."> effectiveDate AdjustableOrRelativeDate (0..1) <"Specifies the date at which the price and quantity become effective. This day may be subject to adjustment in accordance with a business day convention, or could be specified as relative to a trade date, for instance. Optional cardinality, as the effective date is usually specified in the product definition, so it may only need to be specified as part of the PriceQuantity in an increase/decrease scenario for an existing trade."> condition RateOptionObservable: <"When the observable is a rate option, the price type must be interest rate and the arithmetic operator must be specified."> RateOptionObservableCondition - condition ObservableExists: <"When the arithmetic operator is specified, then an observable must be specified."> - if price -> arithmeticOperator exists then observable exists + condition RateOptionObservable: <"When the observable is a rate option, the price type must be interest rate and the arithmetic operator must be specified."> + RateOptionObservableCondition + // convert to index and cover additional scenarios including FX rate + + condition CashQuantity: <"If the quantity refers to cash in a currency, this should be modelled by setting the currency in the unit type of the quantity and not using an Observable. "> + ( quantity -> unit -> currency exists and observable is absent ) + or + ( quantity -> unit -> currency is absent and observable exists ) - condition ActualSettlement: <"Settlement terms must be present when the settlement direction is specified."> - if buyerSeller exists then settlementTerms exists + condition ObservableExists: <"The Observable should be an Asset unless the arithmetic operator is being used."> + if price -> arithmeticOperator exists + then observable -> asset is absent + else observable -> asset exists type FixedPrice: <"A predefined price accorded by the counterparties."> diff --git a/rosetta-source/src/main/rosetta/product-qualification-func.rosetta b/rosetta-source/src/main/rosetta/product-qualification-func.rosetta index dab188d64c..11dd624179 100644 --- a/rosetta-source/src/main/rosetta/product-qualification-func.rosetta +++ b/rosetta-source/src/main/rosetta/product-qualification-func.rosetta @@ -7,9 +7,23 @@ 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 ProductUnderlierQualification: + inputs: + underlier ProductUnderlier (1..*) + securityType SecurityTypeEnum (0..1) + assetClass AssetClassEnum (0..1) + output: + qualifies boolean (1..1) + + set qualifies: + underlier -> Asset -> Instrument -> Security -> securityType all = securityType + or underlier -> Index ->> assetClass all = assetClass + or underlier -> TransferableProduct -> Instrument -> Security -> securityType all = securityType + /* * COMPOSABLE PRODUCT QUALIFICATION based on ISDA Taxonomy v2 * AssetClass - BaseProduct - SubProduct - TransactionType @@ -27,28 +41,31 @@ func Qualify_AssetClass_InterestRate: <"Qualifies a product as having the Asset output: is_product boolean (1..1) - alias optionUnderlier: economicTerms -> payout -> optionPayout only-element -> underlier + alias optionUnderlier: + economicTerms -> payout -> optionPayout only-element -> productUnderlier alias forwardUnderlier: - economicTerms -> payout -> forwardPayout only-element -> underlier + economicTerms -> payout -> forwardPayout only-element -> productUnderlier set is_product: economicTerms -> payout -> interestRatePayout only exists or (economicTerms -> payout -> optionPayout only exists - and (optionUnderlier -> security -> securityType = SecurityTypeEnum -> Debt - or optionUnderlier -> security -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> InterestRate - or optionUnderlier -> index -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> InterestRate - or if optionUnderlier exists - then Qualify_AssetClass_InterestRate( - optionUnderlier -> contractualProduct -> economicTerms - ) = True - or Qualify_AssetClass_InterestRate( - optionUnderlier -> security -> economicTerms - ) = True - else False)) + and (ProductUnderlierQualification(optionUnderlier, SecurityTypeEnum -> Debt, AssetClassEnum -> InterestRate) + or if optionUnderlier -> TransferableProduct exists + then Qualify_AssetClass_InterestRate(optionUnderlier -> TransferableProduct -> economicTerms) = True + else False + or if optionUnderlier -> NonTransferableProduct exists + then Qualify_AssetClass_InterestRate(optionUnderlier -> NonTransferableProduct -> economicTerms) = True + else False + )) or (economicTerms -> payout -> forwardPayout only exists - and (forwardUnderlier -> security -> securityType = SecurityTypeEnum -> Debt - or forwardUnderlier -> security -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> InterestRate - or forwardUnderlier -> index -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> InterestRate)) + and (ProductUnderlierQualification(forwardUnderlier, SecurityTypeEnum -> Debt, AssetClassEnum -> InterestRate) + or if optionUnderlier -> TransferableProduct exists + then Qualify_AssetClass_InterestRate(forwardUnderlier -> TransferableProduct -> economicTerms) = True + else False + or if optionUnderlier -> NonTransferableProduct exists + then Qualify_AssetClass_InterestRate(forwardUnderlier -> NonTransferableProduct -> economicTerms) = True + else False + )) func Qualify_AssetClass_Credit: <"Qualifies a product as having the Asset Class classification Credit Default."> inputs: @@ -56,9 +73,9 @@ func Qualify_AssetClass_Credit: <"Qualifies a product as having the Asset Class output: is_product boolean (1..1) - alias optionUnderlier: economicTerms -> payout -> optionPayout only-element -> underlier + alias optionUnderlier: economicTerms -> payout -> optionPayout only-element -> productUnderlier alias forwardUnderlier: - economicTerms -> payout -> forwardPayout only-element -> underlier + economicTerms -> payout -> forwardPayout only-element -> productUnderlier alias performanceUnderlier: economicTerms -> payout -> performancePayout only-element -> underlier @@ -66,25 +83,27 @@ func Qualify_AssetClass_Credit: <"Qualifies a product as having the Asset Class economicTerms -> payout -> creditDefaultPayout only exists or (economicTerms -> payout -> creditDefaultPayout, economicTerms -> payout -> interestRatePayout) only exists or (economicTerms -> payout -> optionPayout only exists - and if optionUnderlier exists - then (optionUnderlier -> index -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> Credit - or optionUnderlier -> security -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> Credit - or Qualify_AssetClass_Credit( - optionUnderlier -> contractualProduct -> economicTerms - ) - or Qualify_AssetClass_Credit( - optionUnderlier -> security -> economicTerms - )) - else False) + and (ProductUnderlierQualification(optionUnderlier, empty, AssetClassEnum -> Credit) + or if optionUnderlier -> TransferableProduct exists + then Qualify_AssetClass_Credit(optionUnderlier -> TransferableProduct -> economicTerms) = True + else False + or if optionUnderlier -> NonTransferableProduct exists + then Qualify_AssetClass_Credit(optionUnderlier -> NonTransferableProduct -> economicTerms) = True + else False + )) or (economicTerms -> payout -> forwardPayout only exists - and if forwardUnderlier exists - then (forwardUnderlier -> index -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> Credit - or forwardUnderlier -> security -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> Credit) - else False) + and (ProductUnderlierQualification(forwardUnderlier, empty, AssetClassEnum -> Credit) + or if optionUnderlier -> TransferableProduct exists + then Qualify_AssetClass_Credit(forwardUnderlier -> TransferableProduct -> economicTerms) = True + else False + or if optionUnderlier -> NonTransferableProduct exists + then Qualify_AssetClass_Credit(forwardUnderlier -> NonTransferableProduct -> 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 -> loan exists or performanceUnderlier -> security -> securityType = SecurityTypeEnum -> Debt)) + then (performanceUnderlier -> asset -> Instrument -> Loan exists or performanceUnderlier -> asset -> Instrument -> Security -> securityType = SecurityTypeEnum -> Debt)) func Qualify_AssetClass_ForeignExchange: <"Qualifies a product as having the Asset Class classification Foreign Exchange"> inputs: @@ -92,28 +111,24 @@ func Qualify_AssetClass_ForeignExchange: <"Qualifies a product as having the Ass output: is_product boolean (1..1) - alias optionUnderlier: economicTerms -> payout -> optionPayout only-element -> underlier + alias optionUnderlier: economicTerms -> payout -> optionPayout only-element -> productUnderlier alias forwardUnderlier: - economicTerms -> payout -> forwardPayout only-element -> underlier - - set is_product: - economicTerms -> payout -> forwardPayout -> underlier -> foreignExchange exists - or economicTerms -> payout -> optionPayout -> underlier -> foreignExchange exists - or economicTerms -> payout -> performancePayout -> observationTerms -> observable -> currencyPair exists - or optionUnderlier -> index -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> ForeignExchange - or optionUnderlier -> security -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> ForeignExchange - or (if optionUnderlier exists - then Qualify_AssetClass_ForeignExchange( - optionUnderlier -> contractualProduct -> economicTerms - ) - else False) - or (if optionUnderlier exists - then Qualify_AssetClass_ForeignExchange( - optionUnderlier -> security -> economicTerms - ) - else False) - or forwardUnderlier -> index -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> ForeignExchange - or forwardUnderlier -> security -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> ForeignExchange + economicTerms -> payout -> forwardPayout only-element -> productUnderlier + + set is_product: + economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate exists + or economicTerms -> payout -> optionPayout -> productUnderlier -> Index -> ForeignExchangeRate exists + or economicTerms -> payout -> performancePayout -> observationTerms -> observable -> index -> ForeignExchangeRate exists + or (economicTerms -> payout -> optionPayout only exists + and (ProductUnderlierQualification(optionUnderlier, empty, AssetClassEnum -> ForeignExchange) + or if optionUnderlier -> TransferableProduct exists + then Qualify_AssetClass_ForeignExchange(optionUnderlier -> TransferableProduct -> economicTerms) = True + else False + or if optionUnderlier -> NonTransferableProduct exists + then Qualify_AssetClass_ForeignExchange(optionUnderlier -> NonTransferableProduct -> economicTerms) = True + else False + )) + or ProductUnderlierQualification(forwardUnderlier, empty, AssetClassEnum -> ForeignExchange) func Qualify_AssetClass_Equity: inputs: @@ -121,13 +136,13 @@ func Qualify_AssetClass_Equity: output: is_product boolean (1..1) - alias optionUnderlier: economicTerms -> payout -> optionPayout only-element -> underlier + alias optionUnderlier: economicTerms -> payout -> optionPayout only-element -> productUnderlier alias forwardUnderlier: - economicTerms -> payout -> forwardPayout only-element -> underlier + economicTerms -> payout -> forwardPayout only-element -> productUnderlier set is_product: (economicTerms -> payout -> performancePayout -> underlier - extract [ Qualify_UnderlierProduct_Equity(item) ] + extract [ Qualify_UnderlierObservable_Equity(item) ] all = True and ( // Interest Rate Payout + Performance Payout (Price Return Swap, Total Return Swap) (economicTerms -> payout -> interestRatePayout, economicTerms -> payout -> performancePayout) only exists @@ -136,17 +151,23 @@ func Qualify_AssetClass_Equity: // Performance Payout only (Variance, Volatility and Correlation Swap) or economicTerms -> payout -> performancePayout only exists)) or (economicTerms -> payout -> optionPayout only exists - and if optionUnderlier exists - then (Qualify_UnderlierProduct_Equity(optionUnderlier) = True - or optionUnderlier -> index -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> Equity - or optionUnderlier -> security -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> Equity) - else False) + and (ProductUnderlierQualification(optionUnderlier, empty, AssetClassEnum -> Equity) + or if optionUnderlier -> TransferableProduct exists + then Qualify_AssetClass_Equity(optionUnderlier -> TransferableProduct -> economicTerms) = True + else False + or if optionUnderlier -> NonTransferableProduct exists + then Qualify_AssetClass_Equity(optionUnderlier -> NonTransferableProduct -> economicTerms) = True + else False + )) or (economicTerms -> payout -> forwardPayout only exists - and if forwardUnderlier exists - then (Qualify_UnderlierProduct_Equity(forwardUnderlier) - or forwardUnderlier -> index -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> Equity - or forwardUnderlier -> security -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> Equity) - else False) + and (ProductUnderlierQualification(forwardUnderlier, empty, AssetClassEnum -> Equity) + or if forwardUnderlier -> TransferableProduct exists + then Qualify_AssetClass_Equity(forwardUnderlier -> TransferableProduct -> economicTerms) = True + else False + or if forwardUnderlier -> NonTransferableProduct exists + then Qualify_AssetClass_Equity(forwardUnderlier -> NonTransferableProduct -> economicTerms) = True + else False + )) func Qualify_AssetClass_Commodity: <"Qualifies a product as having the Asset Class classification Commodity"> inputs: @@ -154,10 +175,11 @@ func Qualify_AssetClass_Commodity: <"Qualifies a product as having the Asset Cla output: is_product boolean (1..1) - alias optionUnderlier: economicTerms -> payout -> optionPayout only-element -> underlier + alias optionUnderlier: + economicTerms -> payout -> optionPayout only-element -> productUnderlier alias forwardUnderlier: - economicTerms -> payout -> forwardPayout only-element -> underlier + economicTerms -> payout -> forwardPayout only-element -> productUnderlier set is_product: // CO:FixFlo @@ -169,23 +191,28 @@ func Qualify_AssetClass_Commodity: <"Qualifies a product as having the Asset Cla and economicTerms -> payout -> commodityPayout -> underlier -> commodity count = 2) // CO Opt or (economicTerms -> payout -> optionPayout only exists - and if optionUnderlier exists - then (Qualify_AssetClass_Commodity( - optionUnderlier -> contractualProduct -> economicTerms - ) = True - or Qualify_AssetClass_Commodity( - optionUnderlier -> security -> economicTerms - ) = True - or optionUnderlier -> commodity exists - or optionUnderlier -> index -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> Commodity - or optionUnderlier -> security -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> Commodity) - else False) + and (ProductUnderlierQualification(optionUnderlier, empty, AssetClassEnum -> Commodity) + or optionUnderlier -> Asset -> Commodity exists + or optionUnderlier -> TransferableProduct -> Commodity exists + or if optionUnderlier -> TransferableProduct exists + then Qualify_AssetClass_Commodity(optionUnderlier -> TransferableProduct -> economicTerms) = True + else False + or if optionUnderlier -> NonTransferableProduct exists + then Qualify_AssetClass_Commodity(optionUnderlier -> NonTransferableProduct -> economicTerms) = True + else False + )) // CO Fwd or (((economicTerms -> payout -> forwardPayout, economicTerms -> payout -> fixedPricePayout) only exists or (economicTerms -> payout -> forwardPayout, economicTerms -> payout -> commodityPayout) only exists) - and (economicTerms -> payout -> forwardPayout -> underlier -> commodity exists - or forwardUnderlier -> index -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> Commodity - or forwardUnderlier -> security -> productTaxonomy -> primaryAssetClass any = AssetClassEnum -> Commodity)) + and (economicTerms -> payout -> forwardPayout -> productUnderlier -> Asset -> Commodity exists + or forwardUnderlier -> TransferableProduct -> Commodity exists + or if forwardUnderlier -> TransferableProduct exists + then Qualify_AssetClass_Commodity(forwardUnderlier -> TransferableProduct -> economicTerms) = True + else False + or if optionUnderlier -> NonTransferableProduct exists + then Qualify_AssetClass_Commodity(forwardUnderlier -> NonTransferableProduct -> economicTerms) = True + else False + )) /* * ENDOF Qualification of ISDA Taxonomy V2 Level 1 - ASSETCLASS: @@ -258,9 +285,34 @@ func Qualify_CreditDefaultSwaption: <"This product qualification is temporary un set is_product: economicTerms -> payout -> optionPayout only exists and Qualify_AssetClass_Credit( - economicTerms -> payout -> optionPayout only-element -> underlier -> contractualProduct -> economicTerms + economicTerms -> payout -> optionPayout only-element -> productUnderlier -> NonTransferableProduct -> economicTerms ) = True +func Qualify_UnderlierObservable_Equity: <"Qualifies an Observable as having the Asset Class classification Equity."> + inputs: + underlier Observable (1..1) + output: + is_product boolean (1..1) + + set is_product: + underlier -> asset -> Instrument -> Security -> securityType = SecurityTypeEnum -> Equity + or (underlier -> asset -> Instrument -> Security -> securityType = SecurityTypeEnum -> Fund + and underlier -> asset -> Instrument -> Security -> fundType = FundProductTypeEnum -> ExchangeTradedFund) + or (underlier -> asset -> Instrument -> Security -> securityType = SecurityTypeEnum -> Fund + and underlier -> asset -> Instrument -> Security -> fundType = FundProductTypeEnum -> MutualFund) + or underlier -> asset -> Instrument -> Security -> securityType = SecurityTypeEnum -> Warrant + or underlier -> index ->> assetClass = AssetClassEnum -> Equity + // Qualifies that the underlier is a basket composed of equity products only + or (underlier -> basket exists + and (underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Equity + or (underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Fund + and underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> fundType any = FundProductTypeEnum -> ExchangeTradedFund) + or (underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Fund + and underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> fundType any = FundProductTypeEnum -> MutualFund) + or underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Warrant + or underlier -> basket -> basketConstituent -> index ->> assetClass any = AssetClassEnum -> Equity + )) + func Qualify_UnderlierProduct_Equity: <"Qualifies a product as having the Asset Class classification Equity."> inputs: underlier Product (1..1) @@ -274,16 +326,17 @@ func Qualify_UnderlierProduct_Equity: <"Qualifies a product as having the Asset or (underlier -> security -> securityType = SecurityTypeEnum -> Fund and underlier -> security -> fundType = FundProductTypeEnum -> MutualFund) or underlier -> security -> securityType = SecurityTypeEnum -> Warrant - or (underlier -> index exists /* and underlier -> index -> indexType = IndexTypeEnum -> Equity */ ) // No FpML mappings exist for IndexTypeEnum - // Qualifies that the underlier is a basket composed of equity products only + or underlier -> index ->> assetClass = AssetClassEnum -> Equity + // Qualifies that the underlier is a basket composed of equity products only or (underlier -> basket exists - and (underlier -> basket -> basketConstituent -> security -> securityType any = SecurityTypeEnum -> Equity - or (underlier -> basket -> basketConstituent -> security -> securityType any = SecurityTypeEnum -> Fund - and underlier -> basket -> basketConstituent -> security -> fundType any = FundProductTypeEnum -> ExchangeTradedFund) - or (underlier -> basket -> basketConstituent -> security -> securityType any = SecurityTypeEnum -> Fund - and underlier -> basket -> basketConstituent -> security -> fundType any = FundProductTypeEnum -> MutualFund) - or underlier -> basket -> basketConstituent -> security -> securityType any = SecurityTypeEnum -> Warrant - or (underlier -> basket -> basketConstituent -> index exists /* and underlier -> basket -> basketConstituent -> index -> indexType = IndexTypeEnum -> Equity */ ))) + and (underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Equity + or (underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Fund + and underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> fundType any = FundProductTypeEnum -> ExchangeTradedFund) + or (underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Fund + and underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> fundType any = FundProductTypeEnum -> MutualFund) + or underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Warrant + or underlier -> basket -> basketConstituent -> index ->> assetClass any = AssetClassEnum -> Equity + )) func Qualify_BaseProduct_EquitySwap: <"Qualifies a product as having the Asset Class classification Equity and Base Product Classification Swap."> inputs: @@ -321,7 +374,7 @@ func Qualify_EquitySwap_PriceReturnBasicPerformance_SingleName: <"Qualifies a pr and // qualifies that the performance leg has priceReturnTerms performancePayout -> returnTerms -> priceReturnTerms only exists and // qualifies that underlier is a security (single name) - performancePayout -> underlier -> security exists + performancePayout -> underlier -> 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] @@ -334,7 +387,7 @@ func Qualify_EquitySwap_TotalReturnBasicPerformance_SingleName: <"Qualifies a pr // 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 -> security exists + economicTerms -> payout -> performancePayout -> underlier -> 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 @@ -463,7 +516,7 @@ func Qualify_EquitySwap_ParameterReturnVariance_SingleName: <"Qualifies a produc and // qualifies that the only leg has varianceReturnTerms performancePayout -> returnTerms -> varianceReturnTerms only exists and // qualifies that underlier is a security (single name) - performancePayout -> underlier -> security only exists + performancePayout -> underlier -> asset -> Instrument -> Security only 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] @@ -546,7 +599,7 @@ func Qualify_EquitySwap_ParameterReturnVolatility_SingleName: <"Qualifies a prod and // qualifies that the only leg has volatilityReturnTerms performancePayout -> returnTerms -> volatilityReturnTerms only exists and // qualifies that underlier is a security (single name) - performancePayout -> underlier -> security only exists + performancePayout -> underlier -> asset -> Instrument -> Security only 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] @@ -628,7 +681,7 @@ func Qualify_EquitySwap_ParameterReturnDividend_SingleName: <"Qualifies a produc and // qualifies that the performance Payout has dividendReturnTerms performancePayout -> returnTerms -> dividendReturnTerms only exists and // qualifies that underlier is a security (single name) - performancePayout -> underlier -> security only exists + performancePayout -> underlier -> asset -> Instrument -> Security only 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] @@ -694,7 +747,7 @@ func Qualify_EquityOption_PriceReturnBasicPerformance_SingleName: <"Qualifies a // 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 security - and economicTerms -> payout -> optionPayout only-element -> underlier -> security exists + and ProductUnderlierQualification(economicTerms -> payout -> optionPayout only-element -> productUnderlier, empty, AssetClassEnum -> Equity) // qualifies that no feature other than averaging exists and (economicTerms -> payout -> optionPayout -> feature is absent or economicTerms -> payout -> optionPayout -> feature -> averagingFeature only exists) @@ -712,7 +765,7 @@ func Qualify_EquityOption_PriceReturnBasicPerformance_Index: <"Qualifies a produ // 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 -> index exists + and economicTerms -> payout -> optionPayout only-element -> productUnderlier -> 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) @@ -730,7 +783,7 @@ func Qualify_EquityOption_PriceReturnBasicPerformance_Basket: <"Qualifies a prod // 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 -> basket exists + and economicTerms -> payout -> optionPayout only-element -> productUnderlier -> 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) @@ -745,7 +798,7 @@ func Qualify_EquityOption_ParameterReturnVariance_SingleName: <"Qualifies a prod [synonym ISDA_Taxonomy_v2 value "EquityOption_ParameterReturnVariance_SingleName"] alias underlierEconomicTerms: - economicTerms -> payout -> optionPayout -> underlier -> contractualProduct -> economicTerms only-element + economicTerms -> payout -> optionPayout -> productUnderlier -> NonTransferableProduct -> economicTerms only-element set is_product: // qualifies that only the option payout exist and all other payouts are absent economicTerms -> payout -> optionPayout only exists @@ -764,7 +817,7 @@ func Qualify_EquityOption_ParameterReturnVariance_Index: <"Qualifies a product a [synonym ISDA_Taxonomy_v2 value "EquityOption_ParameterReturnVariance_SingleIndex"] alias underlierEconomicTerms: - economicTerms -> payout -> optionPayout -> underlier -> contractualProduct -> economicTerms only-element + economicTerms -> payout -> optionPayout -> productUnderlier -> NonTransferableProduct -> economicTerms only-element set is_product: // qualifies that only the option payout exist and all other payouts are absent economicTerms -> payout -> optionPayout only exists @@ -782,7 +835,7 @@ func Qualify_EquityOption_ParameterReturnVariance_Basket: <"Qualifies a product [synonym ISDA_Taxonomy_v2 value "Qualify_EquityOption_ParameterReturnVariance_Basket"] alias underlierEconomicTerms: - economicTerms -> payout -> optionPayout -> underlier -> contractualProduct -> economicTerms only-element + economicTerms -> payout -> optionPayout -> productUnderlier -> NonTransferableProduct -> economicTerms only-element set is_product: // qualifies that only the option payout exist and all other payouts are absent economicTerms -> payout -> optionPayout only exists @@ -799,7 +852,7 @@ func Qualify_EquityOption_ParameterReturnVolatility_SingleName: <"Qualifies a pr [synonym ISDA_Taxonomy_v2 value "EquityOption_ParameterReturnVolatility_SingleName"] alias underlierEconomicTerms: - economicTerms -> payout -> optionPayout -> underlier -> contractualProduct -> economicTerms only-element + economicTerms -> payout -> optionPayout -> productUnderlier -> NonTransferableProduct -> economicTerms only-element set is_product: // qualifies that only the option payout exist and all other payouts are absent economicTerms -> payout -> optionPayout only exists @@ -818,7 +871,7 @@ func Qualify_EquityOption_ParameterReturnVolatility_Index: <"Qualifies a product [synonym ISDA_Taxonomy_v2 value "EquityOption_ParameterReturnVolatility_SingleIndex"] alias underlierEconomicTerms: - economicTerms -> payout -> optionPayout -> underlier -> contractualProduct -> economicTerms only-element + economicTerms -> payout -> optionPayout -> productUnderlier -> NonTransferableProduct -> economicTerms only-element set is_product: // qualifies that only the option payout exist and all other payouts are absent economicTerms -> payout -> optionPayout only exists @@ -835,7 +888,7 @@ func Qualify_EquityOption_ParameterReturnVolatility_Basket: <"Qualifies a produc [synonym ISDA_Taxonomy_v2 value "Qualify_EquityOption_ParameterReturnVaolatility_Basket"] alias underlierEconomicTerms: - economicTerms -> payout -> optionPayout -> underlier -> contractualProduct -> economicTerms only-element + economicTerms -> payout -> optionPayout -> productUnderlier -> NonTransferableProduct -> economicTerms only-element set is_product: // qualifies that only the option payout exist and all other payouts are absent economicTerms -> payout -> optionPayout only exists @@ -850,7 +903,7 @@ func Qualify_EquityOption_ParameterReturnCorrelation_Basket: <"Qualifies a produ is_product boolean (1..1) alias underlierEconomicTerms: - economicTerms -> payout -> optionPayout -> underlier -> contractualProduct -> economicTerms only-element + economicTerms -> payout -> optionPayout -> productUnderlier -> NonTransferableProduct -> economicTerms only-element set is_product: // qualifies that only the option payout exist and all other payouts are absent economicTerms -> payout -> optionPayout only exists @@ -867,7 +920,7 @@ func Qualify_EquityOption_ParameterReturnDividend_SingleName: <"Qualifies a prod [synonym ISDA_Taxonomy_v2 value "Qualify_EquityOption_ParameterReturnDividend_SingleName"] alias underlierEconomicTerms: - economicTerms -> payout -> optionPayout -> underlier -> contractualProduct -> economicTerms only-element + economicTerms -> payout -> optionPayout -> productUnderlier -> NonTransferableProduct -> economicTerms only-element set is_product: // qualifies that only the option payout exist and all other payouts are absent economicTerms -> payout -> optionPayout only exists @@ -886,7 +939,7 @@ func Qualify_EquityOption_ParameterReturnDividend_Index: <"Qualifies a product a [synonym ISDA_Taxonomy_v2 value "Qualify_EquityOption_ParameterReturnDividend_SingleIndex"] alias underlierEconomicTerms: - economicTerms -> payout -> optionPayout -> underlier -> contractualProduct -> economicTerms only-element + economicTerms -> payout -> optionPayout -> productUnderlier -> NonTransferableProduct -> economicTerms only-element set is_product: // qualifies that only the option payout exist and all other payouts are absent economicTerms -> payout -> optionPayout only exists @@ -903,7 +956,7 @@ func Qualify_EquityOption_ParameterReturnDividend_Basket: <"Qualifies a product [synonym ISDA_Taxonomy_v2 value "Qualify_EquityOption_ParameterReturnDividend_Basket"] alias underlierEconomicTerms: - economicTerms -> payout -> optionPayout -> underlier -> contractualProduct -> economicTerms only-element + economicTerms -> payout -> optionPayout -> productUnderlier -> NonTransferableProduct -> economicTerms only-element set is_product: // qualifies that only the option payout exist and all other payouts are absent economicTerms -> payout -> optionPayout only exists @@ -1364,7 +1417,7 @@ func Qualify_InterestRate_Option_Swaption: <"Qualifies a product as a Swaption t // 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 only-element -> underlier -> contractualProduct -> economicTerms + economicTerms -> payout -> optionPayout -> productUnderlier -> NonTransferableProduct -> 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."> @@ -1381,7 +1434,7 @@ func Qualify_InterestRate_Option_DebtOption: <"Qualifies a product as a Option t // 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 -> security -> securityType all = SecurityTypeEnum -> Debt + and ProductUnderlierQualification(optionPayout -> productUnderlier, SecurityTypeEnum -> Debt, empty) 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] @@ -1394,7 +1447,8 @@ func Qualify_InterestRate_Forward_Debt: <"Qualifies a product as Interest Rate B alias forwardPayout: economicTerms -> payout -> forwardPayout only-element set is_product: Qualify_AssetClass_InterestRate(economicTerms) = True - and forwardPayout -> underlier -> security only exists + and (forwardPayout -> productUnderlier -> Asset -> Instrument -> Security only exists + or forwardPayout -> productUnderlier -> TransferableProduct -> Instrument -> Security only 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] @@ -1407,10 +1461,17 @@ func Qualify_ForeignExchange_Spot_Forward: <"Qualifies a product as Foreign Exch [synonym ISDA_Taxonomy_v2 value "ForeignExchange_Forward"] [synonym ISDA_Taxonomy_v2 value "ForeignExchange_Spot"] set is_product: - Qualify_AssetClass_ForeignExchange(economicTerms) = True - and economicTerms -> payout -> forwardPayout -> underlier -> foreignExchange only exists - and economicTerms -> payout -> forwardPayout -> underlier -> foreignExchange count = 1 - and economicTerms -> payout -> forwardPayout -> settlementTerms -> cashSettlementTerms is absent + ( Qualify_AssetClass_ForeignExchange(economicTerms) = True + // This logic is updated to be syntactically correct for the new model but is probably not the way FX Spot/Fwds should be modelled + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate only exists + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate count = 1 + and economicTerms -> payout -> forwardPayout -> settlementTerms -> cashSettlementTerms is absent ) + // only FX transactions result in the buyer receiving only cash + // other products result in a cash receipt, but not in as a single SettlementPayout + or (economicTerms -> payout -> settlementPayout only exists + and economicTerms -> payout -> settlementPayout -> underlier -> Asset -> Cash only exists + 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] @@ -1420,8 +1481,8 @@ func Qualify_ForeignExchange_Swap: <"Qualifies a product as Foreign Exchange Swa is_product boolean (1..1) set is_product: Qualify_AssetClass_ForeignExchange(economicTerms) = True - and economicTerms -> payout -> forwardPayout -> underlier -> foreignExchange only exists - and economicTerms -> payout -> forwardPayout -> underlier -> foreignExchange count = 2 + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate only exists + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate count = 2 and economicTerms -> payout -> forwardPayout -> 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."> @@ -1433,10 +1494,17 @@ func Qualify_ForeignExchange_NDF: <"Qualifies a product as Foreign Exchange Non- [synonym ISDA_Taxonomy_v1 value "ForeignExchange_NDF"] [synonym ISDA_Taxonomy_v2 value "ForeignExchange_NDF"] set is_product: - Qualify_AssetClass_ForeignExchange(economicTerms) = True - and economicTerms -> payout -> forwardPayout -> underlier -> foreignExchange only exists - and economicTerms -> payout -> forwardPayout -> underlier -> foreignExchange count = 1 - and economicTerms -> payout -> forwardPayout -> settlementTerms -> cashSettlementTerms exists + // This logic is updated to be syntactically correct for the new model but is probably not the way FX Spot/Fwds should be modelled + ( Qualify_AssetClass_ForeignExchange(economicTerms) = True + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate only exists + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate count = 1 + and economicTerms -> payout -> forwardPayout -> settlementTerms -> cashSettlementTerms exists ) + // only FX transactions result in the buyer receiving only cash + // other products result in a cash receipt, but not in as a single SettlementPayout + or (economicTerms -> payout -> settlementPayout only exists + and economicTerms -> payout -> settlementPayout -> underlier -> Asset -> Cash only exists + 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] @@ -1446,8 +1514,8 @@ func Qualify_ForeignExchange_NDS: <"Qualifies a product as Foreign Exchange NDS is_product boolean (1..1) set is_product: Qualify_AssetClass_ForeignExchange(economicTerms) = True - and economicTerms -> payout -> forwardPayout -> underlier -> foreignExchange only exists - and economicTerms -> payout -> forwardPayout -> underlier -> foreignExchange count = 2 + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate only exists + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate count = 2 and economicTerms -> payout -> forwardPayout -> 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."> @@ -1463,7 +1531,7 @@ func Qualify_ForeignExchange_ParameterReturnVariance: <"Qualifies a product as F set is_product: Qualify_AssetClass_ForeignExchange(economicTerms) = True // qualifies that the product is FX (i.e.: has only foreign Exchange underliers) - and performancePayout -> observationTerms -> observable -> currencyPair only exists + and performancePayout -> observationTerms -> observable -> index -> ForeignExchangeRate only exists and // qualifies that there is a single leg of performance type economicTerms -> payout -> performancePayout only exists and economicTerms -> payout -> performancePayout count = 1 @@ -1483,7 +1551,7 @@ func Qualify_ForeignExchange_ParameterReturnVolatility: <"Qualifies a product as set is_product: Qualify_AssetClass_ForeignExchange(economicTerms) = True // qualifies that the product is FX (i.e.: has only foreign Exchange underliers) - and performancePayout -> observationTerms -> observable -> currencyPair only exists + and performancePayout -> observationTerms -> observable -> index -> ForeignExchangeRate only exists and // qualifies that there is a single leg of performance type economicTerms -> payout -> performancePayout only exists and economicTerms -> payout -> performancePayout count = 1 @@ -1508,15 +1576,8 @@ func Qualify_ForeignExchange_ParameterReturnCorrelation: <"Qualifies a product a and // qualifies that the underlier is a basket performancePayout -> underlier -> basket only exists and // qualifies that the product is FX (i.e.: the basket is constituted by foreign exchange constituents) - performancePayout -> underlier -> basket -> basketConstituent -> foreignExchange only exists - and // qualifies that all basket constituents are FX - are these necessary? Should be covered by the "only exists" above - performancePayout -> underlier -> basket -> basketConstituent -> basket is absent - and performancePayout -> underlier -> basket -> basketConstituent -> commodity is absent - and performancePayout -> underlier -> basket -> basketConstituent -> contractualProduct is absent - and performancePayout -> underlier -> basket -> basketConstituent -> index is absent - and performancePayout -> underlier -> basket -> basketConstituent -> loan is absent - and performancePayout -> underlier -> basket -> basketConstituent -> security is absent - + performancePayout -> underlier -> basket -> basketConstituent -> index -> ForeignExchangeRate only exists + 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: @@ -1528,12 +1589,24 @@ func Qualify_ForeignExchange_VanillaOption: <"Qualifies a product as FX Plain Va set is_product: Qualify_AssetClass_ForeignExchange(economicTerms) = True and economicTerms -> payout -> optionPayout exists - and economicTerms -> payout -> optionPayout -> underlier -> foreignExchange only exists + and economicTerms -> payout -> optionPayout -> productUnderlier -> Index -> ForeignExchangeRate 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_SecuritiesFinance: <"Qualifies a product as generic Securities Finance; eg Securities Lending or Repurchase Agreement."> +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 -> AssetUnderlier -> TransferableProduct -> economicTerms -> payout -> assetPayout only exists + and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> 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) @@ -1542,7 +1615,19 @@ func Qualify_SecuritiesFinance: <"Qualifies a product as generic Securities Fina set is_product: economicTerms -> payout -> interestRatePayout only exists and economicTerms -> payout -> interestRatePayout count = 1 - and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> contractualProduct -> economicTerms -> payout -> assetPayout only exists + and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> economicTerms -> payout -> assetPayout only exists + and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> 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 -> AssetUnderlier only 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] @@ -1580,7 +1665,8 @@ func Qualify_Commodity_Option: <"Qualifies a product as a Option that can be exe set is_product: Qualify_AssetClass_Commodity(economicTerms) = True and economicTerms -> payout -> optionPayout only exists - and economicTerms -> payout -> optionPayout -> underlier -> commodity exists + and ( economicTerms -> payout -> optionPayout -> productUnderlier -> Asset -> Commodity exists + or economicTerms -> payout -> optionPayout -> productUnderlier -> TransferableProduct -> Commodity exists ) func Qualify_Commodity_Option_Cash: <"Qualifies a product as a Option that can be exercised into an Commodity."> inputs: @@ -1615,10 +1701,10 @@ func Qualify_Commodity_Swaption: <"Qualifies a product as a Swaption that can be set is_product: economicTerms -> payout -> optionPayout only exists and (Qualify_Commodity_Swap_Basis( - economicTerms -> payout -> optionPayout only-element -> underlier -> contractualProduct -> economicTerms + economicTerms -> payout -> optionPayout only-element -> productUnderlier -> NonTransferableProduct -> economicTerms ) = True or Qualify_Commodity_Swap_FixedFloat( - economicTerms -> payout -> optionPayout only-element -> underlier -> contractualProduct -> economicTerms + economicTerms -> payout -> optionPayout only-element -> productUnderlier -> NonTransferableProduct -> 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."> diff --git a/rosetta-source/src/main/rosetta/product-template-enum.rosetta b/rosetta-source/src/main/rosetta/product-template-enum.rosetta index 2175f088ee..7132e2ed9b 100644 --- a/rosetta-source/src/main/rosetta/product-template-enum.rosetta +++ b/rosetta-source/src/main/rosetta/product-template-enum.rosetta @@ -1,11 +1,18 @@ namespace cdm.product.template : <"Template feature concepts to define payouts."> version "${project.version}" +import cdm.base.staticdata.asset.common.* + enum AveragingInOutEnum: <"The enumerated values to specify the type of averaging used in an Asian option."> In <"The average price is used to derive the strike price. Also known as 'Asian strike' style option."> Out <"The average price is used to derive the expiration price. Also known as 'Asian price' style option."> Both <"The average price is used to derive both the strike and the expiration price."> +enum OptionTypeEnum extends PutCallEnum: <"The enumerated values to specify the type or strategy of the option."> + Payer <"A 'payer' option: If you buy a 'payer' option you have the right but not the obligation to enter into the underlying swap transaction as the 'fixed' rate/price payer and receive float."> + Receiver <"A 'receiver' option: If you buy a 'receiver' option you have the right but not the obligation to enter into the underlying swap transaction as the 'fixed' rate/price receiver and pay float."> + Straddle <"A straddle strategy, which involves the simultaneous buying of a put and a call of the same underlier, at the same strike and same expiration date"> + enum OptionExerciseStyleEnum: <"The enumerated values to specify the option exercise style. i.e., European, Bermuda or American."> European <"Single Exercise"> Bermuda <"Multiple specified exercise dates"> @@ -33,6 +40,10 @@ enum RepoDurationEnum: <"A duration code for a Repo (or Securities Lending) tran Overnight <"Indicates that a contract is classified as overnight, meaning that there is one business day difference between the start and end date of the contract. Business rule: When the repo is overnight, the number of business days between the spot and forward value dates must be one. Forward leg must be specified."> Term <"Indicates that a contract is a regular term contract, with a start date and an end date. Business rule: When the repo is 'Term', both spot and forward legs must be specified."> +enum RepoTypeEnum: <"Repurchase transactions and buy/sell-backs are both types of repo; this enumerator helps differentiate the two."> + Repo <"In the case of a repurchase transaction, an immediate and equal income payment (often call a manufactured payment) is made by the buyer to the seller."> + BuySellBack displayName "Buy/Sell-Back" <"In the case of a buy/sell-back, there is no income payment between buyer and seller. Instead, the repurchase price to be paid on the repurchase date is reduced by the amount of the income payment on the collateral plus some extra interest to compensate the seller for the delay between the income payment date on the collateral and the repurchase date of the repo."> + enum DurationTypeEnum: <"Specifies the duration type of the Security Lending transaction. e.g. Open or Term."> // [deprecated] Term <"Specifies a trade with a termination date."> diff --git a/rosetta-source/src/main/rosetta/product-template-type.rosetta b/rosetta-source/src/main/rosetta/product-template-type.rosetta index e614982f9b..b902e5fdff 100644 --- a/rosetta-source/src/main/rosetta/product-template-type.rosetta +++ b/rosetta-source/src/main/rosetta/product-template-type.rosetta @@ -23,16 +23,17 @@ import cdm.product.collateral.* import cdm.mapping.config.* -type TransferableProduct: <"A TransferableProduct is a type of Product which can be used in a SettlementCommitment for a basic cash settled trade of either an Asset with or without the addition of specific EconomicTerms."> - asset Asset (1..1) - economicTerms EconomicTerms (0..1) +type ProductBase: <"Serves as an abstract class to specify common attributes for all products."> + productTaxonomy ProductTaxonomy (0..*) <"Specifies the product taxonomy, which is composed of a taxonomy value and a taxonomy source."> + economicTerms EconomicTerms (1..1) <"The price forming features, including payouts and provisions."> + +type TransferableProduct extends Asset: <"A TransferableProduct is a type of Product which can be used in a SettlementCommitment for a basic cash settled trade of either an Asset with the addition of specific EconomicTerms."> + economicTerms EconomicTerms (1..1) <"The price forming features, including payouts and provisions."> type ContractualProduct extends ProductBase: <" A class to specify the contractual products' economic terms, alongside their product identification and product taxonomy. The contractual product class is meant to be used across the pre-execution, execution and (as part of the Contract) post-execution lifecycle contexts."> [metadata key] [metadata template] - economicTerms EconomicTerms (1..1) <"The economic terms associated with a contractual product, i.e. the set of features that are price-forming."> - condition PrimaryAssetClass: <"Specifies that when nonStandardisedTerms are True that a primary asset class must be specified."> if economicTerms -> nonStandardisedTerms = True then productTaxonomy -> primaryAssetClass exists @@ -86,6 +87,13 @@ type EconomicTerms: <" This class represents the full set of price-forming featu if payout -> assetPayout -> dividendTerms exists then terminationDate exists +choice ProductUnderlier: <"The product underlying the option, which can be of any type including an Asset, Basket, Index or a NonTransferableProduct."> + Asset <"A financial product that can be owned and transferred in the financial markets"> + Basket <"A collection of Observables with an identifier and optional weightings."> + Index <"An observable computed on the prices, rates or valuations of a number of assets."> + TransferableProduct <"An Asset with the addition of specific EconomicTerms."> + NonTransferableProduct <"Represents a product that can be traded (as part of a TradableProduct) but cannot be transferred to others."> + type OptionPayout extends PayoutBase: <" The option payout specification terms. The associated globalKey denotes the ability to associate a hash value to the respective OptionPayout instantiation for the purpose of model cross-referencing, in support of functionality such as the event effect and the lineage."> [metadata key] @@ -94,15 +102,15 @@ type OptionPayout extends PayoutBase: <" The option payout specification terms. observationTerms ObservationTerms (0..1) <"Class containing terms that are associated with observing a price/benchmark/index across either single or multple observations. To be used for option contracts that reference a benchmark price."> schedule CalculationSchedule (0..1) <"Allows the full representation of a payout by defining a set of schedule periods. It supports standard schedule customization by expressing all the dates, quantities, and pricing data in a non-parametric way."> delivery AssetDeliveryInformation (0..1) <"Contains the information relative to the delivery of the asset."> - underlier Product (1..1) <"The product underlying the option, which can be of any type including ContractualProduct or Security."> + productUnderlier ProductUnderlier (1..1) <"The financial product underlying the option, which can be of any type including an Asset, Basket, Index or a NonTransferableProduct."> optionType OptionTypeEnum (0..1) <"The type of option transaction. From a usage standpoint, put/call is the default option type, while payer/receiver indicator is used for options on index credit default swaps, consistently with the industry practice. Straddle is used for the case of straddle strategy, that combine a call and a put with the same strike."> exerciseTerms ExerciseTerms (1..1) <"The terms for exercising the option, which include the option style (e.g. American style option), the exercise procedure (e.g. manual exercise) and the settlement terms (e.g. physical vs. cash)."> strike OptionStrike (0..1) <"Specifies the strike of the option"> condition ClearedPhysicalSettlementExists: if settlementTerms -> physicalSettlementTerms exists - and underlier -> contractualProduct -> economicTerms -> payout -> interestRatePayout only exists - and underlier -> contractualProduct -> economicTerms -> payout -> interestRatePayout count = 2 + and productUnderlier -> NonTransferableProduct -> economicTerms -> payout -> interestRatePayout only exists + and productUnderlier -> NonTransferableProduct -> economicTerms -> payout -> interestRatePayout count = 2 then settlementTerms -> physicalSettlementTerms -> clearedPhysicalSettlement exists condition DeliveryCapacity: <"Checks that only one of the representations of delivery capacity is present simultaneously."> @@ -161,27 +169,30 @@ type PerformancePayout extends PayoutBase: <"Contains the necessary specificatio observationTerms ObservationTerms (0..1) <"Defines how and when a performance type option or performance type swap is to be observed."> valuationDates ValuationDates (1..1) <"Defines how and when a performance type option or performance type swap is to be valued, including both interim and final valuation."> paymentDates PaymentDates (1..1) <"Defines the payment date schedule, as defined by the parameters that are needed to specify it, either in a parametric way or by reference to another schedule of dates (e.g. the valuation dates)."> - underlier Product (0..1) <"Identifies the underlying product that is referenced for pricing of the applicable leg in a swap. Referenced in the '2018 ISDA CDM Equity Confirmation for Security Equity Swap' as Security."> + underlier Observable (0..1) <"Identifies the underlying product that is referenced for pricing of the applicable leg in a swap. Referenced in the '2018 ISDA CDM Equity Confirmation for Security Equity Swap' as Security."> fxFeature FxFeature (0..*) <"Defines quanto or composite FX features that are included in the swap leg."> returnTerms ReturnTerms (0..1) <"Specifies the type of return of a performance payout."> portfolioReturnTerms PortfolioReturnTerms (0..*) <"Specifies an individual type of return of a Performance Payout, when such individual return is part of an aggregation of multiple similar returns, at Performance Payout level"> initialValuationPrice PriceSchedule (0..*) <"Specifies the net initial valuation price(s) of the underlier at Performance Payout level. This price can be expressed either as an actual amount/currency, as a determination method, or by reference to another value specified in the swap document."> - [metadata address "pointsTo"=PriceQuantity->price] + [metadata address "pointsTo"=PriceQuantity->price] interimValuationPrice PriceSchedule (0..*) <"Specifies the net initial valuation price(s) of the underlier at Performance Payout level. This price can be expressed either as an actual amount/currency, as a determination method, or by reference to another value specified in the swap document."> - [metadata address "pointsTo"=PriceQuantity->price] + [metadata address "pointsTo"=PriceQuantity->price] finalValuationPrice PriceSchedule (0..*) <"Specifies the net final valuation price(s) of the underlier at Performance Payout level. This price can be expressed either as an actual amount/currency, as a determination method, or by reference to another value specified in the swap document."> - [metadata address "pointsTo"=PriceQuantity->price] + [metadata address "pointsTo"=PriceQuantity->price] - condition PorfolioOrStraightReturn: <"Allowing for both returnTerms and portfolioReturnTerms to co-exist, would cause confusion by breaking the aggregation logic that is at parent node level."> - required choice returnTerms, portfolioReturnTerms + condition PorfolioOrStraightReturn: + required choice returnTerms, portfolioReturnTerms + + // condition PorfolioOrStraightReturn: <"Allowing for both returnTerms and portfolioReturnTerms to co-exist, would cause confusion by breaking the aggregation logic that is at parent node level."> + // required choice returnTerms, portfolioReturnTerms condition PortofolioReturnIsMultipleReturns: <"No single portfolioReturnTerms instance shall exist because it would be a duplicate of straight returnTerms."> - if portfolioReturnTerms exists - then portfolioReturnTerms count > 1 + if portfolioReturnTerms exists + then portfolioReturnTerms count > 1 condition UnderlierOfPortfolioIsBasket:<"A portfolio made of multiple individual legs in portfolio, is a strategy that consider the Basket in transparency, thus having a Basket as an underlier of the PerformancePayout that is aggregation level and multiple individual legs in portfolio, each with an underlier to correspond to each Basket consituent. This is particular usage of portfolio attribute, hence the condition, being aknowledged that other usages would not require Basket to exist at this level, for instance a dispersion strategy where 'N+1' multiple portfolio return legs would exist, '1' with underlier->Basket, other 'N' ones with single underliers, where the Basket is at same level as the other legs (therefore no aggregation shall exist via Basket at PerformancePayout level."> - if portfolioReturnTerms -> priceReturnTerms exists - then underlier -> basket only exists + if portfolioReturnTerms -> priceReturnTerms exists + then underlier -> basket only exists condition Quantity: <"When there is an OptionPayout the quantity can be expressed as part of the payoutQuantity, or as part of the underlier in the case of a Swaption. For all other payouts that extend PayoutBase the payoutQuantity is a mandatory attribute."> priceQuantity exists @@ -192,7 +203,7 @@ type PerformancePayout extends PayoutBase: <"Contains the necessary specificatio and returnTerms -> volatilityReturnTerms -> sharePriceDividendAdjustment is absent condition NoSharePriceDividendAdjustmentForeignExchange: <"If the underlier is an foreign exchange, sharePriceAdjustment and sharePriceDividendAdjustment cannot exist."> - if underlier -> foreignExchange exists + if underlier -> index -> ForeignExchangeRate exists then returnTerms -> varianceReturnTerms -> sharePriceDividendAdjustment is absent and returnTerms -> volatilityReturnTerms -> sharePriceDividendAdjustment is absent @@ -201,7 +212,7 @@ type PerformancePayout extends PayoutBase: <"Contains the necessary specificatio then underlier -> basket only exists condition EquitySpecificAttributes: <"Equity specific attributes cannot be present in non-equity products."> - if Qualify_UnderlierProduct_Equity(underlier) = False + if Qualify_UnderlierObservable_Equity(underlier) = False then returnTerms -> varianceReturnTerms -> dividendApplicability is absent and returnTerms -> varianceReturnTerms -> equityUnderlierProvisions is absent and returnTerms -> varianceReturnTerms -> sharePriceDividendAdjustment is absent @@ -226,7 +237,7 @@ type PortfolioReturnTerms extends ReturnTerms : <"Specifies an individual type o finalValuationPrice PriceSchedule (0..*) <"2018 ISDA CDM Equity Confirmation for Security Equity Swap: Final Price | Specifies the final valuation price of the underlier. This price can be expressed either as an actual amount/currency, as a determination method, or by reference to another value specified in the swap document."> [metadata address "pointsTo"=PriceQuantity->price] -type Payout: <"A class to represent the set of future cashflow methodologies in the form of specific payout class(es) that can be associated for the purpose of specifying a financial product. For example, two interest rate payouts can be combined to specify an interest rate swap, or one interest rate payout can be combined with a credit default payout to specify a credit default swap."> +type Payout: <"Represents the set of future cashflow methodologies in the form of specific payout data type(s) which result from the financial product. Examples: a trade in a cash asset will use only a settlement payout; for derivatives, two interest rate payouts can be combined to specify an interest rate swap; one interest rate payout can be combined with a credit default payout to specify a credit default swap."> [metadata key] interestRatePayout InterestRatePayout (0..*) <"All of the terms necessary to define and calculate a cash flow based on a fixed, a floating or an inflation index rate. The interest rate payout can be applied to interest rate swaps and FRA (which both have two associated interest rate payouts), credit default swaps (to represent the fee leg when subject to periodic payments) and equity swaps (to represent the funding leg)."> @@ -237,12 +248,12 @@ type Payout: <"A class to represent the set of future cashflow methodologies in fixedPricePayout FixedPricePayout (0..*) <"Defines a payout in which one or more payouts are defined as a fixed price."> cashflow Cashflow (0..*) <"A cashflow between the parties to the trade. For interest rate and equity products, this corresponds to the FpML additionalPayment element. For credit default swaps, this corresponds to the FpML initialPayment element and the singlePayment element of the fee leg. For option products, it represents the FpML premium element."> performancePayout PerformancePayout (0..*) <"The performance payout, which encompasses the equity price returns, dividend returns, volatility return, variance return and correlation provisions."> - assetPayout AssetPayout (0..*) <"The security payout when the product involves some form of securities, such as collateral in a securities financing transaction"> - settlementCommitment SettlementCommitment (0..1) <"This is a simple payout used to define the commitment to settle a trade, for example a purchase of a cash security."> + assetPayout AssetPayout (0..*) <"Defines the assets and movements in a security financing transaction."> + settlementPayout SettlementPayout (0..1) <"Defines the commitment to settle a trade in a TransferableProduct."> - condition SettlementCommitmentIsExclusive: <"A SettlementCommitment can only be used on its own."> - if settlementCommitment exists - then settlementCommitment only exists + condition SettlementPayoutIsExclusive: <"A SettlementPayout can only be used on its own."> + if settlementPayout exists + then settlementPayout only exists condition ReturnType_Total_Requires_Dividends: <"A total return implies both a price and a dividend return"> if performancePayout -> returnTerms -> priceReturnTerms -> returnType all = ReturnTypeEnum -> Total @@ -268,7 +279,7 @@ type Payout: <"A class to represent the set of future cashflow methodologies in condition Quantity: <"When there is an OptionPayout the quantity can be expressed as part of the payoutQuantity, or as part of the underlier in the case of a Swaption. For all other payouts that extend PayoutBase the payoutQuantity is a mandatory attribute."> if optionPayout exists then optionPayout -> priceQuantity exists - or optionPayout -> underlier -> contractualProduct -> economicTerms -> payout -> interestRatePayout count = 2 + or optionPayout -> productUnderlier -> NonTransferableProduct -> economicTerms -> payout -> interestRatePayout count = 2 condition DayCountFraction: <"FpML specifies a required dayCountFraction element as part of the swapStream/calculationPeriodAmount/calculation. As standardized CDS don't have such specified day count fraction, the cardinality has been relaxed as part of the CDM. This data rule specifies that if the product has two interest rate streams, this provision must exist."> if interestRatePayout count = 2 @@ -296,8 +307,26 @@ type Payout: <"A class to represent the set of future cashflow methodologies in if performancePayout -> priceQuantity -> reset contains True then interestRatePayout exists -type SettlementCommitment extends PayoutBase: <"This is a simple payout used to define the commitment to settle a trade, for example a purchase of a cash security."> - transferableProduct TransferableProduct (1..1) <"A transferable Asset with or without the addition of specific EconomicTerms."> +type SettlementPayout extends PayoutBase: <"This is a payout data type used to define the commitment to settle a trade in an Asset or TransferableProduct. Examples: a purchase of a cash security; an FX trade, either spot or forward. The PayerReceiver in PayoutBase describes which party is the buyer/receiver of the asset defined in underlier, and which party is the seller/payer of this asset. The price/quantity paid is defined in the currency PriceQuantity in TradeLot."> + underlier AssetUnderlier (1..1) <"A transferable Asset with or without the addition of specific EconomicTerms."> + +choice AssetUnderlier: <"The underlier of a payout which can be either an Asset or a Transferable Product, which is an Asset with Economic Terms."> + Asset <"Identifies a transferable asset."> + TransferableProduct <"Defines the transferable asset with an identifier and economic terms."> + +choice Underlier: <"The underlier of a payout which can be either an Asset or a Transferable Product, which is an Asset with Economic Terms."> + NonTransferableProduct <"Specifies the financial product's economic terms, alongside the product identification and product taxonomy."> + AssetUnderlier <"The underlier of a payout which can be either an Asset or a Transferable Product, which is an Asset with Economic Terms."> + +type NonTransferableProduct extends ProductBase: <"A data type to specify the financial product's economic terms, alongside the product identification and product taxonomy. The non-transferable product data type represents a product that can be traded (as part of a TradableProduct) but cannot be transferred to others. It is meant to be used across the pre-execution, execution and (as part of the Contract) post-execution lifecycle contexts."> + [metadata key] + [metadata template] + + identifier ProductIdentifier (0..*) + + condition PrimaryAssetClass: <"Specifies that when nonStandardisedTerms are True that a primary asset class must be specified."> + if economicTerms -> nonStandardisedTerms = True + then productTaxonomy -> primaryAssetClass exists type Product: <"Defines the product that is the subject of a tradable product definition, an underlying product definition, a physical exercise, a position, or other purposes."> [metadata key] @@ -307,33 +336,21 @@ type Product: <"Defines the product that is the subject of a tradable product de loan Loan (0..1) <"Identifies a loan by referencing a product identifier and an optional set of attributes."> foreignExchange ForeignExchange (0..1) <"Defines a foreign exchange spot or forward transaction."> commodity Commodity (0..1) <"Identifies a commodity by referencing a product identifier."> - [metadata address "pointsTo"=Observable->commodity] + //**ART** + // [metadata address "pointsTo"=Observable->commodity] security Security (0..1) <"Identifies a security by referencing a product identifier and a security type, plus an optional set of attributes."> basket Basket (0..1) <"Identifies a custom basket by referencing a product identifier and its constituents."> condition: one-of -type Basket extends ProductBase: <"Defines a custom basket by referencing a product identifier and its consituents."> - basketConstituent BasketConstituent (1..*) <"Identifies the constituents of the basket"> - -type BasketConstituent extends Product :<"Identifies the constituents of the basket"> -quantity NonNegativeQuantitySchedule (0..*) <"Specifies a quantity schedule to be associated to an individual underlier that is a basket constituent. The multiple cardinality is aligned to the one of the PriceQuantity->quantity that this quantity is referencing."> - [metadata address "pointsTo"=PriceQuantity->quantity] -initialValuationPrice PriceSchedule (0..*) <"Specifies an initial price schedule to be associated to an individual underlier that is a basket constituent. The multiple cardinality is aligned to the one of the PriceQuantity->price that this price is referencing."> - [metadata address "pointsTo"=PriceQuantity->price] -interimValuationPrice PriceSchedule (0..*) <"Specifies an interim price schedule to be associated to an individual underlier that is a basket constituent. The multiple cardinality is aligned to the one of the PriceQuantity->price that this price is referencing."> - [metadata address "pointsTo"=PriceQuantity->price] -finalValuationPrice PriceSchedule (0..*) <"Specifies a final price schedule to be associated to an individual underlier that is a basket constituent. The multiple cardinality is aligned to the one of the PriceQuantity->price that this price is referencing."> - [metadata address "pointsTo"=PriceQuantity->price] - type TradeLot: <"Specifies the price and quantity of a trade lot, where the same product could be traded multiple times with the same counterparty but in different lots (at a different date, in a different quantity and at a different price). One trade lot combined with a product definition specifies the entire economics of a trade. The lifecycle mechanics of each such trade lot (e.g. cashflow payments) is independent of the other lots."> lotIdentifier Identifier (0..*) <"Specifies one or more identifiers for the lot, if any."> priceQuantity PriceQuantity (1..*) <"Specifies the settlement characteristics of a trade lot: price, quantity, observable (optionally) and the settlement terms. This attribute has a multiple cardinality to allow to specify the price, quantity and observable of different legs in a single, composite product (e.g. a Swap)."> type TradableProduct: <"Definition of a product as ready to be traded, i.e. included in an execution or contract, by associating a specific price and quantity to this product plus an (optional) mechanism for any potential future quantity adjustment."> - product Product (1..1) <"The underlying product to be included in a contract or execution."> + product NonTransferableProduct (1..1) <"The underlying product to be included in a contract or execution."> tradeLot TradeLot (1..*) <"Specifies the price, quantity and effective date of each trade lot, when the same product may be traded multiple times in different lots with the same counterparty. In a trade increase, a new trade lot is added to the list, with the corresponding effective date. In a trade decrease, the existing trade lot(s) are decreased of the corresponding quantity (and an unwind fee may have to be settled). The multiple cardinality and the ability to increase existing trades is used for Equity Swaps in particular."> counterparty Counterparty (2..2) <"Specifies the parties which are the two counterparties to the transaction. The product is agnostic to the actual parties to the transaction, with the party references abstracted away from the product definition and replaced by the counterparty enum (e.g. CounterpartyEnum values Party1 or Party2). The counterparty enum can then be positioned in the product (e.g. to specify which counterparty is the payer, receiver etc) and this counterparties attribute, which is positioned outside of the product definition, allows the counterparty enum to be associated with an actual party reference."> [docReference ICMA GMRA namingConvention "Party" @@ -346,69 +363,69 @@ type TradableProduct: <"Definition of a product as ready to be traded, i.e. incl condition NotionalAdjustment: <"As the adjustment attribute applies to return swaps, the equity payout needs to be present alongside it."> if adjustment exists - then product -> contractualProduct -> economicTerms -> payout -> performancePayout -> returnTerms -> priceReturnTerms exists - or product -> contractualProduct -> economicTerms -> payout -> performancePayout exists + then product -> economicTerms -> payout -> performancePayout -> returnTerms -> priceReturnTerms exists + or product -> economicTerms -> payout -> performancePayout exists condition PerformancePayout_ExtraordinaryDividendsParty: - if product -> contractualProduct -> economicTerms -> payout -> performancePayout -> returnTerms -> dividendReturnTerms -> extraordinaryDividendsParty exists + if product -> economicTerms -> payout -> performancePayout -> returnTerms -> dividendReturnTerms -> extraordinaryDividendsParty exists then ancillaryParty -> role contains AncillaryRoleEnum -> ExtraordinaryDividendsParty and if ancillaryParty -> role contains AncillaryRoleEnum -> ExtraordinaryDividendsParty - then product -> contractualProduct -> economicTerms -> payout -> performancePayout -> returnTerms -> dividendReturnTerms -> extraordinaryDividendsParty exists + then product -> economicTerms -> payout -> performancePayout -> returnTerms -> dividendReturnTerms -> extraordinaryDividendsParty exists condition OptionPayout_PredeterminedClearingOrganizationParty: - if product -> contractualProduct -> economicTerms -> payout -> optionPayout -> settlementTerms -> physicalSettlementTerms -> predeterminedClearingOrganizationParty exists + if product -> economicTerms -> payout -> optionPayout -> settlementTerms -> physicalSettlementTerms -> predeterminedClearingOrganizationParty exists then ancillaryParty -> role contains AncillaryRoleEnum -> PredeterminedClearingOrganizationParty condition ForwardPayout_PredeterminedClearingOrganizationParty: - if product -> contractualProduct -> economicTerms -> payout -> forwardPayout -> settlementTerms -> physicalSettlementTerms -> predeterminedClearingOrganizationParty exists + if product -> economicTerms -> payout -> forwardPayout -> settlementTerms -> physicalSettlementTerms -> predeterminedClearingOrganizationParty exists then ancillaryParty -> role contains AncillaryRoleEnum -> PredeterminedClearingOrganizationParty condition PredeterminedClearingOrganizationParty: if ancillaryParty -> role contains AncillaryRoleEnum -> PredeterminedClearingOrganizationParty - then product -> contractualProduct -> economicTerms -> payout -> forwardPayout -> settlementTerms -> physicalSettlementTerms -> predeterminedClearingOrganizationParty exists - or product -> contractualProduct -> economicTerms -> payout -> optionPayout -> settlementTerms -> physicalSettlementTerms -> predeterminedClearingOrganizationParty exists + then product -> economicTerms -> payout -> forwardPayout -> settlementTerms -> physicalSettlementTerms -> predeterminedClearingOrganizationParty exists + or product -> economicTerms -> payout -> optionPayout -> settlementTerms -> physicalSettlementTerms -> predeterminedClearingOrganizationParty exists condition ExerciseNoticeReceiverPartyManual: - if product -> contractualProduct -> economicTerms -> payout -> optionPayout -> exerciseTerms -> exerciseProcedure -> manualExercise -> exerciseNotice -> exerciseNoticeReceiver exists + if product -> economicTerms -> payout -> optionPayout -> exerciseTerms -> exerciseProcedure -> manualExercise -> exerciseNotice -> exerciseNoticeReceiver exists then ancillaryParty -> role contains AncillaryRoleEnum -> ExerciseNoticeReceiverPartyManual and if ancillaryParty -> role contains AncillaryRoleEnum -> ExerciseNoticeReceiverPartyManual - then product -> contractualProduct -> economicTerms -> payout -> optionPayout -> exerciseTerms -> exerciseProcedure -> manualExercise -> exerciseNotice -> exerciseNoticeReceiver exists + then product -> economicTerms -> payout -> optionPayout -> exerciseTerms -> exerciseProcedure -> manualExercise -> exerciseNotice -> exerciseNoticeReceiver exists condition ExerciseNoticeReceiverPartyOptionalEarlyTermination: - if product -> contractualProduct -> economicTerms -> terminationProvision -> earlyTerminationProvision -> optionalEarlyTermination -> exerciseNotice -> exerciseNoticeReceiver exists + if product -> economicTerms -> terminationProvision -> earlyTerminationProvision -> optionalEarlyTermination -> exerciseNotice -> exerciseNoticeReceiver exists then ancillaryParty -> role contains AncillaryRoleEnum -> ExerciseNoticeReceiverPartyOptionalEarlyTermination and if ancillaryParty -> role contains AncillaryRoleEnum -> ExerciseNoticeReceiverPartyOptionalEarlyTermination - then product -> contractualProduct -> economicTerms -> terminationProvision -> earlyTerminationProvision -> optionalEarlyTermination -> exerciseNotice -> exerciseNoticeReceiver exists + then product -> economicTerms -> terminationProvision -> earlyTerminationProvision -> optionalEarlyTermination -> exerciseNotice -> exerciseNoticeReceiver exists condition ExerciseNoticeReceiverPartyCancelableProvision: - if product -> contractualProduct -> economicTerms -> terminationProvision -> cancelableProvision -> exerciseNotice -> exerciseNoticeReceiver exists + if product -> economicTerms -> terminationProvision -> cancelableProvision -> exerciseNotice -> exerciseNoticeReceiver exists then ancillaryParty -> role contains AncillaryRoleEnum -> ExerciseNoticeReceiverPartyCancelableProvision and if ancillaryParty -> role contains AncillaryRoleEnum -> ExerciseNoticeReceiverPartyCancelableProvision - then product -> contractualProduct -> economicTerms -> terminationProvision -> cancelableProvision -> exerciseNotice -> exerciseNoticeReceiver exists + then product -> economicTerms -> terminationProvision -> cancelableProvision -> exerciseNotice -> exerciseNoticeReceiver exists condition ExerciseNoticeReceiverPartyExtendibleProvision: - if product -> contractualProduct -> economicTerms -> terminationProvision -> extendibleProvision -> exerciseNotice -> exerciseNoticeReceiver exists + if product -> economicTerms -> terminationProvision -> extendibleProvision -> exerciseNotice -> exerciseNoticeReceiver exists then ancillaryParty -> role contains AncillaryRoleEnum -> ExerciseNoticeReceiverPartyExtendibleProvision and if ancillaryParty -> role contains AncillaryRoleEnum -> ExerciseNoticeReceiverPartyExtendibleProvision - then product -> contractualProduct -> economicTerms -> terminationProvision -> extendibleProvision -> exerciseNotice -> exerciseNoticeReceiver exists + then product -> economicTerms -> terminationProvision -> extendibleProvision -> exerciseNotice -> exerciseNoticeReceiver exists condition CalculationAgentIndependent: - if product -> contractualProduct -> economicTerms -> calculationAgent -> calculationAgentParty exists + if product -> economicTerms -> calculationAgent -> calculationAgentParty exists then ancillaryParty -> role contains AncillaryRoleEnum -> CalculationAgentIndependent and if ancillaryParty -> role contains AncillaryRoleEnum -> CalculationAgentIndependent - then product -> contractualProduct -> economicTerms -> calculationAgent -> calculationAgentParty exists + then product -> economicTerms -> calculationAgent -> calculationAgentParty exists condition CalculationAgentOptionalEarlyTermination: - if product -> contractualProduct -> economicTerms -> terminationProvision -> earlyTerminationProvision -> optionalEarlyTermination -> calculationAgent -> calculationAgentParty exists + if product -> economicTerms -> terminationProvision -> earlyTerminationProvision -> optionalEarlyTermination -> calculationAgent -> calculationAgentParty exists then ancillaryParty -> role contains AncillaryRoleEnum -> CalculationAgentOptionalEarlyTermination and if ancillaryParty -> role contains AncillaryRoleEnum -> CalculationAgentOptionalEarlyTermination - then product -> contractualProduct -> economicTerms -> terminationProvision -> earlyTerminationProvision -> optionalEarlyTermination -> calculationAgent -> calculationAgentParty exists + then product -> economicTerms -> terminationProvision -> earlyTerminationProvision -> optionalEarlyTermination -> calculationAgent -> calculationAgentParty exists condition CalculationAgentMandatoryEarlyTermination: - if product -> contractualProduct -> economicTerms -> terminationProvision -> earlyTerminationProvision -> mandatoryEarlyTermination -> calculationAgent -> calculationAgentParty exists + if product -> economicTerms -> terminationProvision -> earlyTerminationProvision -> mandatoryEarlyTermination -> calculationAgent -> calculationAgentParty exists then ancillaryParty -> role contains AncillaryRoleEnum -> CalculationAgentMandatoryEarlyTermination and if ancillaryParty -> role contains AncillaryRoleEnum -> CalculationAgentMandatoryEarlyTermination - then product -> contractualProduct -> economicTerms -> terminationProvision -> earlyTerminationProvision -> mandatoryEarlyTermination -> calculationAgent -> calculationAgentParty exists + then product -> economicTerms -> terminationProvision -> earlyTerminationProvision -> mandatoryEarlyTermination -> calculationAgent -> calculationAgentParty exists type ConstituentWeight: <"A class describing the weight of each of the underlier constituent within the basket, either in absolute or relative terms."> @@ -422,27 +439,20 @@ type ConstituentWeight: <"A class describing the weight of each of the underlier type ForwardPayout extends PayoutBase: <"Represents a forward settling payout. The underlier attribute captures the underlying payout, which is settled according to the settlementTerms attribute (which is part of PayoutBase). Both FX Spot and FX Forward should use this component."> [metadata key] - underlier Product (1..1) <"Underlying product that the forward is written on, which can be of any type: FX, a contractual product, a security, etc."> + productUnderlier ProductUnderlier (1..1) <"Underlying product that the forward is written on, which can be of any type: FX, a contractual product, a security, etc."> deliveryTerm string (0..1) <"Also called contract month or delivery month. However, it's not always a month. It is usually expressed using a code, e.g. Z23 would be the Dec 2023 contract, (Z = December). For crude oil, the corresponding contract might be called CLZ23."> delivery AssetDeliveryInformation (0..1) <"Contains the information relative to the delivery of the asset."> schedule CalculationSchedule (0..1) <"Allows the full representation of a payout by defining a set of schedule periods. It supports standard schedule customization by expressing all the dates, quantities, and pricing data in a non-parametric way."> - condition SettlementTerms: <"For foreign exchange contracts, the settlement terms must exist."> - if underlier -> foreignExchange exists - then settlementTerms exists - - condition SettlementDate: <"For foreign exchange contracts, either the settlementDate is set or the cashflowDates, but not both. When the cashflowDates are set, they must be the same for the 2 legs of the currency pair."> - if underlier -> foreignExchange exists + condition SettlementDate: <"For foreign exchange contracts, either the settlementDate is set or the cashflowDates, but not both."> + if productUnderlier -> Index -> ForeignExchangeRate exists then (settlementTerms -> settlementDate -> valueDate exists - and underlier -> foreignExchange -> exchangedCurrency1 -> settlementTerms -> settlementDate -> adjustableOrRelativeDate is absent - and underlier -> foreignExchange -> exchangedCurrency2 -> settlementTerms -> settlementDate -> adjustableOrRelativeDate is absent) - or (settlementTerms -> settlementDate -> valueDate is absent - and underlier -> foreignExchange -> exchangedCurrency1 -> settlementTerms -> settlementDate -> adjustableOrRelativeDate exists - and underlier -> foreignExchange -> exchangedCurrency2 -> settlementTerms -> settlementDate -> adjustableOrRelativeDate exists - and underlier -> foreignExchange -> exchangedCurrency1 -> settlementTerms -> settlementDate -> adjustableOrRelativeDate = underlier -> foreignExchange -> exchangedCurrency2 -> settlementTerms -> settlementDate -> adjustableOrRelativeDate) - - condition FxSettlement: <"For foreign exchange contracts, the settlement type must be either fx non-deliverable settlement or not specified, which implies physical settlement in the case of foreign exchange."> - if underlier -> foreignExchange exists + and settlementTerms -> settlementDate -> adjustableOrRelativeDate is absent ) + or (settlementTerms -> settlementDate -> valueDate is absent + and settlementTerms -> settlementDate -> adjustableOrRelativeDate exists) + + condition Settlement: <"For foreign exchange contracts, the settlement type must be either fx non-deliverable settlement or not specified, which implies physical settlement in the case of foreign exchange."> + if productUnderlier -> Index -> ForeignExchangeRate exists then settlementTerms -> physicalSettlementTerms is absent condition DeliveryCapacity: <"Checks that only one of the representations of delivery capacity is present simultaneously."> @@ -890,6 +900,7 @@ type AssetPayout extends PayoutBase: <"Security finance payout specification in [deprecated] minimumFee Money (0..1) <"A contractual minimum amount which the borrower will pay, regardless of the duration of the loan. A mechanism for making sure that a trade generates enough income."> dividendTerms DividendTerms (0..1) <"Specifies the terms under which dividends received by the borrower are passed through to the lender."> + repoType RepoTypeEnum (0..1) <"Repurchase transactions and buy/sell-backs are both types of repo; this enumerator helps differentiate the two."> condition Quantity: <"When there is an OptionPayout the quantity can be expressed as part of the payoutQuantity, or as part of the underlier in the case of a Swaption. For all other payouts that extend PayoutBase the payoutQuantity is a mandatory attribute."> priceQuantity exists From ebce2b5a507737e2a8d57f861d36b5180383fcd6 Mon Sep 17 00:00:00 2001 From: Lionel Smith-Gordon Date: Fri, 19 Jul 2024 17:21:37 +0000 Subject: [PATCH 2/5] Correction to Asset Payout and bring forward P2 changes --- .../rosetta/base-staticdata-asset-common-type.rosetta | 7 ++++++- rosetta-source/src/main/rosetta/event-common-func.rosetta | 4 ++-- .../src/main/rosetta/product-qualification-func.rosetta | 8 ++++---- .../src/main/rosetta/product-template-type.rosetta | 5 +---- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta b/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta index dce6827bd8..7431444022 100755 --- a/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta +++ b/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta @@ -25,8 +25,13 @@ type AssetBase: <"The base data type to specify common attributes for all Assets if exchange exists then isExchangeListed + condition RelatedExchange: <"Related Exchange should only be specified if an Exchange is also specified."> + if exchange is absent + then relatedExchange is absent + type AssetIdentifier: <"The unique identifier for an Asset, specified using an Asset Identifier Type enumerator."> identifier string (1..1) <"The identifier value."> + [metadata scheme] identifierType AssetIdTypeEnum (1..1) <"Defines the symbology source of the Asset Identifier, eg CUSIP, ISIN, etc."> type InstrumentBase extends AssetBase: <"Defines the common attributes for all Instrument data types."> @@ -121,7 +126,7 @@ type Cash extends AssetBase: <"An Asset that consists solely of a monetary holdi taxonomy is absent condition NoExchange: <"Cash cannot be a listed Asset."> - exchange is absent + exchange is absent and isExchangeListed is absent type Commodity extends AssetBase: <"Identifies a specific commodity by referencing a product identifier or by a product definition."> commodityProductDefinition CommodityProductDefinition (0..1) <"Specifies the commodity underlier in the event that no ISDA Commodity Reference Benchmark exists."> diff --git a/rosetta-source/src/main/rosetta/event-common-func.rosetta b/rosetta-source/src/main/rosetta/event-common-func.rosetta index efa88c5bf3..40134780f9 100644 --- a/rosetta-source/src/main/rosetta/event-common-func.rosetta +++ b/rosetta-source/src/main/rosetta/event-common-func.rosetta @@ -679,7 +679,7 @@ func Create_AssetTransfer: <"Defines how Transfer that represents an exchange of } add transfer -> asset -> Instrument -> Security -> identifier: - assetPayout -> securityInformation -> security -> identifier + assetPayout -> securityInformation -> identifier set transfer -> payerReceiver -> payerPartyReference: if instruction -> payerReceiver -> payer exists @@ -791,7 +791,7 @@ func SecurityFinanceCashSettlementAmount: then quantity -> unit -> financialUnit = FinancialUnitEnum -> Share condition IdentifiersMatch: - tradeState -> trade -> tradeLot -> priceQuantity -> observable -> asset ->> identifier = assetPayout -> securityInformation -> security -> identifier + tradeState -> trade -> tradeLot -> priceQuantity -> observable -> asset ->> identifier = assetPayout -> securityInformation -> identifier set cashSettlementAmount -> quantity -> value: securityPrice -> value * securityQuantity -> value * marginRatio diff --git a/rosetta-source/src/main/rosetta/product-qualification-func.rosetta b/rosetta-source/src/main/rosetta/product-qualification-func.rosetta index 11dd624179..80ae981851 100644 --- a/rosetta-source/src/main/rosetta/product-qualification-func.rosetta +++ b/rosetta-source/src/main/rosetta/product-qualification-func.rosetta @@ -1603,8 +1603,8 @@ func Qualify_RepurchaseAgreement: <"Qualifies a product as a Repurchase Agreemen set is_product: economicTerms -> payout -> interestRatePayout only exists and economicTerms -> payout -> interestRatePayout count = 1 - and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> economicTerms -> payout -> assetPayout only exists - and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> economicTerms -> payout -> assetPayout -> repoType all <> RepoTypeEnum -> BuySellBack + and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> NonTransferableProduct -> economicTerms -> payout -> assetPayout only exists + and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> NonTransferableProduct -> 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] @@ -1615,8 +1615,8 @@ func Qualify_BuySellBack: <"Qualifies a product as a Buy/Sell Back based on the set is_product: economicTerms -> payout -> interestRatePayout only exists and economicTerms -> payout -> interestRatePayout count = 1 - and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> economicTerms -> payout -> assetPayout only exists - and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> AssetUnderlier -> TransferableProduct -> economicTerms -> payout -> assetPayout -> repoType any = RepoTypeEnum -> BuySellBack + and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> NonTransferableProduct -> economicTerms -> payout -> assetPayout only exists + and economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product -> NonTransferableProduct -> 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] diff --git a/rosetta-source/src/main/rosetta/product-template-type.rosetta b/rosetta-source/src/main/rosetta/product-template-type.rosetta index b902e5fdff..01cf041ede 100644 --- a/rosetta-source/src/main/rosetta/product-template-type.rosetta +++ b/rosetta-source/src/main/rosetta/product-template-type.rosetta @@ -895,7 +895,7 @@ type AssetPayout extends PayoutBase: <"Security finance payout specification in [metadata key] assetLeg AssetLeg (1..*) <"Defines each asset movement as a buy/sell at different dates, typically 1 near leg and 1 far leg in a securities financing transaction."> - securityInformation Product (1..1) <"Specifies the Purchased Security. Within SecurityPayout we include a condition which validates that the product must be a Security (see below condition 'ProductMustBeSecurity')."> + securityInformation Security (1..1) <"Specifies the Purchased Security."> durationType Duration (1..1) <"Specifies the Duration Terms of the Security Finance transaction. e.g. Open or Term."> [deprecated] minimumFee Money (0..1) <"A contractual minimum amount which the borrower will pay, regardless of the duration of the loan. A mechanism for making sure that a trade generates enough income."> @@ -905,9 +905,6 @@ type AssetPayout extends PayoutBase: <"Security finance payout specification in condition Quantity: <"When there is an OptionPayout the quantity can be expressed as part of the payoutQuantity, or as part of the underlier in the case of a Swaption. For all other payouts that extend PayoutBase the payoutQuantity is a mandatory attribute."> priceQuantity exists - condition ProductMustBeSecurity: <"Validates that the Purchased Security must be a security."> - securityInformation -> security exists - condition DividendTermsValidation: <"Validates that if the transaction has Dividend Terms specified then the Duration should be Term."> if dividendTerms exists then durationType -> durationType = DurationTypeEnum -> Term From f8f52bfac234f2d16014690da902078b1e924ec6 Mon Sep 17 00:00:00 2001 From: Lionel Smith-Gordon Date: Mon, 22 Jul 2024 10:39:30 +0000 Subject: [PATCH 3/5] Refactoring of Index and FRO FloatingRateOption collapsed into new Index structure --- .../base-staticdata-asset-common-type.rosetta | 7 +- .../main/rosetta/event-common-func.rosetta | 26 +++---- .../main/rosetta/event-common-type.rosetta | 2 +- .../rosetta/event-qualification-func.rosetta | 4 +- ...ml-confirmation-tradestate-synonym.rosetta | 10 +-- ...servable-asset-calculatedrate-func.rosetta | 3 +- .../rosetta/observable-asset-fro-func.rosetta | 5 +- .../rosetta/observable-asset-type.rosetta | 31 +-------- .../product-asset-calculation-func.rosetta | 2 +- .../product-asset-floatingrate-func.rosetta | 28 ++++---- .../main/rosetta/product-asset-func.rosetta | 2 +- .../main/rosetta/product-asset-type.rosetta | 23 ++++--- .../product-common-settlement-func.rosetta | 2 +- .../product-qualification-func.rosetta | 68 +++++++++---------- .../rosetta/product-template-type.rosetta | 6 +- 15 files changed, 97 insertions(+), 122 deletions(-) diff --git a/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta b/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta index 7431444022..d66a46d8dc 100755 --- a/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta +++ b/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta @@ -24,10 +24,7 @@ type AssetBase: <"The base data type to specify common attributes for all Assets condition ExchangeListed: <"If Exchange is specified, it must be an exchange-listed Instrument."> if exchange exists then isExchangeListed - - condition RelatedExchange: <"Related Exchange should only be specified if an Exchange is also specified."> - if exchange is absent - then relatedExchange is absent + else relatedExchange is absent type AssetIdentifier: <"The unique identifier for an Asset, specified using an Asset Identifier Type enumerator."> identifier string (1..1) <"The identifier value."> @@ -111,7 +108,7 @@ choice Index: <"An Index is an Observable which is computed based on the prices, CreditIndex <"An index based on credit risk, typically composed using corporate debt instruments in a region or industry sector, e.g. the iTraxx indices."> EquityIndex <"An index based on equity securities, e.g. the S&P 500."> FloatingRateIndex <"An interest rate index which can change over time, e.g. the SONIA (Sterling Overnight Index Average) in the UK."> - ForeignExchangeRate <"A rate based on the exchange of a pair of cash assets in specific currencies, e.g. USD versus GBP."> + ForeignExchangeRateIndex <"A rate based on the exchange of a pair of cash assets in specific currencies, e.g. USD versus GBP."> InflationIndex <"An index that measures inflation in a specific market, e.g. the US Consumer Price Index."> OtherIndex <"An index created by a market participant which doesn't align with the other index types."> diff --git a/rosetta-source/src/main/rosetta/event-common-func.rosetta b/rosetta-source/src/main/rosetta/event-common-func.rosetta index 40134780f9..4936b6d167 100644 --- a/rosetta-source/src/main/rosetta/event-common-func.rosetta +++ b/rosetta-source/src/main/rosetta/event-common-func.rosetta @@ -128,8 +128,8 @@ func ResolveInterestRateObservationIdentifiers: <"Defines which attributes on th output: identifiers ObservationIdentifier (1..1) - set identifiers -> observable -> rateOption: - payout -> rateSpecification -> floatingRate -> rateOption + set identifiers -> observable -> index: + payout -> rateSpecification -> FloatingRateSpecification -> rateOption set identifiers -> observationDate: date // ResolveInterestRateReset is similar to ResolveEquityReset as they both only support the basic use cases for reset. Once support is added for stub periods and thus rate interpolation, the formula to derive the reset value will start to look different between the functions. @@ -159,14 +159,14 @@ func InterestCashSettlementAmount: <"Defines the performance calculations releve interestCashSettlementAmount Transfer (1..1) alias performance: - if interestRatePayout -> rateSpecification -> fixedRate exists + if interestRatePayout -> rateSpecification -> FixedRateSpecification exists then FixedAmount( interestRatePayout, interestRatePayout -> priceQuantity -> quantitySchedule -> value, date, empty ) - else if interestRatePayout -> rateSpecification -> floatingRate exists + else if interestRatePayout -> rateSpecification -> FloatingRateSpecification exists then FloatingAmount( interestRatePayout, resets only-element -> resetValue -> value, @@ -728,8 +728,8 @@ func ResolveTransfer: <"Defines how to calculate the amount due to be transferre ) else if payout -> performancePayout exists then EquityCashSettlementAmount(instruction -> tradeState, instruction -> date) - else if payout -> interestRatePayout -> rateSpecification -> floatingRate exists - or payout -> interestRatePayout -> rateSpecification -> fixedRate exists + else if payout -> interestRatePayout -> rateSpecification -> FloatingRateSpecification exists + or payout -> interestRatePayout -> rateSpecification -> FixedRateSpecification exists then InterestCashSettlementAmount( instruction -> tradeState, payout -> interestRatePayout only-element, @@ -1145,10 +1145,10 @@ func UpdateIndexTransitionPriceAndRateOption: then priceQuantity -> price only-element -> value + instruction -> price only-element -> value else priceQuantity -> price only-element -> value - set updatedPriceQuantity -> observable -> rateOption: <"If instruction exists, update the rate option."> + set updatedPriceQuantity -> observable -> index: <"If instruction exists, update the rate option."> if instruction exists - then instruction -> observable -> rateOption - else priceQuantity -> observable -> rateOption + then instruction -> observable -> index + else priceQuantity -> observable -> index func FindMatchingIndexTransitionInstruction: inputs: @@ -1161,9 +1161,9 @@ func FindMatchingIndexTransitionInstruction: instructions filter // indexTenor period matches - observable -> rateOption -> indexTenor -> period = priceQuantity -> observable -> rateOption -> indexTenor -> period + observable -> index -> FloatingRateIndex -> indexTenor -> period = priceQuantity -> observable -> index -> FloatingRateIndex -> indexTenor -> period // indexTenor periodMultiplier matches - and observable -> rateOption -> indexTenor -> periodMultiplier = priceQuantity -> observable -> rateOption -> indexTenor -> periodMultiplier + and observable -> index -> FloatingRateIndex -> indexTenor -> periodMultiplier = priceQuantity -> observable -> index -> FloatingRateIndex -> indexTenor -> periodMultiplier // quantity currency or price currency matches and (quantity -> unit -> currency = priceQuantity -> quantity -> unit -> currency or price -> unit -> currency = priceQuantity -> price -> unit -> currency) @@ -1266,14 +1266,14 @@ func ResolveSecurityFinanceBillingAmount: <"Calculates the billing amount for a CalculationPeriodRange(recordStartDate, recordEndDate, empty) alias performance: - if interestRatePayout -> rateSpecification -> fixedRate exists + if interestRatePayout -> rateSpecification -> FixedRateSpecification exists then FixedAmount( interestRatePayout, billingQuantity, recordEndDate, calculationPeriodRange ) - else if interestRatePayout -> rateSpecification -> floatingRate exists + else if interestRatePayout -> rateSpecification -> FloatingRateSpecification exists then FloatingAmount( interestRatePayout, reset -> resetValue -> value, diff --git a/rosetta-source/src/main/rosetta/event-common-type.rosetta b/rosetta-source/src/main/rosetta/event-common-type.rosetta index 917e82352c..c6bb360717 100644 --- a/rosetta-source/src/main/rosetta/event-common-type.rosetta +++ b/rosetta-source/src/main/rosetta/event-common-type.rosetta @@ -139,7 +139,7 @@ type IndexTransitionInstruction: <"Defines the information needed to create a In condition PriceQuantity: priceQuantity -> price -> priceType contains PriceTypeEnum -> InterestRate - and priceQuantity -> observable -> rateOption exists + and priceQuantity -> observable -> index exists and priceQuantity -> quantity is absent type TermsChangeInstruction: <"Specifies instructions for terms change consisting of the new transaction terms, and the renegotiation fee."> diff --git a/rosetta-source/src/main/rosetta/event-qualification-func.rosetta b/rosetta-source/src/main/rosetta/event-qualification-func.rosetta index 541a260e50..a69b0bc665 100644 --- a/rosetta-source/src/main/rosetta/event-qualification-func.rosetta +++ b/rosetta-source/src/main/rosetta/event-qualification-func.rosetta @@ -430,8 +430,8 @@ func Qualify_IndexTransition: <"The qualification of an index transition event b alias before: businessEvent -> instruction -> before -> trade alias floatingRateIndexChanged: - before -> tradeLot -> priceQuantity -> observable -> rateOption -> floatingRateIndex exists - and before -> tradeLot -> priceQuantity -> observable -> rateOption -> floatingRateIndex disjoint after -> tradeLot -> priceQuantity -> observable -> rateOption -> floatingRateIndex + before -> tradeLot -> priceQuantity -> observable -> index -> FloatingRateIndex exists + and before -> tradeLot -> priceQuantity -> observable -> index -> FloatingRateIndex disjoint after -> tradeLot -> priceQuantity -> observable -> index -> FloatingRateIndex alias spread: FilterPrice( diff --git a/rosetta-source/src/main/rosetta/mapping-fpml-confirmation-tradestate-synonym.rosetta b/rosetta-source/src/main/rosetta/mapping-fpml-confirmation-tradestate-synonym.rosetta index 37287f9f03..501be231cf 100644 --- a/rosetta-source/src/main/rosetta/mapping-fpml-confirmation-tradestate-synonym.rosetta +++ b/rosetta-source/src/main/rosetta/mapping-fpml-confirmation-tradestate-synonym.rosetta @@ -381,11 +381,13 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML + splitTicket [value "splitTicket"] - FloatingRateOption: - + floatingRateIndex + Index: + + FloatingRateIndex [value "floatingRateIndex" maps 2 meta "floatingRateIndexScheme"] - + inflationRateIndex + + InflationIndex [value "floatingRateIndex" maps 2 meta "floatingRateIndexScheme"] + + FloatingRateIndex: + indexTenor [value "indexTenor" maps 2] @@ -1179,7 +1181,7 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML + averagingStrikeFeature [value "FxAverageStrike"] - FxRateObservable: + ForeignExchangeRateIndex: + quotedCurrencyPair [value "quotedCurrencyPair" meta "quoteBasis"] [meta "rateObservationQuoteBasis"] diff --git a/rosetta-source/src/main/rosetta/observable-asset-calculatedrate-func.rosetta b/rosetta-source/src/main/rosetta/observable-asset-calculatedrate-func.rosetta index 77402df0ad..07dc65b6b2 100644 --- a/rosetta-source/src/main/rosetta/observable-asset-calculatedrate-func.rosetta +++ b/rosetta-source/src/main/rosetta/observable-asset-calculatedrate-func.rosetta @@ -4,6 +4,7 @@ version "${project.version}" import cdm.base.math.* import cdm.base.datetime.* import cdm.base.datetime.daycount.* +import cdm.base.staticdata.asset.common.* import cdm.observable.asset.* @@ -22,7 +23,7 @@ import cdm.observable.asset.fro.* // ====================================================================== func EvaluateCalculatedRate: <"Evaluate a calculated rate as described in the 2021 ISDA Definitions."> inputs: - floatingRateOption FloatingRateOption (1..1) <"The base floating rate inde."> + floatingRateOption Index (1..1) <"The base floating rate index."> calculationParameters FloatingRateCalculationParameters (1..1) <"Floating rate definition for the calculated rate."> resetDates ResetDates (0..1) <"Reset structure (needed only for fallback rates, otherwise will be empty)."> calculationPeriod CalculationPeriodBase (1..1) <"Calculation period for which we want to determine the rate."> diff --git a/rosetta-source/src/main/rosetta/observable-asset-fro-func.rosetta b/rosetta-source/src/main/rosetta/observable-asset-fro-func.rosetta index ba508209ac..2d5e4f31a8 100644 --- a/rosetta-source/src/main/rosetta/observable-asset-fro-func.rosetta +++ b/rosetta-source/src/main/rosetta/observable-asset-fro-func.rosetta @@ -2,6 +2,7 @@ namespace cdm.observable.asset.fro : <"Support for floating rate option definiti version "${project.version}" import cdm.base.staticdata.asset.rates.* +import cdm.base.staticdata.asset.common.* import cdm.observable.asset.* @@ -17,14 +18,14 @@ func IndexValueObservation: <"Retrieve the values of the supplied index on the s // data provider - implementation provides observed value from data source inputs: observationDate date (1..1) - floatingRateOption FloatingRateOption (1..1) + floatingRateOption Index (1..1) output: observedValue number (1..1) func IndexValueObservationMultiple: <"Retrieve the values of the supplied index on the specified observation dates."> inputs: observationDate date (0..*) - floatingRateOption FloatingRateOption (1..1) + floatingRateOption Index (1..1) output: observedValues number (0..*) diff --git a/rosetta-source/src/main/rosetta/observable-asset-type.rosetta b/rosetta-source/src/main/rosetta/observable-asset-type.rosetta index 24c5358378..19ae56ffac 100644 --- a/rosetta-source/src/main/rosetta/observable-asset-type.rosetta +++ b/rosetta-source/src/main/rosetta/observable-asset-type.rosetta @@ -22,7 +22,7 @@ type FloatingRateIndex extends IndexBase: <"Specification of an interest rate i condition InterestRateAssetClass: <"The asset class must be Interest Rate."> assetClass = AssetClassEnum -> InterestRate -type ForeignExchangeRate extends IndexBase: <"Specification of a rate based on the exchange of a pair of cash assets in specific currencies, e.g. USD versus GBP."> +type ForeignExchangeRateIndex extends IndexBase: <"Specification of a rate based on the exchange of a pair of cash assets in specific currencies, e.g. USD versus GBP."> quotedCurrencyPair QuotedCurrencyPair (1..1) <"Describes the composition of a rate that has been quoted or is to be quoted."> primaryFxSpotRateSource InformationSource (1..1) <"Specifies the primary source from which a rate should be observed."> secondaryFxSpotRateSource InformationSource (0..1) <"Specifies an alternative, or secondary, source from which a rate should be observed."> @@ -169,14 +169,8 @@ type Observable: <"Specifies the object to be observed for a price, it could be asset Asset (0..1) <"The object to be observed is an Asset, ie something that can be owned and transferred in the financial markets."> basket Basket (0..1) <"The object to be observed is a Basket, ie a collection of Observables with an identifier and optional weightings."> index Index (0..1) <"The object to be observed is an Index, ie an observable computed on the prices, rates or valuations of a number of assets."> - - //**ART** Will remove ProductIdentifier and map to Asset in Phase 3 - productIdentifier ProductIdentifier (0..*) <"Comprises an identifier and a source of a Product."> - [metadata location] - //**ART** Will remove rateOption and map to Index in Phase 3 - rateOption FloatingRateOption (0..1) <"Specifies a floating rate index and tenor."> [metadata location] - + condition: one-of type Basket extends AssetBase: <"Defines a custom basket by referencing an identifier and its constituents."> @@ -207,12 +201,6 @@ type Money extends Quantity: <"Defines a monetary amount in a specified currency condition CurrencyUnitExists: unit -> currency exists -type FxRateObservable: <"Defines foreign exchange (FX) asset class specific parameters for market observations."> - [deprecated] - quotedCurrencyPair QuotedCurrencyPair (1..1) <"Describes the composition of a rate that has been quoted or is to be quoted."> - primaryFxSpotRateSource InformationSource (1..1) <"Specifies the primary source from which a rate should be observed."> - secondaryFxSpotRateSource InformationSource (0..1) <"Specifies an alternative, or secondary, source from which a rate should be observed."> - type QuotedCurrencyPair: <"A class that describes the composition of a rate that has been quoted or is to be quoted. This includes the two currencies and the quotation relationship between the two currencies and is used as a building block throughout the FX specification."> currency1 string (1..1) <"The first currency specified when a pair of currencies is to be evaluated."> @@ -305,21 +293,6 @@ type ValuationPostponement: <"Specifies how long to wait to get a quote from a s maximumDaysOfPostponement int (1..1) <"The maximum number of days to wait for a quote from the disrupted settlement rate option before proceeding to the next method."> -type FloatingRateOption: <"Specification of a floating rate option as a floating rate index and tenor."> - floatingRateIndex FloatingRateIndexEnum (0..1) <"The reference index that is used to specify the floating interest rate. The FpML standard maintains the list of such indices, which are positioned as enumeration values as part of the CDM."> - [metadata scheme] - inflationRateIndex InflationRateIndexEnum (0..1) <"The reference index that is used to specify the inflation interest rate. The FpML standard maintains the list of such indices, which are positioned as enumeration values as part of the CDM."> - [metadata scheme] - indexTenor Period (0..1) <"The ISDA Designated Maturity, i.e. the floating rate tenor."> - indexReferenceInformation IndexReferenceInformation (0..1) <"This Attribute contains all the terms relevant to defining an Index."> - - condition FloatingRateIndex: <"floating rate and inflation rate index are mutually exclusive"> - optional choice floatingRateIndex, inflationRateIndex - - condition IndexRefInfo: <"If both floating rate and inflation rate index are absent, then indexReferenceInformation is required"> - if floatingRateIndex is absent and inflationRateIndex is absent - then indexReferenceInformation exists - type FxRate: <"A class describing the rate of a currency conversion: pair of currency, quotation mode and exchange rate."> quotedCurrencyPair QuotedCurrencyPair (1..1) <"Defines the two currencies for an FX trade and the quotation relationship between the two currencies."> diff --git a/rosetta-source/src/main/rosetta/product-asset-calculation-func.rosetta b/rosetta-source/src/main/rosetta/product-asset-calculation-func.rosetta index 608409e61a..ae87d89aa4 100644 --- a/rosetta-source/src/main/rosetta/product-asset-calculation-func.rosetta +++ b/rosetta-source/src/main/rosetta/product-asset-calculation-func.rosetta @@ -54,7 +54,7 @@ func GetFixedRate: <"Look up the fixed rate for a calculation period."> set fixedRate: GetRateScheduleAmount( - interestRatePayout -> rateSpecification -> fixedRate -> rateSchedule, + interestRatePayout -> rateSpecification -> FixedRateSpecification -> rateSchedule, calculationPeriod -> adjustedStartDate ) diff --git a/rosetta-source/src/main/rosetta/product-asset-floatingrate-func.rosetta b/rosetta-source/src/main/rosetta/product-asset-floatingrate-func.rosetta index 15351f3ea5..597e81197a 100644 --- a/rosetta-source/src/main/rosetta/product-asset-floatingrate-func.rosetta +++ b/rosetta-source/src/main/rosetta/product-asset-floatingrate-func.rosetta @@ -22,7 +22,7 @@ func DetermineFloatingRateReset: <"Get the value of a floating rate by either ob floatingRate FloatingRateSettingDetails (1..1) <"Details of the rate observation/calculation corresonding to the supplied rate definition and calculation period."> // figure out the characteristics of the rate - alias rateDef: interestRatePayout -> rateSpecification -> floatingRate + alias rateDef: interestRatePayout -> rateSpecification -> FloatingRateSpecification alias processingType: GetFloatingRateProcessingType(rateDef) // get a processing category that will be used to dermine how to process the rate, based on the rate category, style, and calculation method // perform the relevant operation (look up a term rate or do the rate calculation for a calculated rate) set floatingRate: @@ -38,7 +38,7 @@ func GetFloatingRateProcessingType: <"Get a classification of the floating rate alias isCalculatedRate: rateDef -> calculationParameters exists // look up the floating rate option definition from the metadata alias floatingRateDefinition: - FloatingRateIndexMetadata(rateDef -> rateOption -> floatingRateIndex) + FloatingRateIndexMetadata(rateDef -> rateOption -> FloatingRateIndex -> floatingRateIndex) alias calcDefaults: floatingRateDefinition -> calculationDefaults alias category: calcDefaults -> category alias idxStyle: calcDefaults -> indexStyle @@ -80,13 +80,13 @@ func ProcessFloatingRateReset(processingType: FloatingRateIndexProcessingTypeEnu [calculation] // set up convenience aliases alias resetDates: interestRatePayout -> resetDates - alias rateDef: interestRatePayout -> rateSpecification -> floatingRate + alias rateDef: interestRatePayout -> rateSpecification -> FloatingRateSpecification set floatingRate: EvaluateScreenRate(rateDef, resetDates, calcPeriod) // Call the screen rate evaluation logic func ProcessFloatingRateReset(processingType: FloatingRateIndexProcessingTypeEnum -> Modular): <"Evaluate the rate for a modular calculated rate. Call the calculated rate calculation logic to determine the value of the reset."> [calculation] // set up convenience aliases - alias rateDef: interestRatePayout -> rateSpecification -> floatingRate + alias rateDef: interestRatePayout -> rateSpecification -> FloatingRateSpecification alias resetDates: interestRatePayout -> resetDates alias dayCount: interestRatePayout -> dayCountFraction alias fro: rateDef -> rateOption @@ -115,7 +115,7 @@ func ProcessFloatingRateReset(processingType: FloatingRateIndexProcessingTypeEnu func ProcessFloatingRateReset(processingType: FloatingRateIndexProcessingTypeEnum -> OIS): <"Evaluate the rate for an OIS calculated rate. Call the calculated rate calculation logic to determine the value of the reset. See the 2021 ISDA Definitions Section 6.6.3."> [calculation] // set up convenience aliases - alias rateDef: interestRatePayout -> rateSpecification -> floatingRate + alias rateDef: interestRatePayout -> rateSpecification -> FloatingRateSpecification alias resetDates: interestRatePayout -> resetDates alias dayCount: interestRatePayout -> dayCountFraction alias fro: rateDef -> rateOption @@ -140,7 +140,7 @@ func ProcessFloatingRateReset(processingType: FloatingRateIndexProcessingTypeEnu func ProcessFloatingRateReset(processingType: FloatingRateIndexProcessingTypeEnum -> OvernightAvg): <"Evaluate the rate for a daily average calculated FRO. Call the calculated rate calculation logic to determine the value of the reset. See the 2021 ISDA Definitions Section 6.6.3."> [calculation] // set up convenience aliases - alias rateDef: interestRatePayout -> rateSpecification -> floatingRate + alias rateDef: interestRatePayout -> rateSpecification -> FloatingRateSpecification alias resetDates: interestRatePayout -> resetDates alias dayCount: interestRatePayout -> dayCountFraction alias rateOption: rateDef -> rateOption @@ -254,14 +254,14 @@ func GetFloatingRateProcessingParameters: <"Determine the processing parameters alias floor: FloorRateAmount(interestRatePayout, calculationPeriod) alias rounding: - interestRatePayout -> rateSpecification -> floatingRate -> finalRateRounding + interestRatePayout -> rateSpecification -> FloatingRateSpecification -> finalRateRounding alias negativeTreatment: - interestRatePayout -> rateSpecification -> floatingRate -> negativeInterestRateTreatment + interestRatePayout -> rateSpecification -> FloatingRateSpecification -> negativeInterestRateTreatment alias treatment: - interestRatePayout -> rateSpecification -> floatingRate -> rateTreatment + interestRatePayout -> rateSpecification -> FloatingRateSpecification -> rateTreatment set processingParameters -> initialRate: - interestRatePayout -> rateSpecification -> floatingRate -> initialRate + interestRatePayout -> rateSpecification -> FloatingRateSpecification -> initialRate set processingParameters -> spread: spreadRate set processingParameters -> multiplier: multiplier set processingParameters -> treatment: treatment @@ -280,7 +280,7 @@ func SpreadAmount: <"Look up the spread amount for a calculation period."> set spread: GetRateScheduleAmount( - interestRatePayout -> rateSpecification -> floatingRate -> spreadSchedule, + interestRatePayout -> rateSpecification -> FloatingRateSpecification -> spreadSchedule, calculationPeriod -> adjustedStartDate ) @@ -294,7 +294,7 @@ func MultiplierAmount: <"Look up the multiplier amount for a calculation period. set multiplier: GetRateScheduleAmount( - interestRatePayout -> rateSpecification -> floatingRate -> floatingRateMultiplierSchedule, + interestRatePayout -> rateSpecification -> FloatingRateSpecification -> floatingRateMultiplierSchedule, calculationPeriod -> adjustedStartDate ) @@ -308,7 +308,7 @@ func CapRateAmount: <"Look up the cap rate amount for a calculation period."> set capRate: <"Look up and return the rate for the period start date."> GetRateScheduleAmount( - interestRatePayout -> rateSpecification -> floatingRate -> capRateSchedule, + interestRatePayout -> rateSpecification -> FloatingRateSpecification -> capRateSchedule, calculationPeriod -> adjustedStartDate ) @@ -322,7 +322,7 @@ func FloorRateAmount: <"Look up the floor rate amount for a calculation period." set floorRate: <"Look up and return the rate for the period start date."> GetRateScheduleAmount( - interestRatePayout -> rateSpecification -> floatingRate -> floorRateSchedule, + interestRatePayout -> rateSpecification -> FloatingRateSpecification -> floorRateSchedule, calculationPeriod -> adjustedStartDate ) diff --git a/rosetta-source/src/main/rosetta/product-asset-func.rosetta b/rosetta-source/src/main/rosetta/product-asset-func.rosetta index 8ca31186a8..ebfc25a2e1 100644 --- a/rosetta-source/src/main/rosetta/product-asset-func.rosetta +++ b/rosetta-source/src/main/rosetta/product-asset-func.rosetta @@ -119,5 +119,5 @@ func ExtractFixedLeg: <"Extract interest rate payout containing fix rate specifi set fixedRatePayout: interestRatePayouts - filter rateSpecification -> fixedRate exists + filter rateSpecification -> FixedRateSpecification exists then only-element diff --git a/rosetta-source/src/main/rosetta/product-asset-type.rosetta b/rosetta-source/src/main/rosetta/product-asset-type.rosetta index e8b0743ab2..57197166c3 100644 --- a/rosetta-source/src/main/rosetta/product-asset-type.rosetta +++ b/rosetta-source/src/main/rosetta/product-asset-type.rosetta @@ -159,7 +159,7 @@ type InterestRatePayout extends PayoutBase: <" A class to specify all of the ter optional choice paymentDates, paymentDate condition FutureValueNotional: <"The BRL CDI future value notional only applies to a fixed Rate Schedule."> - if rateSpecification -> fixedRate is absent + if rateSpecification -> FixedRateSpecification is absent then priceQuantity -> futureValueNotional is absent condition TerminationDate: <"FpML states that the value date associated with the future value notional should match the adjusted termination date."> @@ -213,20 +213,18 @@ type InterestRatePayout extends PayoutBase: <" A class to specify all of the ter condition FpML_ird_29: <"FpML validation rule ird-29 - If compoundingMethod exists, then fixedRateSchedule must not exist."> if compoundingMethod exists - then rateSpecification -> fixedRate is absent + then rateSpecification -> FixedRateSpecification is absent condition CalculationPeriodDatesFirstCompoundingPeriodEndDate: <"FpML specifies that the firstCompoundingPeriodEndDate must only be specified when the compounding method is specified and not equal to a value of None."> if compoundingMethod is absent or compoundingMethod = CompoundingMethodEnum -> None then calculationPeriodDates -> firstCompoundingPeriodEndDate is absent -type RateSpecification: <" A class to specify the fixed interest rate, floating interest rate or inflation rate."> - - fixedRate FixedRateSpecification (0..1) <"The fixed rate or fixed rate specification expressed as explicit fixed rates and dates."> - floatingRate FloatingRateSpecification (0..1) <"The floating interest rate specification, which includes the definition of the floating rate index. the tenor, the initial value, and, when applicable, the spread, the rounding convention, the averaging method and the negative interest rate treatment."> - inflationRate InflationRateSpecification (0..1) <"An inflation rate calculation definition."> - condition: - one-of +choice RateSpecification: <" A data type to specify the fixed interest rate, floating interest rate or inflation rate."> + FixedRateSpecification <"The fixed rate or fixed rate specification expressed as explicit fixed rates and dates."> + FloatingRateSpecification <"The floating interest rate specification, which includes the definition of the floating rate index. the tenor, the initial value, and, when applicable, the spread, the rounding convention, the averaging method and the negative interest rate treatment."> + InflationRateSpecification <"An inflation rate calculation definition."> + type DividendPayoutRatio: <"A class describing the dividend payout ratio associated with an equity underlier. In certain cases the actual ratio is not known on trade inception, and only general conditions are then specified."> totalRatio number (1..1) <"Specifies the total actual dividend payout ratio associated with the equity underlier. A ratio of 90% should be expressed at 0.90."> @@ -690,12 +688,15 @@ type InflationRateSpecification extends FloatingRateSpecification: <"A data to: type FloatingRateBase: <"A class defining a floating interest rate through the specification of the floating rate index, the tenor, the multiplier schedule, the spread, the qualification of whether a specific rate treatment and/or a cap or floor apply."> [metadata key] - rateOption FloatingRateOption (0..1) - [metadata address "pointsTo"=Observable->rateOption] + rateOption Index (0..1) + [metadata address "pointsTo"=Observable->index] spreadSchedule SpreadSchedule (0..1) <"The ISDA Spread or a Spread schedule expressed as explicit spreads and dates. In the case of a schedule, the step dates may be subject to adjustment in accordance with any adjustments specified in calculationPeriodDatesAdjustments. The spread is a per annum rate, expressed as a decimal. For purposes of determining a calculation period amount, if positive the spread will be added to the floating rate and if negative the spread will be subtracted from the floating rate. A positive 10 basis point (0.1%) spread would be represented as 0.001."> capRateSchedule StrikeSchedule (0..1) <"The cap rate or cap rate schedule, if any, which applies to the floating rate. The cap rate (strike) is only required where the floating rate on a swap stream is capped at a certain level. A cap rate schedule is expressed as explicit cap rates and dates and the step dates may be subject to adjustment in accordance with any adjustments specified in calculationPeriodDatesAdjustments. The cap rate is assumed to be exclusive of any spread and is a per annum rate, expressed as a decimal. A cap rate of 5% would be represented as 0.05."> floorRateSchedule StrikeSchedule (0..1) <"The floor rate or floor rate schedule, if any, which applies to the floating rate. The floor rate (strike) is only required where the floating rate on a swap stream is floored at a certain strike level. A floor rate schedule is expressed as explicit floor rates and dates and the step dates may be subject to adjustment in accordance with any adjustments specified in calculationPeriodDatesAdjustments. The floor rate is assumed to be exclusive of any spread and is a per annum rate, expressed as a decimal. A floor rate of 5% would be represented as 0.05."> + condition FloatingRate: + rateOption -> FloatingRateIndex exists + type FloatingRate extends FloatingRateBase: floatingRateMultiplierSchedule RateSchedule (0..1) <"A rate multiplier or multiplier schedule to apply to the floating rate. A multiplier schedule is expressed as explicit multipliers and dates. In the case of a schedule, the step dates may be subject to adjustment in accordance with any adjustments specified in the calculationPeriodDatesAdjustments. The multiplier can be a positive or negative decimal. This element should only be included if the multiplier is not equal to 1 (one) for the term of the stream."> rateTreatment RateTreatmentEnum (0..1) <"The specification of any rate conversion which needs to be applied to the observed rate before being used in any calculations. The two common conversions are for securities quoted on a bank discount basis which will need to be converted to either a Money Market Yield or Bond Equivalent Yield. See the Annex to the 2000 ISDA Definitions, Section 7.3. Certain General Definitions Relating to Floating Rate Options, paragraphs (g) and (h) for definitions of these terms."> diff --git a/rosetta-source/src/main/rosetta/product-common-settlement-func.rosetta b/rosetta-source/src/main/rosetta/product-common-settlement-func.rosetta index 01d803d661..14f656ddd5 100644 --- a/rosetta-source/src/main/rosetta/product-common-settlement-func.rosetta +++ b/rosetta-source/src/main/rosetta/product-common-settlement-func.rosetta @@ -27,7 +27,7 @@ func RateOptionObservableCondition: <"Implementation for PriceQuantity.RateOptio valid boolean (0..1) set valid: - if pq -> observable -> rateOption exists and pq -> price exists + if pq -> observable -> index exists and pq -> price exists then pq -> price extract [ priceType = PriceTypeEnum -> InterestRate and arithmeticOperator exists diff --git a/rosetta-source/src/main/rosetta/product-qualification-func.rosetta b/rosetta-source/src/main/rosetta/product-qualification-func.rosetta index 80ae981851..a9acbb6454 100644 --- a/rosetta-source/src/main/rosetta/product-qualification-func.rosetta +++ b/rosetta-source/src/main/rosetta/product-qualification-func.rosetta @@ -116,9 +116,9 @@ func Qualify_AssetClass_ForeignExchange: <"Qualifies a product as having the Ass economicTerms -> payout -> forwardPayout only-element -> productUnderlier set is_product: - economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate exists - or economicTerms -> payout -> optionPayout -> productUnderlier -> Index -> ForeignExchangeRate exists - or economicTerms -> payout -> performancePayout -> observationTerms -> observable -> index -> ForeignExchangeRate exists + economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRateIndex exists + or economicTerms -> payout -> optionPayout -> productUnderlier -> Index -> ForeignExchangeRateIndex exists + or economicTerms -> payout -> performancePayout -> observationTerms -> observable -> index -> ForeignExchangeRateIndex exists or (economicTerms -> payout -> optionPayout only exists and (ProductUnderlierQualification(optionUnderlier, empty, AssetClassEnum -> ForeignExchange) or if optionUnderlier -> TransferableProduct exists @@ -974,7 +974,7 @@ func Qualify_BaseProduct_IRSwap: <"Qualifies a product as having the Base Produc and economicTerms -> payout -> interestRatePayout count = 2 and economicTerms -> payout -> interestRatePayout -> paymentDates count = 2 and Qualify_BaseProduct_CrossCurrency(economicTerms) = False - and economicTerms -> payout -> interestRatePayout -> rateSpecification -> inflationRate is absent + and economicTerms -> payout -> interestRatePayout -> rateSpecification -> InflationRateSpecification is absent func Qualify_BaseProduct_CrossCurrency: <"Qualifies a product as having the Base Product classification Cross Currency."> inputs: @@ -1000,7 +1000,7 @@ func Qualify_BaseProduct_Fra: <"Qualifies a product as having the Base Product c Qualify_AssetClass_InterestRate(economicTerms) = True and economicTerms -> payout -> interestRatePayout count = 2 and economicTerms -> payout -> interestRatePayout -> paymentDate count = 2 - and economicTerms -> payout -> interestRatePayout -> rateSpecification -> inflationRate is absent + and economicTerms -> payout -> interestRatePayout -> rateSpecification -> InflationRateSpecification is absent func Qualify_BaseProduct_Inflation: <"Qualifies a product as having the Base Product classification Inflation Swap"> inputs: @@ -1011,7 +1011,7 @@ func Qualify_BaseProduct_Inflation: <"Qualifies a product as having the Base Pro Qualify_AssetClass_InterestRate(economicTerms) = True and economicTerms -> payout -> interestRatePayout count = 2 and economicTerms -> payout -> interestRatePayout -> paymentDates count = 2 - and economicTerms -> payout -> interestRatePayout -> rateSpecification -> inflationRate exists + and economicTerms -> payout -> interestRatePayout -> rateSpecification -> InflationRateSpecification exists func Qualify_SubProduct_FixedFloat: <"Qualifies a product as having the Sub Product classification Fixed Float"> inputs: @@ -1020,12 +1020,12 @@ func Qualify_SubProduct_FixedFloat: <"Qualifies a product as having the Sub Prod is_product boolean (1..1) set is_product: - (economicTerms -> payout -> interestRatePayout -> rateSpecification -> fixedRate count = 1 - and economicTerms -> payout -> interestRatePayout -> rateSpecification -> floatingRate count = 1) - or (economicTerms -> payout -> interestRatePayout -> rateSpecification -> fixedRate count = 1 - and economicTerms -> payout -> interestRatePayout -> rateSpecification -> inflationRate count = 1) - or ((economicTerms -> payout -> interestRatePayout -> rateSpecification -> floatingRate count = 1 - or economicTerms -> payout -> interestRatePayout -> rateSpecification -> inflationRate count = 1) + (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 @@ -1037,7 +1037,7 @@ func Qualify_SubProduct_FixedFixed: <"Qualifies a product as having the Sub Prod output: is_product boolean (1..1) set is_product: - economicTerms -> payout -> interestRatePayout -> rateSpecification -> fixedRate count = 2 + economicTerms -> payout -> interestRatePayout -> rateSpecification -> FixedRateSpecification count = 2 func Qualify_SubProduct_Basis: <"Qualifies a product as having the Sub Product classification Basis"> inputs: @@ -1045,10 +1045,10 @@ func Qualify_SubProduct_Basis: <"Qualifies a product as having the Sub Product c output: is_product boolean (1..1) set is_product: - economicTerms -> payout -> interestRatePayout -> rateSpecification -> floatingRate count = 2 - or (economicTerms -> payout -> interestRatePayout -> rateSpecification -> inflationRate count = 1 - and economicTerms -> payout -> interestRatePayout -> rateSpecification -> floatingRate count = 1) - or economicTerms -> payout -> interestRatePayout -> rateSpecification -> inflationRate count = 2 + 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: @@ -1093,7 +1093,7 @@ func Qualify_Transaction_OIS: <"Qualifies a product as having the Transaction cl is_product boolean (1..1) alias floatingRateIndex: - economicTerms -> payout -> interestRatePayout -> rateSpecification -> floatingRate -> rateOption -> floatingRateIndex + economicTerms -> payout -> interestRatePayout -> rateSpecification -> FloatingRateSpecification -> rateOption -> FloatingRateIndex -> floatingRateIndex set is_product: floatingRateIndex any = FloatingRateIndexEnum -> AUD_AONIA_OIS_COMPOUND @@ -1384,8 +1384,8 @@ func Qualify_InterestRate_Fra: <"Qualifies the product as a Floating Rate Agreem set is_product: Qualify_AssetClass_InterestRate(economicTerms) = True - and economicTerms -> payout -> interestRatePayout -> rateSpecification -> fixedRate count = 1 - and economicTerms -> payout -> interestRatePayout -> rateSpecification -> floatingRate count = 1 + 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."> @@ -1401,8 +1401,8 @@ func Qualify_InterestRate_CapFloor: <"Qualifies a product as an interest rate ca 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 -> floatingRate -> capRateSchedule exists - or economicTerms -> payout -> interestRatePayout -> rateSpecification -> floatingRate -> floorRateSchedule exists + 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] @@ -1463,8 +1463,8 @@ func Qualify_ForeignExchange_Spot_Forward: <"Qualifies a product as Foreign Exch set is_product: ( Qualify_AssetClass_ForeignExchange(economicTerms) = True // This logic is updated to be syntactically correct for the new model but is probably not the way FX Spot/Fwds should be modelled - and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate only exists - and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate count = 1 + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRateIndex only exists + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRateIndex count = 1 and economicTerms -> payout -> forwardPayout -> settlementTerms -> cashSettlementTerms is absent ) // only FX transactions result in the buyer receiving only cash // other products result in a cash receipt, but not in as a single SettlementPayout @@ -1481,8 +1481,8 @@ func Qualify_ForeignExchange_Swap: <"Qualifies a product as Foreign Exchange Swa is_product boolean (1..1) set is_product: Qualify_AssetClass_ForeignExchange(economicTerms) = True - and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate only exists - and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate count = 2 + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRateIndex only exists + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRateIndex count = 2 and economicTerms -> payout -> forwardPayout -> 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."> @@ -1496,8 +1496,8 @@ func Qualify_ForeignExchange_NDF: <"Qualifies a product as Foreign Exchange Non- set is_product: // This logic is updated to be syntactically correct for the new model but is probably not the way FX Spot/Fwds should be modelled ( Qualify_AssetClass_ForeignExchange(economicTerms) = True - and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate only exists - and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate count = 1 + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRateIndex only exists + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRateIndex count = 1 and economicTerms -> payout -> forwardPayout -> settlementTerms -> cashSettlementTerms exists ) // only FX transactions result in the buyer receiving only cash // other products result in a cash receipt, but not in as a single SettlementPayout @@ -1514,8 +1514,8 @@ func Qualify_ForeignExchange_NDS: <"Qualifies a product as Foreign Exchange NDS is_product boolean (1..1) set is_product: Qualify_AssetClass_ForeignExchange(economicTerms) = True - and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate only exists - and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRate count = 2 + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRateIndex only exists + and economicTerms -> payout -> forwardPayout -> productUnderlier -> Index -> ForeignExchangeRateIndex count = 2 and economicTerms -> payout -> forwardPayout -> 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."> @@ -1531,7 +1531,7 @@ func Qualify_ForeignExchange_ParameterReturnVariance: <"Qualifies a product as F set is_product: Qualify_AssetClass_ForeignExchange(economicTerms) = True // qualifies that the product is FX (i.e.: has only foreign Exchange underliers) - and performancePayout -> observationTerms -> observable -> index -> ForeignExchangeRate only exists + and performancePayout -> observationTerms -> observable -> index -> ForeignExchangeRateIndex only exists and // qualifies that there is a single leg of performance type economicTerms -> payout -> performancePayout only exists and economicTerms -> payout -> performancePayout count = 1 @@ -1551,7 +1551,7 @@ func Qualify_ForeignExchange_ParameterReturnVolatility: <"Qualifies a product as set is_product: Qualify_AssetClass_ForeignExchange(economicTerms) = True // qualifies that the product is FX (i.e.: has only foreign Exchange underliers) - and performancePayout -> observationTerms -> observable -> index -> ForeignExchangeRate only exists + and performancePayout -> observationTerms -> observable -> index -> ForeignExchangeRateIndex only exists and // qualifies that there is a single leg of performance type economicTerms -> payout -> performancePayout only exists and economicTerms -> payout -> performancePayout count = 1 @@ -1576,7 +1576,7 @@ func Qualify_ForeignExchange_ParameterReturnCorrelation: <"Qualifies a product a and // qualifies that the underlier is a basket performancePayout -> underlier -> basket only exists and // qualifies that the product is FX (i.e.: the basket is constituted by foreign exchange constituents) - performancePayout -> underlier -> basket -> basketConstituent -> index -> ForeignExchangeRate only exists + performancePayout -> underlier -> basket -> basketConstituent -> index -> ForeignExchangeRateIndex only exists 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] @@ -1589,7 +1589,7 @@ func Qualify_ForeignExchange_VanillaOption: <"Qualifies a product as FX Plain Va set is_product: Qualify_AssetClass_ForeignExchange(economicTerms) = True and economicTerms -> payout -> optionPayout exists - and economicTerms -> payout -> optionPayout -> productUnderlier -> Index -> ForeignExchangeRate only exists + and economicTerms -> payout -> optionPayout -> productUnderlier -> Index -> ForeignExchangeRateIndex 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) diff --git a/rosetta-source/src/main/rosetta/product-template-type.rosetta b/rosetta-source/src/main/rosetta/product-template-type.rosetta index 01cf041ede..fd09286210 100644 --- a/rosetta-source/src/main/rosetta/product-template-type.rosetta +++ b/rosetta-source/src/main/rosetta/product-template-type.rosetta @@ -203,7 +203,7 @@ type PerformancePayout extends PayoutBase: <"Contains the necessary specificatio and returnTerms -> volatilityReturnTerms -> sharePriceDividendAdjustment is absent condition NoSharePriceDividendAdjustmentForeignExchange: <"If the underlier is an foreign exchange, sharePriceAdjustment and sharePriceDividendAdjustment cannot exist."> - if underlier -> index -> ForeignExchangeRate exists + if underlier -> index -> ForeignExchangeRateIndex exists then returnTerms -> varianceReturnTerms -> sharePriceDividendAdjustment is absent and returnTerms -> volatilityReturnTerms -> sharePriceDividendAdjustment is absent @@ -445,14 +445,14 @@ type ForwardPayout extends PayoutBase: <"Represents a forward settling payout. T schedule CalculationSchedule (0..1) <"Allows the full representation of a payout by defining a set of schedule periods. It supports standard schedule customization by expressing all the dates, quantities, and pricing data in a non-parametric way."> condition SettlementDate: <"For foreign exchange contracts, either the settlementDate is set or the cashflowDates, but not both."> - if productUnderlier -> Index -> ForeignExchangeRate exists + if productUnderlier -> Index -> ForeignExchangeRateIndex exists then (settlementTerms -> settlementDate -> valueDate exists and settlementTerms -> settlementDate -> adjustableOrRelativeDate is absent ) or (settlementTerms -> settlementDate -> valueDate is absent and settlementTerms -> settlementDate -> adjustableOrRelativeDate exists) condition Settlement: <"For foreign exchange contracts, the settlement type must be either fx non-deliverable settlement or not specified, which implies physical settlement in the case of foreign exchange."> - if productUnderlier -> Index -> ForeignExchangeRate exists + if productUnderlier -> Index -> ForeignExchangeRateIndex exists then settlementTerms -> physicalSettlementTerms is absent condition DeliveryCapacity: <"Checks that only one of the representations of delivery capacity is present simultaneously."> From 885dc2f00a6db3c17eee5f3043b1cdb5e8fa47eb Mon Sep 17 00:00:00 2001 From: Lionel Smith-Gordon Date: Wed, 24 Jul 2024 16:47:24 +0000 Subject: [PATCH 4/5] FX updates for P3 FX updates for P3 --- .../base-staticdata-asset-common-type.rosetta | 15 +---- .../main/rosetta/event-common-func.rosetta | 29 ++++----- .../main/rosetta/event-common-type.rosetta | 2 +- .../main/rosetta/event-position-type.rosetta | 2 +- .../main/rosetta/mapping-dtcc-synonym.rosetta | 4 +- ...ml-confirmation-tradestate-synonym.rosetta | 61 ++++++++----------- .../main/rosetta/mapping-ore-synonym.rosetta | 15 ++--- ...servable-asset-calculatedrate-func.rosetta | 1 - .../rosetta/observable-asset-fro-func.rosetta | 1 - .../rosetta/observable-asset-type.rosetta | 23 ++++++- .../main/rosetta/product-asset-type.rosetta | 7 +-- .../rosetta/product-collateral-func.rosetta | 2 +- .../product-common-settlement-type.rosetta | 32 ++++++++-- .../product-qualification-func.rosetta | 51 +++++----------- .../rosetta/product-template-type.rosetta | 53 +++++----------- 15 files changed, 132 insertions(+), 166 deletions(-) diff --git a/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta b/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta index d66a46d8dc..7d4a2e6a53 100755 --- a/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta +++ b/rosetta-source/src/main/rosetta/base-staticdata-asset-common-type.rosetta @@ -15,7 +15,7 @@ choice Asset: <"An Asset is defined as something that can be owned and transfer type AssetBase: <"The base data type to specify common attributes for all Assets."> identifier AssetIdentifier (1..*) <"Asset Identifiers are used to uniquely identify an Asset, using a specified Asset Identifier Type."> - taxonomy Taxonomy (0..1) <"Defines the taxonomy of an object by combining a taxonomy source (i.e. the rules to classify the object) and a value (i.e. the output of those rules on the object."> + taxonomy Taxonomy (0..*) <"Defines the taxonomy of an object by combining a taxonomy source (i.e. the rules to classify the object) and a value (i.e. the output of those rules on the object."> isExchangeListed boolean (0..1) <"Defines whether the Asset is listed on a public exchange."> exchange LegalEntity (0..1) <"If the Asset is listed, defines the public exchange of the listing."> [metadata scheme] @@ -99,18 +99,7 @@ type IndexReferenceInformation: <"A class defining information related to Index" condition IndexAttributes: <"A required choice condition for either a floating rate or inflation rate index."> indexName exists or indexId exists -type IndexBase extends AssetBase: <"Identifies an index by referencing an identifier."> - name string (0..1) <"A description of the Index."> - provider LegalEntity (0..1) <"The organisation that creates or maintains the Index."> - assetClass AssetClassEnum (0..1) <"The Asset Class of the Index."> - -choice Index: <"An Index is an Observable which is computed based on the prices, rates or valuations of a number of assets that are tracked in a standardized way. Examples include equity market indices as well as indices on interest rates, inflation and credit instruments."> - CreditIndex <"An index based on credit risk, typically composed using corporate debt instruments in a region or industry sector, e.g. the iTraxx indices."> - EquityIndex <"An index based on equity securities, e.g. the S&P 500."> - FloatingRateIndex <"An interest rate index which can change over time, e.g. the SONIA (Sterling Overnight Index Average) in the UK."> - ForeignExchangeRateIndex <"A rate based on the exchange of a pair of cash assets in specific currencies, e.g. USD versus GBP."> - InflationIndex <"An index that measures inflation in a specific market, e.g. the US Consumer Price Index."> - OtherIndex <"An index created by a market participant which doesn't align with the other index types."> + type Cash extends AssetBase: <"An Asset that consists solely of a monetary holding in a currency. The currency of the Cash asset is held in the string Identifier (from AssetBase) and the AssetIdTypeEnum must be set to define that a CurrencyCode is set. The function SetCashCurrency can be used to create (or update) a Cash object and the function GetCashCurrency can be used to retrieve the currency of a Cash object."> diff --git a/rosetta-source/src/main/rosetta/event-common-func.rosetta b/rosetta-source/src/main/rosetta/event-common-func.rosetta index 4936b6d167..f56d198bda 100644 --- a/rosetta-source/src/main/rosetta/event-common-func.rosetta +++ b/rosetta-source/src/main/rosetta/event-common-func.rosetta @@ -955,9 +955,9 @@ func Create_QuantityChange: <"A specification of the inputs, outputs and constra // Update trade with new TradableProduct. set quantityChange -> trade -> product: tradableProduct -> product - set quantityChange -> trade -> tradeLot: newTradeLots - set quantityChange -> trade -> counterparty: tradableProduct -> counterparty - set quantityChange -> trade -> ancillaryParty: tradableProduct -> ancillaryParty + add quantityChange -> trade -> tradeLot: newTradeLots + add quantityChange -> trade -> counterparty: tradableProduct -> counterparty + add quantityChange -> trade -> ancillaryParty: tradableProduct -> ancillaryParty set quantityChange -> trade -> adjustment: tradableProduct -> adjustment set quantityChange -> state -> positionState: @@ -990,9 +990,9 @@ func Create_TermsChange: <"A specification of the inputs, outputs and constraint // Contract to be updated based on the new terms change inputs. set tradeState -> trade -> product: newProduct - set tradeState -> trade -> tradeLot: tradeState -> trade -> tradeLot - set tradeState -> trade -> counterparty: tradeState -> trade -> counterparty - set tradeState -> trade -> ancillaryParty: newAncillaryParty + add tradeState -> trade -> tradeLot: tradeState -> trade -> tradeLot + add tradeState -> trade -> counterparty: tradeState -> trade -> counterparty + add tradeState -> trade -> ancillaryParty: newAncillaryParty set tradeState -> trade -> adjustment: newAdjustment func FilterOpenTradeStates: <"Filter to only 'open' TradeState - where both the closedState and positionState are not set."> @@ -1017,17 +1017,17 @@ func NewEquitySwapProduct: <"Function specification to create an Equity Swap acc masterConfirmation EquitySwapMasterConfirmation2018 (0..1) <"An (optional) pointer to the Master Confirmation Agreement, if any, that holds further inputs to the Equity Swap"> // performancePayout PerformancePayout (1..1) output: - product Product (1..1) + product NonTransferableProduct (1..1) - alias payout: product -> contractualProduct -> economicTerms -> payout + alias payout: product -> economicTerms -> payout // condition PriceReturnTermsOnlyExists: performancePayout -> returnTerms -> priceReturnTerms only exists condition EquitySecurityType: <"Security must be equity (single name)."> security -> securityType = SecurityTypeEnum -> Equity - add product -> contractualProduct -> economicTerms -> payout -> performancePayout: + add payout -> performancePayout: NewSingleNameEquityPerformancePayout(security, masterConfirmation) - add product -> contractualProduct -> economicTerms -> payout -> interestRatePayout: <"Equity and interest rate payouts must be set-up according to their corresponding payout specifications"> + add payout -> interestRatePayout: <"Equity and interest rate payouts must be set-up according to their corresponding payout specifications"> if masterConfirmation exists then NewFloatingPayout(masterConfirmation) @@ -1040,9 +1040,6 @@ func NewEquitySwapProduct: <"Function specification to create an Equity Swap acc and payout -> fixedPricePayout is absent and payout -> optionPayout is absent - post-condition ContractualProductOnlyExists: <"Non-contractual product types must be absent."> - product -> contractualProduct only exists - func NewSingleNameEquityPerformancePayout: <"Function specification to create the equity payout part of an Equity Swap according to the 2018 ISDA CDM Equity Confirmation template."> inputs: security Security (1..1) @@ -1123,7 +1120,7 @@ func UpdateSpreadAdjustmentAndRateOptions: <"For each of the trade state's price set updatedTradeState: tradeState - set updatedTradeState -> trade -> tradeLot -> priceQuantity: + add updatedTradeState -> trade -> tradeLot -> priceQuantity: tradeState -> trade -> tradeLot only-element -> priceQuantity extract UpdateIndexTransitionPriceAndRateOption( @@ -1433,8 +1430,8 @@ func CheckTradeNotTransferableProduct: <"Identifies whether the product inside isNotTransferableProduct boolean (1..1) set isNotTransferableProduct: - if CheckTradeNotTransferableProduct(tradeState) - then False + if CheckTransferableProduct(tradeState -> trade -> product -> economicTerms) + then False else True func Create_RollPrimitiveInstruction: <"Creates the primitive instructions for a trade roll. A trade roll consists in closing an existing trade and entering into a new one which has the same characteristics as the old one, except with an extended termination date and (possibly) a different price."> inputs: diff --git a/rosetta-source/src/main/rosetta/event-common-type.rosetta b/rosetta-source/src/main/rosetta/event-common-type.rosetta index c6bb360717..4289df730c 100644 --- a/rosetta-source/src/main/rosetta/event-common-type.rosetta +++ b/rosetta-source/src/main/rosetta/event-common-type.rosetta @@ -539,7 +539,7 @@ type CorporateAction: <"Specifies the relevant data regarding a corporate action corporateActionType CorporateActionTypeEnum (1..1) <"The type of corporate action taking place."> exDate date (1..1) <"The date on which the corporate action is known to have taken place."> payDate date (1..1) <"The date on which resulting from the corporate action are delivered."> - underlier Product (1..1) <"The entity impacted by the corporate action."> + underlier ProductUnderlier (1..1) <"The entity impacted by the corporate action."> type TransferBase: identifier Identifier (0..*) <"Represents a unique reference to the transfer."> diff --git a/rosetta-source/src/main/rosetta/event-position-type.rosetta b/rosetta-source/src/main/rosetta/event-position-type.rosetta index 33e40ab9c9..95934f4ebd 100644 --- a/rosetta-source/src/main/rosetta/event-position-type.rosetta +++ b/rosetta-source/src/main/rosetta/event-position-type.rosetta @@ -53,7 +53,7 @@ type AggregationParameters: <" Parameters to be used to filter events that are r positionStatus PositionStatusEnum (0..1) <"To aggregate based on position status (EXECUTED, SETTLED etc)"> party Party (0..*) <"To aggregate based on a selection of party(ies) / legal entity(ies)."> [metadata reference] - product Product (0..*) <"To aggregate based on a selection of products."> + product ProductUnderlier (0..*) <"To aggregate based on a selection of products."> productQualifier string (0..*) <"To aggregate based on a selection of product type(s)."> tradeReference Trade (0..*) [metadata reference] diff --git a/rosetta-source/src/main/rosetta/mapping-dtcc-synonym.rosetta b/rosetta-source/src/main/rosetta/mapping-dtcc-synonym.rosetta index 068e1132b7..dc33bb9d5a 100644 --- a/rosetta-source/src/main/rosetta/mapping-dtcc-synonym.rosetta +++ b/rosetta-source/src/main/rosetta/mapping-dtcc-synonym.rosetta @@ -86,8 +86,8 @@ synonym source DTCC_BASE extends FpML_5_Confirmation_To_WorkflowStep [value "OriginatingUSI"] [value "UTI"] - Product: - + contractualProduct + TransferableProduct: + + Instrument [hint "ProductType"] AssignedIdentifier: diff --git a/rosetta-source/src/main/rosetta/mapping-fpml-confirmation-tradestate-synonym.rosetta b/rosetta-source/src/main/rosetta/mapping-fpml-confirmation-tradestate-synonym.rosetta index 501be231cf..63e24c9538 100644 --- a/rosetta-source/src/main/rosetta/mapping-fpml-confirmation-tradestate-synonym.rosetta +++ b/rosetta-source/src/main/rosetta/mapping-fpml-confirmation-tradestate-synonym.rosetta @@ -1719,7 +1719,7 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML [value "description" path "index" maps 2 mapper "ProductIdentifierSource"] ProductBase: - + productTaxonomy + + taxonomy [hint "primaryAssetClass"] [hint "secondaryAssetClass"] [hint "fra"] @@ -1953,20 +1953,6 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML + notionalAmountReference [value "notionalAmountReference" meta "href"] - Observable: -// + commodity //**ART** needs to be mapped to Asset -// [hint "commodity"] -// [hint "commodityClassification"] - + productIdentifier - [hint "equity"] - [hint "bond"] - [hint "convertibleBond"] - [hint "index"] - [hint "exchangeTradedContractNearest"] - // + currencyPair //**ART** Needs to be mapped to Index/ForeignExchangeRate - // [value "quotedCurrencyPair"] - // [hint "features" , "putCurrencyAmount" , "callCurrencyAmount"] - Cashflow: [meta "id"] + priceQuantity @@ -2077,6 +2063,9 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML + Cash [value "paymentAmount"] [value "fixedAmount"] + + Commodity + [value "commodity"] + [meta "specifiedPrice"] ContractDetails: + documentation @@ -2554,8 +2543,8 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML + settlementPayout [value "ignore"] - Product: - + contractualProduct + ProductUnderlier: + + NonTransferableProduct // For Equity Swap: [value "returnSwap" , "equitySwapTransactionSupplement"] // For Swap Stream: @@ -2614,24 +2603,26 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML [hint "fxVolatilitySwap"] [hint "genericProduct"] [hint "tradeHeader"] - + index - [hint "index"] - + loan + + Instrument: + + Loan [hint "loan"] - + commodity - [value "commodity"] - [meta "specifiedPrice"] - + security + + ListedDerivative + + Security [value "underlyer"] [hint "bond" , "equity" , "mortgage" , "convertibleBond"] + + Observable: + + index + [hint "index"] + basket [value "basket"] -// Index: -// + identifier -// [value "index" meta "instrumentId" mapper "BasketConstituent"] -// [value "index" meta "description"] -// [hint "index"] + IndexBase: + + identifier + [value "index" meta "instrumentId" mapper "BasketConstituent"] + [value "index" meta "description"] + [hint "index"] Basket: + basketConstituent @@ -2747,18 +2738,18 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML [value "notionalAdjustments" path "returnSwap->returnLeg" , "notionalAdjustments" path "equitySwapTransactionSupplement->returnLeg"] RateSpecification: - + fixedRate + + FixedRateSpecification [hint "fixedRateSchedule"] [hint "fixedRate"] [hint "fixedAmountCalculation"] - + floatingRate + + FloatingRateSpecification [value "floatingRateCalculation"] // For FRAs: [hint "floatingRateIndex" , "indexTenor"] // For Credit: [value "floatingAmountCalculation"] [value "floatingRate" path "floatingAmountCalculation"] - + inflationRate + + InflationRateSpecification [value "inflationRateCalculation"] StubPeriod: @@ -3483,12 +3474,8 @@ synonym source FpML_5_Confirmation_To_TradeState extends FpML + stepUpProvision [value "stepUpProvision"] - CreditIndexReferenceInformation: + CreditIndex: [value "IndexReferenceInformation" meta "id"] - + indexName - [value "indexName" meta "indexNameScheme"] - + indexId - [value "indexId" meta "indexIdScheme"] + indexSeries [value "indexSeries"] + indexAnnexVersion diff --git a/rosetta-source/src/main/rosetta/mapping-ore-synonym.rosetta b/rosetta-source/src/main/rosetta/mapping-ore-synonym.rosetta index 33e2fb8acc..c4b67584d2 100644 --- a/rosetta-source/src/main/rosetta/mapping-ore-synonym.rosetta +++ b/rosetta-source/src/main/rosetta/mapping-ore-synonym.rosetta @@ -5,6 +5,7 @@ import cdm.base.math.* import cdm.base.datetime.* import cdm.base.staticdata.party.* import cdm.base.staticdata.asset.rates.* +import cdm.base.staticdata.asset.common.* import cdm.event.common.* @@ -74,8 +75,8 @@ synonym source ORE_1_0_39 extends ORE + datedValue [value "step"] - Product: - + contractualProduct + TradableProduct: + + product [value "SwapData"] Payout: @@ -130,16 +131,16 @@ synonym source ORE_1_0_39 extends ORE + unadjustedDate [value "StartDate"] - FloatingRateOption: - + floatingRateIndex + Index: + + FloatingRateIndex [value "Index" maps 2] RateSpecification: - + fixedRate + + FixedRateSpecification [value "FixedLegData"] - + floatingRate + + FloatingRateSpecification [value "FloatingLegData"] - + inflationRate + + InflationRateSpecification [value "ignore"] FixedRateSpecification: diff --git a/rosetta-source/src/main/rosetta/observable-asset-calculatedrate-func.rosetta b/rosetta-source/src/main/rosetta/observable-asset-calculatedrate-func.rosetta index 07dc65b6b2..820d93361a 100644 --- a/rosetta-source/src/main/rosetta/observable-asset-calculatedrate-func.rosetta +++ b/rosetta-source/src/main/rosetta/observable-asset-calculatedrate-func.rosetta @@ -4,7 +4,6 @@ version "${project.version}" import cdm.base.math.* import cdm.base.datetime.* import cdm.base.datetime.daycount.* -import cdm.base.staticdata.asset.common.* import cdm.observable.asset.* diff --git a/rosetta-source/src/main/rosetta/observable-asset-fro-func.rosetta b/rosetta-source/src/main/rosetta/observable-asset-fro-func.rosetta index 2d5e4f31a8..50451c3976 100644 --- a/rosetta-source/src/main/rosetta/observable-asset-fro-func.rosetta +++ b/rosetta-source/src/main/rosetta/observable-asset-fro-func.rosetta @@ -2,7 +2,6 @@ namespace cdm.observable.asset.fro : <"Support for floating rate option definiti version "${project.version}" import cdm.base.staticdata.asset.rates.* -import cdm.base.staticdata.asset.common.* import cdm.observable.asset.* diff --git a/rosetta-source/src/main/rosetta/observable-asset-type.rosetta b/rosetta-source/src/main/rosetta/observable-asset-type.rosetta index 19ae56ffac..7ffcba9e65 100644 --- a/rosetta-source/src/main/rosetta/observable-asset-type.rosetta +++ b/rosetta-source/src/main/rosetta/observable-asset-type.rosetta @@ -14,6 +14,19 @@ import cdm.mapping.config.* //**ART** Needed to support PriceQuantity in BasketConstituent, which will be refactored import cdm.product.common.settlement.* +type IndexBase extends AssetBase: <"Identifies an index by referencing an identifier."> + name string (0..1) <"A description of the Index."> + provider LegalEntity (0..1) <"The organisation that creates or maintains the Index."> + assetClass AssetClassEnum (0..1) <"The Asset Class of the Index."> + +choice Index: <"An Index is an Observable which is computed based on the prices, rates or valuations of a number of assets that are tracked in a standardized way. Examples include equity market indices as well as indices on interest rates, inflation and credit instruments."> + CreditIndex <"An index based on credit risk, typically composed using corporate debt instruments in a region or industry sector, e.g. the iTraxx indices."> + EquityIndex <"An index based on equity securities, e.g. the S&P 500."> + FloatingRateIndex <"An interest rate index which can change over time, e.g. the SONIA (Sterling Overnight Index Average) in the UK."> + ForeignExchangeRateIndex <"A rate based on the exchange of a pair of cash assets in specific currencies, e.g. USD versus GBP."> + InflationIndex <"An index that measures inflation in a specific market, e.g. the US Consumer Price Index."> + OtherIndex <"An index created by a market participant which doesn't align with the other index types."> + type FloatingRateIndex extends IndexBase: <"Specification of an interest rate index which can change over time, e.g. the SONIA (Sterling Overnight Index Average) in the UK."> floatingRateIndex FloatingRateIndexEnum (1..1) <"The reference index that is used to specify the floating interest rate."> [metadata scheme] @@ -24,6 +37,7 @@ type FloatingRateIndex extends IndexBase: <"Specification of an interest rate i type ForeignExchangeRateIndex extends IndexBase: <"Specification of a rate based on the exchange of a pair of cash assets in specific currencies, e.g. USD versus GBP."> quotedCurrencyPair QuotedCurrencyPair (1..1) <"Describes the composition of a rate that has been quoted or is to be quoted."> + [metadata location] primaryFxSpotRateSource InformationSource (1..1) <"Specifies the primary source from which a rate should be observed."> secondaryFxSpotRateSource InformationSource (0..1) <"Specifies an alternative, or secondary, source from which a rate should be observed."> @@ -164,10 +178,12 @@ type Price extends PriceSchedule: <"Specifies a price as a single value to be as value exists and datedValue is absent type Observable: <"Specifies the object to be observed for a price, it could be an asset or a reference."> - //**ART** Wil make this a choice in P3; currently not supported with annotation + //**ART** Should be a CHOICE; currently not supported with annotation asset Asset (0..1) <"The object to be observed is an Asset, ie something that can be owned and transferred in the financial markets."> + [metadata location] basket Basket (0..1) <"The object to be observed is a Basket, ie a collection of Observables with an identifier and optional weightings."> + [metadata location] index Index (0..1) <"The object to be observed is an Index, ie an observable computed on the prices, rates or valuations of a number of assets."> [metadata location] @@ -210,7 +226,7 @@ type QuotedCurrencyPair: <"A class that describes the composition of a rate that quoteBasis QuoteBasisEnum (1..1) <"The method by which the exchange rate is quoted."> type Curve: - + [deprecated] interestRateCurve InterestRateCurve (0..1) commodityCurve CommodityReferencePriceEnum (0..1) [metadata scheme] @@ -219,7 +235,7 @@ type Curve: one-of type InterestRateCurve: - + [deprecated] floatingRateIndex FloatingRateIndexEnum (1..1) [metadata scheme] tenor Period (1..1) @@ -406,6 +422,7 @@ type SingleValuationDate: <"A class to specify the number of business days after type ValuationSource: <"A class describing the method for obtaining a settlement rate, specified through either an information source (page), a settlement rate option (fixing) or by using quotes from reference banks."> quotedCurrencyPair QuotedCurrencyPair (0..1) <"Defines the two currencies for an FX trade and the quotation relationship between the two currencies. This attribute was formerly part of 'fxSettlementTerms', which is now being harmonised into a common 'CashSettlementTerms' that includes a 'ValuationDate'."> + [metadata address "pointsTo"=Observable->index->ForeignExchangeRateIndex->quotedCurrencyPair] informationSource FxSpotRateSource (0..1) <"The information source where a published or displayed market rate will be obtained, e.g. Telerate Page 3750."> settlementRateOption SettlementRateOption (0..1) <"The rate option to use for the fixing. Currently only applicable to foreign exchange fixing in case of cross-currency settlement."> referenceBanks ReferenceBanks (0..1) <"A container for a set of reference institutions that may be called upon to provide rate quotations as part of the method to determine the applicable cash settlement amount. If institutions are not specified, it is assumed that reference institutions will be agreed between the parties on the exercise date, or in the case of swap transaction to which mandatory early termination is applicable, the cash settlement valuation date."> diff --git a/rosetta-source/src/main/rosetta/product-asset-type.rosetta b/rosetta-source/src/main/rosetta/product-asset-type.rosetta index 57197166c3..594d8e1b14 100644 --- a/rosetta-source/src/main/rosetta/product-asset-type.rosetta +++ b/rosetta-source/src/main/rosetta/product-asset-type.rosetta @@ -28,7 +28,7 @@ type CommodityPayout extends PayoutBase: <"Payout based on the averaged price of schedule CalculationSchedule (0..1) <"Allows the full representation of a payout by defining a set of schedule periods. It supports standard schedule customization by expressing all the dates, quantities, and pricing data in a non-parametric way."> calculationPeriodDates CalculationPeriodDates (0..1) <"Defines the calculation period dates schedule."> paymentDates PaymentDates (1..1) <"Defines the payment date schedule, as defined by the parameters that are needed to specify it, either in a parametric way or by reference to another schedule of dates (e.g. the valuation dates)."> - underlier Product (1..1) <"Identifies the underlying product that is referenced for pricing of the applicable leg in a swap. Referenced in the '2018 ISDA CDM Equity Confirmation for Security Equity Swap' as Security."> + underlier Observable (1..1) <"Identifies the underlying product that is referenced for pricing of the applicable leg in a swap. Referenced in the '2018 ISDA CDM Equity Confirmation for Security Equity Swap' as Security."> fxFeature FxFeature (0..1) <"Defines quanto or composite FX features that are included in the swap leg."> delivery AssetDeliveryInformation (0..1) <"Contains the information relative to the delivery of the asset."> @@ -230,7 +230,7 @@ type DividendPayoutRatio: <"A class describing the dividend payout ratio associa totalRatio number (1..1) <"Specifies the total actual dividend payout ratio associated with the equity underlier. A ratio of 90% should be expressed at 0.90."> cashRatio number (0..1) <"Specifies the cash actual dividend payout ratio associated with the equity underlier. A ratio of 90% should be expressed at 0.90."> nonCashRatio number (0..1) <"Specifies the non cash actual dividend payout ratio associated with the equity underlier. A ratio of 90% should be expressed at 0.90."> - basketConstituent Product (0..1) <"In the case of a basket underlier, specifies to which component of the basket this particular set of dividend payout ratios correspond."> + basketConstituent Observable (0..1) <"In the case of a basket underlier, specifies to which component of the basket this particular set of dividend payout ratios correspond."> condition DividendPayoutRatioTotal: <"The dividend payout ratio should be comprised between 0 and 100%, meaning 0 and 1."> totalRatio >= 0 and totalRatio <= 1 @@ -284,7 +284,6 @@ type FloatingAmountProvisions: stepUpProvision boolean (0..1) <"As specified by the ISDA Standard Terms Supplement for use with trades on mortgage-backed securities. The presence of the element with value set to 'true' signifies that the provision is applicable. If applicable, the applicable step-up terms are specified as part of that ISDA Standard Terms Supplement. From a usage standpoint, this provision is typically applicable in the case of RMBS and not applicable in case of CMBS trades."> type CreditIndexReferenceInformation extends IndexReferenceInformation: <"A class defining a Credit Default Swap Index."> - [deprecated] // to be replaced by CreditIndex [metadata key] indexSeries int (0..1) <"A CDS index series identifier, e.g. 1, 2, 3 etc."> indexAnnexVersion int (0..1) <"A CDS index series version identifier, e.g. 1, 2, 3 etc."> @@ -469,7 +468,7 @@ type DividendPeriod: <"Time bounded dividend payment periods, each with a divide startDate DividendPaymentDate (0..1) <"Dividend period start date."> endDate DividendPaymentDate (0..1) <"Dividend period end date."> dateAdjustments BusinessDayAdjustments (1..1) <"Date adjustments for all unadjusted dates in this dividend period."> - basketConstituent Product (0..1) <"For basket undeliers, reference to the basket component which is paying dividends in the specified period."> + basketConstituent Observable (0..1) <"For basket undeliers, reference to the basket component which is paying dividends in the specified period."> dividendPaymentDate DividendPaymentDate (1..1) <"Specifies when the dividend will be paid to the receiver of the equity return. Has the meaning as defined in the ISDA 2002 Equity Derivatives Definitions. Is not applicable in the case of a dividend reinvestment election."> dividendValuationDate AdjustableOrRelativeDate (0..1) <"Specifies the dividend valuation dates of the swap."> diff --git a/rosetta-source/src/main/rosetta/product-collateral-func.rosetta b/rosetta-source/src/main/rosetta/product-collateral-func.rosetta index ffbb931406..affeb87995 100644 --- a/rosetta-source/src/main/rosetta/product-collateral-func.rosetta +++ b/rosetta-source/src/main/rosetta/product-collateral-func.rosetta @@ -26,7 +26,7 @@ func MergeEligibleCollateralCriteria: <"Java implementation merges criteria1 and func CheckEligibilityForProduct: inputs: specifications EligibleCollateralSpecification (1..*) <"Specifications that determine which collateral meets the eligibility and can be used/posted for delivery. For ICMA usecase - this is the basket(s). For ISDA usecase these are the Elegibility Schedule Lists."> - product Product (0..1) + product TransferableProduct (0..1) output: eligibilityResult CheckEligibilityResult (0..1) diff --git a/rosetta-source/src/main/rosetta/product-common-settlement-type.rosetta b/rosetta-source/src/main/rosetta/product-common-settlement-type.rosetta index ddbb668659..9941ee6d65 100644 --- a/rosetta-source/src/main/rosetta/product-common-settlement-type.rosetta +++ b/rosetta-source/src/main/rosetta/product-common-settlement-type.rosetta @@ -300,6 +300,30 @@ type SettlementTerms extends SettlementBase: <"Specifies the settlement terms, w if physicalSettlementTerms exists /* or fxSettlementTerms exists*/ then settlementType <> SettlementTypeEnum -> Cash +type TestPriceQuantity: <"Defines a settlement as an exchange between two parties of a specified quantity of an asset (the quantity) against a specified quantity of another asset (the price). The settlement is optional and can be either cash or physical. In the case of non-cash products, the settlement of the price/quantity would not be specified here and instead would be delegated to the product mechanics, as parameterised by the price/quantity values."> + [metadata key] + price PriceSchedule (0..*) <"Specifies a price to be used for trade amounts and other purposes."> + [metadata location] + quantity NonNegativeQuantitySchedule (0..*) <"Specifies a quantity to be associated with an event, for example a trade amount."> + [metadata location] + currencyQuantity NonNegativeQuantitySchedule (0..*) + observable Observable (0..1) <"Specifies the object to be observed for a price, it could be an asset or a reference. The cardinality is optional as some quantity / price cases have no observable (e.g. a notional and a fixed rate in a given currency)."> + [metadata location] + effectiveDate AdjustableOrRelativeDate (0..1) <"Specifies the date at which the price and quantity become effective. This day may be subject to adjustment in accordance with a business day convention, or could be specified as relative to a trade date, for instance. Optional cardinality, as the effective date is usually specified in the product definition, so it may only need to be specified as part of the PriceQuantity in an increase/decrease scenario for an existing trade."> + + condition AtLeastOneQuantity: <"There should be one quantity at least; if more than one is used, one of them must be populated in Quantity."> + quantity exists or currencyQuantity count = 1 + + condition CurrencyQuantity: <"The currency quantity must use a currency unit."> + if currencyQuantity exists + then currencyQuantity -> unit -> currency exists + + condition AssetObservable: <"The Observable should be an Asset unless the arithmetic operator is being used."> + if quantity exists + then if price -> arithmeticOperator is absent + then observable -> asset exists + else observable -> index exists + type PriceQuantity: <"Defines a settlement as an exchange between two parties of a specified quantity of an asset (the quantity) against a specified quantity of another asset (the price). The settlement is optional and can be either cash or physical. In the case of non-cash products, the settlement of the price/quantity would not be specified here and instead would be delegated to the product mechanics, as parameterised by the price/quantity values."> [metadata key] price PriceSchedule (0..*) <"Specifies a price to be used for trade amounts and other purposes."> @@ -307,16 +331,14 @@ type PriceQuantity: <"Defines a settlement as an exchange between two parties of quantity NonNegativeQuantitySchedule (0..*) <"Specifies a quantity to be associated with an event, for example a trade amount."> [metadata location] observable Observable (0..1) <"Specifies the object to be observed for a price, it could be an asset or a reference. The cardinality is optional as some quantity / price cases have no observable (e.g. a notional and a fixed rate in a given currency)."> - // buyerSeller BuyerSeller (0..1) <"Defines the direction of the exchange. The convention is that the buyer receives the quantity / pays the price, whereas the seller receives the price / pays the quantity. Attribute is optional in case the price/quantity settlement is defined as part of the product mechanics."> - // settlementTerms SettlementTerms (0..1) <"Whether the settlement is cash or physical and the corresponding terms. Attribute is optional in case the price/quantity settlement is defined as part of the product mechanics."> + [metadata location] effectiveDate AdjustableOrRelativeDate (0..1) <"Specifies the date at which the price and quantity become effective. This day may be subject to adjustment in accordance with a business day convention, or could be specified as relative to a trade date, for instance. Optional cardinality, as the effective date is usually specified in the product definition, so it may only need to be specified as part of the PriceQuantity in an increase/decrease scenario for an existing trade."> condition RateOptionObservable: <"When the observable is a rate option, the price type must be interest rate and the arithmetic operator must be specified."> RateOptionObservableCondition - condition RateOptionObservable: <"When the observable is a rate option, the price type must be interest rate and the arithmetic operator must be specified."> - RateOptionObservableCondition - // convert to index and cover additional scenarios including FX rate + condition InterestRateObservable: <"When the observable is a rate option, the price type must be interest rate and the arithmetic operator must be specified."> + InterestRateObservableCondition condition CashQuantity: <"If the quantity refers to cash in a currency, this should be modelled by setting the currency in the unit type of the quantity and not using an Observable. "> ( quantity -> unit -> currency exists and observable is absent ) diff --git a/rosetta-source/src/main/rosetta/product-qualification-func.rosetta b/rosetta-source/src/main/rosetta/product-qualification-func.rosetta index a9acbb6454..14b9116c67 100644 --- a/rosetta-source/src/main/rosetta/product-qualification-func.rosetta +++ b/rosetta-source/src/main/rosetta/product-qualification-func.rosetta @@ -184,11 +184,11 @@ func Qualify_AssetClass_Commodity: <"Qualifies a product as having the Asset Cla set is_product: // CO:FixFlo ((economicTerms -> payout -> commodityPayout, economicTerms -> payout -> fixedPricePayout) only exists - and economicTerms -> payout -> commodityPayout -> underlier -> commodity exists) + and economicTerms -> payout -> commodityPayout -> underlier -> asset -> Commodity exists) // CO Basis or (economicTerms -> payout -> commodityPayout only exists and economicTerms -> payout -> commodityPayout count = 2 - and economicTerms -> payout -> commodityPayout -> underlier -> commodity count = 2) + and economicTerms -> payout -> commodityPayout -> underlier -> asset -> Commodity count = 2) // CO Opt or (economicTerms -> payout -> optionPayout only exists and (ProductUnderlierQualification(optionUnderlier, empty, AssetClassEnum -> Commodity) @@ -295,48 +295,27 @@ func Qualify_UnderlierObservable_Equity: <"Qualifies an Observable as having the is_product boolean (1..1) set is_product: - underlier -> asset -> Instrument -> Security -> securityType = SecurityTypeEnum -> Equity - or (underlier -> asset -> Instrument -> Security -> securityType = SecurityTypeEnum -> Fund - and underlier -> asset -> Instrument -> Security -> fundType = FundProductTypeEnum -> ExchangeTradedFund) - or (underlier -> asset -> Instrument -> Security -> securityType = SecurityTypeEnum -> Fund - and underlier -> asset -> Instrument -> Security -> fundType = FundProductTypeEnum -> MutualFund) - or underlier -> asset -> Instrument -> Security -> securityType = SecurityTypeEnum -> Warrant + Qualify_SecurityTypeEquity(underlier -> asset -> Instrument -> Security) or underlier -> index ->> assetClass = AssetClassEnum -> Equity // Qualifies that the underlier is a basket composed of equity products only or (underlier -> basket exists - and (underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Equity - or (underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Fund - and underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> fundType any = FundProductTypeEnum -> ExchangeTradedFund) - or (underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Fund - and underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> fundType any = FundProductTypeEnum -> MutualFund) - or underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Warrant - or underlier -> basket -> basketConstituent -> index ->> assetClass any = AssetClassEnum -> Equity + and (Qualify_SecurityTypeEquity(underlier -> basket -> basketConstituent -> asset -> Instrument -> Security) + or underlier -> basket -> basketConstituent -> index ->> assetClass all = AssetClassEnum -> Equity )) -func Qualify_UnderlierProduct_Equity: <"Qualifies a product as having the Asset Class classification Equity."> +func Qualify_SecurityTypeEquity: <"Qualifies that the security type, for all of the provided securities, is Equity-related."> inputs: - underlier Product (1..1) + security Security (1..*) output: - is_product boolean (1..1) + is_equity boolean (1..1) - set is_product: - underlier -> security -> securityType = SecurityTypeEnum -> Equity - or (underlier -> security -> securityType = SecurityTypeEnum -> Fund - and underlier -> security -> fundType = FundProductTypeEnum -> ExchangeTradedFund) - or (underlier -> security -> securityType = SecurityTypeEnum -> Fund - and underlier -> security -> fundType = FundProductTypeEnum -> MutualFund) - or underlier -> security -> securityType = SecurityTypeEnum -> Warrant - or underlier -> index ->> assetClass = AssetClassEnum -> Equity - // Qualifies that the underlier is a basket composed of equity products only - or (underlier -> basket exists - and (underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Equity - or (underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Fund - and underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> fundType any = FundProductTypeEnum -> ExchangeTradedFund) - or (underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Fund - and underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> fundType any = FundProductTypeEnum -> MutualFund) - or underlier -> basket -> basketConstituent -> asset -> Instrument -> Security -> securityType any = SecurityTypeEnum -> Warrant - or underlier -> basket -> basketConstituent -> index ->> assetClass any = AssetClassEnum -> Equity - )) + set is_equity: + security -> securityType all = SecurityTypeEnum -> Equity + or (security -> securityType all = SecurityTypeEnum -> Fund + and security -> fundType all = FundProductTypeEnum -> ExchangeTradedFund) + or (security -> securityType all = SecurityTypeEnum -> Fund + and security -> fundType all = FundProductTypeEnum -> MutualFund) + or security -> securityType all = SecurityTypeEnum -> Warrant func Qualify_BaseProduct_EquitySwap: <"Qualifies a product as having the Asset Class classification Equity and Base Product Classification Swap."> inputs: diff --git a/rosetta-source/src/main/rosetta/product-template-type.rosetta b/rosetta-source/src/main/rosetta/product-template-type.rosetta index fd09286210..265d888177 100644 --- a/rosetta-source/src/main/rosetta/product-template-type.rosetta +++ b/rosetta-source/src/main/rosetta/product-template-type.rosetta @@ -24,20 +24,12 @@ import cdm.product.collateral.* import cdm.mapping.config.* type ProductBase: <"Serves as an abstract class to specify common attributes for all products."> - productTaxonomy ProductTaxonomy (0..*) <"Specifies the product taxonomy, which is composed of a taxonomy value and a taxonomy source."> + taxonomy ProductTaxonomy (0..*) <"Specifies the product taxonomy, which is composed of a taxonomy value and a taxonomy source."> economicTerms EconomicTerms (1..1) <"The price forming features, including payouts and provisions."> -type TransferableProduct extends Asset: <"A TransferableProduct is a type of Product which can be used in a SettlementCommitment for a basic cash settled trade of either an Asset with the addition of specific EconomicTerms."> +type TransferableProduct extends Asset: <"A TransferableProduct is a type of financial product which can be held or transferred, represented as an Asset with the addition of specific EconomicTerms."> economicTerms EconomicTerms (1..1) <"The price forming features, including payouts and provisions."> -type ContractualProduct extends ProductBase: <" A class to specify the contractual products' economic terms, alongside their product identification and product taxonomy. The contractual product class is meant to be used across the pre-execution, execution and (as part of the Contract) post-execution lifecycle contexts."> - [metadata key] - [metadata template] - - condition PrimaryAssetClass: <"Specifies that when nonStandardisedTerms are True that a primary asset class must be specified."> - if economicTerms -> nonStandardisedTerms = True - then productTaxonomy -> primaryAssetClass exists - type EconomicTerms: <" This class represents the full set of price-forming features associated with a contractual product: the payout component, the notional/quantity, the effective and termination date and the date adjustment provisions when applying uniformily across the payout components. This class also includes the legal provisions which have valuation implications: cancelable provision, extendible provision, early termination provision and extraordinary events specification."> effectiveDate AdjustableOrRelativeDate (0..1) <"The first day of the terms of the trade. This day may be subject to adjustment in accordance with a business day convention."> @@ -87,7 +79,7 @@ type EconomicTerms: <" This class represents the full set of price-forming featu if payout -> assetPayout -> dividendTerms exists then terminationDate exists -choice ProductUnderlier: <"The product underlying the option, which can be of any type including an Asset, Basket, Index or a NonTransferableProduct."> +choice ProductUnderlier: <"The product underlying a feature, which can be of any type including an Asset, Basket, Index or a NonTransferableProduct."> Asset <"A financial product that can be owned and transferred in the financial markets"> Basket <"A collection of Observables with an identifier and optional weightings."> Index <"An observable computed on the prices, rates or valuations of a number of assets."> @@ -226,16 +218,17 @@ type PerformancePayout extends PayoutBase: <"Contains the necessary specificatio type PortfolioReturnTerms extends ReturnTerms : <"Specifies an individual type of return of a Performance Payout, when such individual return is part of an aggregation of multiple similar returns, at Performance Payout level."> [metadata key] - payerReceiver PayerReceiver (1..1) <"Canonical representation of the payer and receiver parties applicable to each individual return leg."> - underlier Product (1..1) <"Defines the product that is the subject of a tradable product definition, an underlying product definition, a physical exercise, a position, or other purposes."> - quantity NonNegativeQuantitySchedule (0..1 ) <"Specifies a quantity schedule for the underlier, which applies to each individual return leg."> - [metadata address "pointsTo"=PriceQuantity->quantity] - initialValuationPrice PriceSchedule (0..*) <"Specifies the initial valuation price(s) of the underlier. This price can be expressed either as an actual amount/currency, as a determination method, or by reference to another value specified in the swap document."> - [metadata address "pointsTo"=PriceQuantity->price] - interimValuationPrice PriceSchedule (0..*) <"Specifies the initial valuation price(s) of the underlier. This price can be expressed either as an actual amount/currency, as a determination method, or by reference to another value specified in the swap document."> - [metadata address "pointsTo"=PriceQuantity->price] - finalValuationPrice PriceSchedule (0..*) <"2018 ISDA CDM Equity Confirmation for Security Equity Swap: Final Price | Specifies the final valuation price of the underlier. This price can be expressed either as an actual amount/currency, as a determination method, or by reference to another value specified in the swap document."> - [metadata address "pointsTo"=PriceQuantity->price] + payerReceiver PayerReceiver (1..1) <"Canonical representation of the payer and receiver parties applicable to each individual return leg."> + underlier Observable (1..1) <"Defines the product that is the subject of a tradable product definition, an underlying product definition, a physical exercise, a position, or other purposes."> + [metadata address "pointsTo"=PriceQuantity->observable] + quantity NonNegativeQuantitySchedule (0..1 ) <"Specifies a quantity schedule for the underlier, which applies to each individual return leg."> + [metadata address "pointsTo"=PriceQuantity->quantity] + initialValuationPrice PriceSchedule (0..*) <"Specifies the initial valuation price(s) of the underlier. This price can be expressed either as an actual amount/currency, as a determination method, or by reference to another value specified in the swap document."> + [metadata address "pointsTo"=PriceQuantity->price] + interimValuationPrice PriceSchedule (0..*) <"Specifies the initial valuation price(s) of the underlier. This price can be expressed either as an actual amount/currency, as a determination method, or by reference to another value specified in the swap document."> + [metadata address "pointsTo"=PriceQuantity->price] + finalValuationPrice PriceSchedule (0..*) <"2018 ISDA CDM Equity Confirmation for Security Equity Swap: Final Price | Specifies the final valuation price of the underlier. This price can be expressed either as an actual amount/currency, as a determination method, or by reference to another value specified in the swap document."> + [metadata address "pointsTo"=PriceQuantity->price] type Payout: <"Represents the set of future cashflow methodologies in the form of specific payout data type(s) which result from the financial product. Examples: a trade in a cash asset will use only a settlement payout; for derivatives, two interest rate payouts can be combined to specify an interest rate swap; one interest rate payout can be combined with a credit default payout to specify a credit default swap."> [metadata key] @@ -326,23 +319,7 @@ type NonTransferableProduct extends ProductBase: <"A data type to specify the f condition PrimaryAssetClass: <"Specifies that when nonStandardisedTerms are True that a primary asset class must be specified."> if economicTerms -> nonStandardisedTerms = True - then productTaxonomy -> primaryAssetClass exists - -type Product: <"Defines the product that is the subject of a tradable product definition, an underlying product definition, a physical exercise, a position, or other purposes."> - [metadata key] - - contractualProduct ContractualProduct (0..1) <"Specifies the contractual product's economic terms, product identifier, and product taxonomy."> - index Index (0..1) <"Identifies an index by referencing a product identifier."> - loan Loan (0..1) <"Identifies a loan by referencing a product identifier and an optional set of attributes."> - foreignExchange ForeignExchange (0..1) <"Defines a foreign exchange spot or forward transaction."> - commodity Commodity (0..1) <"Identifies a commodity by referencing a product identifier."> - //**ART** - // [metadata address "pointsTo"=Observable->commodity] - security Security (0..1) <"Identifies a security by referencing a product identifier and a security type, plus an optional set of attributes."> - basket Basket (0..1) <"Identifies a custom basket by referencing a product identifier and its constituents."> - - condition: - one-of + then taxonomy -> primaryAssetClass exists type TradeLot: <"Specifies the price and quantity of a trade lot, where the same product could be traded multiple times with the same counterparty but in different lots (at a different date, in a different quantity and at a different price). One trade lot combined with a product definition specifies the entire economics of a trade. The lifecycle mechanics of each such trade lot (e.g. cashflow payments) is independent of the other lots."> lotIdentifier Identifier (0..*) <"Specifies one or more identifiers for the lot, if any."> From d85967791dc1d6c639c6820f441e763ed24f89b7 Mon Sep 17 00:00:00 2001 From: Lionel Smith-Gordon Date: Thu, 25 Jul 2024 11:16:51 +0000 Subject: [PATCH 5/5] PriceQuantity refactoring PriceQuantity refactoring --- .../product-common-settlement-func.rosetta | 13 -------- .../product-common-settlement-type.rosetta | 32 ++++++++++--------- 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/rosetta-source/src/main/rosetta/product-common-settlement-func.rosetta b/rosetta-source/src/main/rosetta/product-common-settlement-func.rosetta index 14f656ddd5..3794365b33 100644 --- a/rosetta-source/src/main/rosetta/product-common-settlement-func.rosetta +++ b/rosetta-source/src/main/rosetta/product-common-settlement-func.rosetta @@ -20,19 +20,6 @@ func UpdateAmountForEachMatchingQuantity: <"Updates any quantity from the list o output: updatedPriceQuantity PriceQuantity (1..*) <"List of price quantities with quantity amounts updated."> -func RateOptionObservableCondition: <"Implementation for PriceQuantity.RateOptionObservable condition."> - inputs: - pq PriceQuantity (1..1) - output: - valid boolean (0..1) - - set valid: - if pq -> observable -> index exists and pq -> price exists - then pq -> price - extract [ - priceType = PriceTypeEnum -> InterestRate and arithmeticOperator exists - ] all = True - func InterestRateObservableCondition: <"Implementation for PriceQuantity.InterestRateObservable condition."> inputs: pq PriceQuantity (1..1) diff --git a/rosetta-source/src/main/rosetta/product-common-settlement-type.rosetta b/rosetta-source/src/main/rosetta/product-common-settlement-type.rosetta index 9941ee6d65..a492023153 100644 --- a/rosetta-source/src/main/rosetta/product-common-settlement-type.rosetta +++ b/rosetta-source/src/main/rosetta/product-common-settlement-type.rosetta @@ -324,31 +324,33 @@ type TestPriceQuantity: <"Defines a settlement as an exchange between two partie then observable -> asset exists else observable -> index exists -type PriceQuantity: <"Defines a settlement as an exchange between two parties of a specified quantity of an asset (the quantity) against a specified quantity of another asset (the price). The settlement is optional and can be either cash or physical. In the case of non-cash products, the settlement of the price/quantity would not be specified here and instead would be delegated to the product mechanics, as parameterised by the price/quantity values."> +type PriceQuantity: <"Defines a settlement as an exchange between two parties of a specified quantity of an asset (the quantity) against a specified quantity of another asset (the price). The settlement is optional and can be either cash or physical. The quantity can additionally be specified in terms of one or more currency amounts. In the case of non-cash products, the settlement of the price/quantity would not be specified here and instead would be delegated to the product mechanics, as parameterised by the price/quantity values."> [metadata key] price PriceSchedule (0..*) <"Specifies a price to be used for trade amounts and other purposes."> [metadata location] quantity NonNegativeQuantitySchedule (0..*) <"Specifies a quantity to be associated with an event, for example a trade amount."> [metadata location] - observable Observable (0..1) <"Specifies the object to be observed for a price, it could be an asset or a reference. The cardinality is optional as some quantity / price cases have no observable (e.g. a notional and a fixed rate in a given currency)."> + currencyQuantity NonNegativeQuantitySchedule (0..*) <"The value of the observable, in one or more currencies."> + [metadata location] + observable Observable (0..1) <"Specifies the object to be observed for a price, it could be an asset or an index. The cardinality is optional as some quantity / price cases have no observable (e.g. a fixed rate in a given currency)."> [metadata location] effectiveDate AdjustableOrRelativeDate (0..1) <"Specifies the date at which the price and quantity become effective. This day may be subject to adjustment in accordance with a business day convention, or could be specified as relative to a trade date, for instance. Optional cardinality, as the effective date is usually specified in the product definition, so it may only need to be specified as part of the PriceQuantity in an increase/decrease scenario for an existing trade."> - condition RateOptionObservable: <"When the observable is a rate option, the price type must be interest rate and the arithmetic operator must be specified."> - RateOptionObservableCondition - - condition InterestRateObservable: <"When the observable is a rate option, the price type must be interest rate and the arithmetic operator must be specified."> - InterestRateObservableCondition + condition AtLeastOneQuantity: <"There should be one quantity at least; if more than one is used, one and only one of them must be populated in Quantity."> + (quantity count = 1 or currencyQuantity count = 1) and quantity count < 2 - condition CashQuantity: <"If the quantity refers to cash in a currency, this should be modelled by setting the currency in the unit type of the quantity and not using an Observable. "> - ( quantity -> unit -> currency exists and observable is absent ) - or - ( quantity -> unit -> currency is absent and observable exists ) + condition CurrencyQuantity: <"The currency quantity must use a currency unit."> + if currencyQuantity exists + then currencyQuantity -> unit -> currency exists + + condition AssetObservable: <"The Observable should be an Asset unless the arithmetic operator is being used."> + if quantity exists + then if price -> arithmeticOperator is absent + then observable -> asset exists + else observable -> index exists - condition ObservableExists: <"The Observable should be an Asset unless the arithmetic operator is being used."> - if price -> arithmeticOperator exists - then observable -> asset is absent - else observable -> asset exists + condition InterestRateObservable: <"When the observable is an interest rate index, the price type must be interest rate and the arithmetic operator must be specified."> + InterestRateObservableCondition type FixedPrice: <"A predefined price accorded by the counterparties.">