boost::shared_ptr<HazardRateStructure> qlHazardRateFactory::hazardRateTS(TiXmlNode* node) { boost::shared_ptr<HazardRateStructure> hazardCurve; Date referenceDate = Settings::instance().evaluationDate(); std::vector<boost::shared_ptr<DefaultProbabilityHelper> > instruments; qlCalendarFactory calFactory = qlCalendarFactory(); qlTimeUnitFactory timeUnitFactory = qlTimeUnitFactory(); qlYieldTermStructureFactory tsFactory = qlYieldTermStructureFactory(); Calendar calendar = calFactory.calendar(node->FirstChildElement("calendar")->GetText()); Real recoveryRate = strToDouble(node->FirstChildElement("recoveryRate")->GetText()); TiXmlElement* rateNode = node->FirstChildElement("rateData"); std::vector<Period> periods; std::vector<Real> spreadRates; if(rateNode) { for(rateNode; rateNode; rateNode = rateNode->NextSiblingElement("rateData")) { periods.push_back(timeUnitFactory.timeUnit(rateNode)); spreadRates.push_back(strToDouble(rateNode->FirstChildElement("data")->GetText())); } } for (Size i=0; i<periods.size(); i++) { instruments.push_back(boost::shared_ptr<DefaultProbabilityHelper>( new SpreadCdsHelper( Handle<Quote>(boost::shared_ptr<Quote>( new SimpleQuote(spreadRates[i]))), periods[i], 0, calendar, Quarterly, Following, DateGeneration::TwentiethIMM, Actual365Fixed(), recoveryRate, tsCurve_))); } // Bootstrap hazard rates std::string curveType = "HazardRate"; std::string interpolationType = "BackwardFlat"; boost::shared_ptr<PiecewiseDefaultCurve<HazardRate, BackwardFlat> > hazardRateStructure( new PiecewiseDefaultCurve<HazardRate, BackwardFlat>( referenceDate, instruments, Actual365Fixed())); return hazardCurve; }
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)); }
void SimpleRangeAccrualRateETI::initializeImpl(const TimeGrid& timeGrid, const boost::shared_ptr<YieldTermStructure>& discountCurve, const boost::shared_ptr<PathGeneratorFactory>& pathGenFactory) { referenceCalculation_->initialize(timeGrid,discountCurve,pathGenFactory); this->payoffDateInfo_->initialize(timeGrid,discountCurve,pathGenFactory); this->rangeNum_ = simpleRangeRateList_.size(); this->assetNum_ = pathGenFactory->numAssets(); Date today = Settings::instance().evaluationDate(); DayCounter dayCounter = Actual365Fixed(); double fixingStartTime = dayCounter.yearFraction( today , calculationStartDate_ ); Size fixingStartPosition = timeGrid.closestIndex(fixingStartTime); double fixingEndTime = dayCounter.yearFraction( today , calculationEndDate_ ); Size fixingEndPosition = timeGrid.closestIndex(fixingEndTime); Size fixingSize = fixingEndPosition - fixingStartPosition; this->fixingDatePositions_ = std::valarray<Size>(fixingSize); for ( Size position = 0 ; fixingSize ; position++ ) { fixingDatePositions_[position] = fixingStartPosition + position; } for ( Size rng = 0 ; this->rangeNum_ ; rng++ ) { simpleRangeRateList_[rng]->initialize(timeGrid,discountCurve,pathGenFactory); } }
DayCounter ComponentMust::eff_convert_basis(std::string basis) const { //cette fonction fait la conversion //de la convention de calcul (basis) de type string lue de XML de MUST // daycounter; if (basis == "A360") return Actual360(); if (basis == "A365") return Actual365Fixed(); if (basis == "Actual") return ActualActual(); if (basis == "Daily Price") return OneDayCounter(); if (basis == "Business 252") return Business252(); if (basis == "JGB") return Actual365NoLeap(); if (basis == "30/360") return Thirty360(Thirty360::EurobondBasis); return Thirty360(); }
void CompositeSumOptionPricer::initializeImpl(const TimeGrid& timeGrid, const boost::shared_ptr<YieldTermStructure>& discountCurve, const boost::shared_ptr<PathGeneratorFactory>& pathGenFactory) { //this->referenceCal_->initialize(timeGrid,discountCurve); for (Size i=0 ; i < optionListNum_ ; i++) { optionList_[i]->initialize(timeGrid,discountCurve,pathGenFactory); } this->payoffDateInfo_->initialize(timeGrid,discountCurve,pathGenFactory); Date today = Settings::instance().evaluationDate(); DayCounter dayCounter = Actual365Fixed(); //this->discount_ = Array(1); //double payoffTime = dayCounter.yearFraction( today , payoffDateInfo_-> ); //payoffDatePositions_[0] = timeGrid.closestIndex(payoffTime); //discount_[0] = discountCurve->discount(payoffTime); }
ScenarioGenerator(const Calendar &calendar = NullCalendar(), const DayCounter &dc = Actual365Fixed()) : calendar_(calendar), dc_(dc), pathNumber_(0), validPath_(true), validHorizonDate_(true) { resetHorizonDate(); baseDate_ = horizonDate_; }
DailyTenorGBPLibor(Natural settlementDays, const Handle<YieldTermStructure>& h = Handle<YieldTermStructure>()) : DailyTenorLibor("GBPLibor", settlementDays, GBPCurrency(), UnitedKingdom(UnitedKingdom::Exchange), Actual365Fixed(), h) {}
GBPLibor(const Period& tenor, const Handle<YieldTermStructure>& h = Handle<YieldTermStructure>()) : Libor("GBPLibor", tenor, 0, GBPCurrency(), UnitedKingdom(UnitedKingdom::Exchange), Actual365Fixed(), h) {}
Euribor365::Euribor365(const Period& tenor, const Handle<YieldTermStructure>& h) : IborIndex("Euribor365", tenor, 2, // settlement days EURCurrency(), TARGET(), euriborConvention(tenor), euriborEOM(tenor), Actual365Fixed(), h) { QL_REQUIRE(this->tenor().units()!=Days, "for daily tenors (" << this->tenor() << ") dedicated DailyTenor constructor must be used"); }
THBFIX(const Period& tenor, const Handle<YieldTermStructure>& h = Handle<YieldTermStructure>()) : IborIndex("THBFIX", tenor, 2, THBCurrency(), JointCalendar(UnitedKingdom(UnitedKingdom::Exchange), JointCalendar(UnitedStates(UnitedStates::LiborImpact), Thailand())), ModifiedFollowing, true, Actual365Fixed(), h) {}
boost::shared_ptr<BlackVolTermStructure> ProcessInfo::ProcessParser_Impl:: make_vol_ts(const std::string& keyName, std::map<std::string, std::string>& variable_map, std::map<std::string, std::vector<std::string>>& variable_array_map, std::map<std::string, Matrix>& variable_matrix_map) { boost::shared_ptr<BlackVolTermStructure> vol_ts; Date refDate = Settings::instance().evaluationDate(); const std::string& vol_type = "TYPE"; if (variable_map.find(keyName) != variable_map.end()) { double value = std::stod(variable_map[keyName]); vol_ts = boost::shared_ptr<BlackConstantVol>( new BlackConstantVol(refDate, NullCalendar(), value, Actual365Fixed())); return vol_ts; } vol_ts = boost::shared_ptr<BlackConstantVol>( new BlackConstantVol(refDate, NullCalendar(), 0.3, Actual365Fixed())); //if (vol_type == "CONSTANT") //{ // vol_ts = boost::shared_ptr<BlackConstantVol>( // new BlackConstantVol(refDate, NullCalendar(), 0.3, Actual365Fixed())); //} //else if (vol_type == "CURVE") //{ //} //else if (vol_type == "SURFACE") //{ //} //else //{ //} return vol_ts; }
MakeCapFloor::MakeCapFloor(CapFloor::Type capFloorType, const Period& tenor, const shared_ptr<IborIndex>& iborIndex, Rate strike, const Period& forwardStart) : capFloorType_(capFloorType), strike_(strike), firstCapletExcluded_(forwardStart==0*Days), asOptionlet_(false), // setting the fixed leg tenor avoids that MakeVanillaSwap throws // because of an unknown fixed leg default tenor for a currency, // notice that only the floating leg of the swap is used anyway makeVanillaSwap_(MakeVanillaSwap(tenor, iborIndex, 0.0, forwardStart) .withFixedLegTenor(1*Years).withFixedLegDayCount(Actual365Fixed())) {}
Bbsw(const Period& tenor, const Handle<YieldTermStructure>& h = Handle<YieldTermStructure>()) : IborIndex("Bbsw", tenor, 0, // settlement days AUDCurrency(), Australia(), HalfMonthModifiedFollowing, true, Actual365Fixed(), h) { QL_REQUIRE(this->tenor().units() != Days, "for daily tenors (" << this->tenor() << ") dedicated DailyTenor constructor must be used"); }
BlackScholesProcess::BlackScholesProcess( const Handle<Quote>& x0, const Handle<YieldTermStructure>& riskFreeTS, const Handle<BlackVolTermStructure>& blackVolTS, const boost::shared_ptr<discretization>& d) : GeneralizedBlackScholesProcess( x0, // no dividend yield Handle<YieldTermStructure>(boost::shared_ptr<YieldTermStructure>( new FlatForward(0, NullCalendar(), 0.0, Actual365Fixed()))), riskFreeTS, blackVolTS, d) {}
Real SwaptionHelper::blackPrice(Volatility sigma) const { calculate(); Handle<Quote> vol(boost::shared_ptr<Quote>(new SimpleQuote(sigma))); boost::shared_ptr<PricingEngine> engine; switch(volatilityType_) { case ShiftedLognormal: engine = boost::make_shared<BlackSwaptionEngine>( termStructure_, vol, Actual365Fixed(), shift_); break; case Normal: engine = boost::make_shared<BachelierSwaptionEngine>( termStructure_, vol, Actual365Fixed()); break; default: QL_FAIL("can not construct engine: " << volatilityType_); break; } swaption_->setPricingEngine(engine); Real value = swaption_->NPV(); swaption_->setPricingEngine(engine_); return value; }
MurexCurve::MurexCurve(Date referenceDate, vector<Date> maturities, vector<double> discounts, long interpolationMode ) : refDate_(referenceDate),maturities_(maturities),discounts_(discounts),interpolationMode_(interpolationMode) { QL_REQUIRE(maturities.size()==discounts.size(),"Maturities size (" << maturities.size() << ") must match discounts size (" << discounts.size() << ")"); QL_REQUIRE(interpolationMode_==0 || interpolationMode_==1,"Interpolation Mode (" << interpolationMode_ << ") must be 0 or 1."); dc_=Actual365Fixed(); n_=maturities.size()+1; times_=vector<double>(n_); rates_=vector<double>(n_); calculate(); }
GbpLiborSwapIsdaFix::GbpLiborSwapIsdaFix( const Period& tenor, const Handle<YieldTermStructure>& h) : SwapIndex("GbpLiborSwapIsdaFix", // familyName tenor, 0, // settlementDays GBPCurrency(), UnitedKingdom(UnitedKingdom::Exchange), tenor > 1*Years ? // fixedLegTenor 6*Months : 1*Years, ModifiedFollowing, // fixedLegConvention Actual365Fixed(), // fixedLegDaycounter tenor > 1*Years ? shared_ptr<IborIndex>(new GBPLibor(6*Months, h)) : shared_ptr<IborIndex>(new GBPLibor(3*Months, h))) {}
boost::shared_ptr<YieldTermStructure> ProcessInfo::ProcessParser_Impl::make_yield_ts( const std::string& keyName, std::map<std::string, std::string>& variable_map, std::map<std::string, std::vector<std::string>>& variable_array_map, std::map<std::string, Matrix>& variable_matrix_map) { Date refDate = Settings::instance().evaluationDate(); boost::shared_ptr<YieldTermStructure> yield_ts; if (variable_map.find(keyName) != variable_map.end()) { double value = std::stod(variable_map[keyName]); yield_ts = boost::shared_ptr<YieldTermStructure>(new FlatForward(refDate, value, Actual365Fixed())); return yield_ts; } std::string tenor_key = keyName + "_CURVE_TENOR"; std::string value_key = keyName + "_CURVE_VALUE"; std::string interpolation_key = keyName + "_CURVE_INTERPOLATION"; if (variable_array_map.find(tenor_key) == variable_array_map.end()) QL_FAIL(tenor_key << " does not exist."); if (variable_array_map.find(value_key) == variable_array_map.end()) QL_FAIL(value_key << " does not exist."); std::vector<std::string> periods = variable_array_map[tenor_key]; std::vector<std::string> values = variable_array_map[value_key]; std::vector<Real> data; // converting for (Size i = 0; i < values.size(); i++) data.push_back(std::stod(values[i])); QL_REQUIRE(periods.size() == data.size(), "tenor size must be same to value size"); std::string interpolatedID = "LINEAR"; if (variable_map.find(interpolation_key) != variable_map.end()) interpolatedID = variable_map[interpolation_key]; //QL_DEBUG(tenor_key << " does not exist. Linear interpolation is used"); yield_ts = CurveManager::instance().get_yield_curve(refDate, periods, data, interpolatedID); return yield_ts; }
IBFRSwap::IBFRSwap(Type type, Real nominal, Date startDate, Period swapTenor, Period paymentTenor, Rate fixedRate, Rate rateSpread, const boost::shared_ptr<RepoChina>& iborIndex) :RepoCompoundingSwap(type, nominal, Schedule(startDate, startDate + swapTenor, paymentTenor, China(), ModifiedFollowing, ModifiedFollowing, DateGeneration::Backward, false), fixedRate, Actual365Fixed(), Schedule(startDate, startDate + swapTenor, paymentTenor, China(), ModifiedFollowing, ModifiedFollowing, DateGeneration::Backward, false), iborIndex, rateSpread, 0.0, Actual360(), Following) {}
Real InterpolatedYoYOptionletStripper<Interpolator1D>:: ObjectiveFunction::operator()(Volatility guess) const { vvec_[1] = guess; vvec_[0] = guess - slope_ * (tvec_[1] - tvec_[0]) * guess; // could have Interpolator1D instead of Linear boost::shared_ptr<InterpolatedYoYOptionletVolatilityCurve<Linear> > vCurve( new InterpolatedYoYOptionletVolatilityCurve<Linear>( 0, TARGET(), ModifiedFollowing, Actual365Fixed(), lag_, frequency_, indexIsInterpolated_, dvec_, vvec_, -1.0, 3.0) ); // strike limits Handle<YoYOptionletVolatilitySurface> hCurve(vCurve); p_->setVolatility(hCurve); // hopefully this gets to the pricer ... then return priceToMatch_ - capfloor_.NPV(); }
boost::shared_ptr<SmileSection> StrippedOptionletAdapter::smileSectionImpl(Time t) const { std::vector< Rate > optionletStrikes = optionletStripper_->optionletStrikes( 0); // strikes are the same for all times ?! std::vector< Real > stddevs; for (Size i = 0; i < optionletStrikes.size(); i++) { stddevs.push_back(volatilityImpl(t, optionletStrikes[i]) * std::sqrt(t)); } // Extrapolation may be a problem with splines, but since minStrike() // and maxStrike() are set, we assume that no one will use stddevs for // strikes outside these strikes CubicInterpolation::BoundaryCondition bc = optionletStrikes.size() >= 4 ? CubicInterpolation::Lagrange : CubicInterpolation::SecondDerivative; return boost::make_shared< InterpolatedSmileSection< Cubic > >( t, optionletStrikes, stddevs, Null< Real >(), Cubic(CubicInterpolation::Spline, false, bc, 0.0, bc, 0.0), Actual365Fixed(), volatilityType(), displacement()); }
void SimpleRangeRateETI::initializeImpl(const TimeGrid& timeGrid, const boost::shared_ptr<YieldTermStructure>& discountCurve, const boost::shared_ptr<PathGeneratorFactory>& pathGenFactory) { this->payoffDateInfo_->initialize(timeGrid,discountCurve,pathGenFactory); for ( Size i=0 ; i < simpleRangeEventList_.size() ; i++ ) { simpleRangeEventList_[i]->initialize(timeGrid,discountCurve,pathGenFactory); } this->rangeNum_ = simpleRangeEventList_.size(); this->assetNum_ = pathGenFactory->numAssets(); Date today = Settings::instance().evaluationDate(); DayCounter dayCounter = Actual365Fixed(); double calculationYearFrac = 0.0; if ( today < calculationEndDate_ ) { calculationYearFrac = dayCounter.yearFraction( calculationStartDate_ , calculationEndDate_ ); } //if ( today < calculationStart_ ) //{ // calculationYearFrac = dayCounter.yearFraction( calculationStart_ , calculationEnd_ ); //} //else if ( today > calculationEnd_ ) //{ // calculationYearFrac = 0.0;//dayCounter.yearFraction( today , calculationEnd_ ); //} //else {} this->yearFrac_ = calculationYearFrac; }
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()); } }
Jibar(const Period& tenor, const Handle<YieldTermStructure>& h = Handle<YieldTermStructure>()) : IborIndex("Jibar", tenor, 0, ZARCurrency(), SouthAfrica(), ModifiedFollowing, false, Actual365Fixed(), h) {}
void qlMultiAssetCompositeOptionFactory::factoryMultiAssetCompositeOption() { //TiXmlText* rootNode = new TiXmlText(instInfo_.c_str()); TiXmlDocument document; document.Parse(instInfo_.c_str(), 0, TIXML_ENCODING_UTF8); //rootNode.SetValue; TiXmlNode* instNode = document.FirstChild("instrument"); std::string code = instNode->FirstChild("code")->ToElement()->GetText(); FpmlSerialized::Instrument xml_instrument = FpmlSerialized::Instrument(instNode); //boost::shared_ptr<FpmlSerialized::InstPositionInfo> xml_positionInfo = xml_instrument.getInstPositionInfo(); //this->krCode_ = xml_positionInfo->getKrCode()->SValue(); boost::shared_ptr<FpmlSerialized::Excel_interface> xml_interface = xml_instrument.getExcel_interface(); boost::shared_ptr<FpmlSerialized::Excel_multiAssetCompositeOption> xml_multiAssetCompOption = xml_interface->getExcel_multiAssetCompositeOption(); DayCounter daycounter = Actual365Fixed(); Calendar calendar = SouthKorea(); // ? boost::shared_ptr<FpmlSerialized::Excel_noteInfo> xml_noteInfo = xml_multiAssetCompOption->getExcel_issueInfo()->getExcel_noteInfo(); //Date tradeDate = xml_noteInfo->getTradeDate()->dateValue(); Date effectiveDate = xml_noteInfo->getEffectiveDate()->dateValue(); Date maturityDate = xml_noteInfo->getMaturityDate()->dateValue(); notional_ = xml_noteInfo->getNotional()->DValue(); std::vector<boost::shared_ptr<FpmlSerialized::Excel_multiAsset_compositeOption_subtype>> xml_multiAssetCompOptionSubList = xml_multiAssetCompOption->getExcel_multiAsset_compositeOption_subtype(); std::vector<boost::shared_ptr<QuantLib::EventTriggerInfo>> ql_etiList; qlEventTriggerInfoFactory qetif = qlEventTriggerInfoFactory(); for(Size i = 0 ; i<xml_multiAssetCompOptionSubList.size(); ++i ) { const boost::shared_ptr<EventTriggerInfo>& ql_eti = qetif.multiAssetCompOptionSubType(xml_multiAssetCompOptionSubList[i]); ql_etiList.push_back(ql_eti); } qlFixingDateInfoFactory ql_fdf = qlFixingDateInfoFactory(); Real notionalPayment = xml_multiAssetCompOption->getNotionalMaturityPayment()->DValue(); Date notionalPayment_PayoffDate = xml_multiAssetCompOption->getPayoffDate()->dateValue(); const boost::shared_ptr<QuantLib::FixingDateInfo>& ql_fdi = ql_fdf.fixingDateInfo(notionalPayment_PayoffDate); /*const boost::shared_ptr<MCPricer>& pricer*/ this->pricer_ = boost::shared_ptr<CompositeSumOptionPricer>( new CompositeSumOptionPricer(notionalPayment, ql_fdi, ql_etiList)); // --------------------------------- Engine --------------------------------------------- //boost::shared_ptr<FpmlSerialized::Excel_underlyingCalcInfo_para> xml_underlyingCalcInfo_para = xml_hifive->getExcel_underlyingCalcInfo(); const boost::shared_ptr<NoteInst>& noteInst = boost::shared_ptr<NoteInst>( new NoteInst(code,notional_, effectiveDate, maturityDate, daycounter, calendar)); this->engine_ = engine(); noteInst->setPricingEngine(this->engine_); this->instrument_ = noteInst; //std::cout << "Start" << std::endl; //inst_->setPricingEngine(elsEngine); //std::cout << "Eu price : " << els100.NPV() << std::endl; //std::cout << "Calculation End" << std::endl; }
boost::shared_ptr<SwaptionVolatilityStructure> ProcessInfo::ProcessParser_Impl:: make_swaption_vol_ts(std::map<std::string, std::string>& variable_map, std::map<std::string, std::vector<std::string>>& variable_array_map, std::map<std::string, Matrix>& variable_matrix_map) { boost::shared_ptr<SwaptionVolatilityStructure> swaption_vol_ts; Date refDate = Settings::instance().evaluationDate(); const Calendar& calendar = NullCalendar(); BusinessDayConvention bdc = BusinessDayConvention::ModifiedFollowing; DayCounter daycounter = Actual365Fixed(); std::string type_key = "SWAPTION_TYPE"; if (variable_map.find(type_key) == variable_map.end()) QL_FAIL(type_key << " does not exist."); std::string vol_type = variable_map[type_key]; if (vol_type == "CONSTANT") { std::string swaption_flat_vol_key = "SWAP_VOL_CONSTANT"; if (variable_array_map.find(swaption_flat_vol_key) == variable_array_map.end()) QL_FAIL(swaption_flat_vol_key << " does not exist."); Real flatVol = 0.0; swaption_vol_ts = boost::shared_ptr<SwaptionVolatilityStructure>( new ConstantSwaptionVolatility(refDate, calendar, bdc, flatVol, daycounter)); } else if (vol_type == "SURFACE") { std::string optionTenor_key = "SWAPTION_VOL_SURFACE_OPTIONTENOR"; std::string swapTenor_key = "SWAPTION_VOL_SURFACE_SWAPTENOR"; std::string value_key = "SWAPTION_VOL_SURFACE_VALUE"; if (variable_array_map.find(optionTenor_key) == variable_array_map.end()) QL_FAIL(optionTenor_key << " does not exist."); if (variable_array_map.find(swapTenor_key) == variable_array_map.end()) QL_FAIL(swapTenor_key << " does not exist."); if (variable_matrix_map.find(value_key) == variable_matrix_map.end()) QL_FAIL(value_key << " does not exist."); std::vector<std::string> optionTenors = variable_array_map[optionTenor_key]; std::vector<std::string> swapTenors = variable_array_map[swapTenor_key]; Matrix value_matrix = variable_matrix_map[value_key]; std::vector<Period> optionPeriod_data; std::vector<Period> swapPeriod_data; for (Size i = 0; i < optionTenors.size(); i++) optionPeriod_data.push_back(PeriodParser::parse(optionTenors[i])); for (Size i = 0; i < swapTenors.size(); i++) swapPeriod_data.push_back(PeriodParser::parse(swapTenors[i])); // converting QL_REQUIRE(optionTenors.size() * swapTenors.size() == value_matrix.rows() * value_matrix.columns(), "tenor * strike must be same to value matrix size"); //std::string interpolatedID = "LINEAR"; //if (variable_map.find(interpolation_key) != variable_map.end()) // interpolatedID = variable_map[interpolation_key]; //QL_DEBUG(tenor_key << " does not exist. Linear interpolation is used"); swaption_vol_ts = boost::shared_ptr<SwaptionVolatilityStructure>( new SwaptionVolatilityMatrix(refDate, calendar, bdc, optionPeriod_data, swapPeriod_data, value_matrix, daycounter)); } else if (vol_type == "CUBE") { QL_FAIL("not implemeted"); } else { } return swaption_vol_ts; }
explicit Aonia(const Handle<YieldTermStructure>& h = Handle<YieldTermStructure>()) : OvernightIndex("Aonia", 0, AUDCurrency(), Australia(), Actual365Fixed(), h) {}
void VannaVolgaDoubleBarrierEngine::calculate() const { const Real sigmaShift_vega = 0.001; const Real sigmaShift_volga = 0.0001; const Real spotShift_delta = 0.0001 * spotFX_->value(); const Real sigmaShift_vanna = 0.0001; Handle<Quote> x0Quote( //used for shift boost::make_shared<SimpleQuote>(spotFX_->value())); Handle<Quote> atmVolQuote( //used for shift boost::make_shared<SimpleQuote>(atmVol_->value())); boost::shared_ptr<BlackVolTermStructure> blackVolTS = boost::make_shared<BlackConstantVol>( Settings::instance().evaluationDate(), NullCalendar(), atmVolQuote, Actual365Fixed()); boost::shared_ptr<BlackScholesMertonProcess> stochProcess = boost::make_shared<BlackScholesMertonProcess>( x0Quote, foreignTS_, domesticTS_, Handle<BlackVolTermStructure>(blackVolTS)); boost::shared_ptr<PricingEngine> engineBS = boost::make_shared<AnalyticDoubleBarrierEngine>(stochProcess, series_); BlackDeltaCalculator blackDeltaCalculatorAtm( Option::Call, atmVol_->deltaType(), x0Quote->value(), domesticTS_->discount(T_), foreignTS_->discount(T_), atmVol_->value() * sqrt(T_)); Real atmStrike = blackDeltaCalculatorAtm.atmStrike(atmVol_->atmType()); Real call25Vol = vol25Call_->value(); Real put25Vol = vol25Put_->value(); BlackDeltaCalculator blackDeltaCalculatorPut25( Option::Put, vol25Put_->deltaType(), x0Quote->value(), domesticTS_->discount(T_), foreignTS_->discount(T_), put25Vol * sqrt(T_)); Real put25Strike = blackDeltaCalculatorPut25.strikeFromDelta(-0.25); BlackDeltaCalculator blackDeltaCalculatorCall25( Option::Call, vol25Call_->deltaType(), x0Quote->value(), domesticTS_->discount(T_), foreignTS_->discount(T_), call25Vol * sqrt(T_)); Real call25Strike = blackDeltaCalculatorCall25.strikeFromDelta(0.25); //here use vanna volga interpolated smile to price vanilla std::vector<Real> strikes; std::vector<Real> vols; strikes.push_back(put25Strike); vols.push_back(put25Vol); strikes.push_back(atmStrike); vols.push_back(atmVol_->value()); strikes.push_back(call25Strike); vols.push_back(call25Vol); VannaVolga vannaVolga(x0Quote->value(), foreignTS_->discount(T_), foreignTS_->discount(T_), T_); Interpolation interpolation = vannaVolga.interpolate(strikes.begin(), strikes.end(), vols.begin()); interpolation.enableExtrapolation(); const boost::shared_ptr<StrikedTypePayoff> payoff = boost::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff); Real strikeVol = interpolation(payoff->strike()); //vannila option price Real vanillaOption = blackFormula(payoff->optionType(), payoff->strike(), x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_), strikeVol * sqrt(T_), domesticTS_->discount(T_)); //already out if((x0Quote->value() > arguments_.barrier[1] || x0Quote->value() < arguments_.barrier[0]) && arguments_.barrierType[0] == Barrier::DownOut) { results_.value = 0.0; results_.additionalResults["VanillaPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; results_.additionalResults["BarrierInPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; results_.additionalResults["BarrierOutPrice"] = 0.0; } //already in else if((x0Quote->value() > arguments_.barrier[1] || x0Quote->value() < arguments_.barrier[0]) && arguments_.barrierType[0] == Barrier::DownIn) { results_.value = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; results_.additionalResults["VanillaPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; results_.additionalResults["BarrierInPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption; results_.additionalResults["BarrierOutPrice"] = 0.0; } else { //set up BS barrier option pricing //only calculate out barrier option price // in barrier price = vanilla - out barrier boost::shared_ptr<StrikedTypePayoff> payoff = boost::static_pointer_cast<StrikedTypePayoff> (arguments_.payoff); DoubleBarrierOption doubleBarrierOption(arguments_.barrierType, arguments_.barrier, arguments_.rebate, payoff, arguments_.exercise); doubleBarrierOption.setPricingEngine(engineBS); //BS price Real priceBS = doubleBarrierOption.NPV(); Real priceAtmCallBS = blackFormula(Option::Call,atmStrike, x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_), atmVol_->value() * sqrt(T_), domesticTS_->discount(T_)); Real price25CallBS = blackFormula(Option::Call,call25Strike, x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_), atmVol_->value() * sqrt(T_), domesticTS_->discount(T_)); Real price25PutBS = blackFormula(Option::Put,put25Strike, x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_), atmVol_->value() * sqrt(T_), domesticTS_->discount(T_)); //market price Real priceAtmCallMkt = blackFormula(Option::Call,atmStrike, x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_), atmVol_->value() * sqrt(T_), domesticTS_->discount(T_)); Real price25CallMkt = blackFormula(Option::Call,call25Strike, x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_), call25Vol * sqrt(T_), domesticTS_->discount(T_)); Real price25PutMkt = blackFormula(Option::Put,put25Strike, x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_), put25Vol * sqrt(T_), domesticTS_->discount(T_)); //Analytical Black Scholes formula NormalDistribution norm; Real d1atm = (std::log(x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_)/atmStrike) + 0.5*std::pow(atmVolQuote->value(),2.0) * T_)/(atmVolQuote->value() * sqrt(T_)); Real vegaAtm_Analytical = x0Quote->value() * norm(d1atm) * sqrt(T_) * foreignTS_->discount(T_); Real vannaAtm_Analytical = vegaAtm_Analytical/x0Quote->value() *(1.0 - d1atm/(atmVolQuote->value()*sqrt(T_))); Real volgaAtm_Analytical = vegaAtm_Analytical * d1atm * (d1atm - atmVolQuote->value() * sqrt(T_))/atmVolQuote->value(); Real d125call = (std::log(x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_)/call25Strike) + 0.5*std::pow(atmVolQuote->value(),2.0) * T_)/(atmVolQuote->value() * sqrt(T_)); Real vega25Call_Analytical = x0Quote->value() * norm(d125call) * sqrt(T_) * foreignTS_->discount(T_); Real vanna25Call_Analytical = vega25Call_Analytical/x0Quote->value() *(1.0 - d125call/(atmVolQuote->value()*sqrt(T_))); Real volga25Call_Analytical = vega25Call_Analytical * d125call * (d125call - atmVolQuote->value() * sqrt(T_))/atmVolQuote->value(); Real d125Put = (std::log(x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_)/put25Strike) + 0.5*std::pow(atmVolQuote->value(),2.0) * T_)/(atmVolQuote->value() * sqrt(T_)); Real vega25Put_Analytical = x0Quote->value() * norm(d125Put) * sqrt(T_) * foreignTS_->discount(T_); Real vanna25Put_Analytical = vega25Put_Analytical/x0Quote->value() *(1.0 - d125Put/(atmVolQuote->value()*sqrt(T_))); Real volga25Put_Analytical = vega25Put_Analytical * d125Put * (d125Put - atmVolQuote->value() * sqrt(T_))/atmVolQuote->value(); //BS vega boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() + sigmaShift_vega); doubleBarrierOption.recalculate(); Real vegaBarBS = (doubleBarrierOption.NPV() - priceBS)/sigmaShift_vega; boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() - sigmaShift_vega);//setback //BS volga //vegaBar2 //base NPV boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() + sigmaShift_volga); doubleBarrierOption.recalculate(); Real priceBS2 = doubleBarrierOption.NPV(); //shifted npv boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() + sigmaShift_vega); doubleBarrierOption.recalculate(); Real vegaBarBS2 = (doubleBarrierOption.NPV() - priceBS2)/sigmaShift_vega; Real volgaBarBS = (vegaBarBS2 - vegaBarBS)/sigmaShift_volga; boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() - sigmaShift_volga - sigmaShift_vega);//setback //BS Delta //base delta boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() + spotShift_delta);//shift forth doubleBarrierOption.recalculate(); Real priceBS_delta1 = doubleBarrierOption.NPV(); boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() - 2 * spotShift_delta);//shift back doubleBarrierOption.recalculate(); Real priceBS_delta2 = doubleBarrierOption.NPV(); boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() + spotShift_delta);//set back Real deltaBar1 = (priceBS_delta1 - priceBS_delta2)/(2.0*spotShift_delta); //shifted vanna boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() + sigmaShift_vanna);//shift sigma //shifted delta boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() + spotShift_delta);//shift forth doubleBarrierOption.recalculate(); priceBS_delta1 = doubleBarrierOption.NPV(); boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() - 2 * spotShift_delta);//shift back doubleBarrierOption.recalculate(); priceBS_delta2 = doubleBarrierOption.NPV(); boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() + spotShift_delta);//set back Real deltaBar2 = (priceBS_delta1 - priceBS_delta2)/(2.0*spotShift_delta); Real vannaBarBS = (deltaBar2 - deltaBar1)/sigmaShift_vanna; boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() - sigmaShift_vanna);//set back //Matrix Matrix A(3,3,0.0); //analytical A[0][0] = vegaAtm_Analytical; A[0][1] = vega25Call_Analytical; A[0][2] = vega25Put_Analytical; A[1][0] = vannaAtm_Analytical; A[1][1] = vanna25Call_Analytical; A[1][2] = vanna25Put_Analytical; A[2][0] = volgaAtm_Analytical; A[2][1] = volga25Call_Analytical; A[2][2] = volga25Put_Analytical; Array b(3,0.0); b[0] = vegaBarBS; b[1] = vannaBarBS; b[2] = volgaBarBS; Array q = inverse(A) * b; Real H = arguments_.barrier[1]; Real L = arguments_.barrier[0]; Real theta_tilt_minus = ((domesticTS_->zeroRate(T_, Continuous) - foreignTS_->zeroRate(T_, Continuous))/atmVol_->value() - atmVol_->value()/2.0)*std::sqrt(T_); Real h = 1.0/atmVol_->value() * std::log(H/x0Quote->value())/std::sqrt(T_); Real l = 1.0/atmVol_->value() * std::log(L/x0Quote->value())/std::sqrt(T_); CumulativeNormalDistribution cnd; Real doubleNoTouch = 0.0; for(int j = -series_; j< series_; j++ ) { Real e_minus = 2*j*(h-l) - theta_tilt_minus; doubleNoTouch += std::exp(-2.0*j*theta_tilt_minus*(h-l))*(cnd(h+e_minus) - cnd(l+e_minus)) - std::exp(-2.0*j*theta_tilt_minus*(h-l)+2.0*theta_tilt_minus*h)*(cnd(h-2.0*h+e_minus) - cnd(l-2.0*h+e_minus)); } Real p_survival = doubleNoTouch; Real lambda = p_survival ; Real adjust = q[0]*(priceAtmCallMkt - priceAtmCallBS) + q[1]*(price25CallMkt - price25CallBS) + q[2]*(price25PutMkt - price25PutBS); Real outPrice = priceBS + lambda*adjust;// Real inPrice; //adapt Vanilla delta if(adaptVanDelta_ == true) { outPrice += lambda*(bsPriceWithSmile_ - vanillaOption); //capfloored by (0, vanilla) outPrice = std::max(0.0, std::min(bsPriceWithSmile_, outPrice)); inPrice = bsPriceWithSmile_ - outPrice; } else { //capfloored by (0, vanilla) outPrice = std::max(0.0, std::min(vanillaOption , outPrice)); inPrice = vanillaOption - outPrice; } if(arguments_.barrierType[0] == Barrier::DownOut) results_.value = outPrice; else results_.value = inPrice; results_.additionalResults["VanillaPrice"] = vanillaOption; results_.additionalResults["BarrierInPrice"] = inPrice; results_.additionalResults["BarrierOutPrice"] = outPrice; results_.additionalResults["lambda"] = lambda; } }
void setConventions() { calendar = TARGET(); optionBdc = ModifiedFollowing; dayCounter = Actual365Fixed(); }
MakeVanillaSwap::operator ext::shared_ptr<VanillaSwap>() const { Date startDate; if (effectiveDate_ != Date()) startDate = effectiveDate_; else { Date refDate = Settings::instance().evaluationDate(); // if the evaluation date is not a business day // then move to the next business day refDate = floatCalendar_.adjust(refDate); Date spotDate = floatCalendar_.advance(refDate, settlementDays_*Days); startDate = spotDate+forwardStart_; if (forwardStart_.length()<0) startDate = floatCalendar_.adjust(startDate, Preceding); else startDate = floatCalendar_.adjust(startDate, Following); } Date endDate = terminationDate_; if (endDate == Date()) { if (floatEndOfMonth_) endDate = floatCalendar_.advance(startDate, swapTenor_, ModifiedFollowing, floatEndOfMonth_); else endDate = startDate + swapTenor_; } const Currency& curr = iborIndex_->currency(); Period fixedTenor; if (fixedTenor_ != Period()) fixedTenor = fixedTenor_; else { if ((curr == EURCurrency()) || (curr == USDCurrency()) || (curr == CHFCurrency()) || (curr == SEKCurrency()) || (curr == GBPCurrency() && swapTenor_ <= 1 * Years)) fixedTenor = Period(1, Years); else if ((curr == GBPCurrency() && swapTenor_ > 1 * Years) || (curr == JPYCurrency()) || (curr == AUDCurrency() && swapTenor_ >= 4 * Years)) fixedTenor = Period(6, Months); else if ((curr == HKDCurrency() || (curr == AUDCurrency() && swapTenor_ < 4 * Years))) fixedTenor = Period(3, Months); else QL_FAIL("unknown fixed leg default tenor for " << curr); } Schedule fixedSchedule(startDate, endDate, fixedTenor, fixedCalendar_, fixedConvention_, fixedTerminationDateConvention_, fixedRule_, fixedEndOfMonth_, fixedFirstDate_, fixedNextToLastDate_); Schedule floatSchedule(startDate, endDate, floatTenor_, floatCalendar_, floatConvention_, floatTerminationDateConvention_, floatRule_, floatEndOfMonth_, floatFirstDate_, floatNextToLastDate_); DayCounter fixedDayCount; if (fixedDayCount_ != DayCounter()) fixedDayCount = fixedDayCount_; else { if (curr == USDCurrency()) fixedDayCount = Actual360(); else if (curr == EURCurrency() || curr == CHFCurrency() || curr == SEKCurrency()) fixedDayCount = Thirty360(Thirty360::BondBasis); else if (curr == GBPCurrency() || curr == JPYCurrency() || curr == AUDCurrency() || curr == HKDCurrency()) fixedDayCount = Actual365Fixed(); else QL_FAIL("unknown fixed leg day counter for " << curr); } Rate usedFixedRate = fixedRate_; if (fixedRate_ == Null<Rate>()) { VanillaSwap temp(type_, nominal_, fixedSchedule, 0.0, // fixed rate fixedDayCount, floatSchedule, iborIndex_, floatSpread_, floatDayCount_); if (engine_ == 0) { Handle<YieldTermStructure> disc = iborIndex_->forwardingTermStructure(); QL_REQUIRE(!disc.empty(), "null term structure set to this instance of " << iborIndex_->name()); bool includeSettlementDateFlows = false; ext::shared_ptr<PricingEngine> engine(new DiscountingSwapEngine(disc, includeSettlementDateFlows)); temp.setPricingEngine(engine); } else temp.setPricingEngine(engine_); usedFixedRate = temp.fairRate(); } ext::shared_ptr<VanillaSwap> swap(new VanillaSwap(type_, nominal_, fixedSchedule, usedFixedRate, fixedDayCount, floatSchedule, iborIndex_, floatSpread_, floatDayCount_)); if (engine_ == 0) { Handle<YieldTermStructure> disc = iborIndex_->forwardingTermStructure(); bool includeSettlementDateFlows = false; ext::shared_ptr<PricingEngine> engine(new DiscountingSwapEngine(disc, includeSettlementDateFlows)); swap->setPricingEngine(engine); } else swap->setPricingEngine(engine_); return swap; }