/*
 Copyright (C) 2009 Ueli Hofstetter

 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
 . The license is also available online at
 .

 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.processes;

import java.util.ArrayList;
import java.util.List;

import org.jquantlib.QL;
import org.jquantlib.cashflow.CashFlow;
import org.jquantlib.cashflow.IborCoupon;
import org.jquantlib.daycounters.DayCounter;
import org.jquantlib.indexes.IborIndex;
import org.jquantlib.math.matrixutilities.Array;
import org.jquantlib.math.matrixutilities.Matrix;
import org.jquantlib.time.Date;

/**
 * Libor-forward-model process
 * 

* Stochastic process of a libor forward model using the rolling forward measure including predictor-corrector step *

* References: *

  • Glasserman, Paul, 2004, Monte Carlo Methods in Financial Engineering, Springer, Section 3.7
  • *
  • Antoon Pelsser, 2000, Efficient Methods for Valuing Interest Rate Derivatives, Springer, 8
  • *
  • Hull, John, White, Alan, 1999, Forward Rate Volatilities, Swap Rate Volatilities and the Implementation of the Libor Market * Model
  • * * @see FORWARD RATE VOLATILITIES, SWAP RATE VOLATILITIES, * AND THE IMPLEMENTATION OF THE LIBOR MARKET MODEL * * @category processes * * @author Ueli Hofstetter */ // TODO: license, class comments, access modifiers organization, good formatting public class LiborForwardModelProcess extends StochasticProcess { //Exception messages private static final String wrong_number_of_cashflows = "wrong number of cashflows"; private static final String irregular_coupon_types = "irregular coupon types are not suppported"; private final int size_; private final IborIndex index_; private LfmCovarianceParameterization lfmParam_; private final Array initialValues_; private final List fixingTimes_; private final List fixingDates_; private final List accrualStartTimes_; private final List accrualEndTimes_; private final List accrualPeriod_; private final Array m1, m2; public LiborForwardModelProcess(final int size, final IborIndex index) { super(new EulerDiscretization()); if (System.getProperty("EXPERIMENTAL") == null) throw new UnsupportedOperationException("Work in progress"); this.size_ = size; this.index_ = index; this.initialValues_ = new Array(size_); this.fixingDates_ = new ArrayList(size_); this.fixingTimes_ = new ArrayList(size_); this.accrualStartTimes_ = new ArrayList(size_); this.accrualEndTimes_ = new ArrayList(size_); this.accrualPeriod_ = new ArrayList(size_); this.m1 = new Array(size_); this.m2 = new Array(size_); final DayCounter dayCounter = index_.dayCounter(); final List flows = null /* cashFlows() */; // FIXME: translate cashFlows(); QL.require(this.size_ == flows.size() , wrong_number_of_cashflows); // TODO: message final Date settlement = index_.termStructure().currentLink().referenceDate(); final Date startDate = ((IborCoupon) flows.get(0)).fixingDate(); for (int i = 0; i < size_; ++i) { final IborCoupon coupon = (IborCoupon) flows.get(i); QL.require(coupon.date().eq(coupon.accrualEndDate()) , irregular_coupon_types); // TODO: message initialValues_.set(i, coupon.rate()); accrualPeriod_.set(i, coupon.accrualPeriod()); fixingDates_.set(i, coupon.fixingDate()); fixingTimes_.set(i, dayCounter.yearFraction(startDate, coupon.fixingDate())); accrualStartTimes_.set(i, dayCounter.yearFraction(settlement, coupon.accrualStartDate())); accrualEndTimes_.set(i, dayCounter.yearFraction(settlement, coupon.accrualEndDate())); } } // // public methods // public void setCovarParam(final LfmCovarianceParameterization param) { lfmParam_ = param; } public LfmCovarianceParameterization covarParam() { return lfmParam_; } public IborIndex index() { return index_; } // // Overrides StochasticProcess // @Override public Array initialValues() { return initialValues_.clone(); } @Override public int size() { // TODO Auto-generated method stub return 0; } @Override public Array drift(/* @Time */final double t, final Array x) { final Array f = new Array(size_); final Matrix covariance = lfmParam_.covariance(t, x); final int m = 0;//NextA for (int k = m; k < size_; ++k) { m1.set(k, accrualPeriod_.get(k) * x.get(k) / (1 + accrualPeriod_.get(k) * x.get(k))); final double value = m1.innerProduct(covariance.constRangeCol(k), m, k+1-m) - 0.5 * covariance.get(k, k); f.set(k, value); } return f; } @Override public Matrix diffusion(/*@Time*/ final double t, final Array x){ return lfmParam_.diffusion(t, x); } @Override public Matrix covariance(/*@Time*/final double t, final Array x, /*@Time*/ final double dt){ return lfmParam_.covariance(dt, x).mul(lfmParam_.covariance(dt, x).mulAssign(dt)); } @Override public Array apply(final Array x0, final Array dx){ final Array tmp = new Array(size_); for(int k = 0; kdrift(*this, t0, x0, dt); return apply(x0, ( drift_0 + discretization_ ->drift(*this,t0,apply(x0, drift_0 + rnd_0),dt) )*0.5 + rnd_0); The following implementation does the same but is faster. */ if (true) throw new UnsupportedOperationException("work in progress"); final int m = 0;//nextIndexReset(t0); final double sdt = Math.sqrt(dt); final Array f = x0.clone(); final Matrix diff = lfmParam_.diffusion(t0, x0); final Matrix covariance = lfmParam_.covariance(t0, x0); // TODO: review iterators for (int k=m; k cashFlows{ final Date refDate = index_.getTermStructure().getLink().referenceDate(); List floatingLeg = Leg.FloatingLe, schedule, index, paymentDayCounter, paymentAdj, fixingDays, gearings, spreads, caps, floors, isInArrears)( std::vector(1, amount), Schedule(refDate, refDate + Period(index_->tenor().length()*size_, index_->tenor().units()), index_->tenor(), index_->fixingCalendar(), index_->businessDayConvention(), index_->businessDayConvention(), false, false), index_, index_->dayCounter(), index_->businessDayConvention(), index_->fixingDays()); boost::shared_ptr fictitiousPricer(new BlackIborCouponPricer(Handle())); setCouponPricer(floatingLeg,fictitiousPricer); return floatingLeg; } Size LiborForwardModelProcess::size() const { return size_; } Size LiborForwardModelProcess::factors() const { return lfmParam_->factors(); } const std::vector
  • Ads help maintain this website.