22#ifndef QL_PATCH_SOLARIS
24#include <ql/cashflows/cashflows.hpp>
25#include <ql/cashflows/fixedratecoupon.hpp>
26#include <ql/cashflows/simplecashflow.hpp>
27#include <ql/event.hpp>
28#include <ql/math/solvers1d/brent.hpp>
29#include <ql/termstructures/yieldtermstructure.hpp>
41 const Schedule& schedule, Rate upfrontRate, Rate runningRate,
const DayCounter& dayCounter,
42 BusinessDayConvention paymentConvention,
bool settlesAccrual,
43 CreditDefaultSwap::ProtectionPaymentTime protectionPaymentTime, Date protectionStart,
44 Date upfrontDate, boost::optional<Real> notional, Real recoveryRate,
45 const DayCounter& lastPeriodDayCounter)
46 : basket_(basket), side_(side), upfrontRate_(upfrontRate), runningRate_(runningRate),
47 leverageFactor_(notional ? notional.get() / basket->trancheNotional() : 1.), dayCounter_(dayCounter),
48 paymentConvention_(paymentConvention), settlesAccrual_(settlesAccrual),
49 protectionPaymentTime_(protectionPaymentTime),
50 protectionStart_(protectionStart == Null<Date>() ? schedule[0] : protectionStart),
51 recoveryRate_(recoveryRate) {
52 QL_REQUIRE((schedule.rule() == DateGeneration::CDS || schedule.rule() == DateGeneration::CDS2015) ||
54 "protection can not start after accrual for (pre big bang-) CDS");
55 QL_REQUIRE(
basket->names().size() > 0,
"basket is empty");
57 QL_REQUIRE(
basket->refDate() <= schedule.startDate(),
60 "Basket did not exist before contract start.");
66 .withCouponRates(runningRate, dayCounter)
67 .withPaymentAdjustment(paymentConvention)
68 .withLastPeriodDayCounter(lastPeriodDayCounter);
71 Date effectiveUpfrontDate =
72 upfrontDate == Null<Date>()
73 ? schedule.calendar().advance(schedule.calendar().adjust(
protectionStart_, paymentConvention), 3, Days,
83 if (schedule.rule() == DateGeneration::CDS || schedule.rule() == DateGeneration::CDS2015) {
85 effectiveUpfrontDate);
86 Date current = std::max((Date)Settings::instance().evaluationDate(),
protectionStart_);
89 schedule.calendar().advance(current, 3, Days, paymentConvention));
97 for (Size i = 0; i <
basket->names().size(); i++) {
109 registerWith(
basket->pool()->get(
basket->names()[i]).defaultProbability(
basket->pool()->defaultKeys()[i]));
130 if (
side_ == Protection::Buyer)
137 if (
side_ == Protection::Buyer)
165 return detail::simple_event(
normalizedLeg_.back()->date()).hasOccurred();
175 QL_REQUIRE(
arguments != 0,
"wrong argument type");
196 Instrument::fetchResults(r);
199 QL_REQUIRE(
results != 0,
"wrong result type");
210 Instrument::setupExpired();
219 QL_REQUIRE(
side != Protection::Side(-1),
"side not set");
220 QL_REQUIRE(
basket && !
basket->names().empty(),
"no basket given");
221 QL_REQUIRE(
runningRate != Null<Real>(),
"no premium rate given");
222 QL_REQUIRE(
upfrontRate != Null<Real>(),
"no upfront rate given");
223 QL_REQUIRE(!
dayCounter.empty(),
"no day counter given");
227 Instrument::results::reset();
230 upfrontPremiumValue = Null<Real>();
238class ObjectiveFunction {
243 Real operator()(Real guess)
const {
260 const Handle<YieldTermStructure>& discountCurve, Real targetNPV,
261 Real accuracy)
const {
262 QuantLib::ext::shared_ptr<SimpleQuote> correl(
new SimpleQuote(0.0));
264 QuantLib::ext::shared_ptr<GaussianLHPLossModel> lhp(
new GaussianLHPLossModel(Handle<Quote>(correl), recoveries));
277 ObjectiveFunction f(targetNPV, *correl, engineIC,
results);
282 Real solution = Brent().solve(f, accuracy, guess, QL_EPSILON, 1. - QL_EPSILON);
QuantLib::ext::shared_ptr< PricingEngine > engine_
const Instrument::results * results_
CDO base engine taking schedule steps.
QuantLib::ext::shared_ptr< QuantExt::Basket > basket
QuantLib::CreditDefaultSwap::ProtectionPaymentTime protectionPaymentTime
QuantLib::ext::shared_ptr< CashFlow > upfrontPayment
void validate() const override
QuantLib::ext::shared_ptr< CashFlow > accrualRebate
QuantLib::ext::shared_ptr< CashFlow > accrualRebateCurrent
BusinessDayConvention paymentConvention
std::vector< Real > expectedTrancheLoss
Real upfrontPremiumValue_
QuantLib::ext::shared_ptr< CashFlow > accrualRebateCurrent_
std::vector< Real > expectedTrancheLoss() const
Rate fairUpfrontPremium() const
SyntheticCDO(const QuantLib::ext::shared_ptr< QuantExt::Basket > &basket, Protection::Side side, const Schedule &schedule, Rate upfrontRate, Rate runningRate, const DayCounter &dayCounter, BusinessDayConvention paymentConvention, bool settlesAccrual=true, const QuantLib::CreditDefaultSwap::ProtectionPaymentTime protectionPaymentTime=QuantLib::CreditDefaultSwap::ProtectionPaymentTime::atDefault, Date protectionStart=Date(), Date upfrontDate=Date(), boost::optional< Real > notional=boost::none, Real recoveryRate=Null< Real >(), const DayCounter &lastPeriodDayCounter=DayCounter())
QuantLib::CreditDefaultSwap::ProtectionPaymentTime protectionPaymentTime_
QuantLib::ext::shared_ptr< QuantExt::Basket > basket_
const QuantLib::ext::shared_ptr< QuantExt::Basket > & basket() const
void setupArguments(PricingEngine::arguments *) const override
bool isExpired() const override
const Date & maturity() const
Last protection date.
Real implicitCorrelation(const std::vector< Real > &recoveries, const Handle< YieldTermStructure > &discountCurve, Real targetNPV=0., Real accuracy=1.0e-3) const
Rate protectionValue() const
Real protectionLegNPV() const
QuantLib::ext::shared_ptr< CashFlow > accrualRebate_
BusinessDayConvention paymentConvention_
Real premiumLegNPV() const
void setupExpired() const override
const Real leverageFactor_
void fetchResults(const PricingEngine::results *) const override
Rate premiumValue() const
std::vector< Real > expectedTrancheLoss_
Real remainingNotional() const
QuantLib::ext::shared_ptr< CashFlow > upfrontPayment_
Synthetic Collateralized Debt Obligation and pricing engines.