com.opengamma.strata.pricer.bond.DiscountingBondFutureProductPricer.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.strata.pricer.bond.DiscountingBondFutureProductPricer.java

Source

/**
 * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.strata.pricer.bond;

import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Doubles;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.market.sensitivity.PointSensitivities;
import com.opengamma.strata.market.sensitivity.PointSensitivityBuilder;
import com.opengamma.strata.pricer.CompoundedRateType;
import com.opengamma.strata.product.bond.FixedCouponBond;
import com.opengamma.strata.product.bond.ResolvedBondFuture;
import com.opengamma.strata.product.bond.ResolvedFixedCouponBond;

/**
 * Pricer for for bond future products.
 * <p>
 * This function provides the ability to price a {@link ResolvedBondFuture}.
 * 
 * <h4>Price</h4>
 * Strata uses <i>decimal prices</i> for bond futures in the trade model, pricers and market data.
 * This is coherent with the pricing of {@link FixedCouponBond}. The bond futures delivery is a bond
 * for an amount computed from the bond future price, a conversion factor and the accrued interest.
 */
public final class DiscountingBondFutureProductPricer {

    /**
     * Default implementation.
     */
    public static final DiscountingBondFutureProductPricer DEFAULT = new DiscountingBondFutureProductPricer(
            DiscountingFixedCouponBondProductPricer.DEFAULT);

    /**
     * Underlying pricer.
     */
    private final DiscountingFixedCouponBondProductPricer bondPricer;

    /**
     * Creates an instance.
     * 
     * @param bondPricer  the pricer for {@link ResolvedFixedCouponBond}.
     */
    public DiscountingBondFutureProductPricer(DiscountingFixedCouponBondProductPricer bondPricer) {
        this.bondPricer = ArgChecker.notNull(bondPricer, "bondPricer");
    }

    //-------------------------------------------------------------------------
    /**
     * Calculates the number related to bond futures product on which the daily margin is computed.
     * <p>
     * For two consecutive settlement prices C1 and C2, the daily margin is computed as 
     *    {@code (marginIndex(future, C2) - marginIndex(future, C1))}.
     * 
     * @param future  the future
     * @param price  the price of the product, in decimal form
     * @return the index
     */
    double marginIndex(ResolvedBondFuture future, double price) {
        return price * future.getNotional();
    }

    /**
     * Calculates the margin index sensitivity of the bond future product.
     * <p>
     * The margin index sensitivity is the sensitivity of the margin index to the underlying curves.
     * For two consecutive settlement prices C1 and C2, the daily margin is computed as 
     *    {@code (marginIndex(future, C2) - marginIndex(future, C1))}.
     * 
     * @param future  the future
     * @param priceSensitivity  the price sensitivity of the product
     * @return the index sensitivity
     */
    PointSensitivities marginIndexSensitivity(ResolvedBondFuture future, PointSensitivities priceSensitivity) {
        return priceSensitivity.multipliedBy(future.getNotional());
    }

    //-------------------------------------------------------------------------
    /**
     * Calculates the price of the bond future product.
     * <p>
     * The price of the product is the price on the valuation date.
     * <p>
     * Strata uses <i>decimal prices</i> for bond futures. This is coherent with the pricing of {@link FixedCouponBond}.
     * For example, a price of 99.32% is represented in Strata by 0.9932.
     * 
     * @param future  the future
     * @param discountingProvider  the discounting provider
     * @return the price of the product, in decimal form
     */
    public double price(ResolvedBondFuture future, LegalEntityDiscountingProvider discountingProvider) {
        ImmutableList<ResolvedFixedCouponBond> basket = future.getDeliveryBasket();
        int size = basket.size();
        double[] priceBonds = new double[size];
        for (int i = 0; i < size; ++i) {
            ResolvedFixedCouponBond bond = basket.get(i);
            double dirtyPrice = bondPricer.dirtyPriceFromCurves(bond, discountingProvider,
                    future.getLastDeliveryDate());
            priceBonds[i] = bondPricer.cleanPriceFromDirtyPrice(bond, future.getLastDeliveryDate(), dirtyPrice)
                    / future.getConversionFactors().get(i);
        }
        return Doubles.min(priceBonds);
    }

