private double[] GetGridTimes(CallableBond callableBond, IMarketCondition market) { var grids = new[] { market.ValuationDate.Value } .Union(GetGridDates(callableBond, market)) .Select(x => market.DiscountCurve.Value.DayCount.CalcDayCountFraction(market.ValuationDate.Value, x)) .ToArray(); if (_steps == 0) { return(grids); } else { var newGrids = new List <double>(); var dtMax = (grids.Last() - grids[0]) / (_steps); newGrids.Add(grids[0]); for (var i = 1; i < grids.Length; ++i) { var begin = grids[i - 1]; var end = grids[i]; var n = (int)((end - begin) / dtMax + 0.5); if (n == 0) { n = 1; } var dt = (end - begin) / n; for (var j = 1; j <= n; ++j) { newGrids.Add(begin + j * dt); } } return(newGrids.ToArray()); } }
public DiscretizedCallableFixedRateBond(CallableBond.Arguments args, Date referenceDate, DayCounter dayCounter) { arguments_ = args; redemptionTime_ = dayCounter.yearFraction(referenceDate, args.redemptionDate); for (int i = 0; i < args.couponDates.Count ; ++i) couponTimes_.Add(dayCounter.yearFraction(referenceDate, args.couponDates[i])); for (int i = 0; i < args.callabilityDates.Count ; ++i) callabilityTimes_.Add( dayCounter.yearFraction(referenceDate, args.callabilityDates[i])); // similar to the tree swaption engine, we collapse similar coupon // and exercise dates to avoid mispricing. Delete if unnecessary. for (int i = 0; i < callabilityTimes_.Count; i++) { double exerciseTime = callabilityTimes_[i]; for (int j = 0; j < couponTimes_.Count ; j++) { if (withinNextWeek(exerciseTime, couponTimes_[j])) couponTimes_[j] = exerciseTime; } } }
public OasSpreadSolver(CallableBond callableBond, IMarketCondition market, CallableBondEngine <TInterestRateModel> engine) { _callableBond = callableBond; _market = market; _engine = engine; }
public override IPricingResult Calculate(CallableBond callableBond, IMarketCondition market, PricingRequest request) { var result = new PricingResult(market.ValuationDate, request); if (result.IsRequested(PricingRequest.Pv)) { result.Pv = CalcPv(callableBond, market); } return(result); }
public void TestCallableBond() { var valueDate = new Date(2017, 1, 23); var a = 0.05; var vol = 0.01; var flatCurveRate = 0.18; var hullWiteSim = new HullWhite1F(TestHelpers.ZAR, a, vol, flatCurveRate, flatCurveRate); var coordinator = new Coordinator(hullWiteSim, new List <Simulator>(), 5000); var callableBond = new CallableBond(TestHelpers.ZAR); var value1 = coordinator.Value(new Product[] { callableBond }, valueDate); }
public void TestCallableBond() { Date valueDate = new Date(2017, 1, 23); double a = 0.05; double vol = 0.01; double flatCurveRate = 0.18; HullWhite1F hullWiteSim = new HullWhite1F(Currency.ZAR, a, vol, flatCurveRate, flatCurveRate, valueDate); Coordinator coordinator = new Coordinator(hullWiteSim, new List <Simulator>(), 5000); CallableBond callableBond = new CallableBond(); double value1 = coordinator.Value(new Product[] { callableBond }, valueDate); }
private Date[] GetGridDates(CallableBond callableBond, IMarketCondition market) { var dates = new List <Date> { callableBond.UnderlyingMaturityDate } .Union(callableBond.Bond.GetCashflows(market) .Select(cf => cf.PaymentDate)) .ToArray(); var exerciseDates = callableBond.EmbededOptions.SelectMany(x => x.ExerciseDates).ToArray(); if (_adjustCouponDates) { dates = AdjustToGrid(dates, exerciseDates); } return(dates.Union(exerciseDates).Where(x => x >= market.ValuationDate.Value).OrderBy(x => x).ToArray()); }
public void TestCallableBond() { var bond = new Bond( "010001", new Date(2012, 05, 03), new Date(2017, 05, 03), 100, CurrencyCode.CNY, new FixedCoupon(0.068), CalendarImpl.Get("chn_ib"), Frequency.Annual, Stub.LongEnd, new ActActIsma(), new ActAct(), BusinessDayConvention.None, BusinessDayConvention.ModifiedFollowing, null, TradingMarket.ChinaInterBank ); var option = new VanillaOption(new Date(2012, 05, 03), new Date(2017, 05, 03), OptionExercise.European, OptionType.Put, 106.8, InstrumentType.Bond, CalendarImpl.Get("chn_ib"), new Act365(), CurrencyCode.CNY, CurrencyCode.CNY, new[] { new Date(2015, 05, 03) }, new[] { new Date(2015, 05, 03) } ); var callableBond = new CallableBond(bond, new[] { option }, new[] { PriceQuoteType.Dirty }); var market = TestMarket(); var engine = new CallableBondEngine <HullWhite>(new HullWhite(0.1, 0.01), true, 40); var result = engine.Calculate(callableBond, market, PricingRequest.All); Assert.AreEqual(107.0198942139, result.Pv, 1e-8); }
public double CalcPv(CallableBond callableBond, IMarketCondition market) { var referenceDate = market.ValuationDate.Value; var yieldCurve = market.DiscountCurve.Value; var dayCount = yieldCurve.DayCount; var gridTimes = GetGridTimes(callableBond, market); var tree = _model.Tree(gridTimes, 0.0, yieldCurve); var cashflows = GetCashflows(callableBond, market) .Where(cf => cf.PaymentDate >= market.ValuationDate.Value) .Select(cf => Tuple.Create(dayCount.CalcDayCountFraction(referenceDate, cf.PaymentDate), cf.PaymentAmount) ).ToList(); var exerciseInfos = callableBond.GetExerciseInfo(market) .Select(x => Tuple.Create( dayCount.CalcDayCountFraction(referenceDate, x.Item1), (INumericCondition) new CallPutCondition(x.Item2, x.Item3)) ).ToList(); var priceOnGrids = tree.ReverseInduction(cashflows, exerciseInfos); return(priceOnGrids[0][0]); }
private Cashflow[] GetCashflows(CallableBond callableBond, IMarketCondition market) { var exerciseDates = callableBond.EmbededOptions.SelectMany(x => x.ExerciseDates).ToArray(); if (_adjustCouponDates) { return(callableBond.GetCashflows(market) .Select(cf => new Cashflow( cf.AccrualStartDate, cf.AccrualEndDate, AdjustToGrid(new[] { cf.PaymentDate }, exerciseDates)[0], cf.PaymentAmount, cf.PaymentCurrency, cf.CashflowType, cf.IsFixed, market.GetDf(AdjustToGrid(new[] { cf.PaymentDate }, exerciseDates)[0]), cf.CalculationDetails) ).ToArray()); } return(callableBond.GetCashflows(market)); }
public void Test101658062_IB() { var bond = new Bond( "101658062.IB", new Date(2016, 10, 27), new Date(2029, 10, 27), 100, CurrencyCode.CNY, new FixedCoupon(0.045), CalendarImpl.Get("chn_ib"), Frequency.Annual, Stub.LongEnd, new ActActIsma(), new ActAct(), BusinessDayConvention.None, BusinessDayConvention.ModifiedFollowing, null, TradingMarket.ChinaInterBank, false, null, null, false, double.NaN, Double.NaN, AmortizationType.None, null, null, false, new Dictionary <int, double> { { 4, 0.03 } } ); var options = new List <VanillaOption>(); var start = new Date(2016, 10, 27); for (var k = 1; k < 16; k++) { var term = new Term(k, Period.Year); var maturity = term.Next(start); if (maturity > bond.UnderlyingMaturityDate) { continue; ; } options.Add(new VanillaOption(start, maturity, OptionExercise.European, OptionType.Call, 100, InstrumentType.Bond, CalendarImpl.Get("chn_ib"), new Act365(), CurrencyCode.CNY, CurrencyCode.CNY, new[] { maturity }, new[] { maturity } )); } var callableBond = new CallableBond(bond, options.ToArray(), options.Select(x => PriceQuoteType.Clean).ToArray()); var valueDates = new[] { new Date(2016, 10, 28), new Date(2016, 11, 01), new Date(2016, 11, 02), new Date(2016, 11, 03), new Date(2016, 11, 04), new Date(2016, 11, 07), }; foreach (var valueDate in valueDates) { var market = TestMarket2(valueDate); var engine = new CallableBondEngine <HullWhite>(new HullWhite(0.5196, 0.03157), true, 3); var result = engine.Calculate(callableBond, market, PricingRequest.All); Console.WriteLine("{0},{1}", valueDate, result.Pv); } }
private double OasSpread(CallableBond callableBond, IMarketCondition market, CallableBondEngine <TInterestRateModel> engine) { return(BrentZero.Solve(new OasSpreadSolver <TInterestRateModel>(callableBond, market, engine), -1.0, 1.0, 1e-12)); }