Real EquityFXVolSurface::atmForwardVariance(const Date& date1, const Date& date2, bool extrapolate) const { QL_REQUIRE(date1<date2, "wrong dates"); Time t1 = timeFromReference(date1); Time t2 = timeFromReference(date2); return atmForwardVariance(t1, t2, extrapolate); }
InterpolatedYoYInflationCurve<Interpolator>:: InterpolatedYoYInflationCurve(const Date& referenceDate, const Calendar& calendar, const DayCounter& dayCounter, const Period& lag, Frequency frequency, bool indexIsInterpolated, const Handle<YieldTermStructure>& yTS, const std::vector<Date>& dates, const std::vector<Rate>& rates, const Interpolator& interpolator) : YoYInflationTermStructure(referenceDate, calendar, dayCounter, rates[0], lag, frequency, indexIsInterpolated, yTS), InterpolatedCurve<Interpolator>(std::vector<Time>(), rates, interpolator), dates_(dates) { QL_REQUIRE(dates_.size()>1, "too few dates: " << dates_.size()); // check that the data starts from the beginning, // i.e. referenceDate - lag, at least must be in the relevant // period std::pair<Date,Date> lim = inflationPeriod(yTS->referenceDate() - this->observationLag(), frequency); QL_REQUIRE(lim.first <= dates_[0] && dates_[0] <= lim.second, "first data date is not in base period, date: " << dates_[0] << " not within [" << lim.first << "," << lim.second << "]"); QL_REQUIRE(this->data_.size() == dates_.size(), "indices/dates count mismatch: " << this->data_.size() << " vs " << dates_.size()); this->times_.resize(dates_.size()); this->times_[0] = timeFromReference(dates_[0]); for (Size i = 1; i < dates_.size(); i++) { QL_REQUIRE(dates_[i] > dates_[i-1], "dates not sorted"); // YoY inflation data may be positive or negative // but must be greater than -1 QL_REQUIRE(this->data_[i] > -1.0, "year-on-year inflation data < -100 %"); // this can be negative this->times_[i] = timeFromReference(dates_[i]); QL_REQUIRE(!close(this->times_[i],this->times_[i-1]), "two dates correspond to the same time " "under this curve's day count convention"); } this->interpolation_ = this->interpolator_.interpolate(this->times_.begin(), this->times_.end(), this->data_.begin()); this->interpolation_.update(); }
Volatility BlackVolTermStructure::blackForwardVol(const Date& date1, const Date& date2, Real strike, bool extrapolate) const { // (redundant) date-based checks QL_REQUIRE(date1 <= date2, date1 << " later than " << date2); checkRange(date2, extrapolate); // using the time implementation Time time1 = timeFromReference(date1); Time time2 = timeFromReference(date2); return blackForwardVol(time1, time2, strike, extrapolate); }
void CapFloorTermVolSurface::initializeOptionDatesAndTimes() const { for (Size i=0; i<nOptionTenors_; ++i) { optionDates_[i] = optionDateFromTenor(optionTenors_[i]); optionTimes_[i] = timeFromReference(optionDates_[i]); } }
FixedLocalVolSurface::FixedLocalVolSurface( const Date& referenceDate, const std::vector<Date>& dates, const std::vector<Real>& strikes, const boost::shared_ptr<Matrix>& localVolMatrix, const DayCounter& dayCounter, Extrapolation lowerExtrapolation, Extrapolation upperExtrapolation) : LocalVolTermStructure( referenceDate, NullCalendar(), Following, dayCounter), maxDate_(dates.back()), localVolMatrix_(localVolMatrix), strikes_(dates.size(),boost::make_shared<std::vector<Real> >(strikes)), localVolInterpol_(dates.size()), lowerExtrapolation_(lowerExtrapolation), upperExtrapolation_(upperExtrapolation) { QL_REQUIRE(dates[0]>=referenceDate, "cannot have dates[0] < referenceDate"); times_ = std::vector<Time>(dates.size()); for (Size j=0; j<times_.size(); j++) times_[j] = timeFromReference(dates[j]); checkSurface(); setInterpolation<Linear>(); }
boost::shared_ptr<SmileSection> SwaptionVolCube2::smileSectionImpl(const Date& optionDate, const Period& swapTenor) const { calculate(); Rate atmForward = atmStrike(optionDate, swapTenor); Volatility atmVol = atmVol_->volatility(optionDate, swapTenor, atmForward); Time optionTime = timeFromReference(optionDate); Real exerciseTimeSqrt = std::sqrt(optionTime); std::vector<Real> strikes, stdDevs; strikes.reserve(nStrikes_); stdDevs.reserve(nStrikes_); Time length = swapLength(swapTenor); for (Size i=0; i<nStrikes_; ++i) { strikes.push_back(atmForward + strikeSpreads_[i]); stdDevs.push_back(exerciseTimeSqrt*( atmVol + volSpreadsInterpolator_[i](length, optionTime))); } Real shift = atmVol_->shift(optionTime,length); return boost::shared_ptr<SmileSection>(new InterpolatedSmileSection<Linear>(optionTime, strikes, stdDevs, atmForward, Linear(), Actual365Fixed(), volatilityType(), shift)); }
inline Real BlackVolTermStructure::blackVariance(const Date& d, Real strike, bool extrapolate) const { checkRange(d, extrapolate); checkStrike(strike, extrapolate); Time t = timeFromReference(d); return blackVarianceImpl(t, strike); }
void InflationTermStructure::checkRange(Time t, bool extrapolate) const { QL_REQUIRE(t >= timeFromReference(baseDate()), "time (" << t << ") is before base date"); QL_REQUIRE(extrapolate || allowsExtrapolation() || t <= maxTime(), "time (" << t << ") is past max curve time (" << maxTime() << ")"); }
inline Volatility SwaptionVolatilityStructure::volatilityImpl(const Date& optionDate, const Period& swapTenor, Rate strike) const { return volatilityImpl(timeFromReference(optionDate), swapLength(swapTenor), strike); }
inline Volatility CapFloorTermVolatilityStructure::volatility(const Date& d, Rate strike, bool extrap) const { checkRange(d, extrap); Time t = timeFromReference(d); return volatility(t, strike, extrap); }
// 2. blackVariance methods rely on volatility methods inline Real OptionletVolatilityStructure::blackVariance(const Date& optionDate, Rate strike, bool extrapolate) const { Volatility v = volatility(optionDate, strike, extrapolate); Time t = timeFromReference(optionDate); return v*v*t; }
Volatility LocalVolTermStructure::localVol(const Date& d, Real underlyingLevel, bool extrapolate) const { checkRange(d, extrapolate); checkStrike(underlyingLevel, extrapolate); Time t = timeFromReference(d); return localVolImpl(t, underlyingLevel); }
inline Real SwaptionVolatilityStructure::shift(const Date& optionDate, Time swapLength, bool extrapolate) const { checkSwapTenor(swapLength, extrapolate); checkRange(optionDate, extrapolate); Time optionTime = timeFromReference(optionDate); return shiftImpl(optionTime, swapLength); }
void SabrVolSurface::update() { TermStructure::update(); for (Size i=0; i<optionTenors_.size(); ++i) { optionDates_[i] = optionDateFromTenor(optionTenors_[i]); optionTimes_[i] = timeFromReference(optionDates_[i]); } notifyObservers(); }
inline Real SwaptionVolatilityStructure::blackVariance(const Date& optionDate, Time swapLength, Rate strike, bool extrapolate) const { Volatility v = volatility(optionDate, swapLength, strike, extrapolate); Time optionTime = timeFromReference(optionDate); return v*v*optionTime; }
std::pair<Time,Time> CallableBondVolatilityStructure::convertDates( const Date& optionDate, const Period& bondTenor) const { Date end = optionDate + bondTenor; QL_REQUIRE(end>optionDate, "negative bond tenor (" << bondTenor << ") given"); Time optionTime = timeFromReference(optionDate); Time timeLength = dayCounter().yearFraction(optionDate, end); return std::make_pair(optionTime, timeLength); }
inline Volatility SwaptionVolatilityStructure::volatility(const Date& optionDate, Time swapLength, Rate strike, bool extrapolate) const { checkSwapTenor(swapLength, extrapolate); checkRange(optionDate, extrapolate); checkStrike(strike, extrapolate); Time optionTime = timeFromReference(optionDate); return volatilityImpl(optionTime, swapLength, strike); }
Rate YoYInflationTermStructure::yoyRate(const Date &d, const Period& instObsLag, bool forceLinearInterpolation, bool extrapolate) const { Period useLag = instObsLag; if (instObsLag == Period(-1,Days)) { useLag = observationLag(); } Rate yoyRate; if (forceLinearInterpolation) { std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency()); dd.second = dd.second + Period(1,Days); Real dp = dd.second - dd.first; Real dt = (d-useLag) - dd.first; // if we are interpolating we only check the exact point // this prevents falling off the end at curve maturity InflationTermStructure::checkRange(d, extrapolate); Time t1 = timeFromReference(dd.first); Time t2 = timeFromReference(dd.second); Rate y1 = yoyRateImpl(t1); Rate y2 = yoyRateImpl(t2); yoyRate = y1 + (y2-y1) * (dt/dp); } else { if (indexIsInterpolated()) { InflationTermStructure::checkRange(d-useLag, extrapolate); Time t = timeFromReference(d-useLag); yoyRate = yoyRateImpl(t); } else { std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency()); InflationTermStructure::checkRange(dd.first, extrapolate); Time t = timeFromReference(dd.first); yoyRate = yoyRateImpl(t); } } if (hasSeasonality()) { yoyRate = seasonality()->correctYoYRate(d-useLag, yoyRate, *this); } return yoyRate; }
void YoYOptionletVolatilitySurface::checkRange(Time t, Rate strike, bool extrapolate) const { QL_REQUIRE(t >= timeFromReference(baseDate()), "time (" << t << ") is before base date"); QL_REQUIRE(extrapolate || allowsExtrapolation() || t <= maxTime(), "time (" << t << ") is past max curve time (" << maxTime() << ")"); QL_REQUIRE(extrapolate || allowsExtrapolation() || (strike >= minStrike() && strike <= maxStrike()), "strike (" << strike << ") is outside the curve domain [" << minStrike() << "," << maxStrike()<< "] at time = " << t); }
boost::shared_ptr<SmileSection> SwaptionVolatilityHullWhite::smileSectionImpl(const Date& d, const Period& swapTenor) const { calculate(); Time optionTime = timeFromReference(d); Time swapLength = SwaptionVolatilityStructure::swapLength(swapTenor); return boost::shared_ptr<SmileSection>(new HullWhiteSmileSection(d, swapTenor, indexBase_, yts_, reversion_, interpolationSigma_(swapLength,optionTime))); }
Volatility YoYOptionletVolatilitySurface::volatility(const Date& maturityDate, Rate strike, const Period &obsLag, bool extrapolate) const { Period useLag = obsLag; if (obsLag==Period(-1,Days)) { useLag = observationLag(); } if (indexIsInterpolated()) { YoYOptionletVolatilitySurface::checkRange(maturityDate-useLag, strike, extrapolate); Time t = timeFromReference(maturityDate-useLag); return volatilityImpl(t,strike); } else { std::pair<Date,Date> dd = inflationPeriod(maturityDate-useLag, frequency()); YoYOptionletVolatilitySurface::checkRange(dd.first, strike, extrapolate); Time t = timeFromReference(dd.first); return volatilityImpl(t,strike); } }
void AbcdAtmVolCurve::initializeOptionDatesAndTimes() const { // the input time data for (Size i=0; i<nOptionTenors_; ++i) { optionDates_[i] = optionDateFromTenor(optionTenors_[i]); optionTimes_[i] = timeFromReference(optionDates_[i]); } // the time data used for interpolation actualOptionTimes_.clear(); for (Size i=0; i<nOptionTenors_; ++i) { if(inclusionInInterpolation_[i]==true) { actualOptionTimes_.push_back(optionTimes_[i]); actualOptionTenors_.push_back(optionTenors_[i]); } } }
void DefaultProbabilityTermStructure::setJumps() { if (jumpDates_.empty() && !jumps_.empty()) { // turn of year dates jumpDates_.resize(nJumps_); jumpTimes_.resize(nJumps_); Year y = referenceDate().year(); for (Size i=0; i<nJumps_; ++i) jumpDates_[i] = Date(31, December, y+i); } else { // fixed dats QL_REQUIRE(jumpDates_.size()==nJumps_, "mismatch between number of jumps (" << nJumps_ << ") and jump dates (" << jumpDates_.size() << ")"); } for (Size i=0; i<nJumps_; ++i) jumpTimes_[i] = timeFromReference(jumpDates_[i]); latestReference_ = referenceDate(); }
// gets a price that can include an arbitrary number of basis curves inline Real CommodityCurve::price( const Date& d, const boost::shared_ptr<ExchangeContracts>& exchangeContracts, Integer nearbyOffset) const { Date date = nearbyOffset > 0 ? underlyingPriceDate(d, exchangeContracts, nearbyOffset) : d; Time t = timeFromReference(date); Real priceValue = 0; try { priceValue = priceImpl(t); } catch (const std::exception& e) { QL_FAIL("error retrieving price for curve [" << name() << "]: " << e.what()); } return priceValue + basisOfPriceImpl(t); }
std::vector<Volatility> SabrVolSurface::volatilitySpreads(const Date& d) const { Size nOptionsTimes = optionTimes_.size(); Size nAtmRateSpreads = atmRateSpreads_.size(); std::vector<Volatility> interpolatedVols(nAtmRateSpreads); std::vector<Volatility> vols(nOptionsTimes); // the volspread at a given strike for (Size i=0; i<nAtmRateSpreads; ++i) { for (Size j=0; j<nOptionsTimes; ++j) { vols[j] = (**volSpreads_[j][i]).value(); } LinearInterpolation interpolator(optionTimes_.begin(), optionTimes_.end(), vols.begin()); interpolatedVols[i] = interpolator(timeFromReference(d),true); } return interpolatedVols; }
void CallableBondVolatilityStructure::checkRange(const Date& optionDate, const Period& bondTenor, Rate k, bool extrapolate) const { TermStructure::checkRange(timeFromReference(optionDate), extrapolate); QL_REQUIRE(bondTenor.length() > 0, "negative bond tenor (" << bondTenor << ") given"); QL_REQUIRE(extrapolate || allowsExtrapolation() || bondTenor <= maxBondTenor(), "bond tenor (" << bondTenor << ") is past max tenor (" << maxBondTenor() << ")"); QL_REQUIRE(extrapolate || allowsExtrapolation() || (k >= minStrike() && k <= maxStrike()), "strike (" << k << ") is outside the curve domain [" << minStrike() << "," << maxStrike()<< "]"); }
SabrVolSurface::SabrVolSurface( const boost::shared_ptr<InterestRateIndex>& index, const Handle<BlackAtmVolCurve>& atmCurve, const std::vector<Period>& optionTenors, const std::vector<Spread>& atmRateSpreads, const std::vector<std::vector<Handle<Quote> > >& volSpreads) : InterestRateVolSurface(index), atmCurve_(atmCurve), optionTenors_(optionTenors), optionTimes_(optionTenors.size()), optionDates_(optionTenors.size()), atmRateSpreads_(atmRateSpreads), volSpreads_(volSpreads) { checkInputs(); // Creation of reference smile sections // Hard coded isAlphaFixed_ = false; isBetaFixed_ = false; isNuFixed_ = false; isRhoFixed_ = false; vegaWeighted_ = true; sabrGuesses_.resize(optionTenors_.size()); for (Size i=0; i<optionTenors_.size(); ++i) { optionDates_[i] = optionDateFromTenor(optionTenors_[i]); optionTimes_[i] = timeFromReference(optionDates_[i]); // Hard coded sabrGuesses_[i][0] = 0.025; // alpha sabrGuesses_[i][1] = 0.5; // beta sabrGuesses_[i][2] = 0.3; // rho sabrGuesses_[i][3] = 0.0; // nu } registerWithMarketData(); }
InterestRate YieldTermStructure::forwardRate(const Date& d1, const Date& d2, const DayCounter& dayCounter, Compounding comp, Frequency freq, bool extrapolate) const { if (d1==d2) { checkRange(d1, extrapolate); Time t1 = std::max(timeFromReference(d1) - dt/2.0, 0.0); Time t2 = t1 + dt; Real compound = discount(t1, true)/discount(t2, true); // times have been calculated with a possibly different daycounter // but the difference should not matter for very small times return InterestRate::impliedRate(compound, dayCounter, comp, freq, dt); } QL_REQUIRE(d1 < d2, d1 << " later than " << d2); Real compound = discount(d1, extrapolate)/discount(d2, extrapolate); return InterestRate::impliedRate(compound, dayCounter, comp, freq, d1, d2); }
ClonedYieldTermStructure::ClonedYieldTermStructure( const boost::shared_ptr<YieldTermStructure> &source, const ReactionToTimeDecay reactionToTimeDecay, const Processing processing, const Calendar calendar) : YieldTermStructure(source->dayCounter()), reactionToTimeDecay_(reactionToTimeDecay), processing_(processing), originalEvalDate_(Settings::instance().evaluationDate()), originalReferenceDate_(Date(source->referenceDate())), originalMaxDate_(source->maxDate()) { calendar_ = calendar.empty() ? source->calendar() : calendar; QL_REQUIRE(!calendar_.empty() || reactionToTimeDecay_ == FixedReferenceDate, "a floating termstructure needs a calendar, none given and " "source termstructures' calendar is empty, too"); referenceDate_ = originalReferenceDate_; maxDate_ = originalMaxDate_; offset_ = 0.0; valid_ = true; instFwdMax_ = source->forwardRate(maxDate_, maxDate_, Actual365Fixed(), Continuous) .rate(); if (reactionToTimeDecay != FixedReferenceDate) { QL_REQUIRE(originalReferenceDate_ >= originalEvalDate_, "to construct a moving term structure the source term " "structure must have a reference date (" << originalReferenceDate_ << ") after the evaluation date (" << originalEvalDate_ << ")"); try { impliedSettlementDays_ = source->settlementDays(); } catch (...) { // if the source ts has no settlement days we imply // them from the difference of the original reference // date and the original evaluation date impliedSettlementDays_ = this->calendar().businessDaysBetween( originalEvalDate_, originalReferenceDate_); } } logDiscounts_.resize(originalMaxDate_.serialNumber() - originalReferenceDate_.serialNumber() + 1); times_.resize(logDiscounts_.size()); for (BigInteger i = 0; i <= originalMaxDate_.serialNumber() - originalReferenceDate_.serialNumber(); ++i) { Date d = Date(originalReferenceDate_.serialNumber() + i); logDiscounts_[i] = std::log(source->discount(d)); times_[i] = timeFromReference(d); if (processing == PositiveYieldsAndForwards) { logDiscounts_[i] = std::min(0.0, logDiscounts_[i]); } if (processing == PositiveForwards || processing == PositiveYieldsAndForwards) { if (i > 0) logDiscounts_[i] = std::min(logDiscounts_[i - 1], logDiscounts_[i]); } } if (reactionToTimeDecay_ != FixedReferenceDate) { registerWith(Settings::instance().evaluationDate()); } }
inline Real CommodityCurve::basisOfPrice(const Date& d) const { Time t = timeFromReference(d); return basisOfPriceImpl(t); }