23#include <ql/cashflows/couponpricer.hpp>
24#include <ql/cashflows/fixedratecoupon.hpp>
25#include <ql/cashflows/iborcoupon.hpp>
26#include <ql/cashflows/simplecashflow.hpp>
27#include <ql/exercise.hpp>
28#include <ql/instruments/payoffs.hpp>
30#include <ql/utilities/null_deleter.hpp>
37 const Leg& coupons,
const QuantLib::ext::shared_ptr<Exercise>& exercise,
38 const Real conversionRatio,
const DividendSchedule& dividends,
39 const CallabilitySchedule& callability)
40 : Bond(settlementDays, calendar, issueDate, coupons), exercise_(exercise), conversionRatio_(conversionRatio),
41 dividends_(dividends), callability_(callability) {
44 QL_REQUIRE(
callability.back()->date() <= maturityDate_,
"last callability date (" <<
callability.back()->date()
45 <<
") later than maturity ("
46 << maturityDate_ <<
")");
49 QL_REQUIRE(
exercise_,
"no exercise for conversion given");
50 QL_REQUIRE(!
exercise_->dates().empty(),
"exercise does not contain any conversion dates");
52 option_ = QuantLib::ext::make_shared<option>(
this);
57 NPV_ = settlementValue_ =
option_->NPV();
58 additionalResults_ =
option_->additionalResults();
59 errorEstimate_ = Null<Real>();
64 new PlainVanillaPayoff(Option::Call, bond->notionals().front() / bond->conversionRatio())),
67 registerWith(QuantLib::ext::shared_ptr<ConvertibleBond>(
const_cast<ConvertibleBond*
>(bond), null_deleter()));
74 OneAssetOption::setupArguments(args);
77 QL_REQUIRE(moreArgs != 0,
"wrong argument type");
82 :
bond_->notionals().front() /
bond_->conversionRatio();
84 Date settlement =
bond_->settlementDate();
86 Size n =
bond_->callability().size();
95 for (Size i = 0; i < n; i++) {
96 if (!
bond_->callability()[i]->hasOccurred(settlement,
false)) {
100 bond_->notional(
bond_->callability()[i]->date()));
101 if (
bond_->callability()[i]->price().type() == Bond::Price::Clean)
103 bond_->notional(
bond_->callability()[i]->date());
104 QuantLib::ext::shared_ptr<SoftCallability> softCall =
105 QuantLib::ext::dynamic_pointer_cast<SoftCallability>(
bond_->callability()[i]);
113 const Leg& cashflows =
bond_->cashflows();
117 for (Size i = 0; i < cashflows.size(); i++) {
118 if (!cashflows[i]->hasOccurred(settlement,
false)) {
126 Real currentNotional = 0.0;
127 for (std::vector<QuantLib::ext::shared_ptr<CashFlow>>::const_reverse_iterator r =
bond_->redemptions().rbegin();
128 r !=
bond_->redemptions().rend(); ++r) {
131 currentNotional += (*r)->amount();
138 for (Size i = 0; i <
bond_->dividends().size(); i++) {
139 if (!
bond_->dividends()[i]->hasOccurred(settlement,
false)) {
153 OneAssetOption::arguments::validate();
157 "non-negative conversion ratio required: " <<
conversionRatio <<
" not allowed");
159 QL_REQUIRE(settlementDate != Date(),
"null settlement date");
161 QL_REQUIRE(settlementDays != Null<Natural>(),
"null settlement days");
163 QL_REQUIRE(callabilityDates.size() == callabilityTypes.size(),
"different number of callability dates and types");
164 QL_REQUIRE(callabilityDates.size() == callabilityPrices.size(),
"different number of callability dates and prices");
165 QL_REQUIRE(callabilityDates.size() == callabilityTriggers.size(),
166 "different number of callability dates and triggers");
168 QL_REQUIRE(cashflowDates.size() == cashflowAmounts.size(),
"different number of coupon dates and amounts");
170 QL_REQUIRE(
exercise->lastDate() <= maturityDate,
"last conversion date (" <<
exercise->lastDate()
171 <<
") must not be after bond maturity ("
172 << maturityDate <<
")");
QuantLib::ext::shared_ptr< PricingEngine > engine_
std::vector< Date > dividendDates
std::vector< Date > callabilityDates
DividendSchedule dividends
std::vector< Date > cashflowDates
std::vector< Real > cashflowAmounts
std::vector< Real > notionals
std::vector< Real > callabilityTriggers
std::vector< Callability::Type > callabilityTypes
std::vector< Real > callabilityPrices
void validate() const override
std::vector< Date > notionalDates
void setupArguments(PricingEngine::arguments *) const override
bool isExpired() const override
option(const ConvertibleBond *bond)
void performCalculations() const override
ConvertibleBond(Natural settlementDays, const Calendar &calendar, const Date &issueDate, const Leg &coupons, const QuantLib::ext::shared_ptr< Exercise > &exercise, const Real conversionRatio, const DividendSchedule ÷nds, const CallabilitySchedule &callability)
similar to bond ctor, coupons should not contain redemption flows
QuantLib::ext::shared_ptr< Exercise > exercise_
Real conversionRatio() const
const CallabilitySchedule & callability() const
QuantLib::ext::shared_ptr< option > option_
QuantLib::ext::shared_ptr< Exercise > exercise() const
Filter close_enough(const RandomVariable &x, const RandomVariable &y)