/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2005, 2006 Theo Boafo Copyright (C) 2006 StatPro Italia srl This file is part of QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ QuantLib is free software: you can redistribute it and/or modify it under the terms of the QuantLib license. You should have received a copy of the license along with this program; if not, please email . The license is also available online at . This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ #include #include #include namespace QuantLib { DiscretizedConvertible::DiscretizedConvertible( const ConvertibleBond::option::arguments& args) : arguments_(args) { dividendValues_ = Array(arguments_.dividends.size(), 0.0); boost::shared_ptr process = boost::dynamic_pointer_cast( arguments_.stochasticProcess); QL_REQUIRE(process, "Black-Scholes process required"); Date settlementDate = process->riskFreeRate()->referenceDate(); for (Size i=0; idate() >= settlementDate) { dividendValues_[i] = arguments_.dividends[i]->amount() * process->riskFreeRate()->discount( arguments_.dividends[i]->date()); } } } void DiscretizedConvertible::reset(Size size) { // Set to bond redemption values values_ = Array(size, arguments_.redemption); // coupon amounts should be added when adjusting // values_ = Array(size, arguments_.cashFlows.back()->amount()); conversionProbability_ = Array(size, 0.0); spreadAdjustedRate_ = Array(size, 0.0); boost::shared_ptr process = boost::dynamic_pointer_cast( arguments_.stochasticProcess); QL_REQUIRE(process, "Black-Scholes process required"); DayCounter rfdc = process->riskFreeRate()->dayCounter(); // this takes care of convertibility and conversion probabilities adjustValues(); Real creditSpread = arguments_.creditSpread->value(); Date exercise = arguments_.exercise->lastDate(); Rate riskFreeRate = process->riskFreeRate()->zeroRate(exercise, rfdc, Continuous, NoFrequency); // Calculate blended discount rate to be used on roll back. for (Size j=0; jtype()) { case Exercise::American: if (time() <= arguments_.stoppingTimes[1] && time() >= arguments_.stoppingTimes[0]) convertible = true; break; case Exercise::European: if (isOnTime(arguments_.stoppingTimes[0])) convertible = true; break; case Exercise::Bermudan: for (i = 0; i()) { Real conversionValue = arguments_.redemption/arguments_.conversionRatio; Real trigger = conversionValue*arguments_.callabilityTriggers[i]; for (j=0; j= trigger) { // ...and might trigger conversion values_[j] = std::min(std::max( arguments_.callabilityPrices[i], arguments_.conversionRatio*grid[j]), values_[j]); } } } else if (convertible) { for (j=0; j DiscretizedConvertible::adjustedGrid() const { Time t = time(); Array grid = method()->grid(t); // add back all dividend amounts in the future for (Size i=0; i= t || close(dividendTime,t)) { const boost::shared_ptr& d = arguments_.dividends[i]; for (Size j=0; jamount(grid[j]); } } return grid; } }