common-domain-model
common-domain-model copied to clipboard
Entity Identifier Type
Background
Currently in the CDM there is a misalignment between the party and legal entity identification representation.
While party identification allows for the specification of the identifier type
legal identification does not:
Knowing the entity ID type is useful for reporting purposes, and the absence of an enum that determines it makes the reporting process more complex and often not effective (as it is relying on the scheme of the attribute).
Proposal
To extend the existing PartyIdentifierTypeEnum in a new enum EntityIdentifierTypeEnum, with additional values such as RED (RED codes are used oftenly in the current test pack).
Create a new type EntityIdentifier, with the same structure as the already existing type PartyIdentifier but using the new enum. Use that type everywhere in the model where an entity identifier is represented.
ISSUE on behalf of BNPP.
Outcomes of the CDM Contribution Review Working Group - January 21st, 2025 #3310:
- To harmonise the
PartyIdentifiertype andLegalEntitytype representation.LegalEntitytype should reference thePartyIdentifier. - The
PartyIdentifierTypeEnumshould be extended to include the allowed values for the Entity Identifier Type.
Updated proposal:
Outcomes of the CDM Contribution Review Working Group - February 4th, 2025 #3354:
- To define the
LegalEntitytype as an extension of thePartytype.
- The
LegalEntitywould contain acountryCodeattribute for those cases where the legal entity party is a country. Other cases would be defined inLegalEntity -> partyId -> identifier - The
PartyIdentifierTypeEnumwould be extended with the value "RED".
To be analysed the viability of using the Party type in the 16 usages of the LegalEntity type.
Outcomes of the https://github.com/finos/common-domain-model/issues/3354: To define the
LegalEntitytype as an extension of thePartytype.
Could we start from the semantics of what we understand LegalEntity and Party to represent first, and let this drive their relationship in the model?
In my view, the main difference between a legal entity and a party is that, as the name suggests, the latter exists in relation to a 'trade' (i.e. they are a party to something), whereas a legal entity exists independently of any trade. This also explains the additional attributes we have on Party like account, businessUnit or naturalPerson, which are sometimes needed to define a trade (contactInformation on the other hand should legitimately be included in LegalEntity).
In that reading, the relationship should be the other way around, i.e Party extends LegalEntity.
The various use of Party and LegalEntity should then be reviewed in the model, to ensure that the former is only used in relation to a trade.
Also where a Party is legitimately used in relation to a trade, that party should never be specified in any product definition. Instead it should be pseudonymised in the product using either CounterpartyRoleEnum or AncillaryRoleEnum (as the case may be), and only be specified at the Trade or Event level.
The
LegalEntitywould contain acountryCodeattribute for those cases where the legal entity party is a country.
My suggestion is not to have a different attribute for the identifier (i.e. you can use the existing entityId, which is a string). Instead add an enum value for country code in PartyIdentifierTypeEnum. If you look at the existing LEI or MIC values, they refer to their own ISO schemes.
Hi @lolabeis
In that reading, the relationship should be the other way around, i.e
PartyextendsLegalEntity.
This makes sense to me, based upon the comments above and the discussions in the various WGs.
The
LegalEntitywould contain acountryCodeattribute for those cases where the legal entity party is a country.My suggestion is not to have a different attribute for the identifier (i.e. you can use the existing
entityId, which is a string). Instead add an enum value for country code inPartyIdentifierTypeEnum. If you look at the existing LEI or MIC values, they refer to their own ISO schemes.
I agree about adding a new CountryCode option to the enum - however, I think we need to update LegalEntity -> entityId so it is no longer a string otherwise we won't be able to set a LegalEntity as a country. So to get access to the PartyIdentifierTypeEnum, as per Georgina's earlier suggestion, we'd need something like this:
Do you have a different way for a LegalEntity to get access to the PartyIdentifierTypeEnum?
(Plus I'm guessing that if we do change the hierarchy so Party extends LegalEntity then PartyIdentifier and PartyIdentifierTypeEnum may have to be renamed?)
Thanks!
Many thanks @lolabeis and @chrisisla for your comments.
The proposed refactoring for the LegalEntity would be:
LegalEntitytype to contain the not-trade dependent features:identifier,identifierType,nameandcontactInformation.PartyIdentifierTypeEnumrenamed toEntityIdentifierTypeEnum.EntityIdentifierTypeEnumexpanded to include the valuesREDandCountryCode.
The refactoring for the Party type would be to extend the LegalEntity:
Please let us know if any part of the above is missing or incorrect.
We will begin reviewing the usages of Party in the model to ensure it is only used in relation to a trade or event, so we can discuss our findings in the next CRWG meeting.
Thanks,
From my perspective the proposed changes look fine, they enable a LegalEntity to be used instead of a Party for the AssetLocation we are proposing, and also allow a LegalEntity to represent a country/market for AssetLocation too.
One quick point. To define a LegalEntity as the USA for example, we would need to set:
LegalEntity -> identifier -> identifier = "US"LegalEntity -> identifier -> identifierType -> "CountryCode"
This is fine but the actual country code is just a string, which does leave us open to invalid country codes being entered.
CRWG 18/03 Marc/Manuel confirmed will follow up with Leo
@gtarres Thank you for following up on this (and sorry I was unavailable at the last CRWG). Overall the proposal looks good. I would just like to raise a comment in relation to cardinality:
- in
LegalEntity,identifieris optional butnameis mandatory - in
Party, it's the other way round:identifieris mandatory optional butnameis optional
To square this, you will need to:
- make both optional on
LegalEntityand add a condition that at least one them exists - override the cardinality of
identifierinPartyto be mandatory
@chrisisla
This is fine but the actual country code is just a string, which does leave us open to invalid country codes being entered.
This is true, and should be addressed in a similar fashion as #3512. The identifier should be a typeAlias with an extra validation applied when the identifierType is CountryCode.
@chrisisla @lolabeis thank you for the feedback. Adding the conditions to the cardinality, the proposal would look like this:
If we all agree with the proposal, I will proceed with investigating the necessary adjustments to the code in order to move forward with the refactor. So far, I’ve noticed an error in the FISMapperMappingProcessor.java file and we will need to review and tweak the mappings for these types.
Additionally, I will keep aware of the resolution of the issue https://github.com/finos/common-domain-model/issues/3512 regarding the CountryCode and assess the viability of applying the FpMLCodingScheme typeAlias. Currently, the model captures the countryCode in the entityId attribute, which is a string. So, despite being conscious of the necessity to enhance the model to validate the values, if we decide to move on with the changes before adding the typeAlias, we won’t be taking a step back in terms of the value restrictions and validations.
Looks good to me @gtarres
As you say, let's not use typeAlias for now, but bear it in mind for a possible future enhancement.
@gtarres Thanks for adjusting the proposal.
A few minor comments, otherwise this looks good for ratification at the next CRWG:
- You made
identifierandnamemutually exclusive inLegalEntity, which is not the desired behaviour. Instead we want at least one of them to exist (and both can co-exist). - You left a
[metadata scheme]annotation under theLegalEntity'sidentifierattribute (a complex type), which doesn't make sense. Instead the annotation should be moved under theEntityIdentifier'sidentifierattribute (a string) - same as howPartyIdentifierworks today. - Remove the
[metadata key]annotation fromParty, since it already inherits it fromLegalEntity. - The issue has been marked as "backward-incompatible" (a new label), since we're shuffling attribute names / types, and is targeted for v7.0.
@lolabeis - appreciate your feedback. Below the adjusted version to review today at the CRWG:
Reviewed in the CRWG on 1 April 2025 (https://github.com/finos/common-domain-model/discussions/3598).
Also should scan through the model to identify the use of Party in the Model and identify whether LegalEntity would be more appropriate. Also, should LegalEntity be an attribute on Party rather than using inheritence.
Agreed to list out the usage of these types and add to this issue.
OUTCOME: Approved contingent that the above items are addressed in the PR.
I agree that counterparty has a more specific intent but the only difference I see between a Party and LegalEntity would be that a Party can be a person. Same as the use of ancillaryParty which are not a counterparty but references the Party. Even for organizations that may not be considered a counterparty we will need businessUnit, account and contactInformation same as Party. If these attributes are moved to LegalEntity then a legal entity has what it needs and Party extends LegalEntity works.
Adding to SWG pipeline, as this would be a backward-incompatible change
@tomhealey-icma - thank you for your feedback. In this case, the Party and LegalEntity types will look as defined below:
LegalEntity contains all the attributes to represent an organisation:
Party extends the LegalEntity and adds the attributes related to persons:
It doesn't seem quite right to add business unit or account to legal entity. A legal entity may be associated to many different business units or accounts, so these aren't primary attributes of a legal entity. This could lead to single (real-world) legal entity having multiple legal entity instances (in CDM), which would be confusing.
Consider instead:
- Keeping
businessUnitandaccountout ofLegalEntityand including onlycontactInformation - Creating a new type that extends
LegalEntitywithbusinessUnitandaccount- name TBD: maybeOrganisation?
Additional consideration:
- Redefining
Partyto haveorganisationas an attribute, rather than as an extension - paving the way for a party to be a natural person only, not attached to any legal entity
I believe the general rule, based on LEIs, is:
- A LEI can only be assigned to one business unit.
- A business unit can have multiple LEIs (branches, subsidiaries, funds).
- A business unit can perform services on behalf of other business units( branches, trading desks).
So unless by Legal Entity we mean just a name and identifier, otherwise a Legal Entity must (although we make it optional) have a business unit.
We could infer that an account is also a legal entity and just extend account with Legal Entity.
I have no problem with separating Party and LegalEntity as long as the rule separating the two is clear.
@tomhealey-icma
I have no problem with separating Party and LegalEntity as long as the rule separating the two is clear.
In practice in CDM, the BusinessUnit type is used to define entities / organisations that may be more granular than a legal entity (I suspect this may be different from the "business unit" concept that you referred to). A typical use case is a trading desk, that allow separate parties to be defined within the same legal entity to represent intra-company trading. Hence the attribute's description inside Party:
<"Optional organization unit information used to describe the organization units (e.g. trading desks) involved in a transaction or business process, incl. the contact information (when relevant).">
So my proposal is to have 3 clearly delineated concepts: LegalEntity, Organization and Party.
- A
LegalEntityis just a name, identifier and contact information, and aligns with the real-world concept of "legal entity" - An
Organizationallows to define more granular entities by extendingLegalEntitywith extra attributes (such asaccountandbusinessUnit). The same legal entity can be shared as an umbrella by as many distinct organizations as required. - A
Partyis literally an entity that is party to something, like a trade or a legal agreement - and could also be a natural person.
Legal entity and organizations exist as stand-alone objects, whereas a party only exists in relation to something else, where it has a role.
Even for organizations that may not be considered a counterparty we will need businessUnit, account and contactInformation same as Party. If these attributes are moved to LegalEntity then a legal entity has what it needs and Party extends LegalEntity works.
Practically I think introducing the Organization concept (which doesn't exist as such today in CDM) would address your requirements, while keeping LegalEntity aligned to its real-world equivalent.
I understand that this item was previously set to "Approved", so given the continued discussion, I'd suggest bringing it back as a "Follow-up" to the CRWG to get approval on a revised design.
In summary:
- Previously approved design:
PartyextendsLegalEntity(the latter includescontactInformation) - New design:
PartyextendsOrganization, which itself extendsLegalEntity(withbusinessUnitandaccount).
This approach keeps Party and LegalEntity unchanged compared to the previously approved design. It introduces an Organization concept in-between, which will be useful on a stand-alone basis.
- @chrisisla for info, given your interest on this issue which you have a dependency on.
Continue to monitor for Follow-up pending the Steering WG review
New proposal model update to be discussed and completed:
One issue is the relationship of a Organization to another Organization. As it stands a organization is it's own legal entity (correct) but it may also have a parent organization (Fund Manager with separate funds all have different identifiers). So maybe we could add parentOrganization Organization (*..1).
My only other comments are that all the attributes are optional. My suggestions are:
- I think a Party should have a condition of being an organization or a person.
- A organization must have an identifier by way of LegalEntity requiring at least 1 identifier (1..*)
- I would extend the identifier annotation to include ... LEI, MIC, Tax ID...
- I would also add a comment to account that we by account we also mean trading book, portfolio.
Presented at the CDM Contribution Review Working Group - May 6th, 2025. Latest design proposal is aligned with what was approved at a previous CRWG, with the insertion of an additional "Organisation" layer.
Maintainers to further review and approve / comment.
Question: when this change is made will the the CollateralEligibility check that uses EligibilityQuery get updated to match on any name or identifier from the new LegalEntity? Also, should change isserName to issuer?
type EligibilityQuery: <"Query to check against an EligibleCollateralSpecification"> ... issuerName LegalEntity (1..1) <"Specifies the issuing entity name or LEI.">
func CheckIssuerName: inputs: issuerName IssuerName (0..1) query EligibilityQuery (1..1) output: isEqual boolean (1..1)
set isEqual:
issuerName is absent or issuerName -> issuerName contains query -> issuerName
@tomhealey-icma
- I think a Party should have a condition of being an organization or a person.
Yes, we should force at least one of them to be populated (but both can be, if the person relates to that organisation)
- A organization must have an identifier by way of LegalEntity requiring at least 1 identifier (1..*)
This condition is implemented at the Party level. Otherwise a legal entity must have at least a name or an identifier - but it still leaves open the possibility of specifying a legal entity via a name only.
Also Yes to 3 and 4.
Re EligibilityQuery:
At the moment the matching works off a complex LegalEntity type, which could be populated in different ways. This makes the query brittle. I recommend adjusting the criteria to work off the new EntityIdentifier (replacement for PartyIdentifier), which is just an identifier (string) + an identifier type. This would make the collateral eligibility functionality agnostic / robust regarding how higher-level objects may be constructed.
I agree with the proposed fix.
@gtarres Can you proceed to include the final design here including changes to the enums, types (a before / after diagram would help), descriptions, conditions and functions (for collateral eligibility).
There was also an outstanding follow-up that remains to be addressed:
Also should scan through the model to identify the use of Party in the Model and identify whether LegalEntity would be more appropriate.
(According to the new design, we may replace by Organisation rather than LegalEntity)
It would be helpful to put all in one final comment on this issue, as it's currently scattered through the conversation. We'll seek a final "no objection" ratification at the next CRWG.