public static void Compute(Bond bond, double constantAnnualInterestRate) { var par = bond.FaceValue; var c = bond.CouponPayment; var n = bond.TotalPaymentCounts; var r = constantAnnualInterestRate / bond.PaymentsPerYear; var mkt = bond.MarketPrice; // compute fair price var pvFaceValue = TimeValues.ComputePresentValue(par, n, r); var pvCoupon = TimeValues.ComputePresentValueOfCashFlows(c, n, r); bond.FairPrice = pvFaceValue + pvCoupon; // assign fair price to market price if not exist if (mkt == 0 || double.IsNaN(mkt)) { bond.MarketPrice = bond.FairPrice; } // compute ytm var cfs = new List <double> { -bond.FairPrice }; // cf0 = mktvalue or fair price at inception for (int i = 0; i < n - 1; i++) { cfs.Add(c); } cfs.Add(c + par); // cfn = last coupon + repaid par value bond.YieldRate = new IrrCalculator(cfs).Compute(); // compute maca/modified dura & dv01 ComputeDuration(bond, r); }
/// <summary> /// Compute Macauley, Modified and Dollar Durations. /// All of them uses bond.MarketPrice. /// For Effective Duration, please refer to /// </summary> /// <param name="bond"></param> /// <param name="constantAnnualInterestRate"></param> public static void ComputeDuration(Bond bond, double constantAnnualInterestRate) { var p = bond.FaceValue; var n = bond.TotalPaymentCounts; var c = bond.CouponPayment; var r = constantAnnualInterestRate / bond.PaymentsPerYear; var mkt = bond.MarketPrice; // compute maca dura var maca = 0.0; for (int i = 1; i <= n; i++) { maca += TimeValues.ComputePresentValue(i * c, i, r); } maca += TimeValues.ComputePresentValue(n * p, n, r); bond.MacauleyDuration = maca / mkt; // compute modified dura bond.ModifiedDuration = bond.MacauleyDuration / (1 + r); // compute dv01 bond.DollarDuration = mkt * bond.ModifiedDuration / 10000; }