public override void updatePath(List <KeyValuePair <Date, double> > events, NotionalPath path) { path.reset(); for (int i = 0; i < events.Count; ++i) { if (events[i].Value >= threshold_) { path.addReduction(paymentOffset_.paymentDate(events[i].Key), 0.0); } } }
public override void updatePath(List <KeyValuePair <Date, double> > events, NotionalPath path) { path.reset(); double losses = 0; double previousNotional = 1; for (int i = 0; i < events.Count; ++i) { losses += events[i].Value; if (losses > attachement_ && previousNotional > 0) { previousNotional = Math.Max(0.0, (exhaustion_ - losses) / (exhaustion_ - attachement_)); path.addReduction(paymentOffset_.paymentDate(events[i].Key), previousNotional); } } }
protected double pathNpv(bool includeSettlementDateFlows, Date settlementDate, NotionalPath notionalPath) { double totalNPV = 0.0; for (int i = 0; i < arguments_.cashflows.Count; ++i) { if (!arguments_.cashflows[i].hasOccurred(settlementDate, includeSettlementDateFlows)) { double amount = cashFlowRiskyValue(arguments_.cashflows[i], notionalPath); totalNPV += amount * discountCurve_.link.discount(arguments_.cashflows[i].date()); } } return(totalNPV); }
public abstract void updatePath(List <KeyValuePair <Date, double> > events, NotionalPath path);
protected double npv(bool includeSettlementDateFlows, Date settlementDate, Date npvDate, out double lossProbability, out double exhaustionProbability, out double expectedLoss) { const int MAX_PATHS = 10000; //TODO lossProbability = 0.0; exhaustionProbability = 0.0; expectedLoss = 0.0; if (arguments_.cashflows.empty()) { return(0.0); } if (settlementDate == null) { settlementDate = Settings.evaluationDate(); } if (npvDate == null) { npvDate = settlementDate; } double totalNPV = 0.0; Date effectiveDate = Date.Max(arguments_.startDate, settlementDate); Date maturityDate = arguments_.cashflows.Last().date(); CatSimulation catSimulation = catRisk_.newSimulation(effectiveDate, maturityDate); List <KeyValuePair <Date, double> > eventsPath = new List <KeyValuePair <Date, double> >(); NotionalPath notionalPath = new NotionalPath(); double riskFreeNPV = pathNpv(includeSettlementDateFlows, settlementDate, notionalPath); int 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().IsEqual(1)) { exhaustionProbability += 1; } expectedLoss += notionalPath.loss(); } else { totalNPV += riskFreeNPV; } pathCount++; } lossProbability /= pathCount; exhaustionProbability /= pathCount; expectedLoss /= pathCount; return(totalNPV / (pathCount * discountCurve_.link.discount(npvDate))); }
protected double cashFlowRiskyValue(CashFlow cf, NotionalPath notionalPath) { return(cf.amount() * notionalPath.notionalRate(cf.date())); //TODO: fix for more complicated cashflows }