com.opengamma.analytics.financial.interestrate.PresentValueCalculator.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.analytics.financial.interestrate.PresentValueCalculator.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;

import org.apache.commons.lang.Validate;

import com.opengamma.analytics.financial.interestrate.annuity.derivative.Annuity;
import com.opengamma.analytics.financial.interestrate.annuity.derivative.AnnuityCouponFixed;
import com.opengamma.analytics.financial.interestrate.annuity.derivative.AnnuityCouponIbor;
import com.opengamma.analytics.financial.interestrate.bond.definition.BillSecurity;
import com.opengamma.analytics.financial.interestrate.bond.definition.BillTransaction;
import com.opengamma.analytics.financial.interestrate.bond.definition.BondFixedSecurity;
import com.opengamma.analytics.financial.interestrate.bond.definition.BondFixedTransaction;
import com.opengamma.analytics.financial.interestrate.bond.definition.BondIborSecurity;
import com.opengamma.analytics.financial.interestrate.bond.definition.BondIborTransaction;
import com.opengamma.analytics.financial.interestrate.bond.method.BillSecurityDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.bond.method.BillTransactionDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.bond.method.BondSecurityDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.bond.method.BondTransactionDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.cash.derivative.Cash;
import com.opengamma.analytics.financial.interestrate.cash.derivative.DepositZero;
import com.opengamma.analytics.financial.interestrate.cash.method.CashDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.cash.method.DepositZeroDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.fra.ForwardRateAgreement;
import com.opengamma.analytics.financial.interestrate.fra.method.ForwardRateAgreementDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.future.derivative.BondFuture;
import com.opengamma.analytics.financial.interestrate.future.derivative.InterestRateFuture;
import com.opengamma.analytics.financial.interestrate.future.method.BondFutureDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.future.method.InterestRateFutureDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.ForexForward;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponCMS;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponFixed;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIbor;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIborGearing;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIborSpread;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponOIS;
import com.opengamma.analytics.financial.interestrate.payments.derivative.Payment;
import com.opengamma.analytics.financial.interestrate.payments.derivative.PaymentFixed;
import com.opengamma.analytics.financial.interestrate.payments.method.CouponCMSDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.method.CouponIborDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.method.CouponIborGearingDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.method.CouponOISDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.swap.derivative.CrossCurrencySwap;
import com.opengamma.analytics.financial.interestrate.swap.derivative.FixedFloatSwap;
import com.opengamma.analytics.financial.interestrate.swap.derivative.FloatingRateNote;
import com.opengamma.analytics.financial.interestrate.swap.derivative.Swap;
import com.opengamma.analytics.financial.interestrate.swap.derivative.SwapFixedCoupon;
import com.opengamma.analytics.financial.interestrate.swap.derivative.TenorSwap;
import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountCurve;

/**
 * Calculates the present value of an instrument for a given YieldCurveBundle (set of yield curve that the instrument is sensitive to) 
 */
public class PresentValueCalculator extends AbstractInstrumentDerivativeVisitor<YieldCurveBundle, Double> {

    /**
     * The method unique instance.
     */
    private static final PresentValueCalculator INSTANCE = new PresentValueCalculator();

    /**
     * Return the unique instance of the class.
     * @return The instance.
     */
    public static PresentValueCalculator getInstance() {
        return INSTANCE;
    }

    /**
     * Constructor.
     */
    PresentValueCalculator() {
    }

    /**
     * The method used for different instruments.
     */
    private static final CouponOISDiscountingMethod METHOD_OIS = CouponOISDiscountingMethod.getInstance();
    private static final CouponIborDiscountingMethod METHOD_IBOR = CouponIborDiscountingMethod.getInstance();
    private static final CouponIborGearingDiscountingMethod METHOD_IBOR_GEARING = CouponIborGearingDiscountingMethod
            .getInstance();
    private static final ForwardRateAgreementDiscountingMethod METHOD_FRA = ForwardRateAgreementDiscountingMethod
            .getInstance();
    private static final CashDiscountingMethod METHOD_DEPOSIT = CashDiscountingMethod.getInstance();
    private static final DepositZeroDiscountingMethod METHOD_DEPOSIT_ZERO = DepositZeroDiscountingMethod
            .getInstance();
    private static final BillSecurityDiscountingMethod METHOD_BILL_SECURITY = BillSecurityDiscountingMethod
            .getInstance();
    private static final BillTransactionDiscountingMethod METHOD_BILL_TRANSACTION = BillTransactionDiscountingMethod
            .getInstance();
    private static final CouponCMSDiscountingMethod METHOD_CMS_DISCOUNTING = CouponCMSDiscountingMethod
            .getInstance();

