|
From: tibbar <tib...@gm...> - 2008-03-08 01:54:42
|
Here's where I've got to.
I started with the convertible bond example and:
- set conversion ratio to 0.0000001
- removed dividends
- removed the puttable bit
- set my callable terms
But, it seems the market value of the callable bond is unaffected by the
choice of strike prices... (I tried high and low values).
My program is below, I also have some specific questions on syntax:
- what is the 1.20 for in:
SoftCallability(Callability::Price(
callPrices[i],
Callability::Price::Clean),
schedule.date(callLength[i]),
1.20)));
- why do I get time to maturity as 4.00822 in the output, when i set it to
4? If I set it to 3, then the output says 3 exactly...
- what is the 1 for in the coupon definition: std::vector<Real> coupons(1,
0.065)? Is this frequency of coupons per annum?
I'll be grateful for any feedback.
//// CODE SNIPPET/////
boost::timer timer;
std::cout << std::endl;
Option::Type type(Option::Call);
Real underlying = 36.0;
Real spreadRate = 0.;//0.005;
Spread dividendYield = 0.; //0.02;
Rate riskFreeRate = 0.05;
Volatility volatility = 0.10;
Integer settlementDays = 0;
Integer length = 4;
Real redemption = 100.0;
Real conversionRatio = 0.0000001; //redemption/underlying; // at the
money
// set up dates/schedules
Calendar calendar = TARGET();
Date today = calendar.adjust(Date::todaysDate());
Settings::instance().evaluationDate() = today;
Date settlementDate = calendar.advance(today, settlementDays, Days);
Date exerciseDate = calendar.advance(settlementDate, length, Years);
Date issueDate = calendar.advance(exerciseDate, -length, Years);
BusinessDayConvention convention = ModifiedFollowing;
Frequency frequency = Annual;
Schedule schedule(issueDate, exerciseDate,
Period(frequency), calendar,
convention, convention,
DateGeneration::Backward, false);
DividendSchedule dividends;
CallabilitySchedule callability;
std::vector<Real> coupons(1, 0.065);
DayCounter bondDayCount =Actual365Fixed(); // Thirty360();
Integer callLength[] = { 1, 2, 3 }; // Call dates, years 2, 4.
// Integer putLength[] = { 3 }; // Put dates year 3
// these need to be less than npv of redemption and future coupons at 5%
to bite!
Real callPrices[] = { 140.0, 190.0, 102.0 };
// Real putPrices[]= { 105.0 };
// Load call schedules
for (Size i=0; i<LENGTH(callLength); i++) {
callability.push_back(
boost::shared_ptr<Callability>(
new SoftCallability(Callability::Price(
callPrices[i],
Callability::Price::Clean),
schedule.date(callLength[i]),
1.20)));
}
/* for (Size j=0; j<LENGTH(putLength); j++) {
callability.push_back(
boost::shared_ptr<Callability>(
new Callability(Callability::Price(
putPrices[j],
Callability::Price::Clean),
Callability::Put,
schedule.date(putLength[j]))));
}
*/
DayCounter dayCounter = Actual365Fixed();
Time maturity = dayCounter.yearFraction(settlementDate,
exerciseDate);
std::cout << "option type = " << type << std::endl;
std::cout << "Time to maturity = " << maturity
<< std::endl;
std::cout << "Underlying price = " << underlying
<< std::endl;
std::cout << "Risk-free interest rate = " << io::rate(riskFreeRate)
<< std::endl;
std::cout << "Dividend yield = " << io::rate(dividendYield)
<< std::endl;
std::cout << "Volatility = " << io::volatility(volatility)
<< std::endl;
std::cout << std::endl;
std::string method;
std::cout << std::endl ;
// write column headings
Size widths[] = { 35, 14, 14 };
Size totalWidth = widths[0] + widths[1] + widths[2];
std::string rule(totalWidth, '-'), dblrule(totalWidth, '=');
std::cout << dblrule << std::endl;
std::cout << "Tsiveriotis-Fernandes method" << std::endl;
std::cout << dblrule << std::endl;
std::cout << std::setw(widths[0]) << std::left << "Tree type"
<< std::setw(widths[1]) << std::left << "European"
<< std::setw(widths[1]) << std::left << "American"
<< std::endl;
std::cout << rule << std::endl;
boost::shared_ptr<Exercise> exercise(
new
EuropeanExercise(exerciseDate));
boost::shared_ptr<Exercise> amExercise(
new
AmericanExercise(settlementDate,
exerciseDate));
Handle underlyingH(
boost::shared_ptr(new SimpleQuote(underlying)));
Handle<YieldTermStructure> flatTermStructure(
boost::shared_ptr<YieldTermStructure>(
new FlatForward(settlementDate, riskFreeRate, dayCounter)));
Handle<YieldTermStructure> flatDividendTS(
boost::shared_ptr<YieldTermStructure>(
new FlatForward(settlementDate, dividendYield,
dayCounter)));
Handle<BlackVolTermStructure> flatVolTS(
boost::shared_ptr<BlackVolTermStructure>(
new BlackConstantVol(settlementDate, calendar,
volatility, dayCounter)));
boost::shared_ptr<BlackScholesMertonProcess> stochasticProcess(
new BlackScholesMertonProcess(underlyingH,
flatDividendTS,
flatTermStructure,
flatVolTS));
Size timeSteps = 801;
Handle creditSpread(
boost::shared_ptr(new SimpleQuote(spreadRate)));
boost::shared_ptr rate(new SimpleQuote(riskFreeRate));
Handle<YieldTermStructure> discountCurve(
boost::shared_ptr<YieldTermStructure>(
new FlatForward(today, Handle(rate), dayCounter)));
boost::shared_ptr<PricingEngine> engine(
new
BinomialConvertibleEngine<JarrowRudd>(stochasticProcess,
timeSteps));
ConvertibleFixedCouponBond europeanBond(
exercise, conversionRatio, dividends,
callability,
creditSpread, issueDate, settlementDays,
coupons, bondDayCount, schedule, redemption);
europeanBond.setPricingEngine(engine);
ConvertibleFixedCouponBond americanBond(
amExercise, conversionRatio, dividends,
callability,
creditSpread, issueDate, settlementDays,
coupons, bondDayCount, schedule, redemption);
americanBond.setPricingEngine(engine);
method = "Jarrow-Rudd";
europeanBond.setPricingEngine(boost::shared_ptr<PricingEngine>(
new
BinomialConvertibleEngine<JarrowRudd>(stochasticProcess,
timeSteps)));
americanBond.setPricingEngine(boost::shared_ptr<PricingEngine>(
new
BinomialConvertibleEngine<JarrowRudd>(stochasticProcess,
timeSteps)));
std::cout << std::setw(widths[0]) << std::left << method
<< std::fixed
<< std::setw(widths[1]) << std::left << europeanBond.NPV()
<< std::setw(widths[2]) << std::left << americanBond.NPV()
<< std::endl;
tibbar wrote:
>
> Could anyone give me some ideas of how to price callable bonds in
> quantlib?
>
> Bond features are:
>
> - initial deferred period where the bond is not callable
> - seperate strike price for exercise in each remaining year of the bond's
> life.
>
> I've seen some discussions that the convertible bond class should be used,
> but as a newbee I'm a little intimidated by the quantlib terminology.
>
> What I'd really need to know is what changes to make to the standard
> convertible sample code:
>
> http://quantlib.org/reference/_convertible_bonds_8cpp-example.html
>
> Many thanks.
>
--
View this message in context: http://www.nabble.com/callable-bonds-tp15903645p15910210.html
Sent from the quantlib-dev mailing list archive at Nabble.com.
|