/* * Copyright (c) 2012, 2013, Credit Suisse (Anatole Tresch), Werner Keil. Licensed under the Apache * License, Version 2.0 (the "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package org.javamoney.calc.common; import org.javamoney.calc.CalculationContext; import javax.money.MonetaryAmount; import javax.money.MonetaryOperator; import java.math.BigDecimal; import java.math.MathContext; import java.util.Objects; /** * <img src="http://www.financeformulas.net/Formula%20Images/Annuity%20Due%20-%20FV%201.gif" /> * <p> * The future value of annuity due formula is used to calculate the ending value of a series of * payments or cash flows where the first payment is received immediately. The first cash flow * received immediately is what distinguishes an annuity due from an ordinary annuity. An annuity * due is sometimes referred to as an immediate annuity. * <p> * The future value of annuity due formula calculates the value at a future date. The use of the * future value of annuity due formula in real situations is different than that of the present * value for an annuity due. For example, suppose that an individual or company wants to buy an * annuity from someone and the first payment is received today. To calculate the price to pay for * this particular situation would require use of the present value of annuity due formula. However, * if an individual is wanting to calculate what their balance would be after saving for 5 years in * an interest bearing account and they choose to put the first cash flow into the account today, * the future value of annuity due would be used. * * @author Anatole Tresch * @see http://www.financeformulas.net/Future-Value-of-Annuity-Due.html */ public final class FutureValueOfAnnuityDue implements MonetaryOperator { /** * the target rate, not null. */ private Rate rate; /** * the periods, >= 0. */ private int periods; /** * Private constructor. * * @param rate the target rate, not null. * @param periods the periods, >= 0. */ private FutureValueOfAnnuityDue(Rate rate, int periods) { this.rate = Objects.requireNonNull(rate); if (periods < 0) { throw new IllegalArgumentException("Periods < 0"); } this.periods = periods; } public int getPeriods() { return periods; } public Rate getRate() { return rate; } /** * Access a MonetaryOperator for calculation. * * @param rate The rate, not null. * @param periods the target periods, >= 0. * @return the operator, never null. */ public static FutureValueOfAnnuityDue of(Rate rate, int periods) { return new FutureValueOfAnnuityDue(rate, periods); } /** * Performs the calculation. * * @param amount the first payment * @param rate The rate, not null. * @param periods the target periods, >= 0. * @return the resulting amount, never null. */ public static MonetaryAmount calculate(MonetaryAmount amount, Rate rate, int periods) { // Am * (((1 + r).pow(n))-1/rate) BigDecimal base = CalculationContext.one().add(rate.get()); BigDecimal counter = base.pow(periods, CalculationContext.mathContext()).subtract(BigDecimal.ONE); return amount.multiply( counter.divide(rate.get(), CalculationContext.mathContext()).multiply(base)); } @Override public MonetaryAmount apply(MonetaryAmount amount) { return calculate(amount, rate, periods); } @Override public String toString() { return "FutureValueOfAnnuityDue{" + "rate=" + rate + ", periods=" + periods + '}'; } }