    @Override
    public Double visit(final InstrumentDerivative derivative, final YieldCurveBundle curves) {
        Validate.notNull(curves);
        Validate.notNull(derivative);
        return derivative.accept(this, curves);
    }

    @Override
    public Double[] visit(final InstrumentDerivative[] derivative, final YieldCurveBundle curves) {
        Validate.notNull(derivative, "derivative");
        Validate.noNullElements(derivative, "derivative");
        Validate.notNull(curves, "curves");
        final Double[] output = new Double[derivative.length];
        for (int loopderivative = 0; loopderivative < derivative.length; loopderivative++) {
            output[loopderivative] = derivative[loopderivative].accept(this, curves);
        }
        return output;
    }

    @Override
    public Double visitCash(final Cash deposit, final YieldCurveBundle curves) {
        return METHOD_DEPOSIT.presentValue(deposit, curves).getAmount();
    }

    @Override
    public Double visitDepositZero(final DepositZero deposit, final YieldCurveBundle curves) {
        return METHOD_DEPOSIT_ZERO.presentValue(deposit, curves).getAmount();
    }

    @Override
    public Double visitForwardRateAgreement(final ForwardRateAgreement fra, final YieldCurveBundle curves) {
        return METHOD_FRA.presentValue(fra, curves).getAmount();
    }

    /**
     * {@inheritDoc}
     * Future transaction pricing without convexity adjustment.
     */
    @Override
    public Double visitInterestRateFuture(final InterestRateFuture future, final YieldCurveBundle curves) {
        Validate.notNull(curves);
        Validate.notNull(future);
        final InterestRateFutureDiscountingMethod method = InterestRateFutureDiscountingMethod.getInstance();
        return method.presentValue(future, curves).getAmount();
    }

    @Override
    public Double visitSwap(final Swap<?, ?> swap, final YieldCurveBundle curves) {
        Validate.notNull(curves);
        Validate.notNull(swap);
        final double pvFirst = visit(swap.getFirstLeg(), curves);
        final double pvSecond = visit(swap.getSecondLeg(), curves);
        return pvSecond + pvFirst;
    }

    @Override
    public Double visitFixedCouponSwap(final SwapFixedCoupon<?> swap, final YieldCurveBundle curves) {
        return visitSwap(swap, curves);
    }

    @Override
    public Double visitTenorSwap(final TenorSwap<? extends Payment> swap, final YieldCurveBundle curves) {
        Validate.notNull(curves);
        Validate.notNull(swap);
        return visitSwap(swap, curves);
    }

    @Override
    public Double visitBondFixedSecurity(final BondFixedSecurity bond, final YieldCurveBundle curves) {
        Validate.notNull(curves);
        Validate.notNull(bond);
        final BondSecurityDiscountingMethod method = BondSecurityDiscountingMethod.getInstance();
        return method.presentValue(bond, curves);
    }

    @Override
    public Double visitBondFixedTransaction(final BondFixedTransaction bond, final YieldCurveBundle curves) {
        Validate.notNull(curves);
        Validate.notNull(bond);
        final BondTransactionDiscountingMethod method = BondTransactionDiscountingMethod.getInstance();
        return method.presentValue(bond, curves);
    }

    @Override
    public Double visitBondIborSecurity(final BondIborSecurity bond, final YieldCurveBundle curves) {
        Validate.notNull(curves);
        Validate.notNull(bond);
        final BondSecurityDiscountingMethod method = BondSecurityDiscountingMethod.getInstance();
        return method.presentValue(bond, curves);
    }

    @Override
    public Double visitBondIborTransaction(final BondIborTransaction bond, final YieldCurveBundle curves) {
        Validate.notNull(curves);
        Validate.notNull(bond);
        final BondTransactionDiscountingMethod method = BondTransactionDiscountingMethod.getInstance();
        return method.presentValue(bond, curves);
    }

    @Override
    public Double visitBillSecurity(final BillSecurity bill, final YieldCurveBundle curves) {
        Validate.notNull(curves, "Curves");
        Validate.notNull(bill, "Bill");
        return METHOD_BILL_SECURITY.presentValue(bill, curves).getAmount();
    }

    @Override
    public Double visitBillTransaction(final BillTransaction bill, final YieldCurveBundle curves) {
        Validate.notNull(curves, "Curves");
        Validate.notNull(bill, "Bill");
        return METHOD_BILL_TRANSACTION.presentValue(bill, curves).getAmount();
    }

    @Override
    public Double visitBondFuture(final BondFuture bondFuture, final YieldCurveBundle curves) {
        Validate.notNull(curves);
        Validate.notNull(bondFuture);
        final BondFutureDiscountingMethod method = BondFutureDiscountingMethod.getInstance();
        return method.presentValue(bondFuture, curves).getAmount();
    }

    @Override
    public Double visitGenericAnnuity(final Annuity<? extends Payment> annuity, final YieldCurveBundle curves) {
        Validate.notNull(curves);
        Validate.notNull(annuity);
        double pv = 0;
        for (final Payment p : annuity.getPayments()) {
            pv += visit(p, curves);
        }
        return pv;
    }

    @Override
    public Double visitFixedPayment(final PaymentFixed payment, final YieldCurveBundle curves) {
        Validate.notNull(curves);
        Validate.notNull(payment);
        final YieldAndDiscountCurve fundingCurve = curves.getCurve(payment.getFundingCurveName());
        return payment.getAmount() * fundingCurve.getDiscountFactor(payment.getPaymentTime());
    }

    @Override
    public Double visitCouponIborSpread(final CouponIborSpread payment, final YieldCurveBundle curves) {
        Validate.notNull(curves);
        Validate.notNull(payment);
        final YieldAndDiscountCurve fundingCurve = curves.getCurve(payment.getFundingCurveName());
        final YieldAndDiscountCurve liborCurve = curves.getCurve(payment.getForwardCurveName());
        final double forward = (liborCurve.getDiscountFactor(payment.getFixingPeriodStartTime())
                / liborCurve.getDiscountFactor(payment.getFixingPeriodEndTime()) - 1)
                / payment.getFixingYearFraction();
        return payment.getNotional() * (forward + payment.getSpread()) * payment.getPaymentYearFraction()
                * fundingCurve.getDiscountFactor(payment.getPaymentTime());
    }

    @Override
    public Double visitCouponOIS(final CouponOIS payment, final YieldCurveBundle data) {
        return METHOD_OIS.presentValue(payment, data).getAmount();
    }

    @Override
    public Double visitFloatingRateNote(final FloatingRateNote frn, final YieldCurveBundle data) {
        return visitSwap(frn, data);
    }

    @Override
    public Double visitCrossCurrencySwap(final CrossCurrencySwap ccs, final YieldCurveBundle data) {
        final double domesticValue = visit(ccs.getDomesticLeg(), data);
        final double foreignValue = visit(ccs.getForeignLeg(), data);
        final double fx = ccs.getSpotFX();
        return domesticValue - fx * foreignValue;
    }

    @Override
    public Double visitForexForward(final ForexForward fx, final YieldCurveBundle data) {
        final double leg1 = visitFixedPayment(fx.getPaymentCurrency1(), data);
        final double leg2 = visitFixedPayment(fx.getPaymentCurrency2(), data);
        return leg1 + fx.getSpotForexRate() * leg2;
    }

    @Override
    public Double visitForwardLiborAnnuity(final AnnuityCouponIbor annuity, final YieldCurveBundle curves) {
        return visitGenericAnnuity(annuity, curves);
    }

    @Override
    public Double visitCouponFixed(final CouponFixed payment, final YieldCurveBundle curves) {
        Validate.notNull(curves);
        Validate.notNull(payment);
        final YieldAndDiscountCurve fundingCurve = curves.getCurve(payment.getFundingCurveName());
        return payment.getAmount() * fundingCurve.getDiscountFactor(payment.getPaymentTime());
    }

    @Override
    public Double visitFixedCouponAnnuity(final AnnuityCouponFixed annuity, final YieldCurveBundle curves) {
        return visitGenericAnnuity(annuity, curves);
    }

    @Override
    public Double visitFixedFloatSwap(final FixedFloatSwap swap, final YieldCurveBundle curves) {
        return visitFixedCouponSwap(swap, curves);
    }

    @Override
    public Double visitCouponCMS(final CouponCMS cmsCoupon, final YieldCurveBundle curves) {
        return METHOD_CMS_DISCOUNTING.presentValue(cmsCoupon, curves).getAmount();
    }

    @Override
    public Double visitCouponIbor(final CouponIbor coupon, final YieldCurveBundle curves) {
        return METHOD_IBOR.presentValue(coupon, curves).getAmount();
    }

    @Override
    public Double visitCouponIborGearing(final CouponIborGearing coupon, final YieldCurveBundle curves) {
        return METHOD_IBOR_GEARING.presentValue(coupon, curves).getAmount();
    }

}