Package org.jquantlib.termstructures

Source Code of org.jquantlib.termstructures.AbstractTermStructure

/*
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) 2004, 2005, 2006 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;

import java.util.List;

import org.jquantlib.QL;
import org.jquantlib.Settings;
import org.jquantlib.daycounters.Actual365Fixed;
import org.jquantlib.daycounters.DayCounter;
import org.jquantlib.math.Closeness;
import org.jquantlib.math.interpolations.DefaultExtrapolator;
import org.jquantlib.math.interpolations.Extrapolator;
import org.jquantlib.time.Calendar;
import org.jquantlib.time.Date;
import org.jquantlib.time.TimeUnit;
import org.jquantlib.util.DefaultObservable;
import org.jquantlib.util.Observable;
import org.jquantlib.util.Observer;



/**
* Basic term-structure functionality.
*
* <p><b>More Details about constructors:</b>
* <p>There are three ways in which a term structure can keep
* track of its reference date:
* <li>such date is fixed;</li>
* <li>such date is determined by advancing the current date of a given number of business days;</li>
* <li>such date is based on the reference date of some other structure.</li>
*
* <p>Case 1: The constructor taking a date is to be used.
* The default implementation of {@link TermStructure#referenceDate()} will
* then return such date.
*
* <p>Case 2: The constructor taking a number of days and a calendar is to be used
* so that {@link TermStructure#referenceDate()} will return a date calculated based on the
* current evaluation date and the term structure and observers will be notified when the
* evaluation date changes.
*
* <p>Case 3: The {@link TermStructure#referenceDate()} method must
* be overridden in derived classes so that it fetches and
* return the appropriate date.
*
* @author Richard Gomes
*/
public abstract class AbstractTermStructure implements TermStructure {

    static private final String THIS_METHOD_MUST_BE_OVERRIDDEN = "This method must be overridden";


    //
    // private fields
    //

    /**
     * <p>Case 1: The constructor taking a date is to be used.
     * The default implementation of {@link TermStructure#referenceDate()} will
     * then return such date.
     *
     * <p>Case 2: The constructor taking a number of days and a calendar is to be used
     * so that {@link TermStructure#referenceDate()} will return a date calculated based on the
     * current evaluation date and the term structure and observers will be notified when the
     * evaluation date changes.
     *
     * <p>Case 3: The {@link TermStructure#referenceDate()} method must
     * be overridden in derived classes so that it fetches and
     * return the appropriate date.
     */
    private Date referenceDate;

    /**
     * Beware that this variable must always be accessed via {@link #dayCounter()} method.
     * Extended classes have the option to redefine semantics of a day counter by keeping their own private
     * dayCounter variable and providing their own version of {@link #dayCounter()} method. When extended
     * classes fail to provide their version of {@link #dayCounter()} method, <i><b>this</b>.getDayCounter</i>
     * must throw an {@link IllegalStateException} because the private variable dayCounter was never initialised.
     *
     * @see #getDayCounter
     */
    private final DayCounter dayCounter;

    /**
     * This variable must be <i>false</i> when Case 2; <i>true</i> otherwise
     */
    private boolean updated;


    //
    // private final fields
    //

    private final int settlementDays;

    /**
     * This variable must be <i>true</i> when Case 2; <i>false</i> otherwise
     */
    private final boolean moving;


    //
    // protected fields
    //

    /**
     * Beware that this variable must always be accessed via {@link #calendar()} method.
     * Extended classes have the option to redefine semantics of a calendar by keeping their own private
     * calendar variable and providing their own version of {@link #calendar()} method. When extended
     * classes fail to provide their version of {@link #calendar()} method, <i><b>this</b>.getCalendar</i>
     * must throw an {@link IllegalStateException} because the private variable calendar was never initialised.
     *
     * @see #calendar
     */
    protected Calendar calendar;


    //
    // public constructors
    //

    /**
     * <p>This constructor requires an override of method {@link TermStructure#referenceDate()} in
     * derived classes so that it fetches and return the appropriate reference date.
     * This is the <i>Case 3</i> described on the top of this class.
     *
     * @see TermStructure documentation for more details about constructors.
     */
    public AbstractTermStructure() {
        this(new Actual365Fixed());
    }

    /**
     * <p>This constructor requires an override of method {@link TermStructure#referenceDate()} in
     * derived classes so that it fetches and return the appropriate reference date.
     * This is the <i>Case 3</i> described on the top of this class.
     *
     * @see TermStructure documentation for more details about constructors.
     */
    //TODO : What's the calendar in this case?
    public AbstractTermStructure(final DayCounter dc) {
        QL.require(dc!=null , "day counter must be informed"); // QA:[RG]::verified // TODO: message
        this.calendar = null;
        this.settlementDays = 0;
        this.dayCounter = dc;

        // When Case 1 or Case 3
        this.moving = false;
        this.updated = true;

        // initialize reference date without any observers
        this.referenceDate = null;
    }

    /**
     * Initialize with a fixed reference date
     *
     * <p>This constructor takes a date to be used.
     * The default implementation of {@link TermStructure#referenceDate()} will
     * then return such date.
     * This is the <i>Case 1</i> described on the top of this class.
     *
     * @see TermStructure documentation for more details about constructors.
     */
    public AbstractTermStructure(final Date referenceDate, final Calendar calendar) {
        this(referenceDate, calendar, new Actual365Fixed());
    }

    /**
     * Initialize with a fixed reference date
     *
     * <p>This constructor takes a date to be used.
     * The default implementation of {@link TermStructure#referenceDate()} will
     * then return such date.
     * This is the <i>Case 1</i> described on the top of this class.
     *
     * @see TermStructure documentation for more details about constructors.
     */
    public AbstractTermStructure(final Date referenceDate, final Calendar calendar, final DayCounter dc) {
        QL.require(referenceDate!=null , "reference date must be informed"); // QA:[RG]::verified // TODO: message
        QL.require(calendar!=null , "calendar must be informed"); // QA:[RG]::verified // TODO: message
        QL.require(dc!=null , "day counter must be informed"); // QA:[RG]::verified // TODO: message

        this.settlementDays = 0;
        this.calendar = calendar;
        this.dayCounter = dc;

        // When Case 1 or Case 3
        this.moving = false;
        this.updated = true;

        // initialize reference date with this class as observer
        this.referenceDate = referenceDate;
    }

    /**
     * Calculate the reference date based on the global evaluation date
     *
     * <p>This constructor takes a number of days and a calendar to be used
     * so that {@link TermStructure#referenceDate()} will return a date calculated based on the
     * current evaluation date and the term structure. This class will be notified when the
     * evaluation date changes.
     * This is the <i>Case 2</i> described on the top of this class.
     *
     * @see TermStructure documentation for more details about constructors.
     */
    public AbstractTermStructure(final int settlementDays, final Calendar calendar) {
        this(settlementDays, calendar, new Actual365Fixed());
    }


    /**
     * Calculate the reference date based on the global evaluation date
     *
     * <p>This constructor takes a number of days and a calendar to be used
     * so that {@link TermStructure#referenceDate()} will return a date calculated based on the
     * current evaluation date and the term structure. This class will be notified when the
     * evaluation date changes.
     * This is the <i>Case 2</i> described on the top of this class.
     *
     * @see TermStructure documentation for more details about constructors.
     */
    public AbstractTermStructure(final int settlementDays, final Calendar calendar, final DayCounter dc) {
        this.settlementDays = settlementDays;
        this.calendar = calendar;
        this.dayCounter = dc;

        // When Case 2
        this.moving = true;
        this.updated = false;

        // observes date changes
        final Date today = new Settings().evaluationDate();
        today.addObserver(this);

        this.referenceDate = calendar.advance(today, settlementDays, TimeUnit.Days);
    }


    //
    // protected methods
    //

    /**
     * This method performs date-range check
     */
    protected void checkRange(final Date d, final boolean extrapolate) /* @ReadOnly */ {
        QL.require(d.ge(referenceDate()) , "date before reference date"); // QA:[RG]::verified // TODO: message
        QL.require(extrapolate || allowsExtrapolation() || d.le(maxDate()) , "date is past max curve"); // QA:[RG]::verified // TODO: message
    }

    /**
     * This method performs date-range check
     */
    protected void checkRange(/*@Time*/ final double t, final boolean extrapolate) /* @ReadOnly */ {
        QL.require(t >= 0.0 , "negative time given"); // QA:[RG]::verified // TODO: message
        QL.require(extrapolate||allowsExtrapolation()||t<=maxTime()||Closeness.isCloseEnough(t, maxTime()) , "time is past max curve"); // QA:[RG]::verified // TODO: message
    }


