cdm.event.common.functions.Create_OnDemandInterestPaymentPrimitiveInstruction Maven / Gradle / Ivy
package cdm.event.common.functions;
import cdm.base.math.NonNegativeQuantitySchedule;
import cdm.base.math.UnitType;
import cdm.base.math.metafields.ReferenceWithMetaNonNegativeQuantitySchedule;
import cdm.base.staticdata.party.PayerReceiver;
import cdm.event.common.PrimitiveInstruction;
import cdm.event.common.PrimitiveInstruction.PrimitiveInstructionBuilder;
import cdm.event.common.Trade;
import cdm.event.common.TradeState;
import cdm.observable.asset.Money;
import cdm.product.asset.InterestRatePayout;
import cdm.product.common.settlement.Cashflow;
import cdm.product.common.settlement.CashflowType;
import cdm.product.common.settlement.ResolvablePriceQuantity;
import cdm.product.common.settlement.ScheduledTransferEnum;
import cdm.product.common.settlement.SettlementDate;
import cdm.product.template.EconomicTerms;
import cdm.product.template.NonTransferableProduct;
import cdm.product.template.Payout;
import com.google.inject.ImplementedBy;
import com.rosetta.model.lib.expression.CardinalityOperator;
import com.rosetta.model.lib.functions.ConditionValidator;
import com.rosetta.model.lib.functions.ModelObjectValidator;
import com.rosetta.model.lib.functions.RosettaFunction;
import com.rosetta.model.lib.mapper.MapperS;
import com.rosetta.model.metafields.FieldWithMetaString;
import java.math.BigDecimal;
import java.util.Optional;
import javax.inject.Inject;
import static com.rosetta.model.lib.expression.ExpressionOperators.*;
@ImplementedBy(Create_OnDemandInterestPaymentPrimitiveInstruction.Create_OnDemandInterestPaymentPrimitiveInstructionDefault.class)
public abstract class Create_OnDemandInterestPaymentPrimitiveInstruction implements RosettaFunction {
@Inject protected ConditionValidator conditionValidator;
@Inject protected ModelObjectValidator objectValidator;
// RosettaFunction dependencies
//
@Inject protected Create_Cashflow create_Cashflow;
@Inject protected Create_CashflowTermsChangeInstruction create_CashflowTermsChangeInstruction;
/**
* @param tradeState The original trade to be modified.
* @param interestAmount
* @param settlementDate
* @return instruction Result is a Terms Change Instruction.
*/
public PrimitiveInstruction evaluate(TradeState tradeState, Money interestAmount, SettlementDate settlementDate) {
// pre-conditions
conditionValidator.validate(() -> exists(interestRatePayout(tradeState, interestAmount, settlementDate)),
"Only a contractual product with a single interest rate payout can have an on-demand interest payment.");
conditionValidator.validate(() -> areEqual(MapperS.of(interestAmount).map("getUnit", money -> money.getUnit()).map("getCurrency", unitType -> unitType.getCurrency()).map("Type coercion", fieldWithMetaString0 -> fieldWithMetaString0 == null ? null : fieldWithMetaString0.getValue()), interestRatePayout(tradeState, interestAmount, settlementDate).map("getPriceQuantity", _interestRatePayout -> _interestRatePayout.getPriceQuantity()).map("getQuantitySchedule", resolvablePriceQuantity -> resolvablePriceQuantity.getQuantitySchedule()).map("Type coercion", referenceWithMetaNonNegativeQuantitySchedule -> referenceWithMetaNonNegativeQuantitySchedule == null ? null : referenceWithMetaNonNegativeQuantitySchedule.getValue()).map("getUnit", nonNegativeQuantitySchedule -> nonNegativeQuantitySchedule.getUnit()).map("getCurrency", unitType -> unitType.getCurrency()).map("Type coercion", fieldWithMetaString1 -> fieldWithMetaString1 == null ? null : fieldWithMetaString1.getValue()), CardinalityOperator.All),
"The currency of the interest amount must match the currency of the original interest rate payout.");
PrimitiveInstruction.PrimitiveInstructionBuilder instructionBuilder = doEvaluate(tradeState, interestAmount, settlementDate);
final PrimitiveInstruction instruction;
if (instructionBuilder == null) {
instruction = null;
} else {
instruction = instructionBuilder.build();
objectValidator.validate(PrimitiveInstruction.class, instruction);
}
return instruction;
}
protected abstract PrimitiveInstruction.PrimitiveInstructionBuilder doEvaluate(TradeState tradeState, Money interestAmount, SettlementDate settlementDate);
protected abstract MapperS extends InterestRatePayout> interestRatePayout(TradeState tradeState, Money interestAmount, SettlementDate settlementDate);
protected abstract MapperS extends Cashflow> cashflow(TradeState tradeState, Money interestAmount, SettlementDate settlementDate);
public static class Create_OnDemandInterestPaymentPrimitiveInstructionDefault extends Create_OnDemandInterestPaymentPrimitiveInstruction {
@Override
protected PrimitiveInstruction.PrimitiveInstructionBuilder doEvaluate(TradeState tradeState, Money interestAmount, SettlementDate settlementDate) {
PrimitiveInstruction.PrimitiveInstructionBuilder instruction = PrimitiveInstruction.builder();
return assignOutput(instruction, tradeState, interestAmount, settlementDate);
}
protected PrimitiveInstruction.PrimitiveInstructionBuilder assignOutput(PrimitiveInstruction.PrimitiveInstructionBuilder instruction, TradeState tradeState, Money interestAmount, SettlementDate settlementDate) {
instruction = toBuilder(PrimitiveInstruction.builder()
.setTermsChange(create_CashflowTermsChangeInstruction.evaluate(MapperS.of(tradeState).map("getTrade", _tradeState -> _tradeState.getTrade()).map("getProduct", trade -> trade.getProduct()).get(), cashflow(tradeState, interestAmount, settlementDate).get()))
.build());
return Optional.ofNullable(instruction)
.map(o -> o.prune())
.orElse(null);
}
@Override
protected MapperS extends InterestRatePayout> interestRatePayout(TradeState tradeState, Money interestAmount, SettlementDate settlementDate) {
return MapperS.of(MapperS.of(tradeState).map("getTrade", _tradeState -> _tradeState.getTrade()).map("getProduct", trade -> trade.getProduct()).map("getEconomicTerms", nonTransferableProduct -> nonTransferableProduct.getEconomicTerms()).mapC("getPayout", economicTerms -> economicTerms.getPayout()).map("getInterestRatePayout", payout -> payout.getInterestRatePayout()).get());
}
@Override
protected MapperS extends Cashflow> cashflow(TradeState tradeState, Money interestAmount, SettlementDate settlementDate) {
final FieldWithMetaString fieldWithMetaString = interestRatePayout(tradeState, interestAmount, settlementDate).map("getPriceQuantity", _interestRatePayout -> _interestRatePayout.getPriceQuantity()).map("getQuantitySchedule", resolvablePriceQuantity -> resolvablePriceQuantity.getQuantitySchedule()).map("Type coercion", referenceWithMetaNonNegativeQuantitySchedule -> referenceWithMetaNonNegativeQuantitySchedule == null ? null : referenceWithMetaNonNegativeQuantitySchedule.getValue()).map("getUnit", nonNegativeQuantitySchedule -> nonNegativeQuantitySchedule.getUnit()).map("getCurrency", unitType -> unitType.getCurrency()).get();
return MapperS.of(create_Cashflow.evaluate(MapperS.of(interestAmount).map("getValue", money -> money.getValue()).get(), (fieldWithMetaString == null ? null : fieldWithMetaString.getValue()), settlementDate, interestRatePayout(tradeState, interestAmount, settlementDate).map("getPayerReceiver", _interestRatePayout -> _interestRatePayout.getPayerReceiver()).get(), CashflowType.builder()
.setCashflowType(ScheduledTransferEnum.NET_INTEREST)
.build(), null));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy