public void TestBondOptionPrice() { var settleDate = new Date(2008, 1, 17); // Option related var maturityDate = new Date(2009, 8, 1); // Bond related var forwardDate = new Date(2008, 4, 17); // Forward related var notional = 1000000.0; // var annualCouponRate = 0.13; // According to JSE Bond Pricer for R153 var couponMonth1 = 2; // var couponDay1 = 28; // var couponMonth2 = 8; // var couponDay2 = 31; // var booksCloseDateDays = 10; // var zaCalendar = new Calendar("Test"); // var bondOptionR153 = new JSEBondOption(forwardDate, maturityDate, PutOrCall.Call, settleDate); // var bondForwardR153 = new JSEBondForward(forwardDate, maturityDate, notional, annualCouponRate, couponMonth1, couponDay1, couponMonth2, couponDay2, booksCloseDateDays, zaCalendar, TestHelpers.ZAR); var ytm = 0.0930; // var repo = 0.1075; // See example var strike = 0.09; // var vol = 0.07; // var results = JSEBondOptionEx.BlackOption(bondOptionR153, strike, vol, repo, bondForwardR153, ytm); Assert.AreEqual(103.8547113436135, (double)results.GetScalar(JSEBondOptionEx.Keys.BlackOption), 1e-8); }
/// <summary> /// /// </summary> /// <param name="bondforward"></param> /// <param name="settleDate"></param> /// <param name="ytm"></param> /// <param name="repo"></param> /// <returns></returns> public static ResultStore ForwardPrice(this JSEBondForward bondforward, Date settleDate, double ytm, double repo) { var N = 100.0; var couponamount = N * bondforward.underlyingBond.annualCouponRate / 2; var forwardDate = bondforward.forwardDate; if (settleDate > forwardDate) { throw new ArgumentException("settlement date must be before forward date."); } // get all-in price of underlying bond var results = bondforward.underlyingBond.GetSpotMeasures(settleDate, ytm); var AIP = (double)results.GetScalar(BesaJseBondEx.Keys.RoundedAip); // calculate Unadjusted Forward Price var dt = (double)(forwardDate - settleDate) / 365; var ForwardPrice = AIP * (1 + repo * dt); // get coupon dates between settlement and forward date and calculate equivalent value function var CouponDates = GetCouponDates(bondforward.underlyingBond, settleDate, forwardDate); // adjust forward price for any coupons the counterparty might receive var EV = new List <double>(); double AdjustedForwardPrice = 0; if (CouponDates.Any()) { foreach (var date in CouponDates) { if (date <= forwardDate) { EV.Add(1 + repo * (forwardDate - date) / 365); } else { EV.Add(Math.Pow(1 + repo * (date - forwardDate) / 365, -1)); } } AdjustedForwardPrice = ForwardPrice - couponamount * EV.Sum(); } else { AdjustedForwardPrice = ForwardPrice; } var resultStore = new ResultStore(); resultStore.Add(Keys.ForwardPrice, AdjustedForwardPrice); return(resultStore); }
public static double BesaJseForwardPrice( [ExcelArgument(Description = "The underlying bond.")] JSEBondForward bondforward, [ExcelArgument(Description = "The settlement date of the bond.")] Date settleDate, [ExcelArgument(Description = "The yield to maturity of the bond.")] double ytm, [ExcelArgument(Description = "The repo rate of the bond.")] double repo) { var result = (double)bondforward.ForwardPrice(settleDate, ytm, repo).GetScalar(JSEBondForwardEx.Keys.ForwardPrice); return(result); }
// HelpTopic = "http://www.quantsa.org/")] // TODO: public static double FormulaBondOption([ExcelArgument(Description = "The underlying bond option.")] JSEBondOption bondOptionR153, [ExcelArgument(Description = "The strike/struck rate of the option.")] double strike, [ExcelArgument(Description = "Annualized volatility.")] double vol, [ExcelArgument(Description = "The repo rate of the deal.")] double repo, [ExcelArgument(Description = "The yield to maturity of the bond.")] double ytm, [ExcelArgument(Description = "The underlying bond forward from which the forward price is derived.")] JSEBondForward bondForward) { var bondOptionPrice = (double)JSEBondOptionEx.BlackOption(bondOptionR153, strike, vol, repo, bondForward, ytm).GetScalar(JSEBondOptionEx.Keys.BlackOption); return(bondOptionPrice); }
public void TestSettlementDateGreaterThanForwardDate_ReturnArgumentException() { var settleDate = new Date(2006, 6, 20); var forwardDate = new Date(2006, 6, 19); var maturityDate = new Date(2026, 12, 21); var notional = 1000000.0; var annualCouponRate = 0.105; var couponMonth1 = 6; var couponDay1 = 21; var couponMonth2 = 12; var couponDay2 = 21; var booksCloseDateDays = 10; var zaCalendar = new Calendar("Test"); var bondForward = new JSEBondForward(forwardDate, maturityDate, notional, annualCouponRate, couponMonth1, couponDay1, couponMonth2, couponDay2, booksCloseDateDays, zaCalendar, TestHelpers.ZAR); var ytm = 0.0715; var repo = 0.065; Assert.ThrowsException <ArgumentException>(() => bondForward.ForwardPrice(settleDate, ytm, repo)); }
public void TestBondForwardPrice() { var settleDate = new Date(2008, 1, 17); var forwardDate = new Date(2008, 4, 17); var maturityDate = new Date(2009, 8, 1); var notional = 1000000.0; var annualCouponRate = 0.13; var couponMonth1 = 2; var couponDay1 = 28; var couponMonth2 = 8; var couponDay2 = 31; var booksCloseDateDays = 10; var zaCalendar = new Calendar("Test"); var bondForward = new JSEBondForward(forwardDate, maturityDate, notional, annualCouponRate, couponMonth1, couponDay1, couponMonth2, couponDay2, booksCloseDateDays, zaCalendar, TestHelpers.ZAR); var ytm = 0.0930; var repo = 0.1075; var results = bondForward.ForwardPrice(settleDate, ytm, repo); Assert.AreEqual(106.76579546732876, (double)results.GetScalar(JSEBondForwardEx.Keys.ForwardPrice), 1e-8); }
// No books close date that lies in between settlement and forward date public void TestForwardPriceCase3() { var settleDate = new Date(2006, 6, 1); var forwardDate = new Date(2006, 6, 8); var maturityDate = new Date(2026, 12, 21); var notional = 1000000.0; var annualCouponRate = 0.105; var couponMonth1 = 6; var couponDay1 = 21; var couponMonth2 = 12; var couponDay2 = 21; var booksCloseDateDays = 10; var zaCalendar = new Calendar("Test"); var bondForward = new JSEBondForward(forwardDate, maturityDate, notional, annualCouponRate, couponMonth1, couponDay1, couponMonth2, couponDay2, booksCloseDateDays, zaCalendar, TestHelpers.ZAR); var ytm = 0.0715; var repo = 0.065; var results = bondForward.ForwardPrice(settleDate, ytm, repo); Assert.AreEqual(140.63595504, (double)results.GetScalar(JSEBondForwardEx.Keys.ForwardPrice), 1e-8); }
public static ResultStore BlackOption(JSEBondOption bondoption, double strike, double vol, double repo, JSEBondForward bond, double yieldToMaturity) { var settleDate = bondoption.settleDate; var timeToMaturity = bondoption.timeToMaturity; var ytm = yieldToMaturity; var bondforwardprice1 = (double)bond.ForwardPrice(settleDate, ytm, repo).GetScalar(JSEBondForwardEx.Keys.ForwardPrice); var discountFactor = Math.Exp(-repo * timeToMaturity); var optionPrice = BlackEtc.Black(PutOrCall.Call, strike, timeToMaturity, bondforwardprice1, vol, discountFactor); var resultStore = new ResultStore(); resultStore.Add(Keys.BlackOption, optionPrice); return(resultStore); }