    /**
     * Calculates the price of the bond future product with z-spread.
     * <p>
     * The price of the product is the price on the valuation date.
     * <p>
     * The z-spread is a parallel shift applied to continuously compounded rates or periodic compounded rates 
     * of the issuer discounting curve.
     * <p>
     * Strata uses <i>decimal prices</i> for bond futures. This is coherent with the pricing of {@link FixedCouponBond}.
     * For example, a price of 99.32% is represented in Strata by 0.9932.
     * 
     * @param future  the future
     * @param discountingProvider  the discounting provider
     * @param zSpread  the z-spread
     * @param compoundedRateType  the compounded rate type
     * @param periodPerYear  the number of periods per year
     * @return the price of the product, in decimal form
     */
    public double priceWithZSpread(ResolvedBondFuture future, LegalEntityDiscountingProvider discountingProvider,
            double zSpread, CompoundedRateType compoundedRateType, int periodPerYear) {

        ImmutableList<ResolvedFixedCouponBond> basket = future.getDeliveryBasket();
        int size = basket.size();
        double[] priceBonds = new double[size];
        for (int i = 0; i < size; ++i) {
            ResolvedFixedCouponBond bond = basket.get(i);
            double dirtyPrice = bondPricer.dirtyPriceFromCurvesWithZSpread(bond, discountingProvider, zSpread,
                    compoundedRateType, periodPerYear, future.getLastDeliveryDate());
            priceBonds[i] = bondPricer.cleanPriceFromDirtyPrice(bond, future.getLastDeliveryDate(), dirtyPrice)
                    / future.getConversionFactors().get(i);
        }
        return Doubles.min(priceBonds);
    }

    //-------------------------------------------------------------------------
    /**
     * Calculates the price sensitivity of the bond future product.
     * <p>
     * The price sensitivity of the product is the sensitivity of the price to the underlying curves.
     * <p>
     * Note that the price sensitivity should be no currency.
     * 
     * @param future  the future
     * @param discountingProvider  the discounting provider
     * @return the price curve sensitivity of the product
     */
    public PointSensitivities priceSensitivity(ResolvedBondFuture future,
            LegalEntityDiscountingProvider discountingProvider) {
        ImmutableList<ResolvedFixedCouponBond> basket = future.getDeliveryBasket();
        int size = basket.size();
        double[] priceBonds = new double[size];
        int indexCTD = 0;
        double priceMin = 2d;
        for (int i = 0; i < size; i++) {
            ResolvedFixedCouponBond bond = basket.get(i);
            double dirtyPrice = bondPricer.dirtyPriceFromCurves(bond, discountingProvider,
                    future.getLastDeliveryDate());
            priceBonds[i] = bondPricer.cleanPriceFromDirtyPrice(bond, future.getLastDeliveryDate(), dirtyPrice)
                    / future.getConversionFactors().get(i);
            if (priceBonds[i] < priceMin) {
                priceMin = priceBonds[i];
                indexCTD = i;
            }
        }
        ResolvedFixedCouponBond bond = basket.get(indexCTD);
        PointSensitivityBuilder pointSensi = bondPricer.dirtyPriceSensitivity(bond, discountingProvider,
                future.getLastDeliveryDate());
        return pointSensi.multipliedBy(1d / future.getConversionFactors().get(indexCTD)).build();
    }

    /**
     * Calculates the price sensitivity of the bond future product with z-spread.
     * <p>
     * The price sensitivity of the product is the sensitivity of the price to the underlying curves.
     * <p>
     * The z-spread is a parallel shift applied to continuously compounded rates or periodic compounded rates 
     * of the issuer discounting curve.
     * <p>
     * Note that the price sensitivity should be no currency.
     * 
     * @param future  the future
     * @param discountingProvider  the discounting provider
     * @param zSpread  the z-spread
     * @param compoundedRateType  the compounded rate type
     * @param periodPerYear  the number of periods per year
     * @return the price curve sensitivity of the product
     */
    public PointSensitivities priceSensitivityWithZSpread(ResolvedBondFuture future,
            LegalEntityDiscountingProvider discountingProvider, double zSpread,
            CompoundedRateType compoundedRateType, int periodPerYear) {

        ImmutableList<ResolvedFixedCouponBond> basket = future.getDeliveryBasket();
        int size = basket.size();
        double[] priceBonds = new double[size];
        int indexCTD = 0;
        double priceMin = 2d;
        for (int i = 0; i < size; i++) {
            ResolvedFixedCouponBond bond = basket.get(i);
            double dirtyPrice = bondPricer.dirtyPriceFromCurvesWithZSpread(bond, discountingProvider, zSpread,
                    compoundedRateType, periodPerYear, future.getLastDeliveryDate());
            priceBonds[i] = bondPricer.cleanPriceFromDirtyPrice(bond, future.getLastDeliveryDate(), dirtyPrice)
                    / future.getConversionFactors().get(i);
            if (priceBonds[i] < priceMin) {
                priceMin = priceBonds[i];
                indexCTD = i;
            }
        }
        ResolvedFixedCouponBond bond = basket.get(indexCTD);
        PointSensitivityBuilder pointSensi = bondPricer.dirtyPriceSensitivityWithZspread(bond, discountingProvider,
                zSpread, compoundedRateType, periodPerYear, future.getLastDeliveryDate());
        return pointSensi.multipliedBy(1d / future.getConversionFactors().get(indexCTD)).build();
    }

}