Futures conversion factors in Mathematica

Sovereign debt futures in the U.S. and elsewhere are designed to accept multiple different bonds for delivery. The exchange specifies a delivery factor algorithm to normalize the prices of these bonds (or notes) to make them roughly of equal value upon delivery. Since they’re not precisely of equal value, traders can make money trading around the cheapest to deliver bond.

The conversion factor in the U.S. is designed to convert the yield on any bond or note to 6%. Considering the semi-annual or monthly coupon payments on bonds and notes, the formula to do this looks as follows.

Options[conversionfactor] = {type -> "bond"};
(* versus "10yr note", "5yr note", or "2yr note" *)

conversionfactor[coupon_Real, wholeYearsToMaturity_Integer,
stubMonthsToMatury_Integer, OptionsPattern[]] :=
Module[{v, a, b, c, d},
v = If[stubMonthsToMatury < 7, stubMonthsToMatury, If[OptionValue[type] == "bond" || OptionValue[type] == "10yr note", 3, stubMonthsToMatury - 6]](* for 10 year, other options possible for other instruments *); a = 1/1.03^(v/6); b = coupon/2*(6 - v)/6; c = If[stubMonthsToMatury < 7, 1/1.03^(2*wholeYearsToMaturity), 1/ 1.03^(2*wholeYearsToMaturity + 1)]; d = coupon/.06*(1 - c); a*(coupon/2 + c + d) - b]

wholeYearsToMaturity represents the number of whole years from the first day of the delivery month to the maturity (or call) date of the bond or note.

stubMonthsToMatury represents the number of whole months between wholeYearsToMaturity and the maturity (or call) date rounded down to the nearest quarter for Treasury Bonds and 10 Year Note futures, or to the nearest month for 5-year and 2-year note futures.

For a 2 year note with 1 year, 10 months remaining and a coupon of .015,

In[]:= conversionfactor[.015, 1, 10, type -> "2yr note"]
Out[]= 0.922939

For a 5 year note with 4 years, 10 months remaining and a coupon of .0275

In[]:= conversionfactor[.0275, 4, 10, type -> "5yr note"]
Out[]= 0.86533