Package org.jquantlib.pricingengines

Source Code of org.jquantlib.pricingengines.BinomialConvertibleEngine

/*
Copyright (C) 2009 Richard Gomes

This source code is release under the BSD License.

This file is part of JQuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://jquantlib.org/

JQuantLib is free software: you can redistribute it and/or modify it
under the terms of the JQuantLib license.  You should have received a
copy of the license along with this program; if not, please email
<jquant-devel@lists.sourceforge.net>. The license is also available online at
<http://www.jquantlib.org/index.php/LICENSE.TXT>.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the license for more details.

JQuantLib is based on QuantLib. http://quantlib.org/
When applicable, the original copyright notice follows this notice.
*/
package org.jquantlib.pricingengines;

import java.lang.reflect.Constructor;

import org.jquantlib.QL;
import org.jquantlib.daycounters.DayCounter;
import org.jquantlib.instruments.ConvertibleBondOption;
import org.jquantlib.instruments.PlainVanillaPayoff;
import org.jquantlib.lang.exceptions.LibraryException;
import org.jquantlib.lang.reflect.TypeTokenTree;
import org.jquantlib.methods.lattices.BinomialTree;
import org.jquantlib.methods.lattices.Lattice;
import org.jquantlib.methods.lattices.TsiveriotisFernandesLattice;
import org.jquantlib.pricingengines.hybrid.DiscretizedConvertible;
import org.jquantlib.processes.GeneralizedBlackScholesProcess;
import org.jquantlib.processes.StochasticProcess1D;
import org.jquantlib.quotes.Handle;
import org.jquantlib.quotes.Quote;
import org.jquantlib.quotes.SimpleQuote;
import org.jquantlib.termstructures.BlackVolTermStructure;
import org.jquantlib.termstructures.Compounding;
import org.jquantlib.termstructures.YieldTermStructure;
import org.jquantlib.termstructures.volatilities.BlackConstantVol;
import org.jquantlib.termstructures.yieldcurves.FlatForward;
import org.jquantlib.time.Calendar;
import org.jquantlib.time.Date;
import org.jquantlib.time.Frequency;
import org.jquantlib.time.TimeGrid;

/**
* Binomial Tsiveriotis-Fernandes engine for convertible bonds
*
* @category hybridengines
*
* @author Richard Gomes
*/
//TODO: work in progress
public class BinomialConvertibleEngine<T extends BinomialTree> extends ConvertibleBondOption.EngineImpl {

    //
    // private fields
    //

    private final int timeSteps_;
    private final GeneralizedBlackScholesProcess process_;
    private final ConvertibleBondOption.ArgumentsImpl a;
    private final ConvertibleBondOption.ResultsImpl   r;

    private final Class<T> clazz;

    //
    // public constructors
    //

    public BinomialConvertibleEngine(final GeneralizedBlackScholesProcess process, final int timeSteps) {
        this.clazz = (Class<T>)new TypeTokenTree(this.getClass()).getElement(0);
        QL.require(timeSteps>0, "timeSteps must be positive"); // TODO: message
        this.timeSteps_ = timeSteps;
        this.a = arguments;
        this.r = results;
        this.process_ = process;
        this.process_.addObserver(this);
    }


    //
    // implements PricingEngine
    //

    @Override
    public void calculate() /* @ReadOnly */ {

        final DayCounter rfdc  = process_.riskFreeRate().currentLink().dayCounter();
        final DayCounter divdc = process_.dividendYield().currentLink().dayCounter();
        final DayCounter voldc = process_.blackVolatility().currentLink().dayCounter();
        final Calendar volcal = process_.blackVolatility().currentLink().calendar();

        /*@Real*/ double s0 = process_.x0();
        QL.require(s0 > 0.0, "negative or null underlying");
        final /*@Volatility*/ double v = process_.blackVolatility().currentLink().blackVol(a.exercise.lastDate(), s0);
        final Date maturityDate = a.exercise.lastDate();
        final /*@Rate*/ double  riskFreeRate = process_
        .riskFreeRate().currentLink()
        .zeroRate(maturityDate, rfdc, Compounding.Continuous, Frequency.NoFrequency)
        .rate();
        final /*@Rate*/ double  q = process_
        .dividendYield().currentLink()
        .zeroRate(maturityDate, divdc, Compounding.Continuous, Frequency.NoFrequency)
        .rate();
        final Date referenceDate = process_.riskFreeRate().currentLink().referenceDate();

        // subtract dividends
        int i;
        for (i=0; i<a.dividends.size(); i++) {
            if (a.dividends.get(i).date().gt(referenceDate)) {
                s0 -= a.dividends.get(i).amount() *
                process_.riskFreeRate().currentLink().discount(a.dividends.get(i).date());
            }
        }
        QL.require(s0 > 0.0, "negative value after subtracting dividends");

        // binomial trees with constant coefficient
        final Handle<Quote> underlying = new Handle<Quote>(new SimpleQuote(s0));
        final Handle<YieldTermStructure> flatRiskFree = new Handle<YieldTermStructure>(
                new FlatForward(referenceDate, riskFreeRate, rfdc));
        final Handle<YieldTermStructure> flatDividends = new Handle <YieldTermStructure>(
                new FlatForward(referenceDate, q, divdc));
        final Handle<BlackVolTermStructure> flatVol = new Handle<BlackVolTermStructure>(
                new BlackConstantVol(referenceDate, volcal, v, voldc));

        QL.require(a.payoff != null, "non-plain payoff given");
        final PlainVanillaPayoff payoff = (PlainVanillaPayoff) a.payoff;
        final /*@Time*/ double maturity = rfdc.yearFraction(a.settlementDate, maturityDate);
        final GeneralizedBlackScholesProcess bs = new GeneralizedBlackScholesProcess(underlying, flatDividends, flatRiskFree, flatVol);

        // final T tree = new T(bs, maturity, timeSteps_, payoff.strike());
        final T tree;
        try {
            final Constructor<T> c = clazz.getConstructor(StochasticProcess1D.class, double.class, int.class, double.class);
            tree = clazz.cast( c.newInstance(bs, maturity, timeSteps_, payoff.strike() ));
        } catch (final Exception e) {
            throw new LibraryException(e); // QA:[RG]::verified
        }

        final /*@Real*/ double creditSpread = a.creditSpread.currentLink().value();
        final Lattice lattice = new TsiveriotisFernandesLattice<T>(tree, riskFreeRate, maturity, timeSteps_, creditSpread, v, q);
        final DiscretizedConvertible convertible = new DiscretizedConvertible((ConvertibleBondOption.Arguments)a, bs, new TimeGrid(maturity, timeSteps_));

        convertible.initialize(lattice, maturity);
        convertible.rollback(0.0);
        r.value = convertible.presentValue();
    }

}
TOP

Related Classes of org.jquantlib.pricingengines.BinomialConvertibleEngine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.