Cap Floor Collar Consistency Check with QL 0.3.8

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Cap Floor Collar Consistency Check with QL 0.3.8

Peter James-6
Quantlibs,

I've been testing the Cap Floor instruments, and came across strange values
for Floors.  Basically I don't think the Floor is being priced correctly I
get CAP=COLLAR and FLOOR ~= 0.  This isn't the easiest to replicate when
using a term structure containing discount factors.... but here goes.

Assumptions
-----------------
Type c, f
Cap Strike 4.16%, 4.16%
Notional $1,000,000
Volatility 15%
Reference Date 21/03/2005
Reset Frequency quarterly
Index usdlibor

Term Structure
----------------------
21/03/2005 1
22/06/2005 0.992356
22/09/2005 0.983516
22/12/2005 0.973997
22/03/2006 0.964029
22/06/2006 0.953906
22/09/2006 0.943438
22/12/2006 0.932766
22/03/2007 0.921928
22/06/2007 0.911351
24/09/2007 0.900444
24/12/2007 0.889796
24/03/2008 0.879077
23/06/2008 0.868636
22/09/2008 0.858184
22/12/2008 0.847731
23/03/2009 0.837287
22/06/2009 0.827022
22/09/2009 0.81668
22/12/2009 0.806494
22/03/2010 0.796468
22/06/2010 0.786314
22/09/2010 0.776223
22/12/2010 0.766309

Code:  (QuantLibXL based)
-------  Assuming the schedule and values are correctly set

Handle<YieldTermStructure> termStructure
= QlXlfOper(xltermstructure).AsTermStructure(refDate);

std::vector<boost::shared_ptr<CashFlow> >
leg(FloatingRateCouponVector(schedule,
        convention,
        std::vector<Real>(1, nominal),
        index, fixingDays_,
        std::vector<Spread>(),
        index->dayCounter()));


Handle<Quote> vol(boost::shared_ptr<Quote>(
        new SimpleQuote(xlvolatility.AsDouble())));

boost::shared_ptr<BlackModel> model(
        new BlackModel(vol, termStructure));

boost::shared_ptr<PricingEngine> engine(
        new BlackCapFloorEngine(model));

CapFloor::Type type = QlXlfOper(xltype).AsCapFloorType();
boost::shared_ptr<Instrument> capfloor;

if (type == CapFloor::Cap) {
        capfloor = boost::shared_ptr<CapFloor>(
                new Cap(leg, std::vector<Rate>(1, strike),
                        termStructure, engine));
} else if (type == CapFloor::Floor) {
        capfloor = boost::shared_ptr<CapFloor>(
                new Floor(leg, std::vector<Rate>(1, strike),
                        termStructure, engine));
} else if (type == CapFloor::Collar) {
        std::vector<double> strikes = xlstrikes.AsDoubleVector();
        capfloor = boost::shared_ptr<CapFloor>(
                new Collar(leg,
                        std::vector<Rate>(1, strikes[0]),
                        std::vector<Rate>(1, strikes[1]),
                        termStructure, engine));
} else {
        QL_FAIL("unknown cap/floor type");
}

results = capfloor->NPV();


Cap Results = Collar Results @ Strike: 4.16%

22/12/2005
22/03/2006 143.59
22/06/2006 603.22
22/09/2006 1,035.27
22/12/2006 1,382.80
22/03/2007 1,045.18
22/06/2007 1,281.22
24/09/2007 1,446.57
24/12/2007 1,619.73
24/03/2008 1,454.91
23/06/2008 1,575.78
22/09/2008 1,686.52
22/12/2008 1,783.37
23/03/2009 1,713.06
22/06/2009 1,805.33
22/09/2009 1,848.52
22/12/2009 1,882.75
22/03/2010 1,937.14
22/06/2010 1,980.41
22/09/2010 1,998.71
22/12/2010 2,021.92
23/03/2011 2,018.27
22/06/2011