Hello, if you have any need, please feel free to consult us, this is my wechat: wx91due
FRE6831
COMPUTATIONAL FINANCE LABORATORY (PYTHON)
PROJECT: US TREASURY BOND ANALYTICS
The class project is to write Python code to implement a variety of standard bond analytics calculations. As stated in the syllabus, this project is in lieu of a final exam, so that it is due at 11:59 PM on the day that the final exam would have been scheduled. The first part of the project is intended only as a “warm up”, suitable for informal discussion with the TA and, perhaps, other students; it will not be graded. Not only can students use this opportunity to better prepare the second part of the project (which will be graded), but it will also give students the experience of modifying code that they have previously written. Hopefully, this experience will teach the importance of writing code that is easily modifiable, a skill that is very important for supporting actual, frequently changing business processes.
Background
Like most other governments, the federal government of the United States needs to borrow periodically to fund its operations. It does so by issuing a variety of securities known as
. bills (if the funds will be repaid at most a year after they are borrowed),
. notes (if the funds will be repaid between two and ten years after they are borrowed),
. bonds (if the funds will be repaid more than ten years after they are borrowed).
US Government debt issues that have an original maturity of more than 6 months make intermediate interest payments called “coupons”. Although the actual interest payout occurs semi-annually, coupons are usually given as apercentage of the face value that is paid out annually, with the understanding that half of that percentage is the actual payout (Thus, a bond that has a 3% coupon actually generates semi- annual simple interest payments of 1½% of face value.). The dates of these payouts are called “coupon dates”. Bond analytics formulas assume their simplest form on these dates.
US Government debt can be bought and sold; in fact, the so-called secondary market for this debt is the most active market in the world. Once such debt has been issued, its payment schedule is fixed, a fact that can make it either more or less attractive than the payment schedules of debt issued at other times, resulting in sales either above or below the original face or “par” value of the instrument: if the coupon rates for a particular issue exceed prevailing rates, buyers will be willing to pay more than par, but buyers will only be willing to buy the issue for less than par if coupon rates are less than prevailing rates.
The sale of government debt can take place on any business day, but coupons are only paid semi-annually. Settlement of such sales must therefore consist of two parts: transfer of ownership of the security and division of coupon payments. Because the rules for such transfers were formulated long before the internet made instantaneous settlement possible, the settlement date is the business day after the trade date, the date on which the terms of the purchase are agreed upon. It is the settlement date that is used for dividing a coupon payment between the first part of the coupon period, during which the seller still owns the security and should be receiving interest payments, and the second part of the coupon period, during which the buyer owns the security and should be receiving the interest.
Investors have devised various metrics to assess the risks and returns of the various treasury debt issues and related investments, and the project is to implement some of the more standard metrics, as described in great detail in the PowerPoint slide decks “Bond Pricing and YTM.pptx” and “Duration and PVBP.pptx” on BrightSpace (Please review these before reading further, so that you understand the terminology used below.).
The first part of the project is to create a module with the following Python functions:
. getPrice(N, r, c) returns the price of a bond as a percentage of its face value at a coupon date, given the number of coupon periods, N, a periodic discounting rate, r, and a periodic coupon, c (i.e. the formula on slide 11 of “Bond Pricing and YTM.pptx”, but with r in place of y and with c, the periodic coupon, in place of c/2, because c represents the annual coupon in the formula in the slide). Here, r is used in place of y/2 to make clear that this rate need not be the annualized yield to maturity, but any periodic rate that is chosen by the user. It also assumed that the coupon rate is expressed as a decimal and 100% of the face value is returned at maturity. While this price will always be positive, since it is the sum of future positive cashflows, it can be either less than or greater than 100% of the face value, representing the desirability of the bond’s promised cashflows relative to those of other securities currently available in the market.
. getPV01(N, r, c) returns the PV01 of the bond, given the number of payment periods, N, a periodic discounting rate, r, and a periodic coupon, c (the algorithm on slide 25 of “Duration and PVBP.pptx”, but with r in place of y). The slides make clear that there are a number of acceptable definitions, but getPV01 should compute the product of the (calculus!) derivative dP/dr, which is negative, with -0.01, to give the change in value of the bond when r, expressed as a percentage, declines by one basis point (1/100 %).
. getYTM(N, P, c) returns the yield to maturity of the bond, given the number of payment periods, N, the bond price, P, as a percentage of its face value, and a periodic coupon, c, at a coupon date (the algorithm on slide 14 of “Bond Pricing and YTM.pptx” which will return the per. period yield to maturity to an accuracy of 10- 14.). Note that the algorithm requires the calculation of dP/dr for various choices of r, so code a function to compute that and use it for both getModDur and getYTM.
. getModDur(N, P, y, c) returns the modified duration of the bond, given the number of payment periods, N, the bond price, P, as a percentage of its face value, y, the yield to maturity, and aperiodic coupon, c (the algorithm on slide 25 of “Duration and PVBP.pptx”).
. getConvexity(N, P, c) returns the convexity of the bond, given the number of payment periods, N, the bond price, P, as a percentage of its face value, and a periodic coupon, c, at a coupon date (the algorithm on slide 14 of “Bond Pricing and YTM.pptx”). Note that the algorithm requires the calculation of d2P/dr2 for various choices of r.
. getMacaulayDur(N, P, y, c) returns the Macaulay duration of the bond, given the
number of payment periods, N, the bond price, P, as a percentage of its face value, y, the yield to maturity, and a periodic coupon, c (the algorithm on slide 25 of “Duration and PVBP.pptx”).
. parseQuote(quoteString)returns a numeric bond price as a percentage of par, given a
bond quote as a string of the form described on slide 16 of “Bond Pricing and YTM.pptx”. Thus, the function would return 100.75, 100.765625, and 100. 0.7734375, given the respective inputs “100-24”, “100-24+”, and “100-24++”. Note that quoted bond prices are typically clean prices.
Notes:
1. Assume that all rates above are to be input or output as percentages, so, for example, an input rate of 3.00 is to be interpreted as 3%.
2. As per slide 19 of “Bond Pricing and YTM.pptx”, prices are computed differently if there is only one remaining coupon. getPrice , getModDur and getConvexity must therefore do different calculations depending on the number of coupons remaining.
The second part of the project is to create a USTreasurySecurity class, which exposes methods that are minor enhancements of the above functions and adds a few more. Objects instantiated from this class will be initialized via
sec = USTreasurySecurity(
quoteString, N, a, tradeDate, prevCouponDate, nextCouponDate holidayCalendar)
The first two of the arguments, quoteString and N, have the meanings given above. Assume that the quoted price is the clean price of the bond. a is the annualized coupon, which is twice the semi-annual periodic coupon. tradeDate, prevCouponDate and nextCouponDate are, respectively, the date on which the trade has taken place, the coupon date strictly before the settlement date, and the date of the next coupon payout on or after the settlement date, entered as strings of the form “ DD-MM-YYY” (Note that the accrued interest is computed from the settlement date, which is the next business day after the trade date.). holidayCalendar is a string which is the name of a file containing strings of the form “ DD-MM-YYY”, which are the Federal Reserve holidays (available in the Project folder on Brightspace) between the two semi-annual coupon dates. These holidays are needed because the rules stipulate that the settlement date is the next business day after the trade date, and computing the former from the latter requires skipping over weekends and holidays. Assume that the file is to, be read and the USTreasurySecurity class is to be imported from the current directory
The USTreasurySecurity class should include methods that are versions of the functions of the first part of the project, enhanced to support trading between coupon dates and likely use cases. For starters, modify the getPrice function of the first part of the project to be a private method that requires only the single argument r (Why needn’t the other parameters be passed as arguments?). This private method should use the pricing formulas of slides 19 and 20 of “Bond Pricing and YTM.pptx”, rather than the formula on slide 11. The private method and another private method that computes the derivative of the price in slides 19 and 20 should then be used to compute yield to maturity, which should, in turn, be used as the yield in the PV01 and modified duration calculations. The results of these calculations should be exposed as public methods (i.e. available to called whenever the USTreasurySecurity class is instantiated). Two additional public methods are required, namely getDirtyPrice and a getCleanPrice, the latter simply returning the numerical value obtained as the result of parseQuote.
Thus, once the sec object above is instantiated, we should be able to get the appropriate results from the following
print(sec.getYTM()) #prints yield to maturity of instantiated
bond
print(sec.getPV01()) #prints PV01 of instantiated bond
print(sec.getModDur()) #prints modified duration of instantiated
bond
print(sec.getDirtyPrice()) #prints dirty price of instantiated bond
print(sec.getMacaulayDur()) #prints Macaulay duration of instantiated
bond
print(sec.getConvexity()) #prints convexity of instantiated bond
print(sec.getCleanPrice()) #prints clean price of instantiated bond
Notes:
1. Units are even more important here than in the above. You will need the derivative of the price with respect to the per period yield in getYTM; however, the output of getYTM should be the annualized yield. Also, if getPV01 is to return the result of a one basis point change in the annualized yield, the per-period derivative there should be multiplied by 0.005, corresponding to half a basis point change in the per period yield.
2. The version of the above calculations that would actually be implemented by a financial
institution would probably inherit from a base class, such as FixedIncomeSecurity. In all likelihood, this base class would provide infrastructure not discussed in an introductory class, such as error handling and interfaces with realtime data feeds. Such a base class would also provide such infrastructure for similar calculations relevant to the debt issues of the British, Japanese, and other governments.
3. The formulas provided in the PowerPoint slides only apply to US Treasury Notes and Bonds. A different set of pricing formulas apply to US Treasury Bills.
4. EXCEL provides spreadsheet functions for many of the above calculations. An example of these, “Bond Pricing Calcs.xlsx” is posted on BrightSpace.,