    //
    // implements TermStructure
    //

    /* (non-Javadoc)
     * @see org.jquantlib.termstructures.TermStructure#calendar()
     */
    @Override
    public Calendar calendar() /* @ReadOnly */ {
        QL.require(this.calendar != null , THIS_METHOD_MUST_BE_OVERRIDDEN); // QA:[RG]::verified // TODO: message
        return calendar;
    }

    /* (non-Javadoc)
     * @see org.jquantlib.termstructures.TermStructure#settlementDays()
     */
    public /*@Natural*/ int settlementDays() /* @ReadOnly */ {
        return settlementDays;
    }

    /* (non-Javadoc)
     * @see org.jquantlib.termstructures.TermStructure#timeFromReference(org.jquantlib.util.Date)
     */
    @Override
    public final /*@Time*/ double timeFromReference(final Date date) /* @ReadOnly */ {
        return dayCounter().yearFraction(referenceDate(), date);
    }

    /* (non-Javadoc)
     * @see org.jquantlib.termstructures.TermStructure#dayCounter()
     */
    @Override
    public DayCounter dayCounter() /* @ReadOnly */ {
        QL.require(this.dayCounter != null , THIS_METHOD_MUST_BE_OVERRIDDEN); // QA:[RG]::verified // TODO: message
        return dayCounter;
    }

    /* (non-Javadoc)
     * @see org.jquantlib.termstructures.TermStructure#maxTime()
     */
    @Override
    public /*@Time*/ double maxTime() /* @ReadOnly */ {
        return timeFromReference(maxDate());
    }

    /* (non-Javadoc)
     * @see org.jquantlib.termstructures.TermStructure#referenceDate()
     */
    @Override
    public Date referenceDate() /* @ReadOnly */ {
        if (!updated) {
          final Date today = new Settings().evaluationDate();
          referenceDate = calendar().advance(today, settlementDays, TimeUnit.Days);
            updated = true;
        }
        return referenceDate;
    }


    //
    // implements Extrapolator
    //

    /**
     * Implements multiple inheritance via delegate pattern to a inner class
     *
     * @see Extrapolator
     */
    private final DefaultExtrapolator delegatedExtrapolator = new DefaultExtrapolator();

    /**
     * @return
     */
    @Override
    public final boolean allowsExtrapolation() {
        return delegatedExtrapolator.allowsExtrapolation();
    }

    @Override
    public void disableExtrapolation() {
        delegatedExtrapolator.disableExtrapolation();
    }

    @Override
    public void enableExtrapolation() {
        delegatedExtrapolator.enableExtrapolation();
    }


    //
    // implements Observer
    //

    //XXX:registerWith
    //    @Override
    //    public void registerWith(final Observable o) {
    //        o.addObserver(this);
    //    }
    //
    //    @Override
    //    public void unregisterWith(final Observable o) {
    //        o.deleteObserver(this);
    //    }

    @Override
    //XXX::OBS public void update(final Observable o, final Object arg) {
    public void update() {
        if (moving) {
            updated = false;
        }
        notifyObservers();
    }


    //
    // implements Observable
    //

    /**
     * Implements multiple inheritance via delegate pattern to an inner class
     *
     * @see Observable
     * @see DefaultObservable
     */
    private final Observable delegatedObservable = new DefaultObservable(this);

    @Override
    public void addObserver(final Observer observer) {
        delegatedObservable.addObserver(observer);
    }

    @Override
    public int countObservers() {
        return delegatedObservable.countObservers();
    }

    @Override
    public void deleteObserver(final Observer observer) {
        delegatedObservable.deleteObserver(observer);
    }

    @Override
    public void notifyObservers() {
        delegatedObservable.notifyObservers();
    }

    @Override
    public void notifyObservers(final Object arg) {
        delegatedObservable.notifyObservers(arg);
    }

    @Override
    public void deleteObservers() {
        delegatedObservable.deleteObservers();
    }

    @Override
    public List<Observer> getObservers() {
        return delegatedObservable.getObservers();
    }

}
TOP

Related Classes of org.jquantlib.termstructures.AbstractTermStructure

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.