1	
2	/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3	
4	/*!
5	 Copyright (C) 2008 Florent Grenier
6	
7	 This file is part of QuantLib, a free-software/open-source library
8	 for financial quantitative analysts and developers - http://quantlib.org/
9	
10	 QuantLib is free software: you can redistribute it and/or modify it
11	 under the terms of the QuantLib license.  You should have received a
12	 copy of the license along with this program; if not, please email
13	 <quantlib-dev@lists.sf.net>  . The license is also available online at
14	 <http://quantlib.org/license.shtml>.
15	
16	 This program is distributed in the hope that it will be useful, but WITHOUT
17	 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18	 FOR A PARTICULAR PURPOSE.  See the license for more details.
19	 */
20	
21	/*  This example shows how to set up a term structure and then price
22	    some simple bonds. The last part is dedicated to peripherical
23	    computations such as "Yield to Price" or "Price to Yield"
24	 */
25	
26	#include <ql/qldefines.hpp>
27	#ifdef BOOST_MSVC
28	#  include <ql/auto_link.hpp>
29	#endif
30	#include <ql/instruments/bonds/zerocouponbond.hpp>
31	#include <ql/instruments/bonds/floatingratebond.hpp>
32	#include <ql/pricingengines/bond/discountingbondengine.hpp>
33	#include <ql/cashflows/couponpricer.hpp>
34	#include <ql/termstructures/yield/piecewiseyieldcurve.hpp>
35	#include <ql/termstructures/yield/bondhelpers.hpp>
36	#include <ql/termstructures/volatility/optionlet/constantoptionletvol.hpp>
37	#include <ql/indexes/ibor/euribor.hpp>
38	#include <ql/indexes/ibor/usdlibor.hpp>
39	#include <ql/time/calendars/target.hpp>
40	#include <ql/time/calendars/unitedstates.hpp>
41	#include <ql/time/daycounters/actualactual.hpp>
42	#include <ql/time/daycounters/actual360.hpp>
43	#include <ql/time/daycounters/thirty360.hpp>
44	
45	#include <boost/timer.hpp>
46	#include <iostream>
47	#include <iomanip>
48	
49	using namespace QuantLib;
50	
51	#if defined(QL_ENABLE_SESSIONS)
52	namespace QuantLib {
53	
54	Integer sessionId() { return 0; }
55	
56	}
57	#endif
58	
59	
60	int main(int, char* []) {
61	
62	    try {
63	
64	        boost::timer timer;
65	        std::cout << std::endl;
66	
67	        /*********************
68	         ***  MARKET DATA  ***
69	         *********************/
70	
71	        Calendar calendar = TARGET();
72	
73	        Date settlementDate(18, September, 2008);
74	        // must be a business day
75	        settlementDate = calendar.adjust(settlementDate);
76	
77	        Integer fixingDays = 3;
78	        Natural settlementDays = 3;
79	
80	        Date todaysDate = calendar.advance(settlementDate, -fixingDays, Days);
81	        // nothing to do with Date::todaysDate
82	        Settings::instance().evaluationDate() = todaysDate;
83	
84	        std::cout << "Today: " << todaysDate.weekday()
85	        << ", " << todaysDate << std::endl;
86	
87	        std::cout << "Settlement date: " << settlementDate.weekday()
88	        << ", " << settlementDate << std::endl;
89	
90	
91	        // Building of the bonds discounting yield curve
92	
93	        /*********************
94	         ***  RATE HELPERS ***
95	         *********************/
96	
97	        // RateHelpers are built from the above quotes together with
98	        // other instrument dependant infos.  Quotes are passed in
99	        // relinkable handles which could be relinked to some other
100	        // data source later.
101	
102	        // Common data
103	
104	        // ZC rates for the short end
105	         Rate zc3mQuote=0.0096;
106	         Rate zc6mQuote=0.0145;
107	         Rate zc1yQuote=0.0194;
108	
109	         ext::shared_ptr<Quote> zc3mRate(new SimpleQuote(zc3mQuote));
110	         ext::shared_ptr<Quote> zc6mRate(new SimpleQuote(zc6mQuote));
111	         ext::shared_ptr<Quote> zc1yRate(new SimpleQuote(zc1yQuote));
112	
113	         DayCounter zcBondsDayCounter = Actual365Fixed();
114	
115	         ext::shared_ptr<RateHelper> zc3m(new DepositRateHelper(
116	                 Handle<Quote>(zc3mRate),
117	                 3*Months, fixingDays,
118	                 calendar, ModifiedFollowing,
119	                 true, zcBondsDayCounter));
120	         ext::shared_ptr<RateHelper> zc6m(new DepositRateHelper(
121	                 Handle<Quote>(zc6mRate),
122	                 6*Months, fixingDays,
123	                 calendar, ModifiedFollowing,
124	                 true, zcBondsDayCounter));
125	         ext::shared_ptr<RateHelper> zc1y(new DepositRateHelper(
126	                 Handle<Quote>(zc1yRate),
127	                 1*Years, fixingDays,
128	                 calendar, ModifiedFollowing,
129	                 true, zcBondsDayCounter));
130	
131	        // setup bonds
132	        Real redemption = 100.0;
133	
134	        const Size numberOfBonds = 5;
135	
136	        Date issueDates[] = {
137	                Date (15, March, 2005),
138	                Date (15, June, 2005),
139	                Date (30, June, 2006),
140	                Date (15, November, 2002),
141	                Date (15, May, 1987)
142	        };
143	
144	        Date maturities[] = {
145	                Date (31, August, 2010),
146	                Date (31, August, 2011),
147	                Date (31, August, 2013),
148	                Date (15, August, 2018),
149	                Date (15, May, 2038)
150	        };
151	
152	        Real couponRates[] = {
153	                0.02375,
154	                0.04625,
155	                0.03125,
156	                0.04000,
157	0.045
158	        };
159	
160	        Real marketQuotes[] = {
161	                100.390625,
162	                106.21875,
163	                100.59375,
164	                101.6875,
165	102.140625
166	        };
167	
168	        std::vector< ext::shared_ptr<SimpleQuote> > quote;
169	        for (Size i=0; i<numberOfBonds; i++) {
170	            ext::shared_ptr<SimpleQuote> cp(new SimpleQuote(marketQuotes[i]));
171	            quote.push_back(cp);
172	        }
173	
174	        RelinkableHandle<Quote> quoteHandle[numberOfBonds];
175	        for (Size i=0; i<numberOfBonds; i++) {
176	            quoteHandle[i].linkTo(quote[i]);
177	        }
178	
179	        // Definition of the rate helpers
180	        std::vector<ext::shared_ptr<BondHelper> > bondsHelpers;
181	
182	        for (Size i=0; i<numberOfBonds; i++) {
183	
184	            Schedule schedule(issueDates[i], maturities[i], Period(Semiannual), UnitedStates(UnitedStates::GovernmentBond),
185	                    Unadjusted, Unadjusted, DateGeneration::Backward, false);
186	
187	            ext::shared_ptr<FixedRateBondHelper> bondHelper(new FixedRateBondHelper(
188	                    quoteHandle[i],
189	                    settlementDays,
190	                    100.0,
191	                    schedule,
192	                    std::vector<Rate>(1,couponRates[i]),
193	                    ActualActual(ActualActual::Bond),
194	                    Unadjusted,
195	                    redemption,
196	                    issueDates[i]));
197	
198	            // the above could also be done by creating a
199	            // FixedRateBond instance and writing:
200	            //
201	            // ext::shared_ptr<BondHelper> bondHelper(
202	            //         new BondHelper(quoteHandle[i], bond));
203	            //
204	            // This would also work for bonds that still don't have a
205	            // specialized helper, such as floating-rate bonds.
206	
207	
208	            bondsHelpers.push_back(bondHelper);
209	        }
210	
211	        /*********************
212	         **  CURVE BUILDING **
213	         *********************/
214	
215	         // Any DayCounter would be fine.
216	         // ActualActual::ISDA ensures that 30 years is 30.0
217	         DayCounter termStructureDayCounter =
218	             ActualActual(ActualActual::ISDA);
219	
220	         double tolerance = 1.0e-15;
221	
222	         // A depo-bond curve
223	         std::vector<ext::shared_ptr<RateHelper> > bondInstruments;
224	
225	         // Adding the ZC bonds to the curve for the short end
226	         bondInstruments.push_back(zc3m);
227	         bondInstruments.push_back(zc6m);
228	         bondInstruments.push_back(zc1y);
229	
230	         // Adding the Fixed rate bonds to the curve for the long end
231	         for (Size i=0; i<numberOfBonds; i++) {
232	             bondInstruments.push_back(bondsHelpers[i]);
233	         }
234	
235	         ext::shared_ptr<YieldTermStructure> bondDiscountingTermStructure(
236	                 new PiecewiseYieldCurve<Discount,LogLinear>(
237	                         settlementDate, bondInstruments,
238	                         termStructureDayCounter,
239	                         tolerance));
240	
241	         // Building of the Libor forecasting curve
242	         // deposits
243	         Rate d1wQuote=0.043375;
244	         Rate d1mQuote=0.031875;
245	         Rate d3mQuote=0.0320375;
246	         Rate d6mQuote=0.03385;
247	         Rate d9mQuote=0.0338125;
248	         Rate d1yQuote=0.0335125;
249	         // swaps
250	         Rate s2yQuote=0.0295;
251	         Rate s3yQuote=0.0323;
252	         Rate s5yQuote=0.0359;
253	         Rate s10yQuote=0.0412;
254	         Rate s15yQuote=0.0433;
255	
256	
257	         /********************
258	          ***    QUOTES    ***
259	          ********************/
260	
261	         // SimpleQuote stores a value which can be manually changed;
262	         // other Quote subclasses could read the value from a database
263	         // or some kind of data feed.
264	
265	         // deposits
266	         ext::shared_ptr<Quote> d1wRate(new SimpleQuote(d1wQuote));
267	         ext::shared_ptr<Quote> d1mRate(new SimpleQuote(d1mQuote));
268	         ext::shared_ptr<Quote> d3mRate(new SimpleQuote(d3mQuote));
269	         ext::shared_ptr<Quote> d6mRate(new SimpleQuote(d6mQuote));
270	         ext::shared_ptr<Quote> d9mRate(new SimpleQuote(d9mQuote));
271	         ext::shared_ptr<Quote> d1yRate(new SimpleQuote(d1yQuote));
272	         // swaps
273	         ext::shared_ptr<Quote> s2yRate(new SimpleQuote(s2yQuote));
274	         ext::shared_ptr<Quote> s3yRate(new SimpleQuote(s3yQuote));
275	         ext::shared_ptr<Quote> s5yRate(new SimpleQuote(s5yQuote));
276	         ext::shared_ptr<Quote> s10yRate(new SimpleQuote(s10yQuote));
277	         ext::shared_ptr<Quote> s15yRate(new SimpleQuote(s15yQuote));
278	
279	         /*********************
280	          ***  RATE HELPERS ***
281	          *********************/
282	
283	         // RateHelpers are built from the above quotes together with
284	         // other instrument dependant infos.  Quotes are passed in
285	         // relinkable handles which could be relinked to some other
286	         // data source later.
287	
288	         // deposits
289	         DayCounter depositDayCounter = Actual360();
290	
291	         ext::shared_ptr<RateHelper> d1w(new DepositRateHelper(
292	                 Handle<Quote>(d1wRate),
293	                 1*Weeks, fixingDays,
294	                 calendar, ModifiedFollowing,
295	                 true, depositDayCounter));
296	         ext::shared_ptr<RateHelper> d1m(new DepositRateHelper(
297	                 Handle<Quote>(d1mRate),
298	                 1*Months, fixingDays,
299	                 calendar, ModifiedFollowing,
300	                 true, depositDayCounter));
301	         ext::shared_ptr<RateHelper> d3m(new DepositRateHelper(
302	                 Handle<Quote>(d3mRate),
303	                 3*Months, fixingDays,
304	                 calendar, ModifiedFollowing,
305	                 true, depositDayCounter));
306	         ext::shared_ptr<RateHelper> d6m(new DepositRateHelper(
307	                 Handle<Quote>(d6mRate),
308	                 6*Months, fixingDays,
309	                 calendar, ModifiedFollowing,
310	                 true, depositDayCounter));
311	         ext::shared_ptr<RateHelper> d9m(new DepositRateHelper(
312	                 Handle<Quote>(d9mRate),
313	                 9*Months, fixingDays,
314	                 calendar, ModifiedFollowing,
315	                 true, depositDayCounter));
316	         ext::shared_ptr<RateHelper> d1y(new DepositRateHelper(
317	                 Handle<Quote>(d1yRate),
318	                 1*Years, fixingDays,
319	                 calendar, ModifiedFollowing,
320	                 true, depositDayCounter));
321	
322	         // setup swaps
323	         Frequency swFixedLegFrequency = Annual;
324	         BusinessDayConvention swFixedLegConvention = Unadjusted;
325	         DayCounter swFixedLegDayCounter = Thirty360(Thirty360::European);
326	         ext::shared_ptr<IborIndex> swFloatingLegIndex(new Euribor6M);
327	
328	         const Period forwardStart(1*Days);
329	
330	         ext::shared_ptr<RateHelper> s2y(new SwapRateHelper(
331	                 Handle<Quote>(s2yRate), 2*Years,
332	                 calendar, swFixedLegFrequency,
333	                 swFixedLegConvention, swFixedLegDayCounter,
334	                 swFloatingLegIndex, Handle<Quote>(),forwardStart));
335	         ext::shared_ptr<RateHelper> s3y(new SwapRateHelper(
336	                 Handle<Quote>(s3yRate), 3*Years,
337	                 calendar, swFixedLegFrequency,
338	                 swFixedLegConvention, swFixedLegDayCounter,
339	                 swFloatingLegIndex, Handle<Quote>(),forwardStart));
340	         ext::shared_ptr<RateHelper> s5y(new SwapRateHelper(
341	                 Handle<Quote>(s5yRate), 5*Years,
342	                 calendar, swFixedLegFrequency,
343	                 swFixedLegConvention, swFixedLegDayCounter,
344	                 swFloatingLegIndex, Handle<Quote>(),forwardStart));
345	         ext::shared_ptr<RateHelper> s10y(new SwapRateHelper(
346	                 Handle<Quote>(s10yRate), 10*Years,
347	                 calendar, swFixedLegFrequency,
348	                 swFixedLegConvention, swFixedLegDayCounter,
349	                 swFloatingLegIndex, Handle<Quote>(),forwardStart));
350	         ext::shared_ptr<RateHelper> s15y(new SwapRateHelper(
351	                 Handle<Quote>(s15yRate), 15*Years,
352	                 calendar, swFixedLegFrequency,
353	                 swFixedLegConvention, swFixedLegDayCounter,
354	                 swFloatingLegIndex, Handle<Quote>(),forwardStart));
355	
356	
357	         /*********************
358	          **  CURVE BUILDING **
359	          *********************/
360	
361	         // Any DayCounter would be fine.
362	         // ActualActual::ISDA ensures that 30 years is 30.0
363	
364	         // A depo-swap curve
365	         std::vector<ext::shared_ptr<RateHelper> > depoSwapInstruments;
366	         depoSwapInstruments.push_back(d1w);
367	         depoSwapInstruments.push_back(d1m);
368	         depoSwapInstruments.push_back(d3m);
369	         depoSwapInstruments.push_back(d6m);
370	         depoSwapInstruments.push_back(d9m);
371	         depoSwapInstruments.push_back(d1y);
372	         depoSwapInstruments.push_back(s2y);
373	         depoSwapInstruments.push_back(s3y);
374	         depoSwapInstruments.push_back(s5y);
375	         depoSwapInstruments.push_back(s10y);
376	         depoSwapInstruments.push_back(s15y);
377	         ext::shared_ptr<YieldTermStructure> depoSwapTermStructure(
378	                 new PiecewiseYieldCurve<Discount,LogLinear>(
379	                         settlementDate, depoSwapInstruments,
380	                         termStructureDayCounter,
381	                         tolerance));
382	
383	         // Term structures that will be used for pricing:
384	         // the one used for discounting cash flows
385	         RelinkableHandle<YieldTermStructure> discountingTermStructure;
386	         // the one used for forward rate forecasting
387	         RelinkableHandle<YieldTermStructure> forecastingTermStructure;
388	
389	         /*********************
390	          * BONDS TO BE PRICED *
391	          **********************/
392	
393	         // Common data
394	         Real faceAmount = 100;
395	
396	         // Pricing engine
397	         ext::shared_ptr<PricingEngine> bondEngine(
398	                 new DiscountingBondEngine(discountingTermStructure));
399	
400	         // Zero coupon bond
401	         ZeroCouponBond zeroCouponBond(
402	                 settlementDays,
403	                 UnitedStates(UnitedStates::GovernmentBond),
404	                 faceAmount,
405	                 Date(15,August,2013),
406	                 Following,
407	                 Real(116.92),
408	                 Date(15,August,2003));
409	
410	         zeroCouponBond.setPricingEngine(bondEngine);
411	
412	         // Fixed 4.5% US Treasury Note
413	         Schedule fixedBondSchedule(Date(15, May, 2007),
414	                 Date(15,May,2017), Period(Semiannual),
415	                 UnitedStates(UnitedStates::GovernmentBond),
416	                 Unadjusted, Unadjusted, DateGeneration::Backward, false);
417	
418	         FixedRateBond fixedRateBond(
419	                 settlementDays,
420	                 faceAmount,
421	                 fixedBondSchedule,
422	                 std::vector<Rate>(1, 0.045),
423	                 ActualActual(ActualActual::Bond),
424	                 ModifiedFollowing,
425	                 100.0, Date(15, May, 2007));
426	
427	         fixedRateBond.setPricingEngine(bondEngine);
428	
429	         // Floating rate bond (3M USD Libor + 0.1%)
430	         // Should and will be priced on another curve later...
431	
432	         RelinkableHandle<YieldTermStructure> liborTermStructure;
433	         const ext::shared_ptr<IborIndex> libor3m(
434	                 new USDLibor(Period(3,Months),liborTermStructure));
435	         libor3m->addFixing(Date(17, July, 2008),0.0278625);
436	
437	         Schedule floatingBondSchedule(Date(21, October, 2005),
438	                 Date(21, October, 2010), Period(Quarterly),
439	                 UnitedStates(UnitedStates::NYSE),
440	                 Unadjusted, Unadjusted, DateGeneration::Backward, true);
441	
442	         FloatingRateBond floatingRateBond(
443	                 settlementDays,
444	                 faceAmount,
445	                 floatingBondSchedule,
446	                 libor3m,
447	                 Actual360(),
448	                 ModifiedFollowing,
449	                 Natural(2),
450	                 // Gearings
451	                 std::vector<Real>(1, 1.0),
452	                 // Spreads
453	                 std::vector<Rate>(1, 0.001),
454	                 // Caps
455	                 std::vector<Rate>(),
456	                 // Floors
457	                 std::vector<Rate>(),
458	                 // Fixing in arrears
459	                 true,
460	                 Real(100.0),
461	                 Date(21, October, 2005));
462	
463	         floatingRateBond.setPricingEngine(bondEngine);
464	
465	         // Coupon pricers
466	         ext::shared_ptr<IborCouponPricer> pricer(new BlackIborCouponPricer);
467	
468	         // optionLet volatilities
469	         Volatility volatility = 0.0;
470	         Handle<OptionletVolatilityStructure> vol;
471	         vol = Handle<OptionletVolatilityStructure>(
472	                 ext::shared_ptr<OptionletVolatilityStructure>(new
473	                         ConstantOptionletVolatility(
474	                                 settlementDays,
475	                                 calendar,
476	                                 ModifiedFollowing,
477	                                 volatility,
478	                                 Actual365Fixed())));
479	
480	         pricer->setCapletVolatility(vol);
481	         setCouponPricer(floatingRateBond.cashflows(),pricer);
482	
483	         // Yield curve bootstrapping
484	         forecastingTermStructure.linkTo(depoSwapTermStructure);
485	         discountingTermStructure.linkTo(bondDiscountingTermStructure);
486	
487	         // We are using the depo & swap curve to estimate the future Libor rates
488	         liborTermStructure.linkTo(depoSwapTermStructure);
489	
490	         /***************
491	          * BOND PRICING *
492	          ****************/
493	
494	         std::cout << std::endl;
495	
496	         // write column headings
497	         Size widths[] = { 18, 10, 10, 10 };
498	
499	         std::cout << std::setw(widths[0]) <<  "                 "
500	         << std::setw(widths[1]) << "ZC"
501	         << std::setw(widths[2]) << "Fixed"
502	         << std::setw(widths[3]) << "Floating"
503	         << std::endl;
504	
505	         Size width = widths[0] + widths[1] + widths[2] + widths[3];
506	         std::string rule(width, '-');
507	
508	         std::cout << rule << std::endl;
509	
510	         std::cout << std::fixed;
511	         std::cout << std::setprecision(2);
512	
513	         std::cout << std::setw(widths[0]) << "Net present value"
514	         << std::setw(widths[1]) << zeroCouponBond.NPV()
515	         << std::setw(widths[2]) << fixedRateBond.NPV()
516	         << std::setw(widths[3]) << floatingRateBond.NPV()
517	         << std::endl;
518	
519	         std::cout << std::setw(widths[0]) << "Clean price"
520	         << std::setw(widths[1]) << zeroCouponBond.cleanPrice()
521	         << std::setw(widths[2]) << fixedRateBond.cleanPrice()
522	         << std::setw(widths[3]) << floatingRateBond.cleanPrice()
523	         << std::endl;
524	
525	         std::cout << std::setw(widths[0]) << "Dirty price"
526	         << std::setw(widths[1]) << zeroCouponBond.dirtyPrice()
527	         << std::setw(widths[2]) << fixedRateBond.dirtyPrice()
528	         << std::setw(widths[3]) << floatingRateBond.dirtyPrice()
529	         << std::endl;
530	
531	         std::cout << std::setw(widths[0]) << "Accrued coupon"
532	         << std::setw(widths[1]) << zeroCouponBond.accruedAmount()
533	         << std::setw(widths[2]) << fixedRateBond.accruedAmount()
534	         << std::setw(widths[3]) << floatingRateBond.accruedAmount()
535	         << std::endl;
536	
537	         std::cout << std::setw(widths[0]) << "Previous coupon"
538	         << std::setw(widths[1]) << "N/A" // zeroCouponBond
539	         << std::setw(widths[2]) << io::rate(fixedRateBond.previousCouponRate())
540	         << std::setw(widths[3]) << io::rate(floatingRateBond.previousCouponRate())
541	         << std::endl;
542	
543	         std::cout << std::setw(widths[0]) << "Next coupon"
544	         << std::setw(widths[1]) << "N/A" // zeroCouponBond
545	         << std::setw(widths[2]) << io::rate(fixedRateBond.nextCouponRate())
546	         << std::setw(widths[3]) << io::rate(floatingRateBond.nextCouponRate())
547	         << std::endl;
548	
549	         std::cout << std::setw(widths[0]) << "Yield"
550	         << std::setw(widths[1])
551	         << io::rate(zeroCouponBond.yield(Actual360(),Compounded,Annual))
552	         << std::setw(widths[2])
553	         << io::rate(fixedRateBond.yield(Actual360(),Compounded,Annual))
554	         << std::setw(widths[3])
555	         << io::rate(floatingRateBond.yield(Actual360(),Compounded,Annual))
556	         << std::endl;
557	
558	         std::cout << std::endl;
559	
560	         // Other computations
561	         std::cout << "Sample indirect computations (for the floating rate bond): " << std::endl;
562	         std::cout << rule << std::endl;
563	
564	         std::cout << "Yield to Clean Price: "
565	         << floatingRateBond.cleanPrice(floatingRateBond.yield(Actual360(),Compounded,Annual),Actual360(),Compounded,Annual,settlementDate) << std::endl;
566	
567	         std::cout << "Clean Price to Yield: "
568	         << io::rate(floatingRateBond.yield(floatingRateBond.cleanPrice(),Actual360(),Compounded,Annual,settlementDate)) << std::endl;
569	
570	         /* "Yield to Price"
571	            "Price to Yield" */
572	
573	         double seconds = timer.elapsed();
574	         Integer hours = int(seconds/3600);
575	         seconds -= hours * 3600;
576	         Integer minutes = int(seconds/60);
577	         seconds -= minutes * 60;
578	         std::cout << " \nRun completed in ";
579	         if (hours > 0)
580	             std::cout << hours << " h ";
581	         if (hours > 0 || minutes > 0)
582	             std::cout << minutes << " m ";
583	         std::cout << std::fixed << std::setprecision(0)
584	         << seconds << " s\n" << std::endl;
585	
586	         return 0;
587	
588	    } catch (std::exception& e) {
589	        std::cerr << e.what() << std::endl;
590	        return 1;
591	    } catch (...) {
592	        std::cerr << "unknown error" << std::endl;
593	        return 1;
594	    }
595	}
596	
597