/*
Copyright (C) 2011 Tim Blackler
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.termstructures.yieldcurves;
import org.jquantlib.QL;
import org.jquantlib.daycounters.DayCounter;
import org.jquantlib.indexes.BMAIndex;
import org.jquantlib.indexes.IborIndex;
import org.jquantlib.instruments.BMASwap;
import org.jquantlib.lang.annotation.Natural;
import org.jquantlib.pricingengines.swap.DiscountingSwapEngine;
import org.jquantlib.quotes.Handle;
import org.jquantlib.quotes.Quote;
import org.jquantlib.quotes.RelinkableHandle;
import org.jquantlib.termstructures.YieldTermStructure;
import org.jquantlib.time.BusinessDayConvention;
import org.jquantlib.time.Calendar;
import org.jquantlib.time.Date;
import org.jquantlib.time.MakeSchedule;
import org.jquantlib.time.Period;
import org.jquantlib.time.Schedule;
import org.jquantlib.time.TimeUnit;
import org.jquantlib.time.Weekday;
import org.jquantlib.util.PolymorphicVisitor;
import org.jquantlib.util.Visitor;
/**
* Rate helper for bootstrapping over BMA swap rates
*
* @author Tim Blackler
*/
//
public class BMASwapRateHelper extends RelativeDateRateHelper {
protected final Period tenor;
protected /* @Natural */ int settlementDays;
protected final Calendar calendar;
protected final Period bmaPeriod;
protected final BusinessDayConvention bmaConvention;
protected final DayCounter bmaDayCount;
protected final BMAIndex bmaIndex;
protected final IborIndex iborIndex;
protected BMASwap swap;
protected RelinkableHandle termStructureHandle = new RelinkableHandle (null);
//
// public constructors
//
public BMASwapRateHelper(
final Handle liborFraction,
final Period tenor,
final @Natural int settlementDays,
final Calendar calendar,
// bma leg
final Period bmaPeriod,
final BusinessDayConvention bmaConvention,
final DayCounter bmaDayCount,
final BMAIndex bmaIndex,
// libor leg
final IborIndex iborIndex) {
super(liborFraction);
QL.validateExperimentalMode();
this.tenor = tenor;
this.settlementDays = settlementDays;
this.calendar = calendar;
this.bmaPeriod = bmaPeriod;
this.bmaConvention = bmaConvention;
this.bmaDayCount = bmaDayCount;
this.bmaIndex = bmaIndex;
this.iborIndex = iborIndex;
this.iborIndex.addObserver(this);
this.bmaIndex.addObserver(this);
initializeDates();
}
//
// protected methods
//
/**
*
* @see org.jquantlib.termstructures.yield.RelativeDateRateHelper#initializeDates()
*/
@Override
protected void initializeDates() {
earliestDate = calendar.advance(evaluationDate,
new Period(settlementDays, TimeUnit.Days),
BusinessDayConvention.Following);
Date maturity = earliestDate.add(tenor);
BMAIndex clonedIndex = bmaIndex.clone(termStructureHandle);
Schedule bmaSchedule = new MakeSchedule(earliestDate,
maturity,
bmaPeriod,
bmaIndex.fixingCalendar(),
bmaConvention)
.backwards()
.schedule();
Schedule liborSchedule = new MakeSchedule(earliestDate,
maturity,
iborIndex.tenor(),
iborIndex.fixingCalendar(),
iborIndex.businessDayConvention())
.endOfMonth(iborIndex.endOfMonth())
.schedule();
this.swap = new BMASwap(BMASwap.Type.Payer,
100.0,
liborSchedule,
0.75, //arbitary
0.0,
iborIndex,
iborIndex.dayCounter(),
bmaSchedule,
clonedIndex,
bmaDayCount);
this.swap.setPricingEngine(new DiscountingSwapEngine(iborIndex.termStructure()));
Date d = calendar.adjust(swap.maturityDate(), BusinessDayConvention.Following);
Weekday w = d.weekday();
Date nextWednesday = w.value() >=4 ? d.add(11 - w.value()) : d.add(4 - w.value());
latestDate = clonedIndex.valueDate(clonedIndex.fixingCalendar().adjust(nextWednesday));
}
/**
* Do not set the relinkable handle as an observer.
* Force recalculation when needed
*
* @see org.jquantlib.termstructures.BootstrapHelper#setTermStructure
*
* @param t
*/
@Override
public void setTermStructure(final YieldTermStructure t) {
this.termStructureHandle.linkTo(t, false);
super.setTermStructure(t);
}
/**
* @see org.jquantlib.termstructures.BootstrapHelper#getImpliedQuote()
*/
@Override
public /*@Real*/ double impliedQuote() /* @ReadOnly */ {
QL.require(termStructure != null , "term structure not set");
// we didn't register as observers - force calculation
swap.recalculate();
return swap.fairLiborFraction();
}
//
// implements PolymorphicVisitable
//
@Override
public void accept(final PolymorphicVisitor pv) {
final Visitor v = (pv!=null) ? pv.visitor(this.getClass()) : null;
if (v != null) {
v.visit(this);
} else {
super.accept(pv);
}
}
}
Ads help maintain this website.