Example #1
0
 virtual void updatePath(const std::vector<std::pair<Date, Real> >  &events, NotionalPath &path) const
 {
     path.reset();
     Real losses = 0;
     Real previousNotional = 1;
     for(size_t i=0; i<events.size(); ++i)
     {
         losses+=events[i].second;
         if(losses>attachement_ && previousNotional>0)
         {
             previousNotional = std::max(0.0, (exhaustion_-losses)/(exhaustion_-attachement_));
             path.addReduction(paymentOffset_->paymentDate(events[i].first), previousNotional);
         }
     }
 }
    Real MonteCarloCatBondEngine::npv(bool includeSettlementDateFlows, Date settlementDate, Date npvDate, Real& lossProbability, Real &exhaustionProbability, Real& expectedLoss) const
    {
        const size_t MAX_PATHS = 10000; //TODO
        lossProbability =  0.0;
        exhaustionProbability = 0.0;
        expectedLoss = 0.0;
        if (arguments_.cashflows.empty())
            return 0.0;

        if (settlementDate == Date())
            settlementDate = Settings::instance().evaluationDate();

        if (npvDate == Date())
            npvDate = settlementDate;

        Real totalNPV = 0.0;
        Date effectiveDate = std::max(arguments_.startDate, settlementDate);
        Date maturityDate = (*arguments_.cashflows.rbegin())->date();
        boost::shared_ptr<CatSimulation> catSimulation = catRisk_->newSimulation(effectiveDate, maturityDate);
        std::vector<std::pair<Date, Real> > eventsPath;
        NotionalPath notionalPath;
        Real riskFreeNPV = pathNpv(includeSettlementDateFlows, settlementDate, notionalPath);
        size_t pathCount=0;
        while(catSimulation->nextPath(eventsPath) && pathCount<MAX_PATHS)
        {
            arguments_.notionalRisk->updatePath(eventsPath, notionalPath);
            if(notionalPath.loss()>0) { //optimization, most paths will not include any loss
                totalNPV += pathNpv(includeSettlementDateFlows, settlementDate, notionalPath);
                lossProbability+=1;
                if (notionalPath.loss()==1) 
                    exhaustionProbability+=1;
                expectedLoss+=notionalPath.loss();
            } else {
                totalNPV += riskFreeNPV;
            }
            pathCount++;
        }
        lossProbability/=pathCount;
        exhaustionProbability/=pathCount;
        expectedLoss/=pathCount;
        return totalNPV/(pathCount*discountCurve_->discount(npvDate));
    }
    CatBond::results MonteCarloCatBondEngine::npv(bool includeSettlementDateFlows, 
												  Date settlementDate, 
									              Date npvDate) const
    {
	    const size_t MAX_PATHS = 10000; //TODO
		CatBond::results result;
		result.reset();

        double lossProbability =  0.0;
        double exhaustionProbability = 0.0;
        double expectedLoss = 0.0;
		//GenericRiskStatistics<GeneralStatistics> statistics;
		GeneralStatistics statistics;
        if (arguments_.cashflows.empty()) {
			 return result;
		}

        if (settlementDate == Date())
            settlementDate = Settings::instance().evaluationDate();

        if (npvDate == Date())
            npvDate = settlementDate;

        Real totalNPV = 0.0;
        Date effectiveDate = std::max(arguments_.startDate, settlementDate);
        Date maturityDate = (*arguments_.cashflows.rbegin())->date();
        auto catSimulation = catRisk_->newSimulation(effectiveDate, maturityDate);
        std::vector<std::pair<Date, Real> > eventsPath;
        NotionalPath notionalPath;
        Real riskFreeNPV = pathNpv(includeSettlementDateFlows, settlementDate, notionalPath);
        size_t pathCount=0;
        while(catSimulation->nextPath(eventsPath) && pathCount<MAX_PATHS)
        {
            arguments_.notionalRisk->updatePath(eventsPath, notionalPath);
            if(notionalPath.loss()>0) { //optimization, most paths will not include any loss
				double thisNpv = pathNpv(includeSettlementDateFlows, settlementDate, notionalPath);
                totalNPV += thisNpv;
                lossProbability+=1;
                if (notionalPath.loss()==1) 
                    exhaustionProbability+=1;
                expectedLoss+=notionalPath.loss();
				statistics.add(thisNpv, 1.0);
            } else {
                totalNPV += riskFreeNPV;
				statistics.add(riskFreeNPV, 1.0);
            }
            pathCount++;
        }
        lossProbability/=pathCount;
        exhaustionProbability/=pathCount;
        expectedLoss/=pathCount;

		result.valuationDate = settlementDate;

		result.value = totalNPV/(pathCount*discountCurve_->discount(npvDate));
		result.settlementValue = result.value;
		result.lossProbability = lossProbability;
		result.exhaustionProbability = exhaustionProbability;
		result.expectedLoss = expectedLoss;

		if(Null<Real>()!=varLevel_) {
			result.var = result.value - statistics.percentile(1.0-varLevel_);
			result.stdDev = statistics.standardDeviation();
			result.skew = statistics.skewness();
			result.kurtosis = statistics.kurtosis();
		}
        return result;
    }
 Real MonteCarloCatBondEngine::cashFlowRiskyValue(const boost::shared_ptr<CashFlow> cf, 
                                                  const NotionalPath& notionalPath) const {
     return cf->amount()*notionalPath.notionalRate(cf->date()); //TODO: fix for more complicated cashflows
 }