-
Notifications
You must be signed in to change notification settings - Fork 31
Rosetta Syntax Upgrade
This document describes the desired state for the Rosetta DSL. The primary focus of this document is on the Syntax, with details on Scoping and Validation features captured inside code examples.
Further Scoping, Validation and Code Generation details to come.
As part of on-going improvement and to facilitate the opening of CDM contributions to the community, we will implement a number of changes to the Rosetta DSL that will make reading and writing easier. Further, simplifications to the meta-model - the Ecore - should make external Code Generator contributions easier.
Current Rosetta DSL concepts:
- Type (classes, enums, basic types, record types)
- Synonym (mappings, conditionals, custom)
- Validation (choice rules, data rules)
- Calculation (calculation, functions)
- Function Specification
- Regulatory Rule
In essence, we see every model being made up of Types and Functions, and we wish to simplify the Rosetta DSL to reflect this.
The reduced number of objects in Ecore as well as fewer Grammar Rules will support greater reuse of Scoping, Validation and Code Generation features.
Below is a summary of changes to achieve this goal:
- Define consistent syntax (with respect to colon, semi-colons, braces, comments, definitions) between Types and Functions
- Replace
class
,enum
andrecord type
with Types - Replace
calculation
,function
,alias
andspec
with Functions - Reuse consistent Function syntax for
data rule
,choice rule
,one of
andalias
- Support different views for DSL Readers vs. DSL Writers
- Regulatory Rules to be tackled in another phase of work
The anatomy of Rosetta concepts are generally described using Extended Backus–Naur form and describes the Grammar Rules that governs the syntax.
We start by specifying three root elements: Types, Function and Annotation. For each root element, we state its form, then as list of tasks to migrate from the current syntax to the proposed along with examples of current vs. proposed.
Defining a Type objects takes the following form:
'type' Name ('extends' [Type])? ':' Definition?
Annotation*
Attribute+
Condition*
where:
-
Definition:
'<' STRING '>'
-
Annotation:
'[' [Annotation] [Attribute] ']' // square braces represent cross reference to existing Annotation (by Name) and one of its Attributes
-
Attribute:
Name Type Cardinality (':' Definition)? Annotation*
-
Condition:
'condition' Name? ':' Definition? Annotation* RosettaExpression+
- Replace
class
,enum
andrecord type
with Type - Remove semi-colon at end of each attribute
- Remove angle-brackets in Definitions
- Remove quotes in synonym paths and enum synonyms, use a single Grammar tree to represent Synonyms
Current:
class Party key <"A class to specify a party, without a qualification as to whether this party is a legal entity or a natural person, although the model provides the ability to associate a person (or set of persons) to a party, which use case would imply that such party would be a legal entity (even if not formally specified as such). ">
[synonym FpML_5_10, DTCC_11_0, DTCC_9_0 , CME_ClearedConfirm_1_17, CME_SubmissionIRS_1_0 value Party meta id maps 2]
{
partyId string (1..*) scheme <"The identifier associated with a party, e.g. the 20 digits LEI code.">;
[synonym FpML_5_10, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17, CME_SubmissionIRS_1_0 value partyId meta partyIdScheme]
[synonym DTCC_11_0, DTCC_9_0 value partyId maps 2 meta partyIdScheme]
[synonym ISDA_Create_1_0 value id]
name string (0..1) scheme <"The party name.">;
[synonym FpML_5_10, CME_SubmissionIRS_1_0, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17 value partyName meta entityNameScheme]
[synonym FpML_5_10, CME_SubmissionIRS_1_0, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17 value entityName meta entityNameScheme]
[synonym FpML_5_10, CME_SubmissionIRS_1_0, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17 value entityName path "referenceEntity" meta entityNameScheme]
[synonym CME_SubmissionIRS_1_0 value SID path "Hdr"]
[synonym ISDA_Create_1_0 value name]
[synonym ISDA_Create_1_0 value partyA_name, partyB_name]
person NaturalPerson (0..*) <"The person(s) who might be associated with the party as part of the execution, contract or legal document.">;
[synonym FpML_5_10, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17, CME_SubmissionIRS_1_0 value person]
account Account (0..1) <"The account that might be associated with the party. At most one account can be specified, as it is expected that this information is used in the context of a contract or legal document where only one account per party can be associated with such object.">;
[synonym FpML_5_10, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17, CME_SubmissionIRS_1_0, ISDA_Create_1_0 value account]
}
Proposed:
type Party: "A class to specify a party, without a qualification as to whether this party is a legal entity or a natural person, although the model provides the ability to associate a person (or set of persons) to a party, which use case would imply that such party would be a legal entity (even if not formally specified as such)."
[keyed]
[synonym FpML_5_10, DTCC_11_0, DTCC_9_0 , CME_ClearedConfirm_1_17, CME_SubmissionIRS_1_0 value Party meta id maps 2]
partyId string (1..*): <"The identifier associated with a party, e.g. the 20 digits LEI code.">
[metadata scheme]
[synonym FpML_5_10, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17, CME_SubmissionIRS_1_0 value partyId meta partyIdScheme]
[synonym DTCC_11_0, DTCC_9_0 value partyId maps 2 meta partyIdScheme]
[synonym ISDA_Create_1_0 value id]
name string (0..1): <"The party name">
[synonym FpML_5_10, CME_SubmissionIRS_1_0, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17 value partyName meta entityNameScheme]
[synonym FpML_5_10, CME_SubmissionIRS_1_0, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17 value entityName meta entityNameScheme]
[synonym FpML_5_10, CME_SubmissionIRS_1_0, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17 value entityName path referenceEntity meta entityNameScheme]
[synonym CME_SubmissionIRS_1_0 value SID path Hdr]
[synonym ISDA_Create_1_0 value name]
[synonym ISDA_Create_1_0 value partyA_name, partyB_name]
person NaturalPerson (0..*): <"The person(s) who might be associated with the party as part of the execution, contract or legal document">
[synonym FpML_5_10, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17, CME_SubmissionIRS_1_0 value person]
account Account (0..1): <"The account that might be associated with the party. At most one account can be specified, as it is expected that this information is used in the context of a contract or legal document where only one account per party can be associated with such object.">
[synonym FpML_5_10, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17, CME_SubmissionIRS_1_0, ISDA_Create_1_0 value account]
- Move
data rule
intocondition
expression blocks inside Type-Body - Support optional
else
block inif
expression
Current:
class Contract key <"A class to specify a financial contract object...">
[synonym FpML_5_10, CME_SubmissionIRS_1_0, CME_ClearedConfirm_1_17 meta id path "trade"]
[synonym FpML_5_10, CME_SubmissionIRS_1_0, CME_ClearedConfirm_1_17, Rosetta_Workbench meta id]
{
contractIdentifier Identifier (1..*) <"The identifier(s) that uniquely identify a contract...">;
[synonym FpML_5_10, CME_SubmissionIRS_1_0 value partyTradeIdentifier path "trade.tradeHeader"]
tradeDate TradeDate (1..1) <"The date on which the contract has been executed.">;
partyRole PartyRole (0..*) <"The role(s) that party(ies) may have...">;
...
}
data rule Contract_hedgingParty <"FpML specifies that there cannot be more than 2 hedging parties.">
when Contract -> partyRole -> role = PartyRoleEnum.HedgingParty
then Contract -> partyRole -> role count <= 2
Proposed:
annotation keyed: <"Applies to classes. Indicates when a class can be referred to by other classes via an identifier">
type Contract: <"A class to specify a financial contract object...">
[keyed]
[synonym FpML_5_10, CME_SubmissionIRS_1_0, CME_ClearedConfirm_1_17 meta id path trade]
[synonym FpML_5_10, CME_SubmissionIRS_1_0, CME_ClearedConfirm_1_17, Rosetta_Workbench meta id]
contractIdentifier Identifier (1..*): <"The identifier(s) that uniquely identify a contract...">
[synonym FpML_5_10, CME_SubmissionIRS_1_0 value partyTradeIdentifier path trade.tradeHeader]
tradeDate TradeDate (1..1): <"The date on which the contract has been executed.">
...
condition Contract_hedgingParty: <"FpML specifies that there cannot be more than 2 hedging parties.">
if partyRole -> role = PartyRoleEnum.HedgingParty
then partyRole -> role count <= 2
- Move
choice rule
intocondition
expression blocks inside Type-Body - Support syntactic sugar to pass all Attributes/Inputs into a Function call when none specified
Current:
class SecurityValuationModel one of <"The security valuation model choice, which can either be based on nominal amount as for a bond, or on the number of contract units as for equity.">
{
bondValuationModel BondValuationModel (0..1) <"The valuation model when the security is a bond.">;
unitContractValuationModel UnitContractValuationModel (0..1) <"The valuation model when the security is a unit contract like equity.">;
}
class InitialMarginCalculation <"Defines the initial margin calculation applicable to a single piece of collateral.">
{
marginRatio number (0..1) <"An element defining ...">;
[synonym FpML_5_10 value marginRatio]
marginRatioThreshold number (0..2) <"An element defining a margin ratio threshold...">;
[synonym FpML_5_10 value marginRatioThreshold]
haircut number (0..1) <"An element defining a haircut ...">;
[synonym FpML_5_10 value haircut]
...
}
choice rule InitialMarginCalculation_choice
for InitialMarginCalculation required choice between
marginRatio and haircut
Proposed:
type SecurityValuationModel: <"The security valuation model choice, which can either be based on nominal amount as for a bond, or on the number of contract units as for equity.">
bondValuationModel BondValuationModel (0..1): <"The valuation model when the security is a bond.">
unitContractValuationModel UnitContractValuationModel (0..1): <"The valuation model when the security is a unit contract like equity.">
condition: one of; // one of - remains a language feature
type InitialMarginCalculation: <"Defines the initial margin calculation applicable to a single piece of collateral.">
marginRatio number (0..1): <"An element defining ...">
[synonym FpML_5_10 value marginRatio]
marginRatioThreshold number (0..2): <"An element defining a margin ratio threshold...">
[synonym FpML_5_10 value marginRatioThreshold]
haircut number (0..1): <"An element defining a haircut ...">
[synonym FpML_5_10 value haircut]
...
condition InitialMarginCalculation_choice_1: <"Replaces choice rule InitialMarginCalculation_choice">
RequiredChoice( marginRatio, haircut );
func OptionalChoice: "For the set of inputs, at most 1 exists"
[validation]
inputs: inputs any (1..*)
output: result boolean (1..1)
func RequiredChoice: "For the set of inputs, exactly 1 exists"
[validation]
inputs: inputs any (1..*)
output: result boolean (1..1)
Enum and Record Type examples to follow...
calculation
, function
, spec
and alias
are 4 language features that are all Functions
-
function
is a function signature only i.e. function name, inputs and outputs -
calculation
is a function where the inputs are inferred for readability -
alias
is a function that takes an single object as input and outputs a child of that object -
spec
was recently introduced as a way to consolidate the above 3
Functions take the form:
'func' Name ('implements' [Function])? ':' Definition?
Annotation*
Input*
Output*
Alias*
Condition*
Assignment*
Post-Condition*
where:
-
Input
'inputs' ':' Attribute+
-
Output
'output' ':' Attribute
-
Alias: used as a bookmark for long Rosetta Paths (ie
Contract -> product -> contractualProduct -> payout -> ... -> amount
) and complex expressions'alias' Name ':' Definition? RosettaExpression
-
Assignment: used to build the output object
'assign-output' AttributePath ':' Definition? RosettaExpression // Rosetta Expressions do not support assignment operations, hence the
-
AttributePath refers to a reference to an attributes on a Rosetta element i.e.
Contract -> product -> ... -> quantity
-
Post-Condition
'post-condition' Name? ':' Definition? Annotation* RosettaExpression+
- Migrate
spec
tofunc
Current:
spec NewContractFormationFromExecution <"Function specification to create a fully-formed contract following execution on a contractual product. The contract can optionally reference a further legal agreement (such as a CSA or a Master Confirmation).">:
inputs:
executionState ExecutionState (1..1)
partyA Party (1..1)
partyB Party (1..1)
legalAgreement LegalAgreement (0..1)
output:
contractFormation ContractFormation (1..1)
pre-condition <"Parties must be different, and match the contractual parties to the legal agreement when those exists, and the parties to the execution when those exist.">:
partyA <> partyB;
if legalAgreement exists then
legalAgreement -> contractualParty contains partyA and
legalAgreement -> contractualParty contains partyB
else True;
if executionState -> execution -> party exists then
executionState -> execution -> party contains partyA and
executionState -> execution -> party contains partyB
else True;
post-condition <"Before state must be the execution, and the contractual product in the after state must be the underlying product of the contract being formed.">:
contractFormation -> before = executionState;
post-condition <"When an overlaying legal agreement exists, the contract must reference it.">:
if legalAgreement exists then contractFormation -> after -> contract -> documentation -> legalAgreement = legalAgreement else True;
Proposed:
func NewContractFormationFromExecution: <"Function specification to create a fully-formed contract following execution on a contractual product. The contract can optionally reference a further legal agreement (such as a CSA or a Master Confirmation).">
inputs:
executionState ExecutionState (1..1)
partyA Party (1..1)
partyB Party (1..1)
legalAgreement LegalAgreement (0..1)
output:
contractFormation ContractFormation (1..1)
pre-condition: <"Parties must be different, and match the contractual parties to the legal agreement when those exists, and the parties to the execution when those exist.">
partyA <> partyB;
if legalAgreement exists then
legalAgreement -> contractualParty contains partyA and
legalAgreement -> contractualParty contains partyB;
if executionState -> execution -> party exists then
executionState -> execution -> party contains partyA and
executionState -> execution -> party contains partyB;
assign-output contractFormation -> before: <"Before state must be the execution, and the contractual product in the after state must be the underlying product of the contract being formed.">
executionState;
assign-output contractFormation -> after -> contract -> documentation -> legalAgreement: <"When an overlaying legal agreement exists, the contract must reference it.">
if legalAgreement exists then legalAgreement; // implicitly else "nothing"
- Replace
calculation
,function
with Functions. - Introduce a concept of higher-order functions.
- Support resolving and invoking functions based on Enum values.
Current:
calculation FixedAmount <"2006 ISDA Definition Article 5 Section 5.1. Calculation of a Fixed Amount...">
{
fixedAmount : calculationAmount * fixedRate * dayCountFraction
where
calculationAmount : InterestRatePayout -> quantity -> notionalSchedule -> notionalStepSchedule -> initialValue
fixedRate : InterestRatePayout -> rateSpecification -> fixedRate -> initialValue
dayCountFraction : InterestRatePayout -> dayCountFraction
}
calculation DayCountFractionEnum.ACT_360 <"...">
{
: daysInPeriod / 360
where
daysInPeriod <"Number of calendar in the calculation period">:
CalculationPeriod( InterestRatePayout -> calculationPeriodDates ) -> daysInPeriod
}
function ResolveRateIndex( index FloatingRateIndexEnum ) <"The function to specify that...">
{
rate number;
}
function CalculationPeriod( calculationPeriodDates CalculationPeriodDates ) <"...">
{
startDate date;
endDate date;
daysInPeriod int;
daysInLeapYearPeriod int;
isFirstPeriod boolean;
isLastPeriod boolean;
}
Proposed:
func FixedAmount: <"2006 ISDA Definition Article 5 Section 5.1. Calculation of a Fixed Amount...">
inputs:
interestRatePayout InterestRatePayout (1..1)
output:
fixedAmount number (1..1)
alias calculationAmount: <"The calculation amount as extracted from the interest rate payout">
interestRatePayout -> quantity -> notionalSchedule -> notionalStepSchedule -> initialValue
alias fixedRate: <"a shortcut from the Interest Rate Payout to the Fixed Rate">
interestRatePayout -> rateSpecification -> fixedRate -> initialValue
alias dayCountFraction: "..."
DayCountFraction( interestRatePayout, interestRatePayout -> dayCountFraction )
assign-output fixedAmount: <"assigns the output 'fixedAmount' with the result of the mathematical operation">
calculationAmount * fixedRate * dayCountFraction
// Defines DayCountFraction function. No assignments, first parameter is a dispatch enum, the second is the context object
//
func DayCountFraction: <"A description of inputs and outputs for all day count fraction calculations">
inputs:
interestRatePayout InterestRatePayout (1..1)
dayCountFractionEnum DayCountFractionEnum (1..1)
output:
result number (1..1)
// implements DayCountFraction for enum value ACT_365.
// In other words we "preset" dayCountFractionEnum DayCountFractionEnum (1..1) input with a concrete value
//
func DayCountFraction(dayCountFractionEnum: DayCountFractionEnum.ACT_365): <"An concrete specification of a Day Count Fraction calculation, where both inputs and output have been inhereted from its parent: the func DayCountFraction">
alias daysInPeriod:
CalculationPeriod( interestRatePayout -> calculationPeriodDates ) -> daysInPeriod
assign-output result:
daysInPeriod / 360
func ResolveRateIndex: <"The function to ...">
inputs: index FloatingRateIndexEnum (1..1)
output: rate number (1..1)
type CalculationPeriodResult: <"...">
startDate date (1..1)
endDate date (1..1)
daysInPeriod int (1..1)
daysInLeapYearPeriod int (1..1)
isFirstPeriod boolean (1..1)
isLastPeriod boolean (1..1)
func CalculationPeriod: <"...">
inputs: calculationPeriodDates CalculationPeriodDates (1..1)
output: result CalculationPeriodResult (1..1)
--- Alternative Proposal (not yet accepted): ---
func FixedAmount: "2006 ISDA Definition Article 5 Section 5.1. Calculation of a Fixed Amount..."
inputs:
interestRatePayout InterestRatePayout (1..1)
output:
fixedAmount number (1..1)
alias calculationAmount: "The calculation amount as extracted from the interest rate payout"
interestRatePayout -> quantity -> notionalSchedule -> notionalStepSchedule -> initialValue
alias fixedRate: "a shortcut from the Interest Rate Payout to the Fixed Rate"
interestRatePayout -> rateSpecification -> fixedRate -> initialValue
alias dayCountFraction: "..."
interestRatePayout -> dayCountFraction func
assign-output fixedAmount: "assigns the output 'fixedAmount' with the result of the mathematical operation"
calculationAmount * fixedRate * dayCountFraction( interestRatePayout )
Notes on func FixedAmount
- the
func
keyword inalias dayCountFraction
resolves the function that is attached to the Enum's value - The data-type of
alias dayCountFraction
isfunction
whose inputs and output are specified byfunc DayCountFraction
- Scoping: an
alias
can be created oninputs
oroutput
- Scoping: a
condition
can reference only global elements,inputs
andalias
's based oninputs
- Scoping: a
post-condition
can reference global elements,inputs
, theoutput
and anyalias
- Scoping: The name of the
assign-output
block should reference only theoutput
- Scoping: The expression within the
assign-output
can reference global elements, inputs, the output and anyalias
- Validation:
output
is optional in the grammar but is mandatory forfunc
s that don't implement otherfunc
s - Validation: when the
func
keyword is used to resolve a Function, check thatDayCountFractionEnum
isattached to
afunc
and saidfunc
has at least 1 implementation
func DayCountFraction: "A description of inputs and outputs for all day count fraction calculations"
[attached to DayCountFractionEnum]
inputs:
interestRatePayout InterestRatePayout (1..1)
output:
result number (1..1)
func ACT_365 implements DayCountFraction : "An concrete specification of a Day Count Fraction calculation, where both inputs and output have been 'inhereted' from its parent: the func DayCountFraction"
alias daysInPeriod:
CalculationPeriod( interestRatePayout -> calculationPeriodDates ) -> daysInPeriod
assign-output result:
daysInPeriod / 360
Notes on func DayCountFraction
- The
attached to
Annotation states that this Function is associated with the EnumDayCountFractionEnum
- Implicitly, all implementations of DayCountFraction will be
attached to
values onDayCountFractionEnum
- Validation: each Enum type has only a single
func
attached.
Notes on func ACT_365
-
func
s canimplement
at most 1 otherfunc
-
inputs
andoutput
are inherited from the parent with no overriding of inputs or outputs allowed - Validation: input and output definitions are not allowed
- Validation: the
func
's name needs to be a value from the Enum specified in the annotation of the parent - Validation: for each enum value, only a single
func
is attached
--- End of Alternative proposal ---
- Replace
alias
with Functions
Current:
alias forwardFX
ForwardPayout -> underlier -> singleUnderlier -> underlyingProduct -> foreignExchange
Proposed:
func ForwardFX:
[alias]
inputs: forwardPayout ForwardPayout (1..1)
output: foreignExchange ForeignExchange (1..1)
assign-output foreignExchange: forwardPayout -> underlier -> singleUnderlier -> underlyingProduct -> foreignExchange
// support for syntactic sugar?
//
alias forwardFX
ForwardPayout -> underlier -> singleUnderlier -> underlyingProduct -> foreignExchange
Any Function invocation must be done by a Client, where a Client is someone or some system that makes use of the generated code. Functions can call other Functions
Annotations will be a new concept that represents non-core information. For example, the mandatory parts of Types are its name and attributes, therefore all other descriptors should be placed inside annotations. For Attributes, the name, type and cardinality are mandatory and so synonyms are represented in annotations.
Annotations can be defined in the language or in the grammar. Those defined in the language take the following form:
'annotation' Name Definition?
Attribute*
For annotations defined in grammar, they can take on any form definable via the xText Grammar syntax.
Annotation usage take the following forms:
-
Annotation - an annotation with attributes
annotation metadata: "Example definition of an annotation type" scheme string (0..1) reference string (0..1) type Party: "..." partyId string (1..*): "..." [metadata scheme]
-
Marker Annotation - an annotation with no attributes
annotation keyed: "Indicates whether an object should support storage of a `global key`" type Party: "..." [keyed] partyId string (1..*): "..." name string (0..1): "..."
-
Structured Annotation - where the strucutre of the annotation is defined in grammar
type Party: "..." partyId string (1..*): "..." [synonym FpML_5_10 value partyId meta partyIdScheme] // re-uses existing synonym grammar rules
We recognise that a Rosetta reader and a Rosetta editor may want different views of the DSL and so we wish to support in Rosetta Core the ability to switch between "views". When writing Rosetta, the writer needs to be specific about type and cardinality, i.e. when passing object references into functions or nesting function calls.
Everything that is between square brackets is an annotation that provides additional information and can be folded (hidden) in the editor. Taking an example of the data type Party
from CDM, the example "reader" view should look like the below
Before:
class Party key <"A class to specify a party, without a qualification as to whether this party is a legal entity or a natural person, although the model provides the ability to associate a person (or set of persons) to a party, which use case would imply that such party would be a legal entity (even if not formally specified as such). ">
[synonym FpML_5_10, DTCC_11_0, DTCC_9_0 , CME_ClearedConfirm_1_17, CME_SubmissionIRS_1_0 value Party meta id maps 2]
{
partyId string (1..*) scheme <"The identifier associated with a party, e.g. the 20 digits LEI code.">;
[synonym FpML_5_10, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17, CME_SubmissionIRS_1_0 value partyId meta partyIdScheme]
[synonym DTCC_11_0, DTCC_9_0 value partyId maps 2 meta partyIdScheme]
[synonym ISDA_Create_1_0 value id]
name string (0..1) scheme <"The party name.">;
[synonym FpML_5_10, CME_SubmissionIRS_1_0, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17 value partyName meta entityNameScheme]
[synonym FpML_5_10, CME_SubmissionIRS_1_0, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17 value entityName meta entityNameScheme]
[synonym FpML_5_10, CME_SubmissionIRS_1_0, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17 value entityName path "referenceEntity" meta entityNameScheme]
[synonym CME_SubmissionIRS_1_0 value SID path "Hdr"]
[synonym ISDA_Create_1_0 value name]
[synonym ISDA_Create_1_0 value partyA_name, partyB_name]
person NaturalPerson (0..*) <"The person(s) who might be associated with the party as part of the execution, contract or legal document.">;
[synonym FpML_5_10, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17, CME_SubmissionIRS_1_0 value person]
account Account (0..1) <"The account that might be associated with the party. At most one account can be specified, as it is expected that this information is used in the context of a contract or legal document where only one account per party can be associated with such object.">;
[synonym FpML_5_10, DTCC_11_0, DTCC_9_0, CME_ClearedConfirm_1_17, CME_SubmissionIRS_1_0, ISDA_Create_1_0 value account]
}
Proposed
Party: "A class to specify a party..."
- partyId : "The identifier associated with a party, e.g. the 20 digits LEI code."
- name : "The party name"
- person : "The person(s) who might be associated with the party as part of the execution, contract or legal document"
- account : "The account that might be associated with the party. At most one account can be specified, as it is expected that this information is used in the context of a contract or legal document where only one account per party can be associated with such object."
-
An example of the function FixedAmount
from CDM in the "reader" view:
Current:
calculation FixedAmount <"2006 ISDA Definition Article 5 Section 5.1. Calculation of a Fixed Amount...">
{
fixedAmount : calculationAmount * fixedRate * dayCountFraction
where
calculationAmount : InterestRatePayout -> quantity -> notionalSchedule -> notionalStepSchedule -> initialValue
fixedRate : InterestRatePayout -> rateSpecification -> fixedRate -> initialValue
dayCountFraction : InterestRatePayout -> dayCountFraction
}
Proposed
FixedAmount: "2006 ISDA Definition Article 5 Section 5.1. Calculation of a Fixed Amount..."
= calculationAmount * fixedRate * dayCountFraction
where:
calculationAmount: "The quantity or notional used to compute the Fixed Amount."
fixedRate: "The observed rate."
dayCountFraction: "The Day Count Convention used to count the number of days within a period."
An example of how choice rule
s in "reader" view
type InitialMarginCalculation: <"Defines the initial margin calculation applicable to a single piece of collateral.">
- marginRatio: <"An element defining ...">
- marginRatioThreshold: <"An element defining a margin ratio threshold...">
- haircut: <"An element defining a haircut ...">
- InitialMarginCalculation_choice: <"Replaces choice rule InitialMarginCalculation_choice">
RequiredChoice between marginRatio and haircut
Digital Regulatory Reporting is an extension case to core CDM modelling (Products and Events) and will be addressed once the above work has come reached a conclusion.
There are 4 aspects to the report:
- When to report (daily)
- If the event is eligible for reporting
- Define the fields to be reported from the cdm model classes
- Define the mappings to the output reporting format (e.g. ISO 20022)
This is the way we currently can define regulatory context. We define a regulatoryRegime, mandate and segment and combine them to reference a provision.
regulatoryRegime ESMA_MiFID_I
regulatoryRegime ESMA_MiFID_II
regulatoryRegime ESMA_MiFIR
regulatoryRegime CFTC_DFA
mandate regulation
mandate specification
mandate guideline
segment article
segment whereas
segment annex
segment section
segment field
reportingStandard ISO_20022
// Example usage (you can annotate any class, attribute or rule)
// [regulatoryReference ESMA_MiFIR regulation "RTS 22" article "2" provision "Do what I say, not what I do."]
Proposed syntax example:
MifidIITransactionReport
[Report]
reported daily for T-1
when ESMA_MiFIR regulation "RTS 22" applies
using reportingStandard ISO_20022
report fields
// The fields need to reference two rules. One to get data from and one to project data to.
// To start with - we can just use the entire path, then refactor if/when it gets more complex.
- reportStatus from Event -> xxx -> yyy to ISO_20022 -> xxx
- price from Event -> zzz -> ccc to ISO_20022 -> xxx
- txid from Event -> vvv -> ddd to ISO_20022 -> xxx
RTS_22_Is_Transaction: "When eligible for rts 22"
[Eligibility]
[regulatoryReference ESMA_MiFIR regulation "RTS 22" article "2" provision "For the purposes of Article 26 of Regulation (EU) No 600/2014, the conclusion of an acquisition or disposal of a financial instrument referred to in Article 26(2) of Regulation (EU) No 600/2014 shall constitute a transaction."]
for Event
primitive -> inception -> must exist
or
primitive -> termination -> must exist