.cdm-java.6.0.0-dev.72.source-code.event-common-func.rosetta Maven / Gradle / Ivy
namespace cdm.event.common: <"Business event concepts: primitives, contract state and associated state transition function specifications.">
version "${project.version}"
import cdm.base.*
import cdm.base.math.*
import cdm.base.datetime.*
import cdm.base.staticdata.party.*
import cdm.base.staticdata.identifier.*
import cdm.base.staticdata.asset.common.*
import cdm.observable.asset.*
import cdm.observable.common.*
import cdm.observable.event.*
import cdm.product.template.*
import cdm.product.asset.*
import cdm.product.common.schedule.*
import cdm.product.common.settlement.*
import cdm.legaldocumentation.common.*
import cdm.legaldocumentation.master.*
import cdm.event.workflow.*
import cdm.event.position.*
func QuantityIncreased:
inputs:
before TradeState (1..1)
after TradeState (0..*)
output:
result boolean (1..1)
set result: <"Check each after (list item) is greater than before (func input).">
after
extract [
CompareTradeLot(
item -> trade -> tradeLot only-element,
CompareOp -> GreaterThan,
before -> trade -> tradeLot only-element
) = True
] all = True
func QuantityDecreased:
inputs:
before TradeState (1..1)
after TradeState (0..*)
output:
result boolean (1..1)
set result:
after
extract [
// check each after (item) is less than before (input)
CompareTradeLot(
item -> trade -> tradeLot only-element,
CompareOp -> LessThan,
before -> trade -> tradeLot only-element
) = True
and // check each after (item) is greater than zero
CompareTradeLotToAmount(
item -> trade -> tradeLot only-element,
CompareOp -> GreaterThan,
0.0
) = True
] all = True
func QuantityDecreasedToZero:
inputs:
before TradeState (0..*)
after TradeState (0..*)
output:
result boolean (1..1)
set result:
CompareTradeLotToAmount(
before -> trade -> tradeLot only-element,
CompareOp -> GreaterThanOrEquals,
0.0
) = True
and CompareTradeStatesToAmount(after, CompareOp -> Equals, 0.0) = True
func CompareTradeStatesToAmount: <"For each TradeState, compare the Quantity amounts in each TradeState to the given amount (regardless of unit of amount), based on the CompareOp enum.">
inputs:
tradeStates TradeState (0..*) <"List of TradeState to be compared.">
op CompareOp (1..1) <"Comparison operation to use.">
amount number (1..1) <"Quantity amount to use.">
output:
result boolean (1..1)
set result:
tradeStates
extract [
CompareTradeLotToAmount(
item -> trade -> tradeLot only-element,
op,
amount
)
] all = True
func TransfersForDate:
inputs:
transfers Transfer (0..*)
date date (1..1)
output:
transfersForDate Transfer (0..*)
add transfersForDate: transfers filter settlementDate -> adjustedDate = date
func FilterCashTransfers:
inputs:
transfers Transfer (0..*)
output:
cashTransfers Transfer (0..*)
add cashTransfers: transfers filter quantity -> unit -> currency exists
func FilterSecurityTransfers:
inputs:
transfers Transfer (0..*)
output:
securityTransfers Transfer (0..*)
add securityTransfers: transfers filter asset -> Instrument -> Security exists
func ResolveInterestRateObservationIdentifiers: <"Defines which attributes on the InterestRatePayout should be used to locate and resolve the underlier's price, for example for the reset process.">
inputs:
payout InterestRatePayout (1..1)
date date (1..1)
output:
identifiers ObservationIdentifier (1..1)
set identifiers -> observable -> Index -> FloatingRateIndex:
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.
func ResolveInterestRateReset: <"Defines how to resolve the reset value for an InterestRatePayout.">
inputs:
payouts InterestRatePayout (1..*)
observation Observation (1..1)
resetDate date (1..1)
rateRecordDate date (0..1)
output:
reset Reset (1..1)
set reset -> resetValue: <"Assigns the observed value to the reset value.">
observation -> observedValue
set reset -> resetDate: resetDate
set reset -> rateRecordDate: rateRecordDate
add reset -> observations: <"Assigns the observation required to compute the rest value as audit.">
observation
func InterestCashSettlementAmount: <"Defines the performance calculations relevent for a fixed or floating rate payout.">
inputs:
tradeState TradeState (1..1)
interestRatePayout InterestRatePayout (1..1)
resets Reset (1..*)
date date (1..1)
output:
interestCashSettlementAmount Transfer (1..1)
alias performance:
if interestRatePayout -> rateSpecification -> FixedRateSpecification exists
then FixedAmount(
interestRatePayout,
interestRatePayout -> priceQuantity -> quantitySchedule -> value,
date,
empty
)
else if interestRatePayout -> rateSpecification -> FloatingRateSpecification exists
then FloatingAmount(
interestRatePayout,
resets only-element -> resetValue -> value,
interestRatePayout -> priceQuantity -> quantitySchedule -> value,
date,
empty
)
alias payer:
ExtractCounterpartyByRole(
tradeState -> trade -> counterparty,
interestRatePayout -> payerReceiver -> payer
) -> partyReference
alias receiver:
ExtractCounterpartyByRole(
tradeState -> trade -> counterparty,
interestRatePayout -> payerReceiver -> receiver
) -> partyReference
set interestCashSettlementAmount -> quantity -> value: performance
set interestCashSettlementAmount -> quantity -> unit -> currency:
interestRatePayout -> priceQuantity -> quantitySchedule -> unit -> currency
set interestCashSettlementAmount -> payerReceiver -> payerPartyReference:
if performance >= 0 then payer else receiver
set interestCashSettlementAmount -> payerReceiver -> receiverPartyReference:
if performance >= 0 then receiver else payer
set interestCashSettlementAmount -> settlementDate -> adjustedDate: date
set interestCashSettlementAmount -> settlementOrigin -> interestRatePayout:
interestRatePayout as-key
func ResolveReset: <"Defines the interface for adopters to resolve a reset, given a trade state and a date.">
inputs:
tradeState TradeState (1..1)
date date (1..1)
output:
reset Reset (1..1)
func ResolvePerformanceObservationIdentifiers: <"Defines which attributes on the PerformancePayout should be used to locate and resolve the underlier's price, for example for the reset process.">
inputs:
payout PerformancePayout (1..1)
adjustedDate date (1..1)
output:
identifiers ObservationIdentifier (1..1)
alias adjustedFinalValuationDate:
ResolveAdjustableDate(
payout -> valuationDates -> finalValuationDate -> valuationDate
)
alias valuationDates: <"Determine which valuation date to get valuation time and type from.">
if adjustedDate < adjustedFinalValuationDate
then payout -> valuationDates -> interimValuationDate
else payout -> valuationDates -> finalValuationDate
set identifiers -> observable: <"Represents the identifer for the equity underlier.">
payout -> underlier -> Observable
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
then last
set identifiers -> observationTime: <"Specifies the time for which to retrieve the market data value(s).">
ResolvePerformanceValuationTime(
valuationDates -> valuationTime,
valuationDates -> valuationTimeType,
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
func AdjustedValuationDates:
inputs:
valuationDates ValuationDates (1..1)
output:
adjustedValuationDates date (0..*)
set adjustedValuationDates: <"Build sorted list of adjusted valuation dates.">
[
ResolveAdjustableDates(
valuationDates -> interimValuationDate -> valuationDates
),
ResolveAdjustableDate(valuationDates -> finalValuationDate -> valuationDate)
]
sort
func ResolvePerformanceValuationTime: <"Defines how to resolve the observation time from those specified in the Performance Valuation type.">
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.">
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)
set time:
if valuationTime exists
then TimeZoneFromBusinessCenterTime(valuationTime)
set time:
if valuationTimeType exists
then ResolveTimeZoneFromTimeType(
assetIdentifier,
valuationTimeType,
determinationMethod
)
func ResolvePerformanceReset: <"Defines how to resolve the reset value for a performance payout.">
inputs:
performancePayout PerformancePayout (1..1) <"Represents the PerformancePayout to which the reset will apply.">
observation Observation (1..1) <"Represents the observation that will be used to compute the reset value.">
date date (1..1) <"Specifies the date of the reset.">
output:
reset Reset (1..1)
set reset -> resetValue: <"Assigns the observed value to the reset value.">
observation -> observedValue
set reset -> resetDate: date
add reset -> observations: <"Assigns the observation required to compute the rest value as audit.">
observation
func EquityCashSettlementAmount: <"Represents Part 1 Section 12 of the 2018 ISDA CDM Equity Confirmation for Security Equity Swap, Para 72. 'Equity Cash Settlement Amount' means, in respect of an Equity Cash Settlement Date, an amount in the Settlement Currency determined by the Calculation Agent as of the Equity Valuation Date to which the Equity Cash Settlement Amount relates, pursuant to the following formula: Equity Cash Settlement Amount = ABS(Rate Of Return) * Equity Notional Amount.">
inputs:
tradeState TradeState (1..1)
date date (1..1)
output:
equityCashSettlementAmount Transfer (1..1)
alias equityPerformancePayout:
tradeState -> trade -> product -> economicTerms -> payout -> performancePayout only-element
alias equityPerformance:
EquityPerformance(
tradeState -> trade,
tradeState -> resetHistory only-element -> resetValue,
date
)
alias payer:
ExtractCounterpartyByRole(
tradeState -> trade -> counterparty,
equityPerformancePayout -> payerReceiver -> payer
) -> partyReference
alias receiver:
ExtractCounterpartyByRole(
tradeState -> trade -> counterparty,
equityPerformancePayout -> payerReceiver -> receiver
) -> partyReference
set equityCashSettlementAmount -> quantity -> value: <"Equity Cash Settlement Amount is defined here as Abs( Equity Performance ). Per the ISDA Definitions: Equity Performance = (Rate Of Return) Equity Notional Amount and Equity Cash Settlement Amount = ABS(Rate Of Return) Equity Notional Amount; so the calculation for Equity Cash Settlement Amount in the CDM is mathematically equivalent, with the added benefit that Rate of Return does not need to be recomputed, since it was already computed in the Reset Event.">
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 -> tradeLot only-element -> priceQuantity -> price
) -> unit -> currency
set equityCashSettlementAmount -> payerReceiver -> payerPartyReference:
if equityPerformance >= 0 then payer else receiver
set equityCashSettlementAmount -> payerReceiver -> receiverPartyReference:
if equityPerformance >= 0 then receiver else payer
set equityCashSettlementAmount -> settlementDate -> adjustedDate:
ResolveCashSettlementDate(tradeState)
set equityCashSettlementAmount -> settlementOrigin -> performancePayout:
equityPerformancePayout as-key
func EquityPerformance: <"Part 1 Section 12 of the 2018 ISDA CDM Equity Confirmation for Security Equity Swap, Para 75. 'Equity Performance' means, in respect of an Equity Cash Settlement Date, an amount in the Settlement Currency determined by the Calculation Agent as of the Equity Valuation Date to which the Equity Cash Settlement Amount relates, pursuant to the following formula: Equity Performance = (Rate Of Return) Equity Notional Amount.">
inputs:
trade Trade (1..1)
observation Price (1..1)
date date (1..1)
output:
equityPerformance number (1..1)
alias performancePayout:
trade -> product -> economicTerms -> payout -> performancePayout only-element
alias periodStartPrice: <"Only works in the case of a single trade lot.">
ResolvePerformancePeriodStartPrice(
performancePayout,
trade -> tradeLot only-element -> priceQuantity -> price,
trade -> tradeLot -> priceQuantity -> observable only-element,
date
)
alias periodEndPrice: observation
alias numberOfSecurities:
performancePayout -> priceQuantity -> quantitySchedule -> value / periodStartPrice -> value
alias rateOfReturn: RateOfReturn(periodStartPrice, periodEndPrice)
alias notionalAmount: EquityNotionalAmount(numberOfSecurities, periodEndPrice)
condition PriceReturnTermsExists:
trade -> product -> economicTerms -> payout -> performancePayout -> returnTerms -> priceReturnTerms exists
set equityPerformance: rateOfReturn * notionalAmount
func RateOfReturn: <"Part 1 Section 12 of the 2018 ISDA CDM Equity Confirmation for Security Equity Swap, Para 139. 'Rate Of Return' means, in respect of any Equity Valuation Date, the amount determined pursuant to the following formula: Rate Of Return = (Final Price - Initial Price) / Initial Price.">
inputs:
initialPrice PriceSchedule (1..1)
finalPrice PriceSchedule (1..1)
output:
rateOfReturn number (1..1)
alias initialPriceValue: initialPrice -> value
alias finalPriceValue: finalPrice -> value
set rateOfReturn:
if finalPriceValue exists and initialPriceValue exists and initialPriceValue > 0
then (finalPriceValue - initialPriceValue) / initialPriceValue
func EquityNotionalAmount: <"Part 1 Section 12 of the 2018 ISDA CDM Equity Confirmation for Security Equity Swap, Para 74. 'Equity Notional Amount' means the Number Of Securities times the Initial Price, adjusted, if applicable, as provided in Part 1 Section 2.2, 'Equity Notional Reset'. If 'With Reset' is the Equity Notional Reset Election, then in respect of each Equity Cash Settlement Date: (i) the Equity Notional Amount applicable in respect of the first Equity Cash Settlement Date will be the amount specified as such in the definition of Equity Notional Amount; (ii) the Equity Notional Amount applicable in respect of each subsequent Equity Cash Settlement Date will be the sum of (a) the Equity Notional Amount in respect of the prior Equity Cash Settlement Date and (b) the Equity Performance, whether positive or negative, in respect of the prior Equity Cash Settlement Date; and (iii) the Floating Notional Amount will be adjusted as provided in sub-clauses (i) and (ii) above as though it were an Equity Notional Amount.">
inputs:
numberOfSecurities number (1..1)
price Price (1..1)
output:
equityNotionalAmount number (1..1)
alias priceValue: price -> value
set equityNotionalAmount: numberOfSecurities * priceValue
func Create_StockSplit: <"Function specification to create the fully-formed business event which represents the impact of a stock split (or a reverse stock split) on an Equity Derivatives contract on a certain date.">
inputs:
stockSplitInstruction StockSplitInstruction (1..1)
before TradeState (1..1)
output:
after TradeState (1..1)
alias preSplitNumberOfShares: <"Only works in the case of a single trade lot.">
FilterQuantityByFinancialUnit(
before -> trade -> tradeLot only-element -> priceQuantity -> quantity,
FinancialUnitEnum -> Share
)
only-element -> value
alias postSplitNumberOfShares: <"The adjustment ratio is be multiplied by existing shares in an equity derivative contract or other positions to determine the post-split number of shares.">
NonNegativeQuantitySchedule {
value: preSplitNumberOfShares * stockSplitInstruction -> adjustmentRatio,
unit: UnitType {
financialUnit: FinancialUnitEnum -> Share,
...
},
...
}
alias preSplitPrice:
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.">
Price {
value: preSplitPrice -> value / stockSplitInstruction -> adjustmentRatio,
unit: preSplitPrice -> unit,
perUnitOf: preSplitPrice -> perUnitOf,
priceType: preSplitPrice -> priceType,
priceExpression: preSplitPrice -> priceExpression,
composite: preSplitPrice -> composite,
arithmeticOperator: preSplitPrice -> arithmeticOperator,
cashPrice: preSplitPrice -> cashPrice,
datedValue: empty
}
alias postSplitPriceQuantity:
PriceQuantity {
price: postSplitPrice,
quantity: postSplitNumberOfShares,
...
}
alias quantityChangeInstruction:
QuantityChangeInstruction {
change: postSplitPriceQuantity,
direction: QuantityChangeDirectionEnum -> Replace,
lotIdentifier: empty
}
alias primitiveInstruction:
PrimitiveInstruction {
quantityChange: quantityChangeInstruction,
...
}
set after: Create_TradeState(primitiveInstruction, before)
func Create_Execution: <"Specifies the function to compose an execution based on a minimum required set of inputs: product, quantity, parties, etc.">
inputs:
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 -> product: <"Assign the product input to the tradable product of the execution object.">
instruction -> product
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 -> counterparty: <"Assign the counterparty input to the tradable product of the execution object.">
instruction -> counterparty
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
add execution -> trade -> partyRole: <"Assign the party roles input to the execution object.">
instruction -> partyRoles
set execution -> trade -> executionDetails: <"Assign the settlement terms input to the execution object.">
instruction -> executionDetails
set execution -> trade -> tradeDate: <"Assign the tradeDate input to the execution object.">
instruction -> tradeDate
add execution -> trade -> tradeIdentifier: <"Assign the identifier input to the execution object.">
instruction -> tradeIdentifier
set execution -> state -> positionState: <"Assign the position status to executed.">
PositionStatusEnum -> Executed
set execution -> trade -> collateral: <"Assign the anticpated collateral details to the tradable product of the excution object.">
instruction -> collateral
func Create_ContractFormationInstruction:
inputs:
legalAgreement LegalAgreement (0..*)
output:
instruction ContractFormationInstruction (1..1)
condition ExecutedAgreement: <"The full formation of a contract can only be completed with executed legal agreements if any.">
if legalAgreement exists
then legalAgreement -> agreementDate exists
add instruction -> legalAgreement: legalAgreement
func Create_ContractFormation: <"Function specification that represents an executed trade for a contractual product that has been affirmed (or confirmed) by the two parties. The formed contract can reference a legal agreement for instance a master agreement, by using the optional legalAgreement input.">
inputs:
instruction ContractFormationInstruction (1..1) <"Instructions to be used as an input to the function">
execution TradeState (1..1)
output:
contractFormation TradeState (1..1) <"Primitive event containing the execution as its before state and the contract as the after state.">
set contractFormation: execution
add contractFormation -> trade -> contractDetails -> documentation: <"Append any legal agreements from the instructions.">
instruction -> legalAgreement
set contractFormation -> state -> positionState: <"Assign the position status to formed.">
PositionStatusEnum -> Formed
func Create_Exercise: <"Defines the process of putting into effect the rights specified in an options contract, such as to buy or sell a security. Once exercised the option contract is terminated.">
inputs:
exerciseInstruction ExerciseInstruction (1..1) <"Instruction containing the terms of the option exercise.">
originalTrade TradeState (1..1) <"The original trade to be split, which must be of single cardinality.">
output:
exercise TradeState (1..*)
alias optionPayout: <"Extracts the optionPayout from exerciseInstruction if provided or from the original trade if absent">
if exerciseInstruction -> exerciseOption exists
then exerciseInstruction -> exerciseOption
else originalTrade -> trade -> 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 that contains an Observable or a Product as the underlier.">
optionPayout -> underlier
alias resultProduct: <"Find or create the the non transferable product that will result from the exercise.">
if underlier -> Product -> NonTransferableProduct exists // It already exists, no need to create
then underlier -> Product -> NonTransferableProduct
else Create_NonTransferableProduct(underlier, optionPayout -> payerReceiver)
alias productWithDirection: <"If the option is a Put, then the direction on the result product needs to be flipped from that on the underlier.">
if optionPayout -> optionType = OptionTypeEnum -> Put
then Update_ProductDirection(resultProduct, optionPayout -> payerReceiver -> payer, optionPayout -> payerReceiver -> receiver)
else resultProduct
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: productWithDirection,
priceQuantity: originalTrade -> trade -> tradeLot only-element -> priceQuantity,
counterparty: originalTrade -> trade -> counterparty,
ancillaryParty: originalTrade -> trade -> ancillaryParty,
parties: originalTrade -> trade -> party,
partyRoles: originalTrade -> trade -> partyRole,
executionDetails: empty,
tradeDate: originalTrade -> trade -> tradeDate,
tradeIdentifier: exerciseInstruction -> replacementTradeIdentifier,
...
}
)
condition OptionPayoutExists: <"Requires that the original contract contains an option payout.">
optionPayout exists
add exercise: <"Reduces notional / quantity of option by the amount exercised.">
Create_TradeState(exerciseInstruction -> exerciseQuantity, originalTrade)
add exercise: <"Adds the replacement trade">
execution
func Update_ProductDirection: <"Flips the payer and receiver on a product (used when a Put Option is exercised).">
inputs:
before NonTransferableProduct (1..1)
originalPayer CounterpartyRoleEnum (1..1)
originalReceiver CounterpartyRoleEnum (1..1)
output:
after NonTransferableProduct (1..1)
set after: before
set after -> economicTerms -> payout -> optionPayout -> payerReceiver -> payer: originalReceiver
set after -> economicTerms -> payout -> optionPayout -> payerReceiver -> receiver: originalPayer
func Create_NonTransferableProduct: <"Creates a NonTransferableProduct (ie EconomicTerms) from an underlier.">
inputs:
underlier Underlier (1..1)
payerReceiver PayerReceiver (1..1)
output:
newProduct NonTransferableProduct (1..1)
set newProduct -> economicTerms -> payout -> settlementPayout -> underlier: 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.">
tradeState TradeState (1..1) <"Specifies the trade that is resetting.">
output:
reset TradeState (1..1)
alias payout: <"Specifies the payout that is resetting.">
instruction -> payout
alias observationDate: <"If the rateRecordDate is provided in the instructions, it should used as the observation date when determining the fixing rate for an interest rate payout.">
if instruction -> rateRecordDate exists
then instruction -> rateRecordDate
else instruction -> resetDate
alias observationIdentifiers: <"Resolves the ObservationIdentifier to be used to derive the single observation to be used in the reset calculation. Resolving the ObservationIdentifier is dependent on the type of payout in use.">
if payout -> performancePayout count = 1
then ResolvePerformanceObservationIdentifiers(
payout -> performancePayout only-element,
instruction -> resetDate
)
else if payout -> interestRatePayout exists
then ResolveInterestRateObservationIdentifiers(
payout -> interestRatePayout only-element,
observationDate
)
alias observation: <"Represents the single observation that will be used to compute the reset value.">
ResolveObservation([observationIdentifiers], empty)
set reset: tradeState
add reset -> resetHistory: <"To handle the various ways Contracts can change over time, ">
if payout -> performancePayout count = 1
then ResolvePerformanceReset(
payout -> performancePayout only-element,
observation,
instruction -> resetDate
)
else if payout -> interestRatePayout exists
then ResolveInterestRateReset(
payout -> interestRatePayout,
observation,
instruction -> resetDate,
instruction -> rateRecordDate
)
func CalculateTransfer: <"Function specification to calculate a transfer, e.g. following a reset on a contract">
inputs:
instruction CalculateTransferInstruction (1..1)
output:
transfer Transfer (0..*)
add transfer: <"Assigns the result of the Create_Transfer function to the transferHistory attribute.">
if instruction -> payout -> interestRatePayout exists
or instruction -> payout -> performancePayout exists
or instruction -> payout -> assetPayout exists
then Create_CashTransfer(instruction)
add transfer: <"Assigns the result of the Create_AssetTransfer function to the transferHistory attribute.">
if instruction -> payout -> assetPayout exists
then Create_AssetTransfer(instruction)
func Create_Transfer: <"Defines how a transfer should be constructed, when representing the exchange of cash between parties.">
[docReference ICMA GMRA namingConvention "Purchase Price"
provision "As defined in the GMRA, paragraph 2(nn) The Purchase Price is the price at which the Purchased Securities are sold or are to be sold by Seller to Buyer."]
[docReference ICMA ERCCBestPractice namingConvention "Purchase Price"
provision "ERCC Guide: Annex II Glossary of repo terminology. The term for the sum of money paid by the Buyer to the Seller on the Purchase Date of a repo. It is equal to the initial Market Value of the collateral less any haircut or initial margin (called Margin Ratio in the GMRA)."]
inputs:
instruction TransferInstruction (1..1)
tradeState TradeState (1..1) <"Represents the trade and associated state on which to construct the Transfer data type.">
output:
transfer TradeState (1..1)
set transfer: tradeState
add transfer -> transferHistory: <"Assigns the transfer contained in the transfer instruction to the transferHistory attribute.">
instruction -> transferState
func Create_CashTransfer: <"Defines how Transfer that represents an exchange of cash, should be constructed.">
inputs:
instruction CalculateTransferInstruction (1..1)
output:
transfer Transfer (1..1)
set transfer: <"Resolves the cashflow due to be transferred from the trade and associated state.">
ResolveTransfer(instruction)
func Create_AssetTransfer: <"Defines how Transfer that represents an exchange of asset based on an asset payout, should be constructed.">
inputs:
instruction CalculateTransferInstruction (1..1)
output:
transfer Transfer (1..1)
alias assetPayout:
instruction -> tradeState -> trade -> product -> economicTerms -> payout -> assetPayout only-element
alias tradeQuantity: <"Security quantity obtained by filtering on the trade quantity">
FilterQuantityByFinancialUnit(
instruction -> tradeState -> trade -> tradeLot -> priceQuantity -> quantity,
FinancialUnitEnum -> Share
)
only-element
alias securityQuantity:
if instruction -> quantity exists
then instruction -> quantity
else NonNegativeQuantity {
value: tradeQuantity -> value,
unit: tradeQuantity -> unit,
...
}
alias securityPrice:
FilterPrice(
instruction -> tradeState -> trade -> tradeLot -> priceQuantity -> price,
PriceTypeEnum -> AssetPrice,
empty,
empty
)
condition ShareUnits:
if instruction -> quantity exists
then instruction -> quantity -> unit -> financialUnit = FinancialUnitEnum -> Share
set transfer -> quantity:
NonNegativeQuantity {
value: securityQuantity -> value,
unit: securityQuantity -> unit,
...
}
add transfer -> asset -> Instrument -> Security -> identifier:
assetPayout -> underlier ->> identifier
set transfer -> payerReceiver -> payerPartyReference:
if instruction -> payerReceiver -> payer exists
then ExtractCounterpartyByRole(
instruction -> tradeState -> trade -> counterparty,
instruction -> payerReceiver -> payer
) -> partyReference
else if assetPayout -> payerReceiver -> payer exists
then ExtractCounterpartyByRole(
instruction -> tradeState -> trade -> counterparty,
assetPayout -> payerReceiver -> payer
) -> partyReference
set transfer -> payerReceiver -> receiverPartyReference:
if instruction -> payerReceiver -> payer exists
then ExtractCounterpartyByRole(
instruction -> tradeState -> trade -> counterparty,
instruction -> payerReceiver -> receiver
) -> partyReference
else if assetPayout -> payerReceiver -> receiver exists
then ExtractCounterpartyByRole(
instruction -> tradeState -> trade -> counterparty,
assetPayout -> payerReceiver -> receiver
) -> partyReference
set transfer -> settlementDate -> adjustedDate: instruction -> date
set transfer -> settlementOrigin -> assetPayout:
if instruction -> tradeState -> trade -> product -> economicTerms -> payout -> assetPayout exists
then instruction -> tradeState -> trade -> product -> economicTerms -> payout -> assetPayout only-element
as-key
func ResolveTransfer: <"Defines how to calculate the amount due to be transferred after a Reset Event.">
inputs:
instruction CalculateTransferInstruction (1..1)
output:
transfer Transfer (1..1)
alias payout: instruction -> payout
set transfer:
if payout -> assetPayout exists
then SecurityFinanceCashSettlementAmount(
instruction -> tradeState,
instruction -> date,
instruction -> quantity,
instruction -> payerReceiver
)
else if payout -> performancePayout exists
then EquityCashSettlementAmount(instruction -> tradeState, instruction -> date)
else if payout -> interestRatePayout -> rateSpecification -> FloatingRateSpecification exists
or payout -> interestRatePayout -> rateSpecification -> FixedRateSpecification exists
then InterestCashSettlementAmount(
instruction -> tradeState,
payout -> interestRatePayout only-element,
instruction -> resets,
instruction -> date
)
set transfer -> settlementDate -> adjustedDate: instruction -> date
func ResolveCashSettlementDate: <"A product agnostic function that resolves the settlement date of the payout for the period in question">
inputs:
tradeState TradeState (1..1)
output:
date date (1..1)
func SecurityFinanceCashSettlementAmount:
[docReference ICMA GMRA namingConvention "Repurchase Price"
provision "As defined in GMRA paragraph 2(rr) The Repurchase Price is the sum of Purchase Price and Price Differential."]
[docReference ICMA ERCCBestPractice namingConvention "Repurchase Price"
provision "ERCC Guide: Annex II Glossary of repo terminology. The term for the sum of money to be paid by the Seller of a repo to the Buyer on the Repurchase Date to buy back equivalent collateral. It is equal to the Purchase Price plus repo interest. This term also applies to the value of the cash owed to the Buyer on any day during the term of a repo, that is, the Purchase Price plus repo interest accrued up to that particular date. In the case of Buy/Sell-Backs, the Repurchase Price is net of the amount of any coupon, dividend or other income on the collateral paid to the Buyer during the life of the transaction plus reinvestment income to compensate for the delayed payment."]
inputs:
tradeState TradeState (1..1)
date date (1..1)
quantity Quantity (0..1) <"Specifies quantity amount returned if not the full amount from the TradeState, e.g. partial return">
payerReceiver PayerReceiver (0..1)
output:
cashSettlementAmount Transfer (1..1)
alias assetPayout:
tradeState -> trade -> product -> economicTerms -> payout -> assetPayout only-element
alias collateral:
tradeState -> trade -> product -> economicTerms -> collateral
alias securityQuantity: <"Specifies the number of securities.">
if quantity exists
then quantity
else FilterQuantityByFinancialUnit(
tradeState -> trade -> tradeLot -> priceQuantity -> quantity,
FinancialUnitEnum -> Share
)
alias securityPrice: <"Specifies the price per security.">
FilterPrice(
tradeState -> trade -> tradeLot -> priceQuantity -> price,
PriceTypeEnum -> AssetPrice,
empty,
empty
)
alias marginRatio:
if collateral -> collateralProvisions -> eligibleCollateral only-element -> treatment -> valuationTreatment -> haircutPercentage exists
then 1 / (1.0 - collateral -> collateralProvisions -> eligibleCollateral only-element -> treatment -> valuationTreatment -> haircutPercentage)
else if collateral -> collateralProvisions -> eligibleCollateral only-element -> treatment -> valuationTreatment -> marginPercentage exists
then collateral -> collateralProvisions -> eligibleCollateral only-element -> treatment -> valuationTreatment -> marginPercentage
else 1.0
condition ShareUnitExists:
if quantity exists
then quantity -> unit -> financialUnit = FinancialUnitEnum -> Share
condition IdentifiersMatch:
tradeState -> trade -> tradeLot -> priceQuantity -> observable -> Asset ->> identifier = assetPayout -> underlier ->> identifier
set cashSettlementAmount -> quantity -> value:
securityPrice -> value * securityQuantity -> value * marginRatio
set cashSettlementAmount -> quantity -> unit -> currency:
securityPrice -> unit -> currency
set cashSettlementAmount -> payerReceiver -> payerPartyReference:
if payerReceiver exists
then ExtractCounterpartyByRole(
tradeState -> trade -> counterparty,
payerReceiver -> receiver
) -> partyReference
else if assetPayout -> payerReceiver -> receiver exists
then ExtractCounterpartyByRole(
tradeState -> trade -> counterparty,
assetPayout -> payerReceiver -> receiver
) -> partyReference
set cashSettlementAmount -> payerReceiver -> receiverPartyReference:
if payerReceiver exists
then ExtractCounterpartyByRole(
tradeState -> trade -> counterparty,
payerReceiver -> payer
) -> partyReference
else if assetPayout -> payerReceiver -> payer exists
then ExtractCounterpartyByRole(
tradeState -> trade -> counterparty,
assetPayout -> payerReceiver -> payer
) -> partyReference
set cashSettlementAmount -> settlementDate -> adjustedDate: date
set cashSettlementAmount -> settlementOrigin -> assetPayout: assetPayout as-key
func Create_Split: <"Defines the logic for splitting a trade into separate copies. The split instruction contains a breakdown into N set of primitive instructions. Each set contains the primitive instructions to be applied to each post-split trade, eventually producing N trades. The split function underpins a number of business events such as clearing or allocation.">
inputs:
breakdown PrimitiveInstruction (1..*) <"Each primitive instruction contains the set of instructions to be applied to each post-split trade.">
originalTrade TradeState (1..1) <"The original trade to be split, which must be of single cardinality.">
output:
splitTrade TradeState (1..*)
add splitTrade: <"Iterate over each breakdown and apply the set of primitive instructions to each copy of the original trade.">
breakdown extract Create_TradeState(item, originalTrade)
func Create_PartyChange: <"Defines the logic for changing one of the counterparties on a trade. A new trade identifier must be specified as a change of party results in a new trade. An ancillary party can also be specified, for instance to refer to the original executing party on the new trade.">
inputs:
counterparty Counterparty (1..1) <"The counterparty to change and the role it plays in the transaction.">
ancillaryParty AncillaryParty (0..1) <"Optional ancillary party, which can be used to keep a reference to the original executing party, for instance.">
partyRole PartyRole (0..1)
tradeId TradeIdentifier (1..*) <"A mandatory trade identifier must be specified, as the chnage of party results in a new trade.">
originalTrade TradeState (1..1) <"The original trade on which to update the counterparty. The original trade will be terminated.">
output:
newTrade TradeState (1..1)
alias counterparty1:
if counterparty -> role = CounterpartyRoleEnum -> Party1
then Counterparty {
partyReference: counterparty -> partyReference as-key,
role: counterparty -> role
}
else ExtractCounterpartyByRole(
originalTrade -> trade -> counterparty,
CounterpartyRoleEnum -> Party1
)
alias counterparty2:
if counterparty -> role = CounterpartyRoleEnum -> Party2
then Counterparty {
partyReference: counterparty -> partyReference as-key,
role: counterparty -> role
}
else ExtractCounterpartyByRole(
originalTrade -> trade -> counterparty,
CounterpartyRoleEnum -> Party2
)
alias partyToRemove:
ExtractCounterpartyByRole(
originalTrade -> trade -> counterparty,
counterparty -> role
) -> partyReference
set newTrade: <"Copy the original trade.">
originalTrade
set newTrade -> trade -> counterparty: <"Assigns the new counterparties.">
[counterparty1, counterparty2]
set newTrade -> trade -> party: <"Removes the existing party, and adds the new party.">
ReplaceParty(
originalTrade -> trade -> party,
partyToRemove,
counterparty -> partyReference
)
set newTrade -> trade -> tradeIdentifier: <"Replaces the existing trade identifier with the new trade identifier">
tradeId
add newTrade -> trade -> party: <"Add ancillary party as an additional party">
ancillaryParty -> partyReference
add newTrade -> trade -> ancillaryParty: <"Add ancillary party role">
ancillaryParty
add newTrade -> trade -> party: <"Add party role party reference as an additional party">
partyRole -> partyReference
add newTrade -> trade -> partyRole: <"Add party role">
partyRole
set newTrade -> transferHistory: <"Clear transfer history.">
EmptyTransferHistory()
func EmptyTransferHistory:
output:
emptyTransferHistory TransferState (0..*)
func Create_QuantityChange: <"A specification of the inputs, outputs and constraints when calculating the after state of a Quantity Change Primitive Event">
inputs:
instruction QuantityChangeInstruction (1..1)
tradeState TradeState (1..1)
output:
quantityChange TradeState (1..1)
alias trade: <"The Trade from the input TradeState">
tradeState -> trade
alias tradeLotExists: <"The quantity change instruction applies to an existing tradeLot">
FilterTradeLot(trade -> tradeLot, instruction -> lotIdentifier) exists
alias tradeLot: <"Get the existing trade lot if specified, or return only trade lot">
if tradeLotExists
then FilterTradeLot(trade -> tradeLot, instruction -> lotIdentifier)
else trade -> tradeLot only-element
alias newPriceQuantity: <"Update the PriceQuantity based on the change and direction inputs. For an increase, if the trade lot exists, apply the changes to the existing PriceQuantity; otherwise, add the changed PriceQuantity to the list of TradeLots. For a decrease or replace, apply the changes to the existing PriceQuantity.">
if instruction -> direction = QuantityChangeDirectionEnum -> Increase
and tradeLotExists = False
then instruction -> change
else UpdateAmountForEachMatchingQuantity(
tradeLot -> priceQuantity,
instruction -> change,
instruction -> direction
)
alias newTradeLots: <"Add or merge updated TradeLot.">
if instruction -> direction = QuantityChangeDirectionEnum -> Increase
and tradeLotExists = False
then AddTradeLot(
trade,
TradeLot {
lotIdentifier: instruction -> lotIdentifier,
priceQuantity: newPriceQuantity
}
) -> tradeLot
else ReplaceTradeLot(
trade -> tradeLot,
TradeLot {
lotIdentifier: instruction -> lotIdentifier,
priceQuantity: newPriceQuantity
}
)
condition CashPriceOnly: <"Only termination where the termination price is specified as a cash price is supported for now.">
if instruction -> direction = QuantityChangeDirectionEnum -> Decrease
and instruction -> change -> price exists
then instruction -> change -> price -> priceType all = PriceTypeEnum -> CashPrice
set quantityChange: tradeState
// Update trade with new TradableProduct.
set quantityChange -> trade -> product: trade -> product
set quantityChange -> trade -> tradeLot: newTradeLots
set quantityChange -> trade -> counterparty: trade -> counterparty
set quantityChange -> trade -> ancillaryParty: trade -> ancillaryParty
set quantityChange -> trade -> adjustment: trade -> adjustment
set quantityChange -> state -> positionState:
if newTradeLots -> priceQuantity -> quantity -> value all = 0
then PositionStatusEnum -> Closed
func Create_TermsChange: <"A specification of the inputs, outputs and constraints when calculating the after tradeState based Terms Change Primitive Instruction.">
inputs:
termsChange TermsChangeInstruction (1..1) <"Instructions to be used as an input to the function">
before TradeState (1..1) <"current trade to be ammended">
output:
tradeState TradeState (1..1)
alias newProduct:
if termsChange -> product exists
then termsChange -> product
else before -> trade -> product
alias newAncillaryParty:
if termsChange -> ancillaryParty exists
then termsChange -> ancillaryParty
else before -> trade -> ancillaryParty
alias newAdjustment:
if termsChange -> adjustment exists
then termsChange -> adjustment
else before -> trade -> adjustment
set tradeState: before
// 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:
tradeStates TradeState (0..*)
output:
openTradeStates TradeState (0..*)
add openTradeStates: tradeStates filter state -> closedState is absent
func FilterClosedTradeStates: <"Filter to only 'closed' TradeState - where either the closedState or positionState are set.">
inputs:
tradeStates TradeState (0..*)
output:
closedTradeStates TradeState (0..*)
add closedTradeStates: tradeStates filter state -> closedState exists
func NewEquitySwapProduct: <"Function specification to create an Equity Swap according to the 2018 ISDA CDM Equity Confirmation Template, based on a minimum set of inputs which can (optionally) include a Master Confirmation Agreement. The inputs represent the minimum set of inputs required to create an Equity Swap, either based on an existing Master Confirmation Agreement or as a stand-alone Equity Swap">
inputs:
security Security (1..1) <"The underlying Equity asset for the swap.">
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 NonTransferableProduct (1..1)
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 payout -> performancePayout:
NewSingleNameEquityPerformancePayout(security, masterConfirmation)
add payout -> interestRatePayout: <"Equity and interest rate payouts must be set-up according to their corresponding payout specifications">
if masterConfirmation exists
then NewFloatingPayout(masterConfirmation)
post-condition PayoutType: <"Other payout types must be absent.">
if masterConfirmation is absent
then payout -> interestRatePayout is absent
and payout -> cashflow is absent
and payout -> creditDefaultPayout is absent
and payout -> settlementPayout is absent
and payout -> fixedPricePayout is absent
and payout -> optionPayout is absent
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)
masterConfirmation EquitySwapMasterConfirmation2018 (0..1)
output:
performancePayout PerformancePayout (1..1)
condition EquitySecurityType: <"Security must be equity (single name).">
security -> securityType = SecurityTypeEnum -> Equity
set performancePayout -> returnTerms -> priceReturnTerms -> returnType: <"Equity payout must inherit terms from the Master Confirmation Agreement.">
// if masterConfirmation -> typeOfSwapElection -> Price exists
// or masterConfirmation -> typeOfSwapElection -> Total exists then
masterConfirmation -> typeOfSwapElection
set performancePayout -> valuationDates: <"Equity payout must inherit terms from the Master Confirmation Agreement.">
masterConfirmation -> valuationDates
set performancePayout -> paymentDates: <"Equity payout must inherit terms from the Master Confirmation Agreement.">
masterConfirmation -> equityCashSettlementDates
set performancePayout -> settlementTerms: <"Equity payout must inherit terms from the Master Confirmation Agreement.">
masterConfirmation -> settlementTerms
func NewFloatingPayout: <"Function specification to create the interest rate (floating) payout part of an Equity Swap according to the 2018 ISDA CDM Equity Confirmation template.">
inputs:
masterConfirmation EquitySwapMasterConfirmation2018 (0..1)
output:
interestRatePayout InterestRatePayout (1..1)
post-condition InterestRatePayoutTerms: <"Interest rate payout must inherit terms from the Master Confirmation Agreement when it exists.">
if masterConfirmation exists
then // interestRatePayout -> calculationPeriodDates = masterConfirmation -> equityCalculationPeriod and
interestRatePayout -> paymentDates = masterConfirmation -> equityCashSettlementDates
func Create_IndexTransitionTermsChange: <"Function specification to create a terms change that contains changes to the floating rate indexes and adds an adjustment spread to any existing spread.">
inputs:
instruction IndexTransitionInstruction (1..1) <"Specifies the instructions containing the floating rate index, spread adjustment for each leg to be updated, and the effective date.">
tradeState TradeState (1..1) <"Specifies the trade to be updated.">
output:
termsChange TradeState (1..1) <"Specifies the resulting term change.">
set termsChange: <"Updates the trade based on each instruction priceQuantity (e.g. one for each floating rate leg).">
UpdateSpreadAdjustmentAndRateOptions(tradeState, instruction -> priceQuantity)
func Create_Observation: <"Function specification to create an observation that incorporates an observation event into the observation history of a given trade state.">
inputs:
instruction ObservationInstruction (1..1)
before TradeState (1..1) <"Specifies the trade to be updated.">
output:
after TradeState (1..1) <"Specifies the resulting trade state incorporating the observation event in the observation history.">
set after: before
add after -> observationHistory: instruction -> observationEvent
func Create_Valuation: <"Function specification to incorporate a new assessment of the valuation in the valuation history of a given trade state.">
inputs:
instruction ValuationInstruction (1..1)
before TradeState (1..1) <"Specifies the trade to be updated.">
output:
after TradeState (1..1) <"Specifies the resulting trade state incorporating the valuation update in the valuation history.">
alias beforeValuationHistory:
if instruction -> replace = True
then []
else before -> valuationHistory
set after: before
set after -> valuationHistory: beforeValuationHistory
add after -> valuationHistory: instruction -> valuation
func UpdateSpreadAdjustmentAndRateOptions: <"For each of the trade state's price quantity, find a matching price quantity instruction, and call the update function.">
inputs:
tradeState TradeState (1..1) <"Specifies the trade to be updated.">
instructions PriceQuantity (1..*) <"List of PriceQuantity from the IndexTransitionInstruction (e.g. one for each floating rate leg).">
output:
updatedTradeState TradeState (1..1) <"Specifies the updated trade.">
set updatedTradeState: tradeState
set updatedTradeState -> trade -> tradeLot -> priceQuantity:
tradeState -> trade -> tradeLot only-element -> priceQuantity
extract
UpdateIndexTransitionPriceAndRateOption(
item,
FindMatchingIndexTransitionInstruction(instructions, item)
)
func UpdateIndexTransitionPriceAndRateOption:
inputs:
priceQuantity PriceQuantity (1..1)
instruction PriceQuantity (0..1)
output:
updatedPriceQuantity PriceQuantity (1..1)
set updatedPriceQuantity: priceQuantity
set updatedPriceQuantity -> price -> value: <"If instruction exists, sum the existing and instruction spread adjustments.">
if instruction exists
then priceQuantity -> price only-element -> value + instruction -> price only-element -> value
else priceQuantity -> price only-element -> value
set updatedPriceQuantity -> observable -> Index -> FloatingRateIndex: <"If instruction exists, update the rate option.">
if instruction exists
then instruction -> observable -> Index -> FloatingRateIndex
else priceQuantity -> observable -> Index -> FloatingRateIndex
func FindMatchingIndexTransitionInstruction:
inputs:
instructions PriceQuantity (1..*)
priceQuantity PriceQuantity (1..1)
output:
matchingInstruction PriceQuantity (0..1)
set matchingInstruction:
instructions
filter
// indexTenor period matches
observable -> Index -> FloatingRateIndex ->> indexTenor -> period = priceQuantity -> observable -> Index -> FloatingRateIndex ->> indexTenor -> period
// indexTenor periodMultiplier matches
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)
then first
func Create_SecurityLendingInvoice: <"Defines the process of calculating and creating a Security Lending Invoice.">
inputs:
instruction BillingInstruction (1..1) <"Specifies the instructions for creation of a Security Lending billing invoice.">
output:
invoice SecurityLendingInvoice (1..1) <"Produces the Security Lending Invoice">
set invoice -> sendingParty: instruction -> sendingParty
set invoice -> receivingParty: instruction -> receivingParty
set invoice -> billingStartDate: instruction -> billingStartDate
set invoice -> billingEndDate: instruction -> billingEndDate
add invoice -> billingRecord:
Create_BillingRecords(instruction -> billingRecordInstruction)
add invoice -> billingSummary: Create_BillingSummary(invoice -> billingRecord)
func Create_BillingRecords: <"Creates for each billing instruction an individual billing record to be included in a Security Lending Billing Invoice">
inputs:
billingInstruction BillingRecordInstruction (1..*) <"Instruction for creating the billing records contained within the invoice">
output:
billingRecord BillingRecord (1..*)
add billingRecord: billingInstruction extract Create_BillingRecord(item)
func Create_BillingRecord: <"Creates an individual billing record to be included in a Security Lending Billing Invoice">
inputs:
billingInstruction BillingRecordInstruction (1..1) <"Instruction for creating the billing records contained within the invoice">
output:
billingRecord BillingRecord (1..1) <"The billing record">
alias tradeState: <"Creates a trade state with observations attached.">
Create_AssetPayoutTradeStateWithObservations(billingInstruction)
alias billingAmount: <"Resolves the billing amount for the individual trade record.">
ResolveSecurityFinanceBillingAmount(
tradeState,
tradeState -> resetHistory only-element,
billingInstruction -> recordStartDate,
billingInstruction -> recordEndDate,
billingInstruction -> settlementDate
)
set billingRecord -> recordStartDate: billingInstruction -> recordStartDate
set billingRecord -> recordEndDate: billingInstruction -> recordEndDate
set billingRecord -> tradeState: tradeState
set billingRecord -> recordTransfer: billingAmount
func ResolveSecurityFinanceBillingAmount: <"Calculates the billing amount for a Security Finance transaction.">
inputs:
tradeState TradeState (1..1)
reset Reset (1..1)
recordStartDate date (1..1)
recordEndDate date (1..1)
transferDate date (1..1)
output:
transfer Transfer (1..1)
alias securityQuantity: <"Specifies the number of securities.">
FilterQuantityByFinancialUnit(
tradeState -> trade -> tradeLot -> priceQuantity -> quantity,
FinancialUnitEnum -> Share
)
alias interestRatePayout: <"The interest payout that represents the lending fee.">
tradeState -> trade -> product -> economicTerms -> payout -> interestRatePayout only-element
alias assetPayout: <"The security finance payout that represents the securities lent.">
tradeState -> trade -> product -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product ->> economicTerms -> payout -> assetPayout only-element
alias collateral:
tradeState -> trade -> product -> economicTerms -> collateral
alias haircutPercentage:
(1.0 - collateral -> collateralProvisions -> eligibleCollateral only-element -> treatment -> valuationTreatment -> haircutPercentage)
alias valuationPercentage: (1 / haircutPercentage)
alias marginRatio:
if collateral -> collateralProvisions -> eligibleCollateral only-element -> treatment -> valuationTreatment -> haircutPercentage exists
then valuationPercentage
else if collateral -> collateralProvisions -> eligibleCollateral only-element -> treatment -> valuationTreatment -> marginPercentage exists
then collateral -> collateralProvisions -> eligibleCollateral only-element -> treatment -> valuationTreatment -> marginPercentage
else 1.0
alias billingQuantity:
reset -> resetValue -> value * securityQuantity -> value * marginRatio
alias calculationPeriodRange:
CalculationPeriodRange(recordStartDate, recordEndDate, empty)
alias performance:
if interestRatePayout -> rateSpecification -> FixedRateSpecification exists
then FixedAmount(
interestRatePayout,
billingQuantity,
recordEndDate,
calculationPeriodRange
)
else if interestRatePayout -> rateSpecification -> FloatingRateSpecification exists
then FloatingAmount(
interestRatePayout,
reset -> resetValue -> value,
billingQuantity,
recordEndDate,
calculationPeriodRange
)
alias payerPartyReference:
ExtractCounterpartyByRole(
tradeState -> trade -> counterparty,
interestRatePayout -> payerReceiver -> payer
) -> partyReference
alias receiverPartyReference:
ExtractCounterpartyByRole(
tradeState -> trade -> counterparty,
interestRatePayout -> payerReceiver -> receiver
) -> partyReference
set transfer -> quantity -> value: performance
set transfer -> quantity -> unit -> currency:
interestRatePayout -> priceQuantity -> quantitySchedule -> unit -> currency
set transfer -> payerReceiver -> payerPartyReference:
if performance >= 0
then payerPartyReference
else receiverPartyReference
set transfer -> payerReceiver -> receiverPartyReference:
if performance >= 0
then receiverPartyReference
else payerPartyReference
set transfer -> settlementDate -> adjustedDate: transferDate
func ToMoney:
inputs:
quantity Quantity (1..1)
output:
money Money (1..1)
set money -> value: quantity -> value
set money -> unit -> currency: quantity -> unit -> currency
func Create_BillingSummary: <"Creates a billing summary to be included in a Security Lending Billing Invoice.">
inputs:
billingRecord BillingRecord (1..*)
output:
billingSummary BillingSummary (1..1)
//sums all billing records and assigns value to billing summary
//sets enum to ParentTotal
func Create_Return: <"Defines the process of partially or fully returning a Security Lending Transaction.">
[creation BusinessEvent]
inputs:
tradeState TradeState (1..1) <"Specifies a previously formed contractual product with a Security Finance payout. It is required that the description of the contractual product be contained within the previous business event, i.e. its lineage must contain the formation of a contractual product.">
returnInstruction ReturnInstruction (1..1) <"Specifies the information required to fully return the Stock Loan in accordance with the economic terms of the contractual product.">
returnDate date (1..1) <"Specifies the date of the full return.">
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 quantitySchedule:
returnInstruction -> quantity
extract
NonNegativeQuantitySchedule {
value: value,
unit: unit,
...
}
alias changePriceQuantity:
PriceQuantity {
quantity: quantitySchedule,
...
}
add returnEvent -> after: <"Creates a new contract within the quantity change primitive's after state equivalent to the new notional on the partially returned original contract, assuming there's a single security finance transaction in the original financial contract that is part returned.">
Create_QuantityChange(
QuantityChangeInstruction {
change: changePriceQuantity,
direction: QuantityChangeDirectionEnum -> Decrease,
lotIdentifier: empty
},
tradeState
)
set returnEvent -> eventDate: returnDate
func Qualify_Repurchase: <"The qualification of a repurchase event from the fact that (i) a quantityChange instruction exists, (ii) an assetPayout exists, (iii) the remaining quantity = 0, (iv) the closedState of the contract is Terminated, and (v) the intent of the event is 'Repurchase'.">
[qualification BusinessEvent]
inputs:
businessEvent BusinessEvent (1..1)
output:
is_event boolean (1..1)
set is_event:
businessEvent -> intent = EventIntentEnum -> Repurchase
and businessEvent -> after -> trade -> product -> economicTerms -> collateral -> collateralPortfolio -> collateralPosition -> product ->> economicTerms -> payout -> assetPayout exists
and (businessEvent -> instruction count = 1
and (businessEvent -> instruction -> primitiveInstruction -> quantityChange, businessEvent -> instruction -> primitiveInstruction -> transfer) only exists)
and QuantityDecreasedToZero(
businessEvent -> instruction -> before,
businessEvent -> after
) = True
and businessEvent -> after -> state -> closedState -> state all = ClosedStateEnum -> Terminated
func ResolveRepurchaseTransferInstruction: <"Resolves an instruction for settlement of a Repurchase Event">
inputs:
tradeState TradeState (1..1)
repurchaseDate date (1..1)
output:
repurchaseInstruction EventInstruction (1..1)
alias changeQuantity: <"Create distinct list of Quantity with value set to zero.">
tradeState -> trade -> tradeLot -> priceQuantity -> quantity
extract
NonNegativeQuantitySchedule {
value: 0.0,
unit: unit,
...
}
then distinct
alias changePriceQuantity: <"Create change PriceQuantity for QuantityChangeInstruction.">
PriceQuantity {
quantity: changeQuantity,
...
}
set repurchaseInstruction -> intent: EventIntentEnum -> Repurchase
set repurchaseInstruction -> instruction -> before: tradeState
set repurchaseInstruction -> instruction -> primitiveInstruction -> quantityChange:
QuantityChangeInstruction {
change: changePriceQuantity,
direction: QuantityChangeDirectionEnum -> Replace,
lotIdentifier: empty
}
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.">
effectiveRollDate AdjustableOrRelativeDate (1..1) <"The date to close and open a new position.">
terminationDate AdjustableOrRelativeDate (1..1) <"The new termination date.">
priceQuantity PriceQuantity (1..*) <"The price and quantity of the trade to roll into.">
output:
instruction PrimitiveInstruction (1..1)
set instruction -> split -> breakdown: <"Sets the first part of the split to be a termination instruction for the existing trade.">
[Create_TerminationInstruction(tradeState)]
add instruction -> split -> breakdown: <"Sets the second part of the split to be a new contract with the same details as the old one but with effective and termination dates changed (i.e. terms change instruction) and price / quantity changed.">
[
PrimitiveInstruction {
quantityChange: QuantityChangeInstruction {
change: priceQuantity,
direction: QuantityChangeDirectionEnum -> Replace,
lotIdentifier: empty
},
termsChange: Create_RollTermChangeInstruction(
tradeState -> trade -> product,
effectiveRollDate,
terminationDate
),
...
}
]
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:
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:
termsChangeInstruction TermsChangeInstruction (1..1) <"The relevant primitive instruction for the roll, which is a terms change.">
condition DateExists:
effectiveRollDate exists or terminationDate exists
set termsChangeInstruction -> product: product
set termsChangeInstruction -> product -> economicTerms -> effectiveDate:
if effectiveRollDate exists
then effectiveRollDate
else product -> economicTerms -> effectiveDate
set termsChangeInstruction -> product -> economicTerms -> terminationDate:
if terminationDate exists
then 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:
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: product
set termsChangeInstruction -> product -> economicTerms -> effectiveDate:
effectiveRollDate
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.">
[qualification BusinessEvent]
inputs:
businessEvent BusinessEvent (1..1)
output:
is_event boolean (1..1)
alias beforeEconomicterms:
businessEvent -> instruction only-element -> before -> trade -> product -> economicTerms
alias openEconomicTerms:
FilterOpenTradeStates(businessEvent -> after) only-element -> trade -> product -> economicTerms
alias closedTradeState: FilterClosedTradeStates(businessEvent -> after)
set is_event:
// The first 2 conditions imply that there is 1 and only 1 before and 1 open thanks to the "only-element" modifier
beforeEconomicterms exists
and openEconomicTerms exists
and closedTradeState count = 1
and openEconomicTerms -> payout = beforeEconomicterms -> payout
and openEconomicTerms -> collateral = beforeEconomicterms -> collateral
and openEconomicTerms -> effectiveDate = beforeEconomicterms -> terminationDate
and openEconomicTerms -> terminationDate <> beforeEconomicterms -> terminationDate
func Create_OnDemandRateChangePrimitiveInstruction: <"Creates a full primitive instruction for an on-demand rate change event. A rate change consists in closing the original trade and opening a new one with the same details as the original one, but with a new rate (price) and effective date. The business event logic checks that there is only 1 rate price in the original trade to be updated.">
inputs:
tradeState TradeState (1..1) <"The original trade to be modified with new rate.">
effectiveDate AdjustableOrRelativeDate (1..1) <"The date to close and open a new position.">
agreedRate number (1..1) <"The new rate agreed between the parties.">
output:
instruction PrimitiveInstruction (1..1)
condition SingleTradeLot: <"Rate change only works for a trade with a single trade lot.">
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)]
add instruction -> split -> breakdown: <"Sets the second part of the split to be a new contract with the same details as the old one but with effective date and price (rate) changed.">
[
PrimitiveInstruction {
quantityChange: Create_OnDemandRateChangePriceChangeInstruction(
tradeState -> trade -> tradeLot only-element -> priceQuantity,
agreedRate
),
termsChange: Create_OnDemandRateChangeTermsChangeInstruction(
tradeState -> trade -> product,
effectiveDate
),
...
}
]
func Create_OnDemandRateChangePriceChangeInstruction: <"Creates a price change instruction for an on-demand rate change, based on a new rate provided as a single number by matching it to a single rate price.">
inputs:
priceQuantity PriceQuantity (1..*) <"The original price / quantity to be modified with the new rate.">
newRate number (1..1) <"The new rate value, provided as a single number.">
output:
quantityChangeInstruction QuantityChangeInstruction (1..1)
alias currentRatePrice: <"Filter interest rate price and make it into a single element">
priceQuantity
extract price
then flatten
then filter priceType = PriceTypeEnum -> InterestRate
then only-element
alias newPrice: <"Create the new price object.">
Price {
value: newRate,
unit: currentRatePrice -> unit,
perUnitOf: currentRatePrice -> perUnitOf,
priceType: currentRatePrice -> priceType,
priceExpression: currentRatePrice -> priceExpression,
composite: currentRatePrice -> composite,
arithmeticOperator: currentRatePrice -> arithmeticOperator,
cashPrice: currentRatePrice -> cashPrice,
datedValue: empty
}
alias newPriceQuantity: <"Create the new price quantity object.">
PriceQuantity {
price: newPrice,
...
}
condition OneRatePrice: <"There should be 1 and only 1 rate type price in the current price.">
currentRatePrice exists
set quantityChangeInstruction:
QuantityChangeInstruction {
change: newPriceQuantity,
direction: QuantityChangeDirectionEnum -> Replace,
lotIdentifier: empty
}
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:
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: <"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.">
[qualification BusinessEvent]
inputs:
businessEvent BusinessEvent (1..1)
output:
is_event boolean (1..1)
alias beforeTrade:
businessEvent -> instruction only-element -> before -> trade
alias beforeProduct:
beforeTrade -> product
alias beforeEconomicterms:
beforeProduct -> economicTerms
alias openTrade:
FilterOpenTradeStates(businessEvent -> after) only-element -> trade
alias openEconomicTerms:
openTrade -> product -> economicTerms
alias closedTradeState: FilterClosedTradeStates(businessEvent -> after)
alias beforePriceQuantityRateOnly: <"The rate value before. There must be 1 and only 1.">
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.">
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.">
beforeTrade -> tradeLot only-element -> priceQuantity
extract
PriceQuantity {
price: price
filter p [ p -> priceType <> PriceTypeEnum -> InterestRate ],
quantity: quantity,
observable: observable,
...
}
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">
openTrade -> tradeLot only-element -> priceQuantity
extract
PriceQuantity {
price: price
filter p [ p -> priceType <> PriceTypeEnum -> InterestRate ],
quantity: quantity,
observable: observable,
...
}
set is_event:
// The first 2 conditions imply that there is 1 and only 1 before and 1 open thanks to the "only-element" modifier
beforeEconomicterms exists
and openEconomicTerms exists
and closedTradeState count = 1
and // openEconomicTerms -> payout = beforeEconomicterms -> payout and
openEconomicTerms -> collateral = beforeEconomicterms -> collateral
and beforePriceQuantityRateOnly count = 1
and openPriceQuantityRateOnly count = 1
and beforePriceQuantityRateOnly only-element
<> openPriceQuantityRateOnly only-element
and beforePriceQuantityNoRate = openPriceQuantityNoRate
func Create_CancellationPrimitiveInstruction: <"Creates a primitive instruction for early cancellation.">
inputs:
tradeState TradeState (1..1) <"The original trade to be rolled.">
newRepurchasePrice number (0..1) <"The new repurchase price after the new termination date is set.">
cancellationDate AdjustableOrRelativeDate (1..1) <"The new termination date.">
output:
instruction PrimitiveInstruction (1..1)
set instruction -> split -> breakdown: <"Sets the first part of the split to be a termination instruction for the existing trade.">
[Create_TerminationInstruction(tradeState)]
add instruction -> split -> breakdown: <"Sets the second part of the split to be a new contract with the same details as the old one but with termination date changed and price / quantity changed (taking new repurchase price into account).">
[
PrimitiveInstruction {
quantityChange: QuantityChangeInstruction {
change: tradeState -> trade -> tradeLot -> priceQuantity,
direction: QuantityChangeDirectionEnum -> Replace,
lotIdentifier: empty
},
termsChange: Create_CancellationTermChangeInstruction(
tradeState -> trade -> product,
cancellationDate
),
...
}
]
func Create_CancellationTermChangeInstruction: <"Create a terms change instruction for a cancellation that consists in bringing the termination date forward.">
inputs:
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: product
set termsChangeInstruction -> product -> economicTerms -> terminationDate:
cancellationDate
func Qualify_Cancellation: <"Qualification of an cancellation event.">
[qualification BusinessEvent]
inputs:
businessEvent BusinessEvent (1..1)
output:
is_event boolean (1..1)
alias closedEconomicTerms:
FilterClosedTradeStates(businessEvent -> after) only-element -> trade -> product -> economicTerms
alias openEconomicTerms:
FilterOpenTradeStates(businessEvent -> after) only-element -> trade -> product -> economicTerms
set is_event:
businessEvent -> instruction -> before count = 1
and closedEconomicTerms exists
and openEconomicTerms exists
// and openEconomicTerms -> payout = closedEconomicTerms -> payout
// and openEconomicTerms -> collateral = closedEconomicTerms -> collateral
and (if openEconomicTerms -> terminationDate exists
and closedEconomicTerms -> terminationDate exists
then openEconomicTerms -> terminationDate -> adjustableDate -> unadjustedDate < closedEconomicTerms -> terminationDate -> adjustableDate -> unadjustedDate
else openEconomicTerms -> terminationDate exists)
func Create_PairOffInstruction: <"Creates a set of instructions to pair-off a set of trades based on a pair reference. A package component is created based on that pair reference and the list of identifiers for the underlying trades. That package component is then added onto the execution details of every underlying trade. The existing trades are not terminated.">
inputs:
tradeState TradeState (2..*) <"The trades to pair-off. There must be at least 2.">
pairReference Identifier (1..1) <"The reference ID of the paired trades.">
output:
instruction Instruction (1..*)
alias componentId: <"Extract the trade identifier from each trade. This list will be used as the componentId attribute of the package.">
tradeState extract trade -> tradeIdentifier only-element
set instruction: <"Create a list of new execution instructions for each trade. The new execution instructions include new execution details, with the package component created using the pair reference and the componentId list.">
tradeState
extract
Instruction {
before: item,
primitiveInstruction: PrimitiveInstruction {
contractFormation: if item -> state -> positionState = PositionStatusEnum -> Formed
then Create_ContractFormationInstruction(
item -> trade -> contractDetails -> documentation
),
execution: ExecutionInstruction {
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(
item -> trade -> executionDetails,
pairReference,
componentId
),
tradeDate: item -> trade -> tradeDate,
tradeIdentifier: item -> trade -> tradeIdentifier,
...
},
...
}
}
func Qualify_PairOff: <"Qualifies an event as a pair-off when all the details of the existing trades are maintained, except for their execution details which are updated to include a package component. This package component must be unique across all trades.">
[qualification BusinessEvent]
inputs:
businessEvent BusinessEvent (1..1)
output:
is_event boolean (1..1)
alias openTradeState: FilterOpenTradeStates(businessEvent -> after)
alias newTradeInstruction: <"New trade instructions, that contain only an execution primitive and (optionally) a contract formation primitive.">
businessEvent -> instruction
filter NewTradeInstructionOnlyExists(item -> primitiveInstruction)
alias packageRef: <"Package details on the new trades.">
openTradeState -> trade -> executionDetails -> packageReference
set is_event:
// The first condition asserts that there are only new executions
newTradeInstruction count = businessEvent -> instruction count
// All the trade details (except the execution instructions) are unchanged
// and openTradeNoExecutionDetails = beforeTradeNoExecutionDetails
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
func Create_ShapingInstruction: <"Creates a set of instructions to shape a trade based on shaped quantities and a package ID. The original trade is closed and split into (smaller) shaped trades based on a set of trade lots containing the shaped quantities and an identifier for each shaped trade. A package component is created based on the package ID and the list of identifiers for the shaped trades. That package component is then added onto the execution details of every shaped trade.">
inputs:
tradeState TradeState (1..1) <"The original trade to be shaped.">
tradeLots TradeLot (2..*) <"The shaped quantities provided as full set of trade lots with price and quantity. Each trade lot also contains an identifier to associate to the corresponding shaped trade. Shaping must result in at least 2 shaped trades.">
shapeIdentifier Identifier (1..1) <"The package ID of the shaped trades.">
output:
instruction PrimitiveInstruction (1..1)
alias componentId: <"Extract the trade identifier from each trade lot. This list will be used as the componentId attribute of the package.">
tradeLots extract item -> lotIdentifier only-element
set instruction -> split -> breakdown: <"Sets the first part of the split to be a termination instruction for the existing trade.">
[Create_TerminationInstruction(tradeState)]
add instruction -> split -> breakdown: <"The second part of the split consists in a quantity change and a new execution for each provided trade lot. The quantity change takes care of the shaping according to the provided quantities. The execution adds the required package component to the execution details.">
tradeLots
extract priceQuantity
then extract
PrimitiveInstruction {
contractFormation: if tradeState -> state -> positionState = PositionStatusEnum -> Formed
then Create_ContractFormationInstruction(
tradeState -> trade -> contractDetails -> documentation
),
execution: ExecutionInstruction {
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(
tradeState -> trade -> executionDetails,
shapeIdentifier,
componentId
),
tradeDate: tradeState -> trade -> tradeDate,
tradeIdentifier: tradeState -> trade -> tradeIdentifier,
...
},
quantityChange: QuantityChangeInstruction {
change: item,
direction: QuantityChangeDirectionEnum -> Replace,
lotIdentifier: empty
},
...
}
func Qualify_Shaping: <"The qualification of a shaping event from the fact that (i) the only primitive is a split where the original trade is closed, (ii) the parties before and after the split remain the same (by contrast with an allocation, for instance) and (iii) the split trades contain a package component in their execution details. This package ties together the resulting shapes trades' identifiers and must be the same across all shaped trades. Note that SplitPrimitive type has a condition to check that the post-split quantities sum to the pre-split quantity.">
[qualification BusinessEvent]
inputs:
businessEvent BusinessEvent (1..1)
output:
is_event boolean (1..1)
alias beforeTradeState: businessEvent -> instruction -> before only-element
alias closedTradeState: FilterClosedTradeStates(businessEvent -> after) only-element
alias openTradeStates: FilterOpenTradeStates(businessEvent -> after)
alias packageRef: <"Package details on the new trades.">
openTradeStates -> trade -> executionDetails -> packageReference
alias openTradeNoExecutionDetails: <"List of open trades with no execution details on, for comparison.">
openTradeStates extract TradeNoExecutionDetails(item -> trade)
set is_event:
// There is a single before trade with a split instruction, resulting in a single closed trade and multiple open trades
beforeTradeState exists
and closedTradeState exists
and openTradeStates count > 1
and businessEvent -> instruction -> primitiveInstruction -> split only exists
// Open trade counterparties should match before trade counterparties
and openTradeStates
extract [
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
and packageRef distinct count = 1
func Create_PartialDeliveryPrimitiveInstruction: <"Creates the primitive instruction for partial delivery of a repo transaction at settlement.">
inputs:
tradeState TradeState (1..1) <"The original trade to be closed.">
deliveredPriceQuantity PriceQuantity (1..*) <"The price and quantity of the delivered amount.">
output:
instruction PrimitiveInstruction (1..1)
set instruction -> split -> breakdown: <"Sets the first part of the split to be a termination instruction for the existing trade.">
[Create_TerminationInstruction(tradeState)]
set instruction -> split -> breakdown: <"Sets the first part of the split to be a termination instruction for the existing trade.">
[
PrimitiveInstruction {
quantityChange: QuantityChangeInstruction {
change: deliveredPriceQuantity,
direction: QuantityChangeDirectionEnum -> Replace,
lotIdentifier: tradeState -> trade -> tradeLot -> lotIdentifier
},
...
}
]
func Qualify_PartialDelivery: <"Qualification of a partial delivery which constitutes a change in quantity and open with the remaining quantity and termination date.">
[qualification BusinessEvent]
inputs:
businessEvent BusinessEvent (1..1)
output:
is_event boolean (1..1)
alias beforeEconomicterms: ExtractBeforeEconomicTerms(businessEvent)
alias openEconomicTerms: ExtractOpenEconomicTerms(businessEvent)
alias openTrades: FilterOpenTradeStates(businessEvent -> after) -> trade
alias closedTradeState: FilterClosedTradeStates(businessEvent -> after)
alias beforeTrade: ExtractBeforeTrade(businessEvent)
alias afterTrade: ExtractAfterTrade(businessEvent)
alias beforeTradeCollateralQuantity:
ExtractTradeCollateralQuantity(beforeTrade)
alias afterTradeCollateralQuantity: ExtractTradeCollateralQuantity(afterTrade)
set is_event:
beforeEconomicterms exists
and openEconomicTerms exists
and openTrades count = 1
and closedTradeState count = 1
and openEconomicTerms -> payout -> interestRatePayout = beforeEconomicterms -> payout -> interestRatePayout
and openEconomicTerms -> collateral = beforeEconomicterms -> collateral
and beforeTradeCollateralQuantity > afterTradeCollateralQuantity
and openEconomicTerms -> terminationDate = beforeEconomicterms -> terminationDate
and openEconomicTerms -> effectiveDate = beforeEconomicterms -> effectiveDate
func Create_RepricePrimitiveInstruction: <"Creates the primitive instructions for a repricing that alters the cash amount of the trade. Transaction value and variation margin are processed separately as are transfers of cash and securities.">
inputs:
tradeState TradeState (1..1) <"The original trade state and trade to be repriced.">
newAllinPrice number (1..1) <"The collateral new all-in price.">
newCashValue number (1..1) <"The new cash amount.">
effectiveRepriceDate AdjustableOrRelativeDate (1..1) <"The date to reprice the collateral">
output:
instruction PrimitiveInstruction (1..1)
alias oldPriceQuantity:
tradeState -> trade -> tradeLot -> priceQuantity
alias currentAssetPrice: <"Filter interest rate price and make it into a single element">
oldPriceQuantity
extract price
then flatten
then filter priceType = PriceTypeEnum -> AssetPrice
then only-element
alias newPrice: <"Create the new price object.">
Price {
value: newAllinPrice,
unit: currentAssetPrice -> unit,
perUnitOf: currentAssetPrice -> perUnitOf,
priceType: currentAssetPrice -> priceType,
priceExpression: currentAssetPrice -> priceExpression,
composite: currentAssetPrice -> composite,
arithmeticOperator: currentAssetPrice -> arithmeticOperator,
cashPrice: currentAssetPrice -> cashPrice,
datedValue: empty
}
alias changeCashQuantity: <"Create distinct list of Quantity with value set to newAssetQuantity">
tradeState -> trade -> tradeLot only-element -> priceQuantity -> quantity
extract
NonNegativeQuantitySchedule {
value: newCashValue,
unit: unit,
...
}
then distinct
alias newPriceQuantity: <"Create the new price quantity object.">
PriceQuantity {
price: [newPrice],
quantity: changeCashQuantity,
...
}
set instruction -> split -> breakdown: [Create_TerminationInstruction(tradeState)]
add instruction -> split -> breakdown: <"Sets the second part of the split to be a new contract with a new asset payout.">
[
PrimitiveInstruction {
quantityChange: QuantityChangeInstruction {
change: [newPriceQuantity],
direction: QuantityChangeDirectionEnum -> Replace,
lotIdentifier: empty
},
termsChange: Create_EffectiveOrTerminationDateTermChangeInstruction(
tradeState -> trade -> product,
effectiveRepriceDate,
empty
),
...
}
]
func Create_AdjustmentPrimitiveInstruction: <"Creates the primitive instructions for a repricing that alters the collateral quantity and value of the trade. Transaction value and variation margin are processed separately as are transfers of cash and securities.">
inputs:
tradeState TradeState (1..1) <"The original trade state and trade to be repriced.">
newAllinPrice number (1..1) <"The collateral new all-in price.">
newAssetQuantity number (1..1) <"The collateral new quantity.">
effectiveRepriceDate AdjustableOrRelativeDate (1..1) <"The date to reprice the collateral">
output:
instruction PrimitiveInstruction (1..1)
alias oldPriceQuantity:
tradeState -> trade -> tradeLot -> priceQuantity
alias currentAssetPrice: <"Filter interest rate price and make it into a single element">
oldPriceQuantity
extract price
then flatten
then filter priceType = PriceTypeEnum -> AssetPrice
then only-element
alias newPrice: <"Create the new price object.">
Price {
value: newAllinPrice,
unit: currentAssetPrice -> unit,
perUnitOf: currentAssetPrice -> perUnitOf,
priceType: currentAssetPrice -> priceType,
priceExpression: currentAssetPrice -> priceExpression,
composite: currentAssetPrice -> composite,
arithmeticOperator: currentAssetPrice -> arithmeticOperator,
cashPrice: currentAssetPrice -> cashPrice,
datedValue: empty
}
alias changeQuantity: <"Create distinct list of Quantity with value set to newAssetQuantity">
tradeState -> trade -> tradeLot only-element -> priceQuantity -> quantity
extract
NonNegativeQuantitySchedule {
value: newAssetQuantity,
unit: unit,
...
}
then distinct
alias newPriceQuantity: <"Create the new price quantity object.">
PriceQuantity {
price: [newPrice],
quantity: changeQuantity,
...
}
condition SingleTradeLot: <"This repricing function applies only to trades with a single lot.">
tradeState -> trade -> tradeLot count = 1
set instruction -> split -> breakdown: [Create_TerminationInstruction(tradeState)]
add instruction -> split -> breakdown: <"Sets the second part of the split to be a new contract with a new asset payout.">
[
PrimitiveInstruction {
quantityChange: QuantityChangeInstruction {
change: [newPriceQuantity],
direction: QuantityChangeDirectionEnum -> Replace,
lotIdentifier: empty
},
termsChange: Create_EffectiveOrTerminationDateTermChangeInstruction(
tradeState -> trade -> product,
effectiveRepriceDate,
empty
),
...
}
]
func Qualify_Reprice: <"This qualification function is used to qualify repricing of a contractual product with an interest rate payout and assetPayout.">
[qualification BusinessEvent]
inputs:
businessEvent BusinessEvent (1..1)
output:
is_event boolean (1..1)
alias openTrades: FilterOpenTradeStates(businessEvent -> after) -> trade
alias closedTradeState: FilterClosedTradeStates(businessEvent -> after)
alias beforeTrade: ExtractBeforeTrade(businessEvent)
alias afterTrade: ExtractAfterTrade(businessEvent)
alias beforeTradePurchasePrice: ExtractTradePurchasePrice(beforeTrade)
alias afterTradePurchasePrice: ExtractTradePurchasePrice(afterTrade)
alias beforeTradeCollateralQuantity:
ExtractTradeCollateralQuantity(beforeTrade)
alias afterTradeCollateralQuantity: ExtractTradeCollateralQuantity(afterTrade)
alias beforeTradeCollateralPrice: ExtractTradeCollateralPrice(beforeTrade)
alias afterTradeCollateralPrice: ExtractTradeCollateralPrice(afterTrade)
alias beforeEconomicterms: ExtractBeforeEconomicTerms(businessEvent)
alias openEconomicTerms: ExtractOpenEconomicTerms(businessEvent)
set is_event:
businessEvent -> after -> trade -> product -> economicTerms -> payout -> interestRatePayout exists
and openTrades count = 1
and closedTradeState count = 1
and beforeTradePurchasePrice exists
and afterTradePurchasePrice exists
and afterTradePurchasePrice <> beforeTradePurchasePrice
and beforeTradeCollateralQuantity = afterTradeCollateralQuantity
and beforeTradeCollateralPrice <> afterTradeCollateralPrice
and beforeEconomicterms exists
and openEconomicTerms exists
and openEconomicTerms -> terminationDate = beforeEconomicterms -> terminationDate
func Qualify_Adjustment: <"This qualification function is used to qualify adjustment of the collateral amount when a transaction is repriced.">
[qualification BusinessEvent]
inputs:
businessEvent BusinessEvent (1..1)
output:
is_event boolean (1..1)
alias beforeTrade: ExtractBeforeTrade(businessEvent)
alias afterTrade: ExtractAfterTrade(businessEvent)
alias beforeTradePurchasePrice: ExtractTradePurchasePrice(beforeTrade)
alias afterTradePurchasePrice: ExtractTradePurchasePrice(afterTrade)
alias beforeTradeCollateralQuantity:
ExtractTradeCollateralQuantity(beforeTrade)
alias afterTradeCollateralQuantity: ExtractTradeCollateralQuantity(afterTrade)
alias beforeTradeCollateralPrice: ExtractTradeCollateralPrice(beforeTrade)
alias afterTradeCollateralPrice: ExtractTradeCollateralPrice(afterTrade)
alias beforeEconomicterms: ExtractBeforeEconomicTerms(businessEvent)
alias openEconomicTerms: ExtractOpenEconomicTerms(businessEvent)
set is_event:
businessEvent -> after -> trade -> product -> economicTerms -> payout -> interestRatePayout exists
and openEconomicTerms -> payout = beforeEconomicterms -> payout
and beforeTradePurchasePrice exists
and afterTradePurchasePrice exists
and afterTradePurchasePrice = beforeTradePurchasePrice
and beforeTradeCollateralQuantity <> afterTradeCollateralQuantity
and beforeTradeCollateralPrice <> afterTradeCollateralPrice
and beforeEconomicterms exists
and openEconomicTerms exists
and openEconomicTerms -> terminationDate = beforeEconomicterms -> terminationDate
and openEconomicTerms -> effectiveDate <> beforeEconomicterms -> effectiveDate
func Create_SubstitutionPrimitiveInstruction: <"Creates the primitive instructions for a substitution of collateral by replacing the assetpayout of the trade.">
inputs:
tradeState TradeState (1..1) <"The original trade to be for substitution of collateral.">
effectiveDate AdjustableOrRelativeDate (1..1) <"The date to close and open a new trade with new collateral.">
newCollateralPortfolio CollateralPortfolio (1..1) <"New collateral portfolio to subtitute for the original collateral.">
priceQuantity PriceQuantity (1..*) <"The price and quantity of the substituted product.">
output:
instruction PrimitiveInstruction (1..1)
condition SecurityFinance: <"Only security finance products can substitute collateral.">
tradeState -> trade -> product -> economicTerms -> collateral exists
set instruction: <"Sets the second part of the split to be a new contract with a new asset payout.">
PrimitiveInstruction {
quantityChange: QuantityChangeInstruction {
change: priceQuantity,
direction: QuantityChangeDirectionEnum -> Replace,
lotIdentifier: empty
},
termsChange: Create_SubstitutionInstruction(
tradeState -> trade -> product,
effectiveDate,
newCollateralPortfolio
),
...
}
func Create_SubstitutionInstruction: <"Creates the terms change instruction that updates the payout with the new substitution payout.">
inputs:
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:
termsChangeInstruction TermsChangeInstruction (1..1)
set termsChangeInstruction:
Create_EffectiveOrTerminationDateTermChangeInstruction(
product,
effectiveDate,
empty
)
set termsChangeInstruction -> product -> economicTerms -> collateral -> collateralPortfolio:
newCollateralPortfolio
func Qualify_Substitution: <"Qualification of a collateral substitution event.">
[qualification BusinessEvent]
inputs:
businessEvent BusinessEvent (1..1)
output:
is_event boolean (1..1)
alias beforeEconomicterms: ExtractBeforeEconomicTerms(businessEvent)
alias openEconomicTerms: ExtractOpenEconomicTerms(businessEvent)
set is_event:
beforeEconomicterms exists
and openEconomicTerms exists
and openEconomicTerms -> payout <> beforeEconomicterms -> payout
and openEconomicTerms -> collateral <> beforeEconomicterms -> collateral
and openEconomicTerms -> effectiveDate = beforeEconomicterms -> terminationDate
and openEconomicTerms -> terminationDate = beforeEconomicterms -> terminationDate
func Create_PackageExecutionDetails: <"Add a package component to an execution details object. This package component is constructed using an identifier for the package and the list of identifiers for its components.">
inputs:
executionDetails ExecutionDetails (0..1) <"The original execution details. These may be empty.">
listId Identifier (1..1) <"The identifier for the package.">
componentId Identifier (2..*) <"The list of identifiers for the package components. There must be at least 2.">
output:
newExecutionDetails ExecutionDetails (1..1)
set newExecutionDetails -> executionType: executionDetails -> executionType
set newExecutionDetails -> executionVenue: executionDetails -> executionVenue
set newExecutionDetails -> packageReference -> listId: listId
set newExecutionDetails -> packageReference -> componentId: componentId
func NewTradeInstructionOnlyExists:
inputs:
primitiveInstruction PrimitiveInstruction (1..1)
output:
result boolean (1..1)
set result:
primitiveInstruction -> execution only exists
or (primitiveInstruction -> execution, primitiveInstruction -> contractFormation) only exists
func TradeNoExecutionDetails:
inputs:
trade Trade (1..1)
output:
newTrade Trade (1..1)
set newTrade: trade
set newTrade -> executionDetails: EmptyExecutionDetails()
func EmptyExecutionDetails:
output:
executionDetails ExecutionDetails (0..1)
func Create_OnDemandInterestPaymentPrimitiveInstruction: <"An instruction to make a interium interest payment by adding a payout leg to the deal.">
inputs:
tradeState TradeState (1..1) <"The original trade to be modified.">
interestAmount Money (1..1)
settlementDate SettlementDate (1..1)
output:
instruction PrimitiveInstruction (1..1) <"Result is a Terms Change Instruction.">
alias interestRatePayout:
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(
interestAmount -> value,
interestRatePayout -> priceQuantity -> quantitySchedule -> unit -> currency,
settlementDate,
interestRatePayout -> payerReceiver,
CashflowType {
cashflowType: ScheduledTransferEnum -> NetInterest,
... // TODO: set either cashPrice or priceExpression.
},
empty
)
condition InterestRatePayoutExists: <"Only a contractual product with a single interest rate payout can have an on-demand interest payment.">
interestRatePayout exists
condition Currency: <"The currency of the interest amount must match the currency of the original interest rate payout.">
interestAmount -> unit -> currency = interestRatePayout -> priceQuantity -> quantitySchedule -> unit -> currency
set instruction:
PrimitiveInstruction {
termsChange: Create_CashflowTermsChangeInstruction(
tradeState -> trade -> product,
cashflow
),
...
}
func Qualify_OnDemandPayment: <"Qualification of a on-demand payment.">
[qualification BusinessEvent]
inputs:
businessEvent BusinessEvent (1..1)
output:
is_event boolean (1..1)
alias afterTradeStates: FilterOpenTradeStates(businessEvent -> after)
alias beforeCashFlow:
FilterClosedTradeStates(businessEvent -> after) only-element -> trade -> product -> economicTerms -> payout -> cashflow
alias afterCashFlow:
FilterOpenTradeStates(businessEvent -> after) only-element -> trade -> product -> economicTerms -> payout -> cashflow
set is_event:
businessEvent -> instruction -> before count = 1
and businessEvent -> after count = 1
and afterTradeStates count = 1
and businessEvent -> instruction -> primitiveInstruction -> termsChange only exists
and afterCashFlow count > beforeCashFlow count // allows for adding multiple cashflows
and afterCashFlow -> cashflowType -> cashflowType all = ScheduledTransferEnum -> NetInterest
func Create_CashflowTermsChangeInstruction:
inputs:
product NonTransferableProduct (1..1)
cashFlow Cashflow (1..1)
output:
termsChangeInstruction TermsChangeInstruction (1..1)
set termsChangeInstruction -> product: product
add termsChangeInstruction -> product -> economicTerms -> payout -> cashflow:
cashFlow
func Create_Cashflow:
inputs:
amount number (1..1)
currency string (1..1)
settlementDate SettlementDate (1..1)
payerReceiver PayerReceiver (1..1)
cashflowType CashflowType (1..1)
paymentDiscounting PaymentDiscounting (0..1)
output:
cashflow Cashflow (1..1)
set cashflow -> settlementTerms -> settlementDate: settlementDate
set cashflow -> payerReceiver: payerReceiver
set cashflow -> cashflowType: cashflowType
set cashflow -> paymentDiscounting: paymentDiscounting
set cashflow -> priceQuantity:
ResolvablePriceQuantity {
quantitySchedule: NonNegativeQuantitySchedule {
value: amount,
unit: UnitType {
currency: currency,
...
},
...
},
...
}
func Create_TerminationInstruction: <"Creates the relevant primitive instruction for a termination, which consists in a quantity change to bring the quantity to zero.">
inputs:
tradeState TradeState (1..1) <"The original trade to be termintaed.">
output:
instruction PrimitiveInstruction (1..1)
alias changeQuantity: <"Create distinct list of Quantity with value set to zero.">
tradeState -> trade -> tradeLot only-element -> priceQuantity -> quantity
extract
NonNegativeQuantitySchedule {
value: 0.0,
unit: item -> unit,
...
}
then distinct
alias changePriceQuantity: <"Create change PriceQuantity for QuantityChangeInstruction.">
PriceQuantity {
quantity: changeQuantity,
...
}
set instruction -> quantityChange: <"Set primitive instruction to be only a quantity change instruction (with values set to zero).">
QuantityChangeInstruction {
change: changePriceQuantity,
direction: QuantityChangeDirectionEnum -> Replace,
lotIdentifier: empty
}
// End of ICMA - Phase 2 Contribution
func Create_BusinessEvent: <"Creates a business event from instructions containing primitive instructions and optionally a trade state.">
[creation BusinessEvent]
inputs:
instruction Instruction (1..*)
intent EventIntentEnum (0..1)
eventDate date (1..1)
effectiveDate date (1..1)
output:
businessEvent BusinessEvent (1..1)
add businessEvent -> instruction: instruction
set businessEvent -> intent: intent
set businessEvent -> eventDate: eventDate
set businessEvent -> effectiveDate: effectiveDate
add businessEvent -> after:
instruction
extract
if item -> primitiveInstruction -> split exists
then Create_Split(
item -> primitiveInstruction -> split -> breakdown,
item -> before
)
else if item -> primitiveInstruction -> exercise exists
then Create_Exercise(
item -> primitiveInstruction -> exercise,
item -> before
)
else [Create_TradeState(item -> primitiveInstruction, item -> before)]
then flatten
// TODO: we should have a condition to ensure that no trade is 'lost' between the before(s) and the after(s).
// This can be implemented by looking at the trade identifier attribute on the before state, and making sure it exists in the after state.
// So for instance where there is a party change (which results in a different trade with a different trade id), the original trade should be split first, and one of the copies should 'close' the trade.
func Create_TradeState: <"Creates a single trade state by applying primitive instructions to an existing trade state (optional in case an execution instruction is included).
The primitive instructions are applied in the following order:
Always first:
- execution, if it exists, otherwise a before state must be provided
The following 3 can be executed in any order, because they touch separate components of the trade:
- quantity change
- terms change
- party change
Always last:
- contract formation, otherwise the contract could be invalid.">
inputs:
primitiveInstruction PrimitiveInstruction (0..1) <"The set of primitive instructions to apply to the trade.">
before TradeState (0..1) <"The original trade on which the primitive instructions are applied">
output:
after TradeState (1..1) <"The returned trade state must be of single cardinality. Where a different trade is created and the original trade must be persisted (for instance showing as 'closed'), it should be preceded by a split instruction.">
alias execution: <"Create execution if instruction exists. If not, then before must exist.">
if primitiveInstruction -> execution is absent
then before
else Create_Execution(primitiveInstruction -> execution)
alias quantityChange: <"Apply quantity change if instructions exist.">
if primitiveInstruction -> quantityChange is absent
then execution
else Create_QuantityChange(primitiveInstruction -> quantityChange, execution)
alias termsChange: <"Apply terms change if instructions exist.">
if primitiveInstruction -> termsChange is absent
then quantityChange
else Create_TermsChange(primitiveInstruction -> termsChange, quantityChange)
alias partyChange: <"Apply party change if instructions exist.">
if primitiveInstruction -> partyChange is absent
then termsChange
else Create_PartyChange(
primitiveInstruction -> partyChange -> counterparty,
primitiveInstruction -> partyChange -> ancillaryParty,
primitiveInstruction -> partyChange -> partyRole,
primitiveInstruction -> partyChange -> tradeId,
termsChange /*after*/
)
alias contractFormation: <"Create contract formation if instructions exist.">
if primitiveInstruction exists
and primitiveInstruction -> contractFormation is absent
then partyChange
else Create_ContractFormation(
primitiveInstruction -> contractFormation,
partyChange
)
alias transfer:
if primitiveInstruction -> transfer is absent
then contractFormation
else Create_Transfer(primitiveInstruction -> transfer, contractFormation)
alias reset:
if primitiveInstruction -> reset is absent
then transfer
else Create_Reset(primitiveInstruction -> reset, transfer)
alias indexTransition:
if primitiveInstruction -> indexTransition is absent
then reset
else Create_IndexTransitionTermsChange(
primitiveInstruction -> indexTransition,
reset
)
alias observation:
if primitiveInstruction -> observation is absent
then indexTransition
else Create_Observation(primitiveInstruction -> observation, indexTransition)
alias valuation:
if primitiveInstruction -> valuation is absent
then observation
else Create_Valuation(primitiveInstruction -> valuation, observation)
alias stockSplit:
if primitiveInstruction -> stockSplit is absent
then valuation
else Create_StockSplit(primitiveInstruction -> stockSplit, valuation)
condition NoSplit: <"The primitive instruction cannot contain a split, as this function is designed to return a single trade state.">
primitiveInstruction -> split is absent
set after: <"Initiate applying primitive instructions.">
stockSplit
set after -> state -> closedState:
if contractFormation -> state -> positionState = PositionStatusEnum -> Closed
then ClosedState {
state: ClosedStateEnum -> Terminated,
activityDate: empty, // TODO: set this property
...
}
func ExtractBeforeEconomicTerms:
inputs:
businessEvent BusinessEvent (1..1)
output:
economicTerms EconomicTerms (0..1)
set economicTerms:
businessEvent -> instruction only-element -> before -> trade -> product -> economicTerms
func ExtractOpenEconomicTerms:
inputs:
businessEvent BusinessEvent (1..1)
output:
economicTerms EconomicTerms (0..1)
set economicTerms:
FilterOpenTradeStates(businessEvent -> after) only-element -> trade -> product -> economicTerms
func ExtractBeforeTrade:
inputs:
businessEvent BusinessEvent (1..1)
output:
trade Trade (0..1)
set trade:
businessEvent -> instruction only-element -> before -> trade
func ExtractAfterTrade:
inputs:
businessEvent BusinessEvent (1..1)
output:
trade Trade (0..1)
set trade:
FilterOpenTradeStates(businessEvent -> after) only-element -> trade
func ExtractTradePurchasePrice:
inputs:
tradableProduct TradableProduct (1..1)
output:
value number (0..*)
set value:
tradableProduct -> tradeLot only-element -> priceQuantity
extract item -> quantity
then flatten
then extract item -> value
func ExtractTradeCollateralQuantity:
inputs:
tradableProduct TradableProduct (1..1)
output:
value number (0..*)
set value:
tradableProduct -> tradeLot only-element -> priceQuantity
extract item -> quantity
then flatten
then extract item -> value
func ExtractTradeCollateralPrice:
inputs:
tradableProduct TradableProduct (1..1)
output:
value number (0..*)
set value:
tradableProduct -> tradeLot only-element -> priceQuantity
extract item -> price
then flatten
then filter item -> priceType = PriceTypeEnum -> AssetPrice
then extract item -> value
© 2015 - 2025 Weber Informatics LLC | Privacy Policy