/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2006 Ferdinando Ametrano Copyright (C) 2006 François du Vignaud 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 . 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. */ #include #include namespace QuantLib { SwaptionVolatilityDiscrete::SwaptionVolatilityDiscrete( const std::vector& optionTenors, const std::vector& swapTenors, Natural settlementDays, const Calendar& cal, const DayCounter& dc, BusinessDayConvention bdc) : SwaptionVolatilityStructure(settlementDays, cal, dc, bdc), nOptionTenors_(optionTenors.size()), optionTenors_(optionTenors), optionDates_(nOptionTenors_), optionTimes_(nOptionTenors_), optionDatesAsReal_(nOptionTenors_), nSwapTenors_(swapTenors.size()), swapTenors_(swapTenors), swapLengths_(nSwapTenors_) { checkOptionTenors(); initializeOptionDatesAndTimes(); checkSwapTenors(); optionInterpolator_= LinearInterpolation(optionTimes_.begin(), optionTimes_.end(), optionDatesAsReal_.begin()); optionInterpolator_.update(); optionInterpolator_.enableExtrapolation(); } SwaptionVolatilityDiscrete::SwaptionVolatilityDiscrete( const std::vector& optionTenors, const std::vector& swapTenors, const Date& referenceDate, const Calendar& cal, const DayCounter& dc, BusinessDayConvention bdc) : SwaptionVolatilityStructure(referenceDate, cal, dc, bdc), nOptionTenors_(optionTenors.size()), optionTenors_(optionTenors), optionDates_(nOptionTenors_), optionTimes_(nOptionTenors_), optionDatesAsReal_(nOptionTenors_), nSwapTenors_(swapTenors.size()), swapTenors_(swapTenors), swapLengths_(nSwapTenors_) { checkOptionTenors(); initializeOptionDatesAndTimes(); checkSwapTenors(); optionInterpolator_= LinearInterpolation(optionTimes_.begin(), optionTimes_.end(), optionDatesAsReal_.begin()); optionInterpolator_.update(); optionInterpolator_.enableExtrapolation(); } SwaptionVolatilityDiscrete::SwaptionVolatilityDiscrete( const std::vector& optionDates, const std::vector& swapTenors, const Date& referenceDate, const Calendar& cal, const DayCounter& dc, BusinessDayConvention bdc) : SwaptionVolatilityStructure(referenceDate, cal, dc, bdc), nOptionTenors_(optionDates.size()), optionTenors_(nOptionTenors_), optionDates_(optionDates), optionTimes_(nOptionTenors_), optionDatesAsReal_(nOptionTenors_), nSwapTenors_(swapTenors.size()), swapTenors_(swapTenors), swapLengths_(nSwapTenors_) { checkOptionDates(); initializeOptionTimes(); checkSwapTenors(); optionInterpolator_= LinearInterpolation(optionTimes_.begin(), optionTimes_.end(), optionDatesAsReal_.begin()); optionInterpolator_.update(); optionInterpolator_.enableExtrapolation(); } void SwaptionVolatilityDiscrete::checkOptionDates() const { QL_REQUIRE(optionDates_[0]>=referenceDate(), "first option date (" << optionDates_[0] << ") is after reference date (" << referenceDate() << ")"); for (Size i=1; ioptionDates_[i-1], "non increasing option dates: " << io::ordinal(i-1) << " is " << optionDates_[i-1] << ", " << io::ordinal(i) << " is " << optionDates_[i]); } } void SwaptionVolatilityDiscrete::checkOptionTenors() const { Date rollingExDate = optionDateFromTenor(optionTenors_[0]); QL_REQUIRE(rollingExDate>=referenceDate(), "first option tenor is negative (" << optionTenors_[0] << ")"); for (Size i=1; irollingExDate, "non increasing option tenor: " << io::ordinal(i-1) << " is " << optionTenors_[i-1] << ", " << io::ordinal(i) << " is " << optionTenors_[i]); rollingExDate = optionDateFromTenor(optionTenors_[i]); } } void SwaptionVolatilityDiscrete::checkSwapTenors() const { Date startDate = optionDates_[0]; // as good as any Date endDate = startDate + swapTenors_[0]; QL_REQUIRE(endDate>startDate, "first swap tenor is negative (" << swapTenors_[0] << ")"); for (Size i=1; iendDate, "non increasing swap tenor: " << io::ordinal(i-1) << " is " << swapTenors_[i-1] << ", " << io::ordinal(i) << " is " << swapTenors_[i]); Date endDate = startDate + swapTenors_[i]; } } void SwaptionVolatilityDiscrete::initializeOptionDatesAndTimes() const { for (Size i=0; i(optionDates_[i].serialNumber()); } initializeOptionTimes(); } void SwaptionVolatilityDiscrete::initializeOptionTimes() const { for (Size i=0; i SwaptionVolatilityDiscrete::convertDates(const Date& optionDate, const Period& swapTenor) const { Time optionTime = timeFromReference(optionDate); Date startDate = optionDates_.front(); // for consistency Date endDate = startDate + swapTenor; Time swapLength = dayCounter().yearFraction(startDate, endDate); return std::make_pair(optionTime, swapLength); } }