All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdm.product.asset.calculation.functions.FixedAmountCalculation Maven / Gradle / Ivy

package cdm.product.asset.calculation.functions;

import cdm.base.datetime.daycount.metafields.FieldWithMetaDayCountFractionEnum;
import cdm.base.math.UnitType;
import cdm.observable.asset.Money;
import cdm.product.asset.FixedAmountCalculationDetails;
import cdm.product.asset.FixedAmountCalculationDetails.FixedAmountCalculationDetailsBuilder;
import cdm.product.asset.InterestRatePayout;
import cdm.product.common.schedule.CalculationPeriodBase;
import com.google.inject.ImplementedBy;
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 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(FixedAmountCalculation.FixedAmountCalculationDefault.class)
public abstract class FixedAmountCalculation implements RosettaFunction {
	
	@Inject protected ModelObjectValidator objectValidator;
	
	// RosettaFunction dependencies
	//
	@Inject protected CalculateYearFraction calculateYearFraction;
	@Inject protected GetFixedRate getFixedRate;
	@Inject protected GetNotionalAmount getNotionalAmount;

	/**
	* @param interestRatePayout 
	* @param calculationPeriod 
	* @param notional 
	* @return fixedAmountDetails 
	*/
	public FixedAmountCalculationDetails evaluate(InterestRatePayout interestRatePayout, CalculationPeriodBase calculationPeriod, BigDecimal notional) {
		FixedAmountCalculationDetails.FixedAmountCalculationDetailsBuilder fixedAmountDetailsBuilder = doEvaluate(interestRatePayout, calculationPeriod, notional);
		
		final FixedAmountCalculationDetails fixedAmountDetails;
		if (fixedAmountDetailsBuilder == null) {
			fixedAmountDetails = null;
		} else {
			fixedAmountDetails = fixedAmountDetailsBuilder.build();
			objectValidator.validate(FixedAmountCalculationDetails.class, fixedAmountDetails);
		}
		
		return fixedAmountDetails;
	}

	protected abstract FixedAmountCalculationDetails.FixedAmountCalculationDetailsBuilder doEvaluate(InterestRatePayout interestRatePayout, CalculationPeriodBase calculationPeriod, BigDecimal notional);

	protected abstract MapperS fixedRate(InterestRatePayout interestRatePayout, CalculationPeriodBase calculationPeriod, BigDecimal notional);

	protected abstract MapperS calculationAmount(InterestRatePayout interestRatePayout, CalculationPeriodBase calculationPeriod, BigDecimal notional);

	protected abstract MapperS dcf(InterestRatePayout interestRatePayout, CalculationPeriodBase calculationPeriod, BigDecimal notional);

	protected abstract MapperS yearFraction(InterestRatePayout interestRatePayout, CalculationPeriodBase calculationPeriod, BigDecimal notional);

	protected abstract MapperS calcAmt(InterestRatePayout interestRatePayout, CalculationPeriodBase calculationPeriod, BigDecimal notional);

	public static class FixedAmountCalculationDefault extends FixedAmountCalculation {
		@Override
		protected FixedAmountCalculationDetails.FixedAmountCalculationDetailsBuilder doEvaluate(InterestRatePayout interestRatePayout, CalculationPeriodBase calculationPeriod, BigDecimal notional) {
			FixedAmountCalculationDetails.FixedAmountCalculationDetailsBuilder fixedAmountDetails = FixedAmountCalculationDetails.builder();
			return assignOutput(fixedAmountDetails, interestRatePayout, calculationPeriod, notional);
		}
		
		protected FixedAmountCalculationDetails.FixedAmountCalculationDetailsBuilder assignOutput(FixedAmountCalculationDetails.FixedAmountCalculationDetailsBuilder fixedAmountDetails, InterestRatePayout interestRatePayout, CalculationPeriodBase calculationPeriod, BigDecimal notional) {
			fixedAmountDetails
				.setCalculationPeriod(calculationPeriod);
			
			fixedAmountDetails
				.getOrCreateCalculationPeriodNotionalAmount()
				.setValue(calcAmt(interestRatePayout, calculationPeriod, notional).get());
			
			final FieldWithMetaString fieldWithMetaString = calculationAmount(interestRatePayout, calculationPeriod, notional).map("getUnit", money -> money.getUnit()).map("getCurrency", unitType -> unitType.getCurrency()).get();
			fixedAmountDetails
				.getOrCreateCalculationPeriodNotionalAmount()
				.getOrCreateUnit()
				.setCurrencyValue((fieldWithMetaString == null ? null : fieldWithMetaString.getValue()));
			
			fixedAmountDetails
				.setFixedRate(fixedRate(interestRatePayout, calculationPeriod, notional).get());
			
			fixedAmountDetails
				.setYearFraction(yearFraction(interestRatePayout, calculationPeriod, notional).get());
			
			fixedAmountDetails
				.setCalculatedAmount(MapperMaths.multiply(MapperMaths.multiply(calcAmt(interestRatePayout, calculationPeriod, notional), MapperS.of(fixedAmountDetails).map("getFixedRate", fixedAmountCalculationDetails -> fixedAmountCalculationDetails.getFixedRate())), MapperS.of(fixedAmountDetails).map("getYearFraction", fixedAmountCalculationDetails -> fixedAmountCalculationDetails.getYearFraction())).get());
			
			return Optional.ofNullable(fixedAmountDetails)
				.map(o -> o.prune())
				.orElse(null);
		}
		
		@Override
		protected MapperS fixedRate(InterestRatePayout interestRatePayout, CalculationPeriodBase calculationPeriod, BigDecimal notional) {
			return MapperS.of(getFixedRate.evaluate(interestRatePayout, calculationPeriod));
		}
		
		@Override
		protected MapperS calculationAmount(InterestRatePayout interestRatePayout, CalculationPeriodBase calculationPeriod, BigDecimal notional) {
			return MapperS.of(getNotionalAmount.evaluate(interestRatePayout, calculationPeriod));
		}
		
		@Override
		protected MapperS dcf(InterestRatePayout interestRatePayout, CalculationPeriodBase calculationPeriod, BigDecimal notional) {
			return MapperS.of(interestRatePayout).map("getDayCountFraction", _interestRatePayout -> _interestRatePayout.getDayCountFraction());
		}
		
		@Override
		protected MapperS yearFraction(InterestRatePayout interestRatePayout, CalculationPeriodBase calculationPeriod, BigDecimal notional) {
			final FieldWithMetaDayCountFractionEnum fieldWithMetaDayCountFractionEnum = dcf(interestRatePayout, calculationPeriod, notional).get();
			return MapperS.of(calculateYearFraction.evaluate(interestRatePayout, (fieldWithMetaDayCountFractionEnum == null ? null : fieldWithMetaDayCountFractionEnum.getValue()), calculationPeriod));
		}
		
		@Override
		protected MapperS calcAmt(InterestRatePayout interestRatePayout, CalculationPeriodBase calculationPeriod, BigDecimal notional) {
			if (exists(MapperS.of(notional)).getOrDefault(false)) {
				return MapperS.of(notional);
			}
			return calculationAmount(interestRatePayout, calculationPeriod, notional).map("getValue", money -> money.getValue());
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy