Package org.jquantlib.termstructures.volatilities

Source Code of org.jquantlib.termstructures.volatilities.BlackVarianceSurface

/*
Copyright (C) 2008 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.
*/

/*
Copyright (C) 2002, 2003, 2004 Ferdinando Ametrano
Copyright (C) 2003, 2004 StatPro Italia srl

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

QuantLib is free software: you can redistribute it and/or modify it
under the terms of the QuantLib license.  You should have received a
copy of the license along with this program; if not, please email
<quantlib-dev@lists.sf.net>. The license is also available online at
<http://quantlib.org/license.shtml>.

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.
*/

package org.jquantlib.termstructures.volatilities;

import org.jquantlib.QL;
import org.jquantlib.daycounters.DayCounter;
import org.jquantlib.math.interpolations.Interpolation2D;
import org.jquantlib.math.interpolations.Interpolation.Interpolator;
import org.jquantlib.math.interpolations.factories.Bilinear;
import org.jquantlib.math.matrixutilities.Array;
import org.jquantlib.math.matrixutilities.Matrix;
import org.jquantlib.termstructures.BlackVarianceTermStructure;
import org.jquantlib.termstructures.TermStructure;
import org.jquantlib.time.Date;
import org.jquantlib.util.TypedVisitor;
import org.jquantlib.util.Visitor;

/**
* This class calculates time/strike dependent Black volatilities using as input
* a matrix of Black volatilities observed in the market.
*
* The calculation is performed interpolating on the variance surface. Bilinear
* interpolation is used as default; this can be changed by the
* setInterpolation() method.
*
* @author Richard Gomes
*/
// TODO: check time extrapolation
public class BlackVarianceSurface extends BlackVarianceTermStructure {

    public enum Extrapolation {
        ConstantExtrapolation, InterpolatorDefaultExtrapolation
    };


    //
    // private fields
    //

    private final DayCounter dayCounter;
    private final Date maxDate;
    private final /* @Time */ Array times;
    private /* @Real */ Array strikes;
    private final /* @Variance */ Matrix variances;
    private Interpolation2D varianceSurface;
    private final Extrapolation lowerExtrapolation;
    private final Extrapolation upperExtrapolation;
    private final Interpolation2D.Interpolator2D factory;


    //
    // public constructors
    //

    public BlackVarianceSurface(final Date referenceDate, final Date[] dates,
            final/* @Real */ Array strikes, final/* @Volatility */ Matrix blackVolMatrix, final DayCounter dayCounter) {

        this(referenceDate, dates, strikes, blackVolMatrix, dayCounter,
                Extrapolation.InterpolatorDefaultExtrapolation,
                Extrapolation.InterpolatorDefaultExtrapolation);
    }

    public BlackVarianceSurface(
            final Date referenceDate,
            final Date[] dates,
            final/* @Real */ Array strikes,
            final/* @Volatility */ Matrix blackVolMatrix,
            final DayCounter dayCounter,
            final Extrapolation lowerExtrapolation,
            final Extrapolation upperExtrapolation) {

        super(referenceDate);
        QL.require(dates.length == blackVolMatrix.columns() , "mismatch between date vector and vol matrix colums"); // QA:[RG]::verified // TODO: message
        QL.require(strikes.size() == blackVolMatrix.rows() , "mismatch between money-strike vector and vol matrix rows"); // QA:[RG]::verified // TODO: message
        QL.require(dates[0].gt(referenceDate) , "cannot have dates[0] <= referenceDate"); // QA:[RG]::verified // TODO: message

        this.dayCounter = dayCounter;
        this.maxDate = dates[dates.length-1]; // TODO: code review: index seems to be wrong
        // TODO: code review :: use of clone()
        this.strikes = strikes.clone();
        this.lowerExtrapolation = lowerExtrapolation;
        this.upperExtrapolation = upperExtrapolation;


        this.times = new Array(dates.length+1); // TODO: verify if length is correct
        this.variances = new Matrix(strikes.size(), dates.length+1); // TODO: verify if length is correct
        this.strikes = new Array(strikes.size()+1); // TODO: verify if length is correct

        for(int i = 1; i < strikes.size()+1; i++) {
            this.strikes.set(i, strikes.get(i-1));
        }

        for (int j = 1; j <= blackVolMatrix.columns(); j++) {
            times.set(j, timeFromReference(dates[j-1]));
            QL.require(times.get(j) > times.get(j-1) , "dates must be sorted unique!"); // QA:[RG]::verified // TODO: message
            for (int i = 0; i < blackVolMatrix.rows(); i++) {
                final double elem = blackVolMatrix.get(i, j-1);
                final double ijvar = times.get(j) * elem * elem;
                variances.set(i, j, ijvar);
                QL.require(ijvar >= variances.get(i, j-1) , "variance must be non-decreasing"); // QA:[RG]::verified // TODO: message
            }
        }
        // default: bilinear interpolation
        factory = new Bilinear();
    }


    //
    // public methods
    //

    public void setInterpolation(final Interpolator i) {
        varianceSurface = factory.interpolate(times, strikes, variances);
        varianceSurface.enableExtrapolation();
        varianceSurface.update();
        notifyObservers();
    }


    //
    // Overrides TermStructure
    //

    @Override
    public final DayCounter dayCounter() {
        return dayCounter;
    }

    @Override
    public final Date maxDate() {
        return maxDate;
    }


    //
    // Overrides BlackVolTermStructure
    //

    @Override
    public final /* @Real */ double minStrike() {
        return strikes.first();
    }

    @Override
    public final /* @Real */ double maxStrike() {
        return strikes.last();
    }

    @Override
    protected final/* @Variance */double blackVarianceImpl(/* @Time */final double t, /* @Real */double strike) /* @ReadOnly */{

        if (t == 0.0) {
            return 0.0;
        }

        // enforce constant extrapolation when required
        if (strike < strikes.first() && lowerExtrapolation == Extrapolation.ConstantExtrapolation) {
            strike = strikes.first();
        }
        if (strike > strikes.last()  && upperExtrapolation == Extrapolation.ConstantExtrapolation) {
            strike = strikes.last();
        }

        if (t <= times.last()) {
            return varianceSurface.op(t, strike);
        } else {
            // TODO: code review :: please verify against QL/C++ code
            // t>times_.back() || extrapolate
            /* @Time */final double lastTime = times.last();
            return varianceSurface.op(lastTime, strike) * t / lastTime;
        }
    }


    //
    // implements TypedVisitable
    //

    @Override
    public void accept(final TypedVisitor<TermStructure> v) {
        final Visitor<TermStructure> v1 = (v!=null) ? v.getVisitor(this.getClass()) : null;
        if (v1 != null) {
            v1.visit(this);
        } else {
            super.accept(v);
        }
    }

}
TOP

Related Classes of org.jquantlib.termstructures.volatilities.BlackVarianceSurface

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.