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

cdm.observable.asset.calculatedrate.functions.ApplyCompoundingFormula Maven / Gradle / Ivy

There is a newer version: 6.0.0-dev.89
Show newest version
package cdm.observable.asset.calculatedrate.functions;

import cdm.base.math.ArithmeticOperationEnum;
import cdm.base.math.functions.VectorGrowthOperation;
import cdm.base.math.functions.VectorOperation;
import cdm.base.math.functions.VectorScalarOperation;
import cdm.observable.asset.calculatedrate.CalculatedRateDetails;
import cdm.observable.asset.calculatedrate.CalculatedRateDetails.CalculatedRateDetailsBuilder;
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.Mapper;
import com.rosetta.model.lib.mapper.MapperC;
import com.rosetta.model.lib.mapper.MapperS;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import javax.inject.Inject;


@ImplementedBy(ApplyCompoundingFormula.ApplyCompoundingFormulaDefault.class)
public abstract class ApplyCompoundingFormula implements RosettaFunction {
	
	@Inject protected ModelObjectValidator objectValidator;
	
	// RosettaFunction dependencies
	//
	@Inject protected VectorGrowthOperation vectorGrowthOperation;
	@Inject protected VectorOperation vectorOperation;
	@Inject protected VectorScalarOperation vectorScalarOperation;

	/**
	* @param observations A vector of observation value.
	* @param weights A vector of weights (should be same size as observations, 1 weight per observation.
	* @param yearFrac Year fraction of a single day (i.e. 1/basis.
	* @return results Details of the compounding calculation.
	*/
	public CalculatedRateDetails evaluate(List observations, List weights, BigDecimal yearFrac) {
		CalculatedRateDetails.CalculatedRateDetailsBuilder resultsBuilder = doEvaluate(observations, weights, yearFrac);
		
		final CalculatedRateDetails results;
		if (resultsBuilder == null) {
			results = null;
		} else {
			results = resultsBuilder.build();
			objectValidator.validate(CalculatedRateDetails.class, results);
		}
		
		return results;
	}

	protected abstract CalculatedRateDetails.CalculatedRateDetailsBuilder doEvaluate(List observations, List weights, BigDecimal yearFrac);

	protected abstract Mapper weightedObservations(List observations, List weights, BigDecimal yearFrac);

	protected abstract Mapper scaledAndWeightedObservations(List observations, List weights, BigDecimal yearFrac);

	protected abstract Mapper growthFactors(List observations, List weights, BigDecimal yearFrac);

	protected abstract Mapper growthCurve(List observations, List weights, BigDecimal yearFrac);

	protected abstract Mapper finalValue(List observations, List weights, BigDecimal yearFrac);

	protected abstract Mapper totalWeight(List observations, List weights, BigDecimal yearFrac);

	protected abstract Mapper overallYearFrac(List observations, List weights, BigDecimal yearFrac);

	protected abstract Mapper calculatedRate(List observations, List weights, BigDecimal yearFrac);

	public static class ApplyCompoundingFormulaDefault extends ApplyCompoundingFormula {
		@Override
		protected CalculatedRateDetails.CalculatedRateDetailsBuilder doEvaluate(List observations, List weights, BigDecimal yearFrac) {
			CalculatedRateDetails.CalculatedRateDetailsBuilder results = CalculatedRateDetails.builder();
			return assignOutput(results, observations, weights, yearFrac);
		}
		
		protected CalculatedRateDetails.CalculatedRateDetailsBuilder assignOutput(CalculatedRateDetails.CalculatedRateDetailsBuilder results, List observations, List weights, BigDecimal yearFrac) {
			results
				.setAggregateValue(MapperS.of(finalValue(observations, weights, yearFrac).get()).get());
			
			results
				.setAggregateWeight(MapperS.of(totalWeight(observations, weights, yearFrac).get()).get());
			
			results
				.setCalculatedRate(MapperS.of(calculatedRate(observations, weights, yearFrac).get()).get());
			
			results
				.addCompoundedGrowth(MapperC.of(growthCurve(observations, weights, yearFrac).getMulti()).getMulti());
			
			results
				.addGrowthFactor(MapperC.of(growthFactors(observations, weights, yearFrac).getMulti()).getMulti());
			
			results
				.addWeightedRates(MapperC.of(weightedObservations(observations, weights, yearFrac).getMulti()).getMulti());
			
			return Optional.ofNullable(results)
				.map(o -> o.prune())
				.orElse(null);
		}
		
		@Override
		protected Mapper weightedObservations(List observations, List weights, BigDecimal yearFrac) {
			return MapperC.of(vectorOperation.evaluate(MapperS.of(ArithmeticOperationEnum.MULTIPLY).get(), MapperC.of(observations).getMulti(), MapperC.of(weights).getMulti()));
		}
		
		@Override
		protected Mapper scaledAndWeightedObservations(List observations, List weights, BigDecimal yearFrac) {
			return MapperC.of(vectorScalarOperation.evaluate(MapperS.of(ArithmeticOperationEnum.MULTIPLY).get(), MapperC.of(weightedObservations(observations, weights, yearFrac).getMulti()).getMulti(), MapperS.of(yearFrac).get()));
		}
		
		@Override
		protected Mapper growthFactors(List observations, List weights, BigDecimal yearFrac) {
			return MapperC.of(vectorScalarOperation.evaluate(MapperS.of(ArithmeticOperationEnum.ADD).get(), MapperC.of(scaledAndWeightedObservations(observations, weights, yearFrac).getMulti()).getMulti(), MapperS.of(new BigDecimal("1.0")).get()));
		}
		
		@Override
		protected Mapper growthCurve(List observations, List weights, BigDecimal yearFrac) {
			return MapperC.of(vectorGrowthOperation.evaluate(MapperS.of(new BigDecimal("1.0")).get(), MapperC.of(growthFactors(observations, weights, yearFrac).getMulti()).getMulti()));
		}
		
		@Override
		protected Mapper finalValue(List observations, List weights, BigDecimal yearFrac) {
			return MapperC.of(growthCurve(observations, weights, yearFrac).getMulti())
				.last();
		}
		
		@Override
		protected Mapper totalWeight(List observations, List weights, BigDecimal yearFrac) {
			return MapperC.of(weights)
				.sumBigDecimal();
		}
		
		@Override
		protected Mapper overallYearFrac(List observations, List weights, BigDecimal yearFrac) {
			return MapperMaths.multiply(MapperS.of(totalWeight(observations, weights, yearFrac).get()), MapperS.of(yearFrac));
		}
		
		@Override
		protected Mapper calculatedRate(List observations, List weights, BigDecimal yearFrac) {
			return MapperMaths.divide(MapperMaths.subtract(MapperS.of(finalValue(observations, weights, yearFrac).get()), MapperS.of(Integer.valueOf(1))), MapperS.of(overallYearFrac(observations, weights, yearFrac).get()));
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy