Matching Bloomberg with the Bond Analytics Library


#1

Hi

We’ve been attempting to match the Price, Modified Duration and Convexity for a particular bond in Bloomberg using the OpenGamma Analytics library. However, so far we haven’t been able to match all three at once.

I think the problem might be the values that we are using to generate the flat risk-free and credit yield curves.
We’ve tried a number of values from Bloomberg (including Yield, Z-Spread, OAS). Any idea which particular values from the bond and risk-free instrument on Bloomberg should be used to create the curves?

Also, I’ve noticed that the bond analytics only supports two Yield Conventions (US_STREET and UK_BUMP_DMO_METHOD), the Bond is traded on a German exchange so I’m not sure if this is a problem.

I’ve included the Bloomberg screenshots for the bond instrument + the risk-free instrument, and the code used to perform the test.

http://imgur.com/sEnbDWv,sG41NRN,2MRTIoz,QBZuRiX,dwzkJKh

Thanks
Peter


#2

Hi,

I looked at the example you gave. If I see well, the Bloomberg example and the code do not correspond to the same bond (one is maturity 2022 and the other 2020).

The bond figures are conventional figures. In version 1.2 we have only US_STREET and UK_BUMP_DMO_METHOD, in the next version, we have added GERMAN_BOND (same as US_STREET) and FRANCE_COMPOUND_METHOD (difference only when in the last coupon period).

We have implemented method to computed yield, (clean and dirty) price, modified duration, etc. one from the other. It is important to use the right conventions, for the bond indicated in your screen it is: Day Count: “Actual/Actual ICMA”, Coupon 1.5%, maturity: 2022-9-4, coupon frequency: annual.

To compute the yield from the price, no curve is needed. The curves can be used to compute a price starting from the issuer specific discounting curves.

If you start from the clean price on the screen short: 1.0124, you can compute the other number with:
BondSecurityDiscountingMethod METHOD_BOND = BondSecurityDiscountingMethod.getInstance();
double cleanPriceInput = 1.0124;
double modifiedDuration = METHOD_BOND.modifiedDurationFromCleanPrice(bond, cleanPriceInput);
double yield = METHOD_BOND.yieldFromCleanPrice(bond, cleanPriceInput);
double dirtyPrice = METHOD_BOND.dirtyPriceFromCleanPrice(bond, cleanPriceInput);

It is also possible to compute then starting from a different initial number, like the yield. The method “BondSecurityDiscountingMethod” provides most of the combinations.

Using those methods the results (using your code, with the conventions changed to the one of the bond on the screen shot) are:
Yield: 0.013565312950256038
modifiedDuration: 8.52134902726142
accruedInterest: 10931.506849315068
CleanPrice: 1.0124
DirtyPrice: 1.023331506849315

They are matching the one on the screen shot.

I hope this helps.

Marc Henrard
OpenGamma


#3

Hi Marc

Thanks for that, the BondSecurityDiscountingMethod class should be useful.

However, the bond you performed the calculations for was the German Government Bond which we were trying to use as the basis for the risk-free curve.
There were multiple screenshots in the imgur link. Apologies, I should have made that more clear.

The bond we were actually trying to match Bloomberg for was UPCB 6-3/8 09/15/22 xs0832993397 which is shown in the fourth image.

UPCB 6-3/8 09/15/22 is actually a callable bond which is why I tried 2020 as the maturity because its listed as the workout date for the modified duration and convexity. I’ve now tried using the BondSecurityDiscountingMethod to perform the calculations for that bond again but the values are still a little off… but close.

OpenGamma vs Bloomberg
Convexity: 40.66497528968151 vs 0.412 (I’m guessing we need to divide OpenGamma Convexity by 100 to match the Bloomberg display format?)
Modified Duration: 5.760100517356581 vs 5.603

Any ideas?

Here’s a link to the revised code:

Cheers
Peter


#4

For the moment we do not support callable bond out-of-the-box. We support bonds and options like swaptions and will combine them as soon as a (paying) client is asking for it :wink:

Nevertheless it is possible to obtain the yield and other figures to the “worst” date like you are doing.

I looked at your fourth image. The figures for yield (street convention) and duration are (I don’t see convexity in the image):
date: 09/15/20
yield: 5.510765
Mod duration: 5.757

When running your new code on my machine, I have (adding the yield):
date: 09/15/20
Convexity: 40.66497528968151 yield: 0.05510764640259674 modifiedDuration: 5.7574173423074395 accruedInterest: 12927.083333333334 CleanPrice: 1.05125 DirtyPrice: 1.0641770833333333
Which is the same as your screen shot.

I’m not sure where the 5.603 in your comment comes from. I don’t see it on the fourth image.

Also changing the date to 2022 provide the same figures as your screen shot.

With regard to scaling, in OG-analytics, we always work with “decimal numbers”, not percent or basis points. We are internally consistent, but to compare with external figures, the quoted numbers need to be adjusted by their implicit “dimension” (like percent or basis points).

Regards,

Marc


#5

Hi Marc

Thanks for that.

There’s another Bloomberg tab for UPCB 6-3/8 09/15/22 xs0832993397 in the third image which is where I got my figures for Modified Duration and Convexity from.

It’s interesting because the figure you matched for mod duration is listed as adj duration in Bloomberg so I tried the Macaulay Duration to see if this matches the mod duration on image 3 but its even further out (5.916). Do you think these figures aren’t matching because it’s a callable bond?

Thanks
Peter