//! Annuity at time 0 double LmmVanillaSwapPricer::annuity0(const VanillaSwap& vanillaSwap, const std::vector<double>& liborsInitValue) const { assert(pLMMTenorStructure_->get_horizon()+1 == liborsInitValue.size()); assert(pLMMTenorStructure_->get_horizon() >= vanillaSwap.get_indexEnd()); // if not cannot price this swap; size_t horizon = pLMMTenorStructure_->get_horizon(); const double & fixedLegdelta_T = vanillaSwap.get_fixedLegTenorType().YearFraction(); const double & floatingLegdelta_T = vanillaSwap.get_floatingLegTenorType().YearFraction(); //! ZC[i] = P(T_0,T_i) std::vector<double> ZC(vanillaSwap.get_indexEnd()+1); ZC[0] = 1.0; for(size_t i=1; i<ZC.size(); ++i) { size_t indexLibor = i-1; //double deltaT = vanillaSwap.get_DeltaTFloatLeg(indexLibor); // YY bug double deltaT = floatingLegdelta_T; ZC[i] = ZC[i-1]/(1+deltaT*liborsInitValue[indexLibor]); } double price = 0.0; const std::vector<LMM::Index>& fixedLegPaymentIndexSchedule = vanillaSwap.get_fixedLegPaymentIndexSchedule(); for(size_t itr = 0; itr < fixedLegPaymentIndexSchedule.size(); ++itr) { size_t fixedLegPaymentIndex = fixedLegPaymentIndexSchedule[itr]; double delta_T = vanillaSwap.get_DeltaTFixedLeg(itr); //std::cout << "numeraire[indexValuationDate]/numeraire[fixedLegPaymentIndex] = " << numeraire[indexValuationDate]/numeraire[fixedLegPaymentIndex] << std::endl; price += delta_T*ZC[fixedLegPaymentIndex]; } return price; }
double LmmVanillaSwapPricer::swapRate_Analytical(const VanillaSwap& vanillaSwap, const std::vector<double>& liborsInitValue) const { assert(pLMMTenorStructure_->get_horizon()+1 == liborsInitValue.size()); assert(pLMMTenorStructure_->get_horizon() >= vanillaSwap.get_indexEnd()); // if not cannot price this swap; size_t horizon = pLMMTenorStructure_->get_horizon(); const double & fixedLegdelta_T = vanillaSwap.get_fixedLegTenorType().YearFraction(); const double & floatingLegdelta_T = vanillaSwap.get_floatingLegTenorType().YearFraction(); //! ZC[i] = P(T_0,T_i) std::vector<double> ZC(vanillaSwap.get_indexEnd()+1); ZC[0] = 1.0; for(size_t i=1; i<ZC.size(); ++i) { size_t indexLibor = i-1; //double deltaT = vanillaSwap.get_DeltaTFloatLeg(indexLibor); // YY bug double deltaT = floatingLegdelta_T; ZC[i] = ZC[i-1]/(1+deltaT*liborsInitValue[indexLibor]); } //! pvFloatingLeg: 1 - 1 double pvFloatingLegValue = ZC[vanillaSwap.get_indexStart()] - ZC[vanillaSwap.get_indexEnd()]; //! pvAnnuity double pvAnnuity = annuity0(vanillaSwap, liborsInitValue); //! swapRate return pvFloatingLegValue / pvAnnuity; }
UpperTriangularIndexPairMatrix UpperTriangleVanillaSwaptionQuotes::get_UpperTriangularSwaptionIndexMatrix() const { if(LMM::WARNLMM ()) std::cout<<LMM::WARN_MSG << "UpperTriangleVanillaSwaptionQuotes::get_UpperTriangularSwaptionIndexMatrix() generate matrix copy, DO NOT USE IN A LOOP" << std::endl; size_t nbRow = upperTriangleVanillaSwaptionQuotes_.size1(); size_t nbCol = upperTriangleVanillaSwaptionQuotes_.size2(); assert(nbRow == nbCol); UpperTriangularIndexPairMatrix swap_indices_matrix(nbRow,nbCol ); for(size_t k=0;k<nbRow;++k)//not use first row firt column { swap_indices_matrix(0,k)=std::pair<size_t,size_t>(-1,-1); swap_indices_matrix(k,0)=std::pair<size_t,size_t>(-1,-1); } for(size_t iExpirity = 1; iExpirity<nbRow; ++iExpirity) // row { for(size_t jTenor = 1; jTenor<nbCol-iExpirity; ++jTenor) // col { std::pair<size_t,size_t> swap_pair_indice; const VanillaSwap swap = upperTriangleVanillaSwaptionQuotes_(iExpirity,jTenor).first.getUnderlyingSwap(); swap_pair_indice.first = swap.get_indexStart(); swap_pair_indice.second = swap.get_indexEnd(); swap_indices_matrix(iExpirity,jTenor) = swap_pair_indice; } } return swap_indices_matrix; }
double LmmVanillaSwapPricer::pvFixedLeg( const LMM::Index indexValuationDate, const VanillaSwap & vanillaSwap, const std::vector<double> & numeraire) const { assert(indexValuationDate <= vanillaSwap.get_indexStart()); //YY TODO: this test too slow, esp: within MC simulation assert(pLMMTenorStructure_->get_horizon() >= vanillaSwap.get_indexEnd()); // if not cannot price this swap; const double calculatedAnuity = this->annuity(indexValuationDate,vanillaSwap,numeraire); return vanillaSwap.get_strike()*calculatedAnuity; }
double LmmVanillaSwapPricer::swapNPV_Analytical_2(const VanillaSwap& vanillaSwap, const std::vector<double>& liborsInitValue) const // initLibor[i] = L_i[T_0] { assert(pLMMTenorStructure_->get_horizon()+1 == liborsInitValue.size()); assert(pLMMTenorStructure_->get_horizon() >= vanillaSwap.get_indexEnd()); // if not cannot price this swap; size_t horizon = pLMMTenorStructure_->get_horizon(); const double & floatingLegdelta_T = vanillaSwap.get_floatingLegTenorType().YearFraction(); const double & fixedLegdelta_T = vanillaSwap.get_fixedLegTenorType().YearFraction(); //! ZC[i] = P(T_0,T_i) std::vector<double> ZC(horizon+2); ZC[0] = 1.0; for(size_t i=1; i<ZC.size(); ++i) { ZC[i] = ZC[i-1]/(1+floatingLegdelta_T*liborsInitValue[i-1]); } //! numeraire std::vector<double> numeraire(ZC.size() ); // determinisitc IR for(size_t i=0; i<ZC.size(); ++i) { numeraire[i] = 1.0/ZC[i]; } //! pvFloatingLeg: 1 - 1 const std::vector<LMM::Index>& floatingLegPaymentIndexSchedule = vanillaSwap.get_floatingLegPaymentIndexSchedule(); //size_t floatingLegTenorLmmTenorRatio = vanillaSwap.get_floatingLegTenorLmmTenorRatio(); LMM::Index indexFloatingLegStart = floatingLegPaymentIndexSchedule.front(); LMM::Index indexFloatingLegEnd = floatingLegPaymentIndexSchedule.back(); double pvFloatingLegValue = ZC[indexFloatingLegStart-1] - ZC[indexFloatingLegEnd]; ////! pvFloatingLeg: exact //double pvFloatingLeg = 0.0; //const std::vector<LMM::Index>& floatingLegPaymentIndexSchedule = vanillaSwap.get_floatingLegPaymentIndexSchedule(); //for(size_t itr = 0; itr < floatingLegPaymentIndexSchedule.size(); ++itr) //{ // //! At time T_{i+1}, pay: L_i(T_i) // size_t floatingLegPaymentIndex = floatingLegPaymentIndexSchedule[itr]; // = i+1 // size_t indexLibor = floatingLegPaymentIndex-1; // =i, because : floatingTenor = lmmTenor // pvFloatingLeg += floatingLegdelta_T*initLibor[indexLibor]*ZC[floatingLegPaymentIndex]; //} LMM::Index indexValuationDate = 0; double pvFixedLegValue = pvFixedLeg(indexValuationDate,vanillaSwap,numeraire); return pvFloatingLegValue - pvFixedLegValue; }
double LmmVanillaSwapPricer::annuity( const LMM::Index indexValuationDate, const VanillaSwap & vanillaSwap, const std::vector<double> & numeraire) const { assert(indexValuationDate <= vanillaSwap.get_indexStart()); //YY TODO: this test too slow, esp: within MC simulation assert(pLMMTenorStructure_->get_horizon() >= vanillaSwap.get_indexEnd()); // if not cannot price this swap; double price = 0.0; const std::vector<LMM::Index>& fixedLegPaymentIndexSchedule = vanillaSwap.get_fixedLegPaymentIndexSchedule(); for(size_t itr = 0; itr < fixedLegPaymentIndexSchedule.size(); ++itr) { size_t fixedLegPaymentIndex = fixedLegPaymentIndexSchedule[itr]; double delta_T = vanillaSwap.get_DeltaTFixedLeg(itr); //std::cout << "numeraire[indexValuationDate]/numeraire[fixedLegPaymentIndex] = " << numeraire[indexValuationDate]/numeraire[fixedLegPaymentIndex] << std::endl; price += delta_T*numeraire[indexValuationDate]/numeraire[fixedLegPaymentIndex]; } return price; }