예제 #1
0
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 McLmmVanillaSwaptionPricer::price(const VanillaSwaption& vanillaSwaption, size_t nbSimulation)  const
{
	clock_t start_pricing = std::clock();
	assert( mcLmm_->get_lmm()->get_LMMTenorStructure()->get_tenorType() == vanillaSwaption.get_lmmTenorStructureTenorType()); // this pricer can price this swaption

	VanillaSwap vanillaSwap = vanillaSwaption.getUnderlyingSwap();

	double result   = 0.0;
	double variance = 0.0;

	LMM::Index indexValuationdate = 0;
	LMM::Index indexMaturity = vanillaSwaption.get_indexMaturity();

	for(size_t itrSimulation=0; itrSimulation<nbSimulation; ++itrSimulation)
	{
		mcLmm_->simulateLMM();  // YY TODO: not efficient at all, don't need to do all the simulation ... 
		const matrix& liborMatrix  = mcLmm_->get_liborMatrix();
		const std::vector<double>& numeraire = mcLmm_->get_numeraire();
		double npvFloatingLeg      = pvFloatingLeg(indexMaturity, vanillaSwap, numeraire, liborMatrix);
		double npvFixedLeg         = pvFixedLeg   (indexMaturity, vanillaSwap, numeraire);
		double payoffAtMaturity    = vanillaSwaption.payoff(npvFloatingLeg,npvFixedLeg);
		double value               = payoffAtMaturity * numeraire[indexValuationdate]/numeraire[indexMaturity];
		result					  += value;

		variance += value*value;
	}
	result /= nbSimulation; 

	clock_t end_pricing = std::clock();
	double pricing_duration = double(end_pricing - start_pricing) / CLOCKS_PER_SEC;

	if(LMM::DEUBGLMM())
	{
		variance = (variance/nbSimulation-result*result);	
		std::cout << LMM::NOTIF_MSG 
			      << " mcScheme = " << MCSchemeType::mcSchemeType2String(mcLmm_->get_mcSchemeType())
			      << ", nbSimualtion = " << nbSimulation
				  << ", Pricing Time = " << pricing_duration
				  << ", SwaptionPriceMC = " << result
			      << ",  99% confidential interval = " << 2.57*std::sqrt(variance / nbSimulation) << std::endl;
	}

	return result;
}