cdm.product.asset.floatingrate.functions.ApplyFloatingRateProcessing Maven / Gradle / Ivy
package cdm.product.asset.floatingrate.functions;
import cdm.base.math.functions.Max;
import cdm.observable.asset.Price;
import cdm.product.asset.NegativeInterestRateTreatmentEnum;
import cdm.product.asset.RateTreatmentEnum;
import cdm.product.asset.floatingrate.FloatingRateProcessingDetails;
import cdm.product.asset.floatingrate.FloatingRateProcessingDetails.FloatingRateProcessingDetailsBuilder;
import cdm.product.asset.floatingrate.FloatingRateProcessingParameters;
import cdm.product.common.schedule.CalculationPeriodBase;
import com.google.inject.ImplementedBy;
import com.rosetta.model.lib.expression.CardinalityOperator;
import com.rosetta.model.lib.expression.MapperMaths;
import com.rosetta.model.lib.functions.ModelObjectValidator;
import com.rosetta.model.lib.functions.RosettaFunction;
import com.rosetta.model.lib.mapper.MapperS;
import java.math.BigDecimal;
import java.util.Optional;
import javax.inject.Inject;
import static com.rosetta.model.lib.expression.ExpressionOperators.*;
@ImplementedBy(ApplyFloatingRateProcessing.ApplyFloatingRateProcessingDefault.class)
public abstract class ApplyFloatingRateProcessing implements RosettaFunction {
@Inject protected ModelObjectValidator objectValidator;
// RosettaFunction dependencies
//
@Inject protected ApplyFloatingRatePostSpreadProcessing applyFloatingRatePostSpreadProcessing;
@Inject protected ApplyUSRateTreatment applyUSRateTreatment;
@Inject protected Max max;
/**
* @param processing THe parameters to be used for processing, such as multipliers, spreads, cap rates, etc.
* @param rawRate The floating rate prior to treatment, either a single term rate, or a calculated rate such as an OIS or lookback compounded rate.
* @param calculationPeriod The calculation period for with the processing need to be performed.
* @param isInitialPeriod Is this the initial calculation period of the payout?
* @return details Results are details of the rate treatment.
*/
public FloatingRateProcessingDetails evaluate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
FloatingRateProcessingDetails.FloatingRateProcessingDetailsBuilder detailsBuilder = doEvaluate(processing, rawRate, calculationPeriod, isInitialPeriod);
final FloatingRateProcessingDetails details;
if (detailsBuilder == null) {
details = null;
} else {
details = detailsBuilder.build();
objectValidator.validate(FloatingRateProcessingDetails.class, details);
}
return details;
}
protected abstract FloatingRateProcessingDetails.FloatingRateProcessingDetailsBuilder doEvaluate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
protected abstract MapperS multiplier(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
protected abstract MapperS multiplied(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
protected abstract MapperS multipliedRate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
protected abstract MapperS treatedRate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
protected abstract MapperS negativeTreatment(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
protected abstract MapperS negativeTreatedRate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
protected abstract MapperS spreadRate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
protected abstract MapperS added(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
protected abstract MapperS ratePlusSpread(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
protected abstract MapperS negativeTreatedRatePlusSpread(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
protected abstract MapperS doInitialRate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
protected abstract MapperS initialRate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
protected abstract MapperS initialRatePluSpread(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
protected abstract MapperS initialRatePlusSpread(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod);
public static class ApplyFloatingRateProcessingDefault extends ApplyFloatingRateProcessing {
@Override
protected FloatingRateProcessingDetails.FloatingRateProcessingDetailsBuilder doEvaluate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
FloatingRateProcessingDetails.FloatingRateProcessingDetailsBuilder details = FloatingRateProcessingDetails.builder();
return assignOutput(details, processing, rawRate, calculationPeriod, isInitialPeriod);
}
protected FloatingRateProcessingDetails.FloatingRateProcessingDetailsBuilder assignOutput(FloatingRateProcessingDetails.FloatingRateProcessingDetailsBuilder details, FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
details
.setProcessingParameters(processing);
details
.setRawRate(rawRate);
final BigDecimal ifThenElseResult0;
if (areEqual(doInitialRate(processing, rawRate, calculationPeriod, isInitialPeriod), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) {
ifThenElseResult0 = initialRatePluSpread(processing, rawRate, calculationPeriod, isInitialPeriod).get();
} else {
ifThenElseResult0 = applyFloatingRatePostSpreadProcessing.evaluate(ratePlusSpread(processing, rawRate, calculationPeriod, isInitialPeriod).get(), processing);
}
details
.setProcessedRate(ifThenElseResult0);
final BigDecimal ifThenElseResult1;
if (areEqual(doInitialRate(processing, rawRate, calculationPeriod, isInitialPeriod), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) {
ifThenElseResult1 = initialRate(processing, rawRate, calculationPeriod, isInitialPeriod).get();
} else {
ifThenElseResult1 = applyFloatingRatePostSpreadProcessing.evaluate(negativeTreatedRate(processing, rawRate, calculationPeriod, isInitialPeriod).get(), processing);
}
details
.setSpreadExclusiveRate(ifThenElseResult1);
return Optional.ofNullable(details)
.map(o -> o.prune())
.orElse(null);
}
@Override
protected MapperS multiplier(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
return MapperS.of(processing).map("getMultiplier", floatingRateProcessingParameters -> floatingRateProcessingParameters.getMultiplier());
}
@Override
protected MapperS multiplied(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
return MapperMaths.multiply(MapperS.of(rawRate), multiplier(processing, rawRate, calculationPeriod, isInitialPeriod));
}
@Override
protected MapperS multipliedRate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
if (exists(multiplier(processing, rawRate, calculationPeriod, isInitialPeriod)).getOrDefault(false)) {
return multiplied(processing, rawRate, calculationPeriod, isInitialPeriod);
}
return MapperS.of(rawRate);
}
@Override
protected MapperS treatedRate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
return MapperMaths.multiply(MapperS.of(applyUSRateTreatment.evaluate(multipliedRate(processing, rawRate, calculationPeriod, isInitialPeriod).get(), MapperS.of(processing).map("getTreatment", floatingRateProcessingParameters -> floatingRateProcessingParameters.getTreatment()).get(), calculationPeriod)), MapperS.of(new BigDecimal("1.0")));
}
@Override
protected MapperS negativeTreatment(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
return MapperS.of(processing).map("getNegativeTreatment", floatingRateProcessingParameters -> floatingRateProcessingParameters.getNegativeTreatment());
}
@Override
protected MapperS negativeTreatedRate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
if (areEqual(negativeTreatment(processing, rawRate, calculationPeriod, isInitialPeriod), MapperS.of(NegativeInterestRateTreatmentEnum.ZERO_INTEREST_RATE_EXCLUDING_SPREAD_METHOD), CardinalityOperator.All).getOrDefault(false)) {
return MapperS.of(max.evaluate(new BigDecimal("0.0"), treatedRate(processing, rawRate, calculationPeriod, isInitialPeriod).get()));
}
return treatedRate(processing, rawRate, calculationPeriod, isInitialPeriod);
}
@Override
protected MapperS spreadRate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
return MapperS.of(processing).map("getSpread", floatingRateProcessingParameters -> floatingRateProcessingParameters.getSpread());
}
@Override
protected MapperS added(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
return MapperMaths.add(negativeTreatedRate(processing, rawRate, calculationPeriod, isInitialPeriod), spreadRate(processing, rawRate, calculationPeriod, isInitialPeriod));
}
@Override
protected MapperS ratePlusSpread(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
if (exists(spreadRate(processing, rawRate, calculationPeriod, isInitialPeriod)).getOrDefault(false)) {
return added(processing, rawRate, calculationPeriod, isInitialPeriod);
}
return negativeTreatedRate(processing, rawRate, calculationPeriod, isInitialPeriod);
}
@Override
protected MapperS negativeTreatedRatePlusSpread(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
if (areEqual(negativeTreatment(processing, rawRate, calculationPeriod, isInitialPeriod), MapperS.of(NegativeInterestRateTreatmentEnum.ZERO_INTEREST_RATE_METHOD), CardinalityOperator.All).getOrDefault(false)) {
return MapperS.of(max.evaluate(new BigDecimal("0.0"), ratePlusSpread(processing, rawRate, calculationPeriod, isInitialPeriod).get()));
}
return ratePlusSpread(processing, rawRate, calculationPeriod, isInitialPeriod);
}
@Override
protected MapperS doInitialRate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
if (areEqual(MapperS.of(isInitialPeriod), MapperS.of(true), CardinalityOperator.All).and(exists(MapperS.of(processing).map("getInitialRate", floatingRateProcessingParameters -> floatingRateProcessingParameters.getInitialRate()))).getOrDefault(false)) {
return MapperS.of(true);
}
return MapperS.of(false);
}
@Override
protected MapperS initialRate(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
return MapperS.of(processing).map("getInitialRate", floatingRateProcessingParameters -> floatingRateProcessingParameters.getInitialRate()).map("getValue", price -> price.getValue());
}
@Override
protected MapperS initialRatePluSpread(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
return MapperMaths.add(initialRate(processing, rawRate, calculationPeriod, isInitialPeriod), spreadRate(processing, rawRate, calculationPeriod, isInitialPeriod));
}
@Override
protected MapperS initialRatePlusSpread(FloatingRateProcessingParameters processing, BigDecimal rawRate, CalculationPeriodBase calculationPeriod, Boolean isInitialPeriod) {
if (exists(spreadRate(processing, rawRate, calculationPeriod, isInitialPeriod)).getOrDefault(false)) {
return initialRatePluSpread(processing, rawRate, calculationPeriod, isInitialPeriod);
}
return initialRate(processing, rawRate, calculationPeriod, isInitialPeriod);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy