# Select Cheapest-to-Deliver Bond Using `BondFuture` Instrument

This example shows how to select the cheapest-to-deliver (CTD) bond for Treasury bond future contracts using a `BondFuture` instrument. It demonstrates two workflows for selecting the CTD bond:

When a Treasury bond future contract matures, the party that is in the short position of the contract can deliver the underlying bond to the party that is in the long position of the contract. Typically, there can be many different bonds that satisfy the terms of the contract during the delivery month. For example, you can meet the delivery obligation for a 30-year US Treasury bond future contract with any US Treasury bond that has at least 15 years to maturity at the time of delivery. Furthermore, these deliverable bonds can have different coupons and maturities. Since the party in the short position has the option to choose which bond to deliver from these deliverable bonds, it is in the interest of that party to select the CTD bond that minimizes the delivery cost. You can select the CTD bond at the time of delivery during the delivery month of the future contract using the current market prices. Alternatively, you can predict the CTD bond several months before the delivery month based on the current zero curve.

### Select CTD Bond at Time of Delivery

In this workflow, you determine the delivery cost by comparing the invoice price that the short position receives from the long position against the price of the deliverable bond. For a particular deliverable bond, the invoice price that the short position receives from the long position is:

```InvoicePrice = (QuotedFuturePrice x ConversionFactor + AccruedInterest)/BondPrincipal x FutureNotional ```

For example, in the 30-year US Treasury bond futures market, typically, `BondPrincipal` is \$100 and `FutureNotional` is \$100,000. In return, the short position delivers the bond to the long position by buying the deliverable bond that has the following purchase cost in the market:

```PurchaseCost = (SpotPrice + AccruedInterest)/BondPrincipal x FutureNotional ```

Here, `SpotPrice` is the clean market price of the bond at the time of delivery. From this purchase cost, subtracting the invoice amount to be received by the short position from the long position gives the following formula for the overall delivery cost:

```OverallDeliveryCost = (SpotPrice - QuotedFuturePrice x ConversionFactor)/BondPrincipal x FutureNotional ```

You can compute the delivery cost for every deliverable bond and determine the CTD bond by selecting the bond with the lowest delivery cost. The `OverallDeliveryCost` formula applies only at the time of delivery. This method is equivalent to using the `cashsettle` method of the `BondFuture` instrument at the time of delivery. To demonstrate this workflow, the following example uses fictitious data, and selects the CTD bond using the `BondFuture` instrument on the delivery day of a hypothetical 30-year US Treasury bond future contract maturing in December 2021.

```% Create a zero curve. Settle = datetime(2021,12,21); ZeroDates = Settle + [calmonths([1 2 3 6]) calyears([1 2 3 5 7 10 20 30])]'; ZeroRates = [0.06 0.04 0.06 0.07 0.21 0.60 0.95 1.34 1.60 1.69 2.15 2.05]'./100; ZeroCurve = ratecurve("zero",Settle,ZeroDates,ZeroRates,Compounding=2); % Define the data for the deliverable bonds. ReferenceDate = datetime(2021,12,1); BondMaturity = datetime(datevec(["2/15/2045","2/15/2037","8/15/2040",... "5/15/2041","5/15/2037","2/15/2042","11/15/2043","11/15/2044",... "5/15/2038","2/15/2041"],'mm/dd/yyyy')); CouponRate = [2.5 4.75 3.875 2.25 5.0 3.125 3.75 3.0 4.5 4.75]'/100; IssueDate = datetime(datevec(["2/17/2015","2/15/2007","8/16/2010",... "6/1/2021","8/15/2007","2/15/2012","11/15/2013","11/17/2014",... "8/15/2008","2/15/2011"],'mm/dd/yyyy')); SpotPrice = [109.06;140.78;130.60;104.04;144.02;119.03;131.05;118.23;138.08;145.25]; NumBonds = length(BondMaturity); BondID = (1:NumBonds)'; % Use convfactor to compute the conversion factors. ConversionFactor = convfactor(ReferenceDate,BondMaturity,CouponRate)```
```ConversionFactor = 10×1 0.5664 0.8775 0.7645 0.5752 0.9009 0.6677 0.7286 0.6302 0.8456 0.8594 ```
```% Create a vector of FixedBond instruments. BondPrincipal = 100; DeliverableBonds = fininstrument("FixedBond",Maturity=BondMaturity,... CouponRate=CouponRate,IssueDate=IssueDate,Principal=BondPrincipal)```
```DeliverableBonds=10×1 object 10x1 FixedBond array with properties: CouponRate Period Basis EndMonthRule Principal DaycountAdjustedCashFlow BusinessDayConvention Holidays IssueDate FirstCouponDate LastCouponDate StartDate Maturity Name ```
```% Create a vector of BondFuture instruments. FutureMaturity = datetime(2021,12,21); QuotedFuturePrice = 159.53; FutureNotional = 100000; BondFutureContracts = fininstrument("BondFuture",Maturity=FutureMaturity,... QuotedPrice=QuotedFuturePrice,Bond=DeliverableBonds,... ConversionFactor=ConversionFactor,Notional=FutureNotional)```
```BondFutureContracts=10×1 object 10x1 BondFuture array with properties: Maturity QuotedPrice Bond ConversionFactor Notional Name ```

To compute the delivery cost, use the `cashsettle` method of the `BondFuture` instrument to compute the delivery cost because this method estimates the undiscounted net cash settlement amount that could be paid by the short position to the long position at future maturity instead of physical delivery.

```% Use the cashsettle method to compute the delivery costs. DeliveryCost = nan(NumBonds,1); for k=1:NumBonds outCS = cashsettle(BondFutureContracts(k), SpotPrice(k), ZeroCurve); DeliveryCost(k) = outCS.CashSettleAmount; end % List the deliverable bonds and delivery costs in a table. DeliverableBondTable = table(BondID, BondMaturity, IssueDate, ... CouponRate, SpotPrice, ConversionFactor, DeliveryCost)```
```DeliverableBondTable=10×7 table BondID BondMaturity IssueDate CouponRate SpotPrice ConversionFactor DeliveryCost ______ ____________ ___________ __________ _________ ________________ ____________ 1 15-Feb-2045 17-Feb-2015 0.025 109.06 0.56643 18697 2 15-Feb-2037 15-Feb-2007 0.0475 140.78 0.8775 792.87 3 15-Aug-2040 16-Aug-2010 0.03875 130.6 0.76447 8643.6 4 15-May-2041 01-Jun-2021 0.0225 104.04 0.57524 12272 5 15-May-2037 15-Aug-2007 0.05 144.02 0.9009 299.73 6 15-Feb-2042 15-Feb-2012 0.03125 119.03 0.66773 12508 7 15-Nov-2043 15-Nov-2013 0.0375 131.05 0.72859 14818 8 15-Nov-2044 17-Nov-2014 0.03 118.23 0.63022 17690 9 15-May-2038 15-Aug-2008 0.045 138.08 0.84558 3185.1 10 15-Feb-2041 15-Feb-2011 0.0475 145.25 0.85942 8146.4 ```

Once you have computed the delivery costs for all of the deliverable bonds, you can determine the CTD bond by selecting the bond with the lowest delivery cost.

```% Determine the CTD bond with the lowest delivery cost. [~,CTDBondIdx] = min(DeliverableBondTable.DeliveryCost); CTDBondTableDecember2021 = DeliverableBondTable(CTDBondIdx,:)```
```CTDBondTableDecember2021=1×7 table BondID BondMaturity IssueDate CouponRate SpotPrice ConversionFactor DeliveryCost ______ ____________ ___________ __________ _________ ________________ ____________ 5 15-May-2037 15-Aug-2007 0.05 144.02 0.9009 299.73 ```
`BondFutureContracts(CTDBondIdx)`
```ans = BondFuture with properties: Maturity: 21-Dec-2021 QuotedPrice: 159.5300 Bond: [1x1 fininstrument.FixedBond] ConversionFactor: 0.9009 Notional: 100000 Name: "" ```

Among the ten deliverable bonds, the CTD bond with the lowest delivery cost for the December 2021 future contract is the bond with a 5% coupon rate maturing on May 15, 2037. This CTD bond is determined at the time of delivery on December 21, 2021.

Since the delivery costs in this example are computed at the time of delivery, the delivery costs computed by the `cashsettle` method of the `BondFuture` instrument for this future contract are in agreement with those computed using the following formula for the overall delivery cost at delivery:

```OverallDeliveryCost = (SpotPrice - QuotedFuturePrice x ConversionFactor)/BondPrincipal x FutureNotional ```
```% Compare calculated delivery cost using cashsettle with the delivery cost formula. DeliveryCostFormula = ... (SpotPrice - QuotedFuturePrice.*ConversionFactor)/BondPrincipal*FutureNotional; table(DeliveryCostFormula, DeliveryCost)```
```ans=10×2 table DeliveryCostFormula DeliveryCost ___________________ ____________ 18697 18697 792.87 792.87 8643.6 8643.6 12272 12272 299.73 299.73 12508 12508 14818 14818 17690 17690 3185.1 3185.1 8146.4 8146.4 ```

### Select CTD Bond Months Before Delivery Month

The previous overall delivery cost formula applies only at the time of delivery. However, if a current zero curve is available, you can still compute the estimated delivery cost using the `cashsettle` method of the `BondFuture` instrument, even when it is several months before the delivery month. In the following example, you select the CTD bond using the `BondFuture` instrument in November 2021 for a hypothetical 30-year US Treasury bond future contract maturing several months later in June 2022. The overall workflow is similar to the workflow in Select CTD Bond at Time of Delivery, except that you select the CTD bond several months before the delivery month and the overall delivery cost formula no longer applies.

```% Create a zero curve. Settle = datetime(2021,11,22); ZeroDates = Settle + [calmonths([1 2 3 6]) calyears([1 2 3 5 7 10 20 30])]'; ZeroRates = [0.07 0.04 0.05 0.07 0.20 0.63 0.95 1.34 1.57 1.65 2.09 2.01]'./100; ZeroCurve = ratecurve("zero",Settle,ZeroDates,ZeroRates,Compounding=2); % Define the data for the deliverable bonds. ReferenceDate = datetime(2022,6,1); BondMaturity = datetime(datevec(["11/15/2046","2/15/2038","11/15/2040",... "11/15/2041","5/15/2044","5/15/2042","5/15/2045","8/15/2041",... "8/15/2043","8/15/2039"],'mm/dd/yyyy')); CouponRate = [2.875 4.375 4.25 3.125 3.375 3.0 3.0 1.75 3.625 4.5]'/100; IssueDate = datetime(datevec(["11/15/2016","2/15/2008","11/15/2010",... " 11/15/2011","5/15/2014","5/15/2012","5/15/2015","8/31/2021",... "8/15/2013","8/17/2009"],'mm/dd/yyyy')); SpotPrice = [117.84;137.13;137.53;119.17;125.03;117.34;119.03;95.97;128.84;140.56]; NumBonds = length(BondMaturity); BondID = 10+(1:NumBonds)'; % Use convfactor to compute the conversion factors. ConversionFactor = convfactor(ReferenceDate,BondMaturity,CouponRate)```
```ConversionFactor = 10×1 0.6033 0.8375 0.8074 0.6743 0.6834 0.6555 0.6302 0.5220 0.7185 0.8415 ```
```% Create a vector of FixedBond instruments. BondPrincipal = 100; DeliverableBonds = fininstrument("FixedBond",Maturity=BondMaturity, ... CouponRate=CouponRate,IssueDate=IssueDate,Principal=BondPrincipal)```
```DeliverableBonds=10×1 object 10x1 FixedBond array with properties: CouponRate Period Basis EndMonthRule Principal DaycountAdjustedCashFlow BusinessDayConvention Holidays IssueDate FirstCouponDate LastCouponDate StartDate Maturity Name ```
```% Create a vector of BondFuture instruments. FutureMaturity = datetime(2022,6,21); QuotedFuturePrice = 160.31; FutureNotional = 100000; BondFutureContracts = fininstrument("BondFuture",Maturity=FutureMaturity, ... QuotedPrice=QuotedFuturePrice,Bond=DeliverableBonds, ... ConversionFactor=ConversionFactor,Notional=FutureNotional)```
```BondFutureContracts=10×1 object 10x1 BondFuture array with properties: Maturity QuotedPrice Bond ConversionFactor Notional Name ```
```% Use the cashsettle method to compute the delivery costs. DeliveryCost = nan(NumBonds,1); for k=1:NumBonds outCS = cashsettle(BondFutureContracts(k), SpotPrice(k), ZeroCurve); DeliveryCost(k) = outCS.CashSettleAmount; end % List the deliverable bonds and delivery costs in a table. DeliverableBondTable = table(BondID, BondMaturity, IssueDate, ... CouponRate, SpotPrice, ConversionFactor, DeliveryCost)```
```DeliverableBondTable=10×7 table BondID BondMaturity IssueDate CouponRate SpotPrice ConversionFactor DeliveryCost ______ ____________ ___________ __________ _________ ________________ ____________ 11 15-Nov-2046 15-Nov-2016 0.02875 117.84 0.60331 19515 12 15-Feb-2038 15-Feb-2008 0.04375 137.13 0.8375 409.62 13 15-Nov-2040 15-Nov-2010 0.0425 137.53 0.80741 5695.6 14 15-Nov-2041 15-Nov-2011 0.03125 119.17 0.67433 9314.9 15 15-May-2044 15-May-2014 0.03375 125.03 0.68337 13582 16 15-May-2042 15-May-2012 0.03 117.34 0.65551 10574 17 15-May-2045 15-May-2015 0.03 119.03 0.63022 16318 18 15-Aug-2041 31-Aug-2021 0.0175 95.97 0.52204 11320 19 15-Aug-2043 15-Aug-2013 0.03625 128.84 0.71855 11618 20 15-Aug-2039 17-Aug-2009 0.045 140.56 0.84151 3125.4 ```
```% Determine the CTD bond with the lowest delivery cost. [~,CTDBondIdx] = min(DeliverableBondTable.DeliveryCost); CTDBondTableJune2022 = DeliverableBondTable(CTDBondIdx,:)```
```CTDBondTableJune2022=1×7 table BondID BondMaturity IssueDate CouponRate SpotPrice ConversionFactor DeliveryCost ______ ____________ ___________ __________ _________ ________________ ____________ 12 15-Feb-2038 15-Feb-2008 0.04375 137.13 0.8375 409.62 ```
`BondFutureContracts(CTDBondIdx)`
```ans = BondFuture with properties: Maturity: 21-Jun-2022 QuotedPrice: 160.3100 Bond: [1x1 fininstrument.FixedBond] ConversionFactor: 0.8375 Notional: 100000 Name: "" ```

Among the ten deliverable bonds, the CTD bond with the lowest delivery cost for the June 2022 future contract is the bond with a 4.375% coupon rate maturing on February 15, 2038. This CTD bond is predicted using the zero curve available on November 22, 2021, which is several months before the delivery month in June 2022.