Could you please explain the formula used for computing the discount of a yield curve?
I tried to feed QuantLib the following simple case: cash deposit for 3 months (DepositRateHelper) with rate = 100% per year. Use 365 days per year and no bussiness days adjustment: time in years is simply days_offset / 365.0. What is the present value of 1$ in 90 days (QuantLib call to YieldTermStructure.discount(90 / 365.0))? I couldn't find any documentation on the algorithm used for computing the discount, so i had to assume some. For instance: http://en.wikipedia.org/wiki/Compound_interest However, the interest as computed by Quantlib doesn't seem to be neither simple, nor periodically-compounded, nor continuously-compounded. If it were continuously-compounded, then the discount would be: 1 / exp(r * t) = 1 / exp((100/100.0) * (90 / 365.0)) =~ 0.781472. Instead, i'm getting: 0.802198. Furthermore, if it were continuously-compounded, the result wouldn't depend on deposit's period expressed in days vs. months. But, when expressing the deposit in 3*Months instead of 90*Days, i'm getting a different result: 0.809476. ** This leads me to the conclusion that it's better to ask what algorithm you are using instead of guessing or reverse-engineering the code. ** Actually i tried other compounding conventions from the Wikipedia link but without success. ** Reverse-engineering the code (the call to discount() method) also didn't work: the code it's definitely not self-documenting. The only bit of documentation i found was in Luigi Ballabio's "Implementing QuantLib" PDF, chapter 3, parahraph 3.2.1. and it sais "Of course, there is a relationship between zero rates, forward rates, and discount factors; the knowledge of any one of them is sufficient to deduce the others (I won’t bore you with the formulas here—you know them.)" Looks like as a matter of fact, i (we) don't know them, or better said (as the example above shows), those which i know don't match what QuantLib it's using. So could you please give a bit more mathematical detail on these calculations? Below it's an approximate listing of the code i was using: >> >> Calendar calendar = TARGET(); >> Date settlementDate(24, January, 2011); >> >> Integer fixingDays = 0; >> Date todaysDate = calendar.advance(settlementDate, -fixingDays, Days); >> Settings::instance().evaluationDate() = todaysDate; >> >> // deposit: 100% per year >> Rate d1Quote=1.0; >> boost::shared_ptr<Quote> d1Rate(new SimpleQuote(d1Quote)); >> >> DayCounter depositDayCounter = Actual365Fixed(); >> boost::shared_ptr<RateHelper> d1(new DepositRateHelper( >> Handle<Quote>(d1Rate), >> 90*Days, >> //3*Months, >> fixingDays, >> calendar, >> Unadjusted, >> true, >> depositDayCounter)); >> >> DayCounter termStructureDayCounter = Actual365Fixed(); >> >> // Deposit test curve >> std::vector<boost::shared_ptr<RateHelper> > depoInstruments; >> depoInstruments.push_back(d1); >> boost::shared_ptr<YieldTermStructure> depoInstrumentsTermStructure( >> new PiecewiseYieldCurve<Discount,LogLinear>( >> settlementDate, >> depoInstruments, >> termStructureDayCounter, >> 1.0e-15)); // tolerance >> >> Time elapsedTime = 90.0 / 365.0; >> double discountFactor = depoInstrumentsTermStructure->discount(elapsedTime, true); >> |
Mihai,
In your case (based on the code, settlement in D+0, Rate object, etc...) simple interest rates is used: Df = 1 / (1+ 90/365 * 100%) = 0.802197802 >> Rate d1Quote=1.0; In QuantLib when you use "Rate" it is probably simple interest rate. InterestRate class is used for more complex interest rate setup. I can't guarantee this rule will work 100% of times, but in most of the code I saw it works. You should take a look at InterestRate code to learn how to calculate the types covered by QuantLib. Regards, _____________________ Piter Dias [hidden email] http://www.piterdias.com ------------------------------------------------------------------------------ Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)! Finally, a world-class log management solution at an even better price-free! Download using promo code Free_Logger_4_Dev2Dev. Offer expires February 28th, so secure your free ArcSight Logger TODAY! http://p.sf.net/sfu/arcsight-sfd2d _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Hello Peter,
thanks for your response. I tried to use simple interest rate to explain the results of YieldTermStructure.discount() on the example described in my mail. But: - When using the YieldTermStructure to compute the discount for 1 year, the result is 0.424343 while simple InterestRate computes 1 / (1 + 1 * 365 / 365.0) = 1/2 = 0.5. - When using the YieldTermStructure to compute the discount for 30 days, the result is 0.931969 while simple InterestRate computes 1 / (1 + 1 * 30 / 365.0) = 0.924051. So it looks like the yield curve computation of discount() cannot be exaplaind by assuming simple interest rate. I also tried using Compounded interest rate, as in the following code: InterestRate *interestRateAnnual = new InterestRate(d1Quote, Actual365Fixed(), Compounded, Annual); double discountFactorAnnual = interestRateAnnual ->discountFactor(elapsedTime); InterestRate *interestRateDaily = new InterestRate(d1Quote, Actual365Fixed(), Compounded, Daily); double discountFactorDaily = interestRateDaily ->discountFactor(elapsedTime); Got the following results: - computed by YieldTermStructure.discount(): 0.809476 - discountFactorAnnual: 0.842895 - discountFactorDaily: 0.781736 (close to Continuous compounding 1 / e^(r * t) = 1 / e^(1 * 90/365.0)) I also tried placing a breakpoint in the constructor of InterestRate with the intention to see if used inside YieldTermStructure.discount() - but the breakpoint never got hit so it seems the code doesn't use InterestRate for computation. So it looks like YieldTermStructure.discount() does a computation of it's own, which doesn't fall on any known pattern. Perhaps it is a bug? ----- P.S. Now i got into another source of confusement: QuantLib Compounded InterestRate results in the values presented above for annual and daily. But replicating the result by hand, results in: - annual: 1 / (1 + 1 / 1) ^ (1 * (90/365)) = 0.842895 (same as QuantLib) - daily: 1 / (1 + 1 / 365) ^ (365 * (90/365)) = 0.7838777 (different from QuantLib!) I have to dig deeper into these calculations... Regards, Mihai Bunea. |
Mihai,
Your code had just one curve node, 90 days. Everything before or after that is extrapolation and you should look at extrapolation rules before checking the discount factor. Try adding more points in your curve. Regarding InterestRate, I meant you should play a little with it in order to understand rate/factor conversion. -- Sent from my Android phone with K-9 Mail. Please excuse my brevity. ------------------------------------------------------------------------------ Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)! Finally, a world-class log management solution at an even better price-free! Download using promo code Free_Logger_4_Dev2Dev. Offer expires February 28th, so secure your free ArcSight Logger TODAY! http://p.sf.net/sfu/arcsight-sfd2d _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
On Wed, 2011-01-26 at 07:00 -0300, Piter Dias wrote:
> Your code had just one curve node, 90 days. That might also be the problem. If you're passing 90 days as the tenor, the deposit-rate helper takes it to be 90 business days, not calendar days (the reason for this is that when using days, one is almost always specifying deposits such as the overnight, spot-next etc. for which you want this kind of behavior.) Thus, if you pass 90 days, you'll get more than 4 months, instead of the 3 you expected. If you want 3 months, you'll have to pass three months. This said, if you want to check for consistency, you should call your curve's nodes() method, which returns the vector of (date,discount) pairs which is interpolated to return the results. This way, you can see exactly what dates are being used (which might move, due to holiday adjustments) and what discounts are calculated for those dates based on the input rates. Luigi -- Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Martin Golding ------------------------------------------------------------------------------ Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)! Finally, a world-class log management solution at an even better price-free! Download using promo code Free_Logger_4_Dev2Dev. Offer expires February 28th, so secure your free ArcSight Logger TODAY! http://p.sf.net/sfu/arcsight-sfd2d _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
In reply to this post by Piter Dias-4
Thanks Piter,
i'll do some more tests with InterestRate and YieldTermStructure (before possibly asking more questions). Regards, Mihai Bunea. |
Free forum by Nabble | Edit this page |