Skip to content

Commit

Permalink
Migrate event visualisations and remove deprecated types and funcs (f…
Browse files Browse the repository at this point in the history
…inos#1558)

* Reset

Reset

* Migrate Create_ResetPrimitive to composable event model

* Migrate Create_IndexTransitionTermsChangePrimitive to composable event model

* Restore commodity samples

* Fix index transition qualification

* Add stock split

* SL

* Fix expectations

* Remove legacy type and funcs

* Remove legacy qualifications

* Remove legacy event effects

* Fix JSOM serialised number format

* Update expectations

* Release note

* Update RELEASE.md

* Fix pom

Co-authored-by: hugohills <[email protected]>
  • Loading branch information
hugohills-regnosys and hugohills authored Apr 21, 2022
1 parent 889a72b commit 4671a42
Show file tree
Hide file tree
Showing 793 changed files with 19,100 additions and 26,664 deletions.
24 changes: 4 additions & 20 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,11 @@
# *Legal Agreement Model - Enhancements for the categorisation of legal agreement*

_Background_

The categorisation of legal agreements has been enhanced and a few data validation rule have been adjusted based on feedback from users.

# *Event Model - Index Transition, Reset, Stock Split visualisation examples*

_What is being Released_

This release follows the recent work on the composable business event model and the corresponding creation function, `Create_BusinessEvent`. Visualisation examples have been created for Index Transition, Reset and Stock Split business events.

1. Change of data type name `LegalAgreementType` to `LegalAgreementIdentification`. This change uses a more relevant type name for identifying the legal agreement and avoids the unnecessary use of suffix 'type' in the label.

2. Conditions have been updated in the model due to the renaming of `LegalAgreementType` to `legalAgreementIdentification`.

2. Data type `AgreementName` has an additional condition added for `creditSupportAgreement` This condition ensures a credit support agreement type is specified if the legal agreement is a credit support agreement.

3. Changes have been made to the logic in haircut percentages and Asset type conditions. In Data type `CollateralValuationTreatment` the related conditions for `HaircutPercentage`, `FxHaircutPercentage` and `AdditionalHaircutPercentage`, have all been adjusted so the higher range of population is <1 instead of <=1. `HaircutPercentage` has been adjusted so the lower range is >=0 instead of >0. These changes will address errors reported by users when using the model.

4. Data type `AssetType` and its related condition `OtherAssetSubType` have been changed as foolows (`assetType` <> `AssetTypeEnum` to `assetType` = `AssetTypeEnum`). These changes will address errors reported by users when using the model.

5. Within `MasterAgreementTypeEnum` `ISDA` has been amended to `ISDAMaster`, this change was recommended by ISDA legal team and is more in line with the document name and avoids confusion with the publisher used when identifying the agreement type at a higher level in the model. Updates have also been made to the related ISDACreate and FPML synonyms

This release also removes deprecated types and functions from the old event model. Some deprecated components from the old event model are still in use, mostly in ingestion examples, which will be migrated to the new event model and removed in future releases.

_Review Directions_

In the CDM Portal, select the Textual Browser and inspect the changes outlined above

In the CDM Portal, select the Instance Viewer, review the visualisation examples in the Index Transition Business Event and Stock Split Business Event folders.
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.regnosys.granite.ingestor.IngestionReport;
import com.regnosys.granite.ingestor.XMLSchema;
import com.regnosys.granite.ingestor.postprocess.pathduplicates.PathCollector;
import com.regnosys.granite.ingestor.postprocess.qualify.QualifyProcessorStep;
import com.regnosys.granite.ingestor.service.IngestionFactory;
Expand All @@ -21,7 +19,6 @@
import com.regnosys.rosetta.common.validation.RosettaTypeValidator;
import com.rosetta.model.lib.RosettaModelObject;
import org.isda.cdm.CdmRuntimeModule;
import org.isda.cdm.processor.EventEffectProcessStep;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -70,7 +67,6 @@ public void init(String[] args) throws IOException, URISyntaxException {
globalKeyProcessStep,
new ReKeyProcessStep(globalKeyProcessStep),
new ReferenceResolverProcessStep(injector.getInstance(ReferenceConfig.class)),
new EventEffectProcessStep(globalKeyProcessStep),
qualifyProcessorStep,
new PathCollector<>(),
validator);
Expand Down
34 changes: 16 additions & 18 deletions documentation/source/documentation-style-guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -270,29 +270,27 @@ Example of how a code snippet should be edited in the documentation:
.. code-block:: Haskell
type EventEffect:
effectedTrade TradeState (0..*)
[metadata reference]
trade TradeState (0..*)
[metadata reference]
productIdentifier ProductIdentifier (0..*)
[metadata reference]
transfer TransferPrimitive (0..*)
[metadata reference]
type Party:
[metadata key]
partyId string (1..*)
[metadata scheme]
name string (0..1)
[metadata scheme]
person NaturalPerson (0..*)
account Account (0..1)
And the result will be rendered as:

.. code-block:: Haskell
type EventEffect:
effectedTrade TradeState (0..*)
[metadata reference]
trade TradeState (0..*)
[metadata reference]
productIdentifier ProductIdentifier (0..*)
[metadata reference]
transfer TransferPrimitive (0..*)
[metadata reference]
type Party:
[metadata key]
partyId string (1..*)
[metadata scheme]
name string (0..1)
[metadata scheme]
person NaturalPerson (0..*)
account Account (0..1)
.. note:: Code snippets that appear in the user documentation are being compared against actual CDM components during the CDM build process, and any mismatch will trigger an error in the build. This mechanism ensures that the user documentation is kept in sync with the model in production prior to any release.

Expand Down
106 changes: 9 additions & 97 deletions documentation/source/documentation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,6 @@ A ``PrimitiveEvent`` can only include one of the primitive components, which is
contractFormation ContractFormationPrimitive (0..1)
split SplitPrimitive (0..1)
quantityChange QuantityChangePrimitive (0..1)
reset ResetPrimitive (0..1)
termsChange TermsChangePrimitive (0..1)
transfer TransferPrimitive (0..1)
Expand Down Expand Up @@ -958,12 +957,12 @@ A Business Event represents a transaction lifecycle event and is built according
[metadata key]
[rootType]
primitives PrimitiveEvent (0..*)
[deprecated]
intent EventIntentEnum (0..1)
functionCall string (0..1)
eventQualifier eventType (0..1)
eventDate date (1..1)
effectiveDate date (0..1)
eventEffect EventEffect (0..1)
packageInformation IdentifiedList (0..1)
instruction Instruction (0..*)
after TradeState (0..*)
Expand All @@ -985,85 +984,7 @@ Selected attributes of a business event are further explained below:
Intent
""""""

The Intent attribute is an enumeration value that represents the intent of a particular business event, e.g. ``Allocation``, ``EarlyTermination``, ``PartialTermination`` etc. It is used in cases where the primitive events are not sufficient to uniquely inferr a lifecycle event. As an example, a reduction in a trade quantity/notional could apply to a correction event or a partial termination.

Event Effect
""""""""""""

The event effect attribute corresponds to the set of operational and positional effects associated with a lifecycle event. This information is generated by a post-processor associated to the CDM. Certain events such as observations do not have any event effect, hence the optional cardinality.

The ``eventEffect`` contains a set of pointers to the relevant objects that are affected by the event and annotated with ``[metadata reference]``.

.. code-block:: Haskell
type EventEffect:
effectedTrade TradeState (0..*)
[metadata reference]
trade TradeState (0..*)
[metadata reference]
productIdentifier ProductIdentifier (0..*)
[metadata reference]
transfer TransferPrimitive (0..*)
[metadata reference]
The JSON snippet below for a quantity change event on a trade illustrates the use of multiple metadata reference values in ``eventEffect``.

.. code-block:: Javascript
"effectiveDate": "2018-03-15",
"eventDate": "2018-03-14",
"eventEffect": {
"trade": [
{
"globalReference": "600e4873"
}
],
"effectedTrade": [
{
"globalReference": "d36e1d72"
}
]
},
(...)
"primitive": {
"quantityChange": [
{
"after": {
(...)
"meta": {
"globalKey": "600e4873"
}
"trade": {
(...)
"tradeDate": {
"date": "2002-12-04",
"meta": {
"globalKey": "793cd7c"
}
}
}
},
"before": {
(...)
"meta": {
"globalKey": "d36e1d72"
},
"trade": {
(...)
"tradeDate": {
"date": "2002-12-04",
"meta": {
"globalKey": "793cd7c"
}
}
}
}
}
]
}
* For the ``effectedTrade``: ``d36e1d72`` points to the original trade in the ``before`` state of the ``quantityChange`` primitive event.
* For the ``trade``: ``600e4873`` points to the new trade in the ``after`` state of the ``quantityChange`` primitive event. Note how the new contract retains the initial ``tradeDate`` attribute of the original trade even after a quantity change.
The Intent attribute is an enumeration value that represents the intent of a particular business event, e.g. ``Allocation``, ``EarlyTermination``, ``PartialTermination`` etc. It is used in cases where the primitive events are not sufficient to uniquely infer a lifecycle event. As an example, a reduction in a trade quantity/notional could apply to a correction event or a partial termination.

Other Misc. Information
"""""""""""""""""""""""
Expand Down Expand Up @@ -1118,16 +1039,9 @@ The list of business events for which this process is currently implemented in t
type Instruction:
[rootType]
instructionFunction string (0..1)
allocation AllocationInstruction (0..1)
clearing ClearingInstruction (0..1)
contractFormation ContractFormationInstruction (0..1)
execution ExecutionInstruction (0..1)
exercise ExerciseInstruction (0..1)
reset ResetInstruction (0..1)
[deprecated]
transfer TransferInstruction (0..1)
quantityChange QuantityChangeInstruction (0..1)
indexTransition IndexTransitionInstruction (0..1)
termination TerminationInstruction (0..1)
[deprecated]
primitiveInstruction PrimitiveInstruction (0..1)
before TradeState (0..1)
[metadata reference]
Expand Down Expand Up @@ -2279,11 +2193,9 @@ These above steps are codified in the ``Create_ResetPrimitive`` function, which
.. code-block:: Haskell
func Create_ResetPrimitive:
[creation PrimitiveEvent]
inputs:
tradeState TradeState (1..1)
instruction ResetInstruction (1..1)
resetDate date (1..1)
tradeState TradeState (1..1)
output:
resetPrimitive ResetPrimitive (1..1)
Expand All @@ -2293,10 +2205,10 @@ These above steps are codified in the ``Create_ResetPrimitive`` function, which
alias observationDate:
if instruction -> rateRecordDate exists
then instruction -> rateRecordDate
else resetDate
else instruction -> resetDate
alias observationIdentifiers:
if payout -> equityPayout count = 1 then ResolveEquityObservationIdentifiers(payout -> equityPayout only-element, resetDate)
if payout -> equityPayout count = 1 then ResolveEquityObservationIdentifiers(payout -> equityPayout only-element, instruction -> resetDate)
else if payout -> interestRatePayout exists then ResolveInterestRateObservationIdentifiers(payout -> interestRatePayout only-element, observationDate)
alias observation:
Expand All @@ -2309,8 +2221,8 @@ These above steps are codified in the ``Create_ResetPrimitive`` function, which
tradeState
add resetPrimitive -> after -> resetHistory:
if payout -> equityPayout count = 1 then ResolveEquityReset(payout -> equityPayout only-element, observation, resetDate)
else if payout -> interestRatePayout exists then ResolveInterestRateReset(payout -> interestRatePayout, observation, resetDate, instruction -> rateRecordDate)
if payout -> equityPayout count = 1 then ResolveEquityReset(payout -> equityPayout only-element, observation, instruction -> resetDate)
else if payout -> interestRatePayout exists then ResolveInterestRateReset(payout -> interestRatePayout, observation, instruction -> resetDate, instruction -> rateRecordDate)
First, ``ResolveEquityObservationIdentifiers`` defines the specific product definition terms used to resolve ``ObservationIdentifier``s. An ``ObservationIdentifier`` uniquely identifies an ``Observation``, which inside holds a single item of market data and in this scenario will hold an equity price.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import cdm.base.math.metafields.ReferenceWithMetaQuantity;
import cdm.base.staticdata.identifier.AssignedIdentifier;
import cdm.base.staticdata.identifier.Identifier;
import cdm.base.staticdata.party.Counterparty;
import cdm.base.staticdata.party.CounterpartyRoleEnum;
import cdm.base.staticdata.party.Party;
import cdm.base.staticdata.party.PayerReceiver;
import cdm.base.staticdata.party.metafields.ReferenceWithMetaParty;
Expand Down Expand Up @@ -74,8 +76,8 @@ private Trade createFxSwapContractExample() {
PriceQuantity priceQuantity = createPriceQuantity(currency1Str, quantity1, currency2Str, quantity2, rate);

Product underlier = createForeignExchangeUnderlier(
createExchangeCurrency(party1, party2),
createExchangeCurrency(party2, party1));
createExchangeCurrency(CounterpartyRoleEnum.PARTY_1, CounterpartyRoleEnum.PARTY_2),
createExchangeCurrency(CounterpartyRoleEnum.PARTY_2, CounterpartyRoleEnum.PARTY_1));

Date settlementDate = of(2001, 10, 25);

Expand All @@ -86,14 +88,10 @@ private Trade createFxSwapContractExample() {
Identifier citi123 = createIdentifier("CITI123", "http://www.citi.com/fx/trade-id", party1);
Identifier barc987 = createIdentifier("BARC987", "http://www.barclays.com/fx/trade-id", party2);

// QuantityNotation quantityNotation1 = createQuantityNotation(currency1, quantity1);
// QuantityNotation quantityNotation2 = createQuantityNotation(currency2, quantity2);

List<Identifier> identifiers = List.of(citi123, barc987);
List<Party> parties = List.of(party1, party2);
// List<QuantityNotation> quantityNotations = List.of(quantityNotation1, quantityNotation2);

return createFxSwapContract(identifiers, parties, priceQuantity, contractualProduct, tradeDate);
return createFxSwapContract(identifiers, parties, priceQuantity, contractualProduct, tradeDate, party1, party2);
}

private PriceQuantity createPriceQuantity(String currency1Str, long quantity1, String currency2Str, long quantity2, double rate) {
Expand Down Expand Up @@ -137,10 +135,22 @@ private PriceQuantity createPriceQuantity(String currency1Str, long quantity1, S
.build();
}

private Trade createFxSwapContract(List<Identifier> identifiers, List<Party> parties, PriceQuantity priceQuantity, ContractualProduct contractualProduct, Date tradeDate) {
private Trade createFxSwapContract(List<Identifier> identifiers,
List<Party> parties,
PriceQuantity priceQuantity,
ContractualProduct contractualProduct,
Date tradeDate,
Party party1,
Party party2) {
Trade trade = Trade.builder()
.addTradeIdentifier(identifiers)
.setTradableProduct(TradableProduct.builder()
.addCounterparty(Counterparty.builder()
.setPartyReferenceValue(party1)
.setRole(CounterpartyRoleEnum.PARTY_1))
.addCounterparty(Counterparty.builder()
.setPartyReferenceValue(party2)
.setRole(CounterpartyRoleEnum.PARTY_2))
.addTradeLot(TradeLot.builder()
.addPriceQuantity(priceQuantity))
.setProduct(Product.builder().setContractualProduct(contractualProduct)))
Expand All @@ -160,18 +170,16 @@ private Product createForeignExchangeUnderlier(Cashflow exchangedCurrency1, Cash
.build();
}

private Cashflow createExchangeCurrency(Party payer, Party receiver) {
private Cashflow createExchangeCurrency(CounterpartyRoleEnum payer, CounterpartyRoleEnum receiver) {
return Cashflow.builder()
.setPayoutQuantity(ResolvablePayoutQuantity.builder()
.setResolvedQuantity(ReferenceWithMetaQuantity.builder()
.setReference(Reference.builder()
.setScope("DOCUMENT")
.setReference("quantity-2"))))
.setReference(Reference.builder()
.setScope("DOCUMENT")
.setReference("quantity-2"))))
.setPayerReceiver(PayerReceiver.builder()
.setReceiverPartyReference(ReferenceWithMetaParty.builder()
.setGlobalReference(getGlobalReference(receiver)))
.setPayerPartyReference(ReferenceWithMetaParty.builder()
.setGlobalReference(getGlobalReference(payer))))
.setPayer(payer)
.setReceiver(receiver))
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import cdm.base.math.UnitType;
import cdm.base.math.metafields.ReferenceWithMetaQuantity;
import cdm.base.staticdata.asset.rates.FloatingRateIndexEnum;
import cdm.base.staticdata.party.CounterpartyRoleEnum;
import cdm.base.staticdata.party.PayerReceiver;
import cdm.base.staticdata.party.metafields.ReferenceWithMetaParty;
import cdm.observable.asset.FloatingRateOption;
import cdm.observable.asset.Price;
import cdm.observable.asset.PriceExpression;
Expand Down Expand Up @@ -82,9 +82,8 @@ public static InterestRatePayout getFloatingRatePayout() {
.setPeriodMultiplier(6)))))

.setPayerReceiver(PayerReceiver.builder()
.setPayerPartyReference(ReferenceWithMetaParty.builder().setExternalReference("giga-bank").build())
.setReceiverPartyReference(ReferenceWithMetaParty.builder().setExternalReference("mega-bank").build()))

.setPayer(CounterpartyRoleEnum.PARTY_1)
.setReceiver(CounterpartyRoleEnum.PARTY_2))
.build();
}

Expand Down Expand Up @@ -143,9 +142,8 @@ public static InterestRatePayout getFixedRatePayout(BigDecimal fixedRate) {
.setPriceExpression(PriceExpression.builder()
.setPriceType(PriceTypeEnum.INTEREST_RATE)))))))
.setPayerReceiver(PayerReceiver.builder()
.setPayerPartyReference(ReferenceWithMetaParty.builder().setExternalReference("mega-bank").build())
.setReceiverPartyReference(ReferenceWithMetaParty.builder().setExternalReference("giga-bank").build()))

.setPayer(CounterpartyRoleEnum.PARTY_2)
.setReceiver(CounterpartyRoleEnum.PARTY_1))
.build();
}
}
Loading

0 comments on commit 4671a42

Please sign in to comment.