com.opengamma.analytics.financial.interestrate.annuity.derivative.Annuity.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.analytics.financial.interestrate.annuity.derivative.Annuity.java

Source

/**
 * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.analytics.financial.interestrate.annuity.derivative;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang.ObjectUtils;

import com.opengamma.analytics.financial.interestrate.InstrumentDerivative;
import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitor;
import com.opengamma.analytics.financial.interestrate.payments.derivative.Payment;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;

/**
 * A generic annuity is a set of payments (cash flows) at known future times. All payments have the same currency.
 * There payments can be known in advance, or depend on the future value of some (possibly several) indices, e.g. the Libor.
 * @param <P> The payment type
 */
public class Annuity<P extends Payment> implements InstrumentDerivative {

    /**
     * The list of the annuity payments.
     */
    private final P[] _payments;
    /**
     * Flag indicating if the annuity is payer (true) or receiver (false). Deduced from the first non-zero amount;
     * if all amounts don't have the same sign, the flag may be incorrect.
     */
    private final boolean _isPayer;

    /**
     * @param payments The payments, not null or empty
     */
    public Annuity(final P[] payments) {
        ArgumentChecker.noNulls(payments, "payments");
        ArgumentChecker.isTrue(payments.length > 0, "Have no payments in annuity");
        final Currency currency0 = payments[0].getCurrency();
        double amount = payments[0].getReferenceAmount();
        for (int loopcpn = 1; loopcpn < payments.length; loopcpn++) {
            ArgumentChecker.isTrue(currency0.equals(payments[loopcpn].getCurrency()),
                    "currency not the same for all payments");
            amount = (amount == 0) ? payments[loopcpn].getReferenceAmount() : amount;
        }
        _payments = payments;
        _isPayer = (amount < 0);
    }

    /**
     * @param payments The payments, not null or empty
     * @param pType The type of the payments, not null
     * @param isPayer True if the annuity is to be paid
     */
    public Annuity(final List<? extends P> payments, final Class<P> pType, final boolean isPayer) {
        ArgumentChecker.noNulls(payments, "payments");
        ArgumentChecker.notNull(pType, "type");
        ArgumentChecker.isTrue(payments.size() > 0, "Payments size must be greater than zero");
        _payments = payments.toArray((P[]) Array.newInstance(pType, 0));
        _isPayer = isPayer;
    }

    /**
     * Gets the number of payments in the annuity.
     * @return The number of payments
     */
    public int getNumberOfPayments() {
        return _payments.length;
    }

    /**
     * Gets the nth payment in an annuity. <b>Note that n = 0 will give the first payment</b>.
     * @param n The number of the payment
     * @return The nth payment
     */
    public P getNthPayment(final int n) {
        return _payments[n];
    }

    /**
     * Return the currency of the annuity.
     * @return The currency.
     */
    public Currency getCurrency() {
        return _payments[0].getCurrency();
    }

    /**
     * Check if the payments of an annuity is of the type CouponFixed or CouponIbor. Used to check that payment are of vanilla type.
     * @return  True if IborCoupon or FixedCoupon
     */
    public boolean isIborOrFixed() { //TODO: is this method necessary?
        boolean result = true;
        for (final P payment : _payments) {
            result = result && payment.isIborOrFixed();
        }
        return result;
    }

    /**
     * Gets the payments array.
     * @return the payments
     */
    public P[] getPayments() {
        return _payments;
    }

    /**
     * Gets the payer flag: payer (true) or receiver (false)
     * @return The payer flag.
     */
    public boolean isPayer() {
        return _isPayer;
    }

    /**
     * Return the discounting (or funding) curve name. Deduced from the first payment.
     * @return The name.
     * @deprecated Curve names should not be set in {@link InstrumentDerivative}s
     */
    @Deprecated
    public String getDiscountCurve() {
        return getNthPayment(0).getFundingCurveName();
    }

    /**
     * Create a new annuity with the payments of the original one paying strictly after the given time.
     * @param trimTime The time.
     * @return The trimmed annuity.
     */
    @SuppressWarnings("unchecked")
    public Annuity<P> trimBefore(final double trimTime) {
        final List<P> list = new ArrayList<>();
        list.clear();
        for (final P payment : _payments) {
            if (payment.getPaymentTime() > trimTime) {
                list.add(payment);
            }
        }
        return new Annuity<>(list.toArray((P[]) new Payment[list.size()]));
    }

    /**
     * Create a new annuity with the payments of the original one paying before or on the given time.
     * @param trimTime The time.
     * @return The trimmed annuity.
     */
    @SuppressWarnings("unchecked")
    public Annuity<P> trimAfter(final double trimTime) {
        final List<P> list = new ArrayList<>();
        for (final P payment : _payments) {
            if (payment.getPaymentTime() <= trimTime) {
                list.add(payment);
            }
        }
        return new Annuity<>(list.toArray((P[]) new Payment[list.size()]));
    }

    @Override
    public String toString() {
        final StringBuffer result = new StringBuffer("Annuity:");
        for (final P payment : _payments) {
            result.append(payment.toString());
            result.append("\n");
        }
        return result.toString();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + Arrays.hashCode(_payments);
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Annuity<?> other = (Annuity<?>) obj;
        if (_payments.length != other._payments.length) {
            return false;
        }
        for (int i = 0; i < _payments.length; i++) {
            if (!ObjectUtils.equals(_payments[i], other._payments[i])) {
                return false;
            }
        }
        return true;
    }

    @Override
    public <S, T> T accept(final InstrumentDerivativeVisitor<S, T> visitor, final S data) {
        ArgumentChecker.notNull(visitor, "visitor");
        return visitor.visitGenericAnnuity(this, data);
    }

    @Override
    public <T> T accept(final InstrumentDerivativeVisitor<?, T> visitor) {
        ArgumentChecker.notNull(visitor, "visitor");
        return visitor.visitGenericAnnuity(this);
    }

}