public void LessComplexCurve() { var startDate = new DateTime(2016, 05, 20); var depoTenors = new Frequency[] { 3.Months() }; var OISdepoTenors = new Frequency[] { 1.Bd() }; double[] depoPricesZAR = { 0.06 }; string[] FRATenors = { "3x6", "6x9", "9x12", "12x15", "15x18", "18x21", "21x24" }; double[] FRAPricesZAR = { 0.065, 0.07, 0.075, 0.077, 0.08, 0.081, 0.082 }; var ZARpillarDatesDepo = depoTenors.Select(x => startDate.AddPeriod(RollType.MF, _jhb, x)).ToArray(); var ZARpillarDatesFRA = FRATenors.Select(x => startDate.AddPeriod(RollType.MF, _jhb, new Frequency(x.Split('x')[1] + "M"))).ToArray(); var ZARpillarDates3m = ZARpillarDatesDepo.Union(ZARpillarDatesFRA).Distinct().OrderBy(x => x).ToArray(); var ZARdepos = new IrSwap[depoTenors.Length]; var ZARFRAs = new ForwardRateAgreement[FRATenors.Length]; var FIC = new FundingInstrumentCollection(); for (var i = 0; i < FRATenors.Length; i++) { ZARFRAs[i] = new ForwardRateAgreement(startDate, FRATenors[i], FRAPricesZAR[i], _zar3m, SwapPayReceiveType.Payer, FraDiscountingType.Isda, "ZAR.JIBAR.3M", "ZAR.JIBAR.3M") { SolveCurve = "ZAR.JIBAR.3M" }; FIC.Add(ZARFRAs[i]); } for (var i = 0; i < depoTenors.Length; i++) { ZARdepos[i] = new IrSwap(startDate, depoTenors[i], _zar3m, depoPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.JIBAR.3M") { SolveCurve = "ZAR.JIBAR.3M" }; FIC.Add(ZARdepos[i]); } var ZARcurve3m = new IrCurve(ZARpillarDates3m, new double[ZARpillarDates3m.Length], startDate, "ZAR.JIBAR.3M", Interpolator1DType.LinearFlatExtrap) { SolveStage = 0 }; var engine = new FundingModel(startDate, new IrCurve[] { ZARcurve3m }); var S = new NewtonRaphsonMultiCurveSolverStagedWithAnalyticJacobian(); //var S = new NewtonRaphsonMultiCurveSolverStaged(); S.Solve(engine, FIC); foreach (var ins in FIC) { var pv = ins.Pv(engine, false); Assert.Equal(0.0, pv, 7); } }
public static object CreateFRA( [ExcelArgument(Description = "Object name")] string ObjectName, [ExcelArgument(Description = "Value date")] DateTime ValDate, [ExcelArgument(Description = "FRA code e.g. 3X6")] string PeriodCode, [ExcelArgument(Description = "Rate Index")] string RateIndex, [ExcelArgument(Description = "Currency")] string Currency, [ExcelArgument(Description = "Par Rate")] double ParRate, [ExcelArgument(Description = "Notional")] double Notional, [ExcelArgument(Description = "Forecast Curve")] string ForecastCurve, [ExcelArgument(Description = "Discount Curve")] string DiscountCurve, [ExcelArgument(Description = "DiscountingType")] object DiscountingType, [ExcelArgument(Description = "Pay / Receive")] object PayRec, [ExcelArgument(Description = "Solve Curve name ")] object SolveCurve, [ExcelArgument(Description = "Solve Pillar Date")] object SolvePillarDate) { return(ExcelHelper.Execute(_logger, () => { var discType = DiscountingType.OptionalExcel("Isda"); var payRec = PayRec.OptionalExcel("Pay"); if (!ContainerStores.GetObjectCache <FloatRateIndex>().TryGetObject(RateIndex, out var rIndex)) { _logger?.LogInformation("Rate index {index} not found in cache", RateIndex); return $"Rate index {RateIndex} not found in cache"; } if (!Enum.TryParse(payRec, out SwapPayReceiveType pType)) { return $"Could not parse pay/rec - {payRec}"; } if (!Enum.TryParse(discType, out FraDiscountingType fType)) { return $"Could not parse FRA discounting type - {discType}"; } ContainerStores.CurrencyProvider.TryGetCurrency(Currency, out var ccy); var product = new ForwardRateAgreement(ValDate, PeriodCode, ParRate, rIndex.Value, pType, fType, ForecastCurve, DiscountCurve) { Notional = Notional, TradeId = ObjectName, SolveCurve = SolveCurve.OptionalExcel(rIndex.Name), Currency = ccy }; product.PillarDate = SolvePillarDate.OptionalExcel(product.FlowScheduleFra.Flows.Last().AccrualPeriodEnd); return ExcelHelper.PushToCache(product, ObjectName); })); }
public void testCurveConsistency <T, I, B>(CommonVars vars, I interpolator, double tolerance) where T : ITraits <YieldTermStructure>, new() where I : IInterpolationFactory, new() where B : IBootStrap <PiecewiseYieldCurve>, new() { vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.instruments, new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator); RelinkableHandle <YieldTermStructure> curveHandle = new RelinkableHandle <YieldTermStructure>(); curveHandle.linkTo(vars.termStructure); // check deposits for (int i = 0; i < vars.deposits; i++) { Euribor index = new Euribor(new Period(vars.depositData[i].n, vars.depositData[i].units), curveHandle); double expectedRate = vars.depositData[i].rate / 100, estimatedRate = index.fixing(vars.today); QAssert.IsTrue(Math.Abs(expectedRate - estimatedRate) < tolerance, vars.depositData[i].n + " " + (vars.depositData[i].units == TimeUnit.Weeks ? "week(s)" : "month(s)") + " deposit:" + "\n estimated rate: " + estimatedRate + "\n expected rate: " + expectedRate); } // check swaps IborIndex euribor6m = new Euribor6M(curveHandle); for (int i = 0; i < vars.swaps; i++) { Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units); VanillaSwap swap = new MakeVanillaSwap(tenor, euribor6m, 0.0) .withEffectiveDate(vars.settlement) .withFixedLegDayCount(vars.fixedLegDayCounter) .withFixedLegTenor(new Period(vars.fixedLegFrequency)) .withFixedLegConvention(vars.fixedLegConvention) .withFixedLegTerminationDateConvention(vars.fixedLegConvention); double expectedRate = vars.swapData[i].rate / 100, estimatedRate = swap.fairRate(); double error = Math.Abs(expectedRate - estimatedRate); QAssert.IsTrue(error < tolerance, vars.swapData[i].n + " year(s) swap:\n" + "\n estimated rate: " + estimatedRate + "\n expected rate: " + expectedRate + "\n error: " + error + "\n tolerance: " + tolerance); } // check bonds vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.bondHelpers, new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator); curveHandle.linkTo(vars.termStructure); for (int i = 0; i < vars.bonds; i++) { Date maturity = vars.calendar.advance(vars.today, vars.bondData[i].n, vars.bondData[i].units); Date issue = vars.calendar.advance(maturity, -vars.bondData[i].length, TimeUnit.Years); List <double> coupons = new List <double>() { vars.bondData[i].coupon / 100.0 }; FixedRateBond bond = new FixedRateBond(vars.bondSettlementDays, 100.0, vars.schedules[i], coupons, vars.bondDayCounter, vars.bondConvention, vars.bondRedemption, issue); IPricingEngine bondEngine = new DiscountingBondEngine(curveHandle); bond.setPricingEngine(bondEngine); double expectedPrice = vars.bondData[i].price, estimatedPrice = bond.cleanPrice(); QAssert.IsTrue(Math.Abs(expectedPrice - estimatedPrice) < tolerance, i + 1 + " bond failure:" + "\n estimated price: " + estimatedPrice + "\n expected price: " + expectedPrice); } // check FRA vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.fraHelpers, new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator); curveHandle.linkTo(vars.termStructure); IborIndex euribor3m = new Euribor3M(curveHandle); for (int i = 0; i < vars.fras; i++) { Date start = vars.calendar.advance(vars.settlement, vars.fraData[i].n, vars.fraData[i].units, euribor3m.businessDayConvention(), euribor3m.endOfMonth()); Date end = vars.calendar.advance(start, 3, TimeUnit.Months, euribor3m.businessDayConvention(), euribor3m.endOfMonth()); ForwardRateAgreement fra = new ForwardRateAgreement(start, end, Position.Type.Long, vars.fraData[i].rate / 100, 100.0, euribor3m, curveHandle); double expectedRate = vars.fraData[i].rate / 100, estimatedRate = fra.forwardRate().rate(); QAssert.IsTrue(Math.Abs(expectedRate - estimatedRate) < tolerance, i + 1 + " FRA failure:" + "\n estimated rate: " + estimatedRate + "\n expected rate: " + expectedRate); } }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(ForwardRateAgreement obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
static void Main() { DateTime timer = DateTime.Now; /********************* *** MARKET DATA *** *********************/ RelinkableHandle <YieldTermStructure> euriborTermStructure = new RelinkableHandle <YieldTermStructure>(); IborIndex euribor3m = new Euribor3M(euriborTermStructure); Date todaysDate = new Date(23, Month.May, 2006); Settings.setEvaluationDate(todaysDate); Calendar calendar = euribor3m.fixingCalendar(); int fixingDays = euribor3m.fixingDays(); Date settlementDate = calendar.advance(todaysDate, fixingDays, TimeUnit.Days); Console.WriteLine("Today: " + todaysDate.DayOfWeek + ", " + todaysDate); Console.WriteLine("Settlement date: " + settlementDate.DayOfWeek + ", " + settlementDate); // 3 month term FRA quotes (index refers to monthsToStart) double[] threeMonthFraQuote = new double[10]; threeMonthFraQuote[1] = 0.030; threeMonthFraQuote[2] = 0.031; threeMonthFraQuote[3] = 0.032; threeMonthFraQuote[6] = 0.033; threeMonthFraQuote[9] = 0.034; /******************** *** QUOTES *** ********************/ // SimpleQuote stores a value which can be manually changed; // other Quote subclasses could read the value from a database // or some kind of data feed. // FRAs SimpleQuote fra1x4Rate = new SimpleQuote(threeMonthFraQuote[1]); SimpleQuote fra2x5Rate = new SimpleQuote(threeMonthFraQuote[2]); SimpleQuote fra3x6Rate = new SimpleQuote(threeMonthFraQuote[3]); SimpleQuote fra6x9Rate = new SimpleQuote(threeMonthFraQuote[6]); SimpleQuote fra9x12Rate = new SimpleQuote(threeMonthFraQuote[9]); RelinkableHandle <Quote> h1x4 = new RelinkableHandle <Quote>(); h1x4.linkTo(fra1x4Rate); RelinkableHandle <Quote> h2x5 = new RelinkableHandle <Quote>(); h2x5.linkTo(fra2x5Rate); RelinkableHandle <Quote> h3x6 = new RelinkableHandle <Quote>(); h3x6.linkTo(fra3x6Rate); RelinkableHandle <Quote> h6x9 = new RelinkableHandle <Quote>(); h6x9.linkTo(fra6x9Rate); RelinkableHandle <Quote> h9x12 = new RelinkableHandle <Quote>(); h9x12.linkTo(fra9x12Rate); /********************* *** RATE HELPERS *** *********************/ // RateHelpers are built from the above quotes together with // other instrument dependant infos. Quotes are passed in // relinkable handles which could be relinked to some other // data source later. DayCounter fraDayCounter = euribor3m.dayCounter(); BusinessDayConvention convention = euribor3m.businessDayConvention(); bool endOfMonth = euribor3m.endOfMonth(); RateHelper fra1x4 = new FraRateHelper(h1x4, 1, 4, fixingDays, calendar, convention, endOfMonth, fraDayCounter); RateHelper fra2x5 = new FraRateHelper(h2x5, 2, 5, fixingDays, calendar, convention, endOfMonth, fraDayCounter); RateHelper fra3x6 = new FraRateHelper(h3x6, 3, 6, fixingDays, calendar, convention, endOfMonth, fraDayCounter); RateHelper fra6x9 = new FraRateHelper(h6x9, 6, 9, fixingDays, calendar, convention, endOfMonth, fraDayCounter); RateHelper fra9x12 = new FraRateHelper(h9x12, 9, 12, fixingDays, calendar, convention, endOfMonth, fraDayCounter); /********************* ** CURVE BUILDING ** *********************/ // Any DayCounter would be fine. // ActualActual::ISDA ensures that 30 years is 30.0 DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA); double tolerance = 1.0e-15; // A FRA curve List <RateHelper> fraInstruments = new List <RateHelper>(); fraInstruments.Add(fra1x4); fraInstruments.Add(fra2x5); fraInstruments.Add(fra3x6); fraInstruments.Add(fra6x9); fraInstruments.Add(fra9x12); YieldTermStructure fraTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>( settlementDate, fraInstruments, termStructureDayCounter, new List <Handle <Quote> >(), new List <Date>(), tolerance); // Term structures used for pricing/discounting RelinkableHandle <YieldTermStructure> discountingTermStructure = new RelinkableHandle <YieldTermStructure>(); discountingTermStructure.linkTo(fraTermStructure); /*********************** *** construct FRA's *** ***********************/ Calendar fraCalendar = euribor3m.fixingCalendar(); BusinessDayConvention fraBusinessDayConvention = euribor3m.businessDayConvention(); Position.Type fraFwdType = Position.Type.Long; double fraNotional = 100.0; const int FraTermMonths = 3; int[] monthsToStart = new [] { 1, 2, 3, 6, 9 }; euriborTermStructure.linkTo(fraTermStructure); Console.WriteLine("\nTest FRA construction, NPV calculation, and FRA purchase\n"); int i; for (i = 0; i < monthsToStart.Length; i++) { Date fraValueDate = fraCalendar.advance( settlementDate, monthsToStart[i], TimeUnit.Months, fraBusinessDayConvention); Date fraMaturityDate = fraCalendar.advance( fraValueDate, FraTermMonths, TimeUnit.Months, fraBusinessDayConvention); double fraStrikeRate = threeMonthFraQuote[monthsToStart[i]]; ForwardRateAgreement myFRA = new ForwardRateAgreement(fraValueDate, fraMaturityDate, fraFwdType, fraStrikeRate, fraNotional, euribor3m, discountingTermStructure); Console.WriteLine("3m Term FRA, Months to Start: " + monthsToStart[i]); Console.WriteLine("strike FRA rate: {0:0.00%}", fraStrikeRate); Console.WriteLine("FRA 3m forward rate: {0:0.00%}", myFRA.forwardRate()); Console.WriteLine("FRA market quote: {0:0.00%}", threeMonthFraQuote[monthsToStart[i]]); Console.WriteLine("FRA spot value: " + myFRA.spotValue()); Console.WriteLine("FRA forward value: " + myFRA.forwardValue()); Console.WriteLine("FRA implied Yield: {0:0.00%}", myFRA.impliedYield(myFRA.spotValue(), myFRA.forwardValue(), settlementDate, Compounding.Simple, fraDayCounter)); Console.WriteLine("market Zero Rate: {0:0.00%}", discountingTermStructure.link.zeroRate(fraMaturityDate, fraDayCounter, Compounding.Simple)); Console.WriteLine("FRA NPV [should be zero]: {0}\n", myFRA.NPV()); } Console.WriteLine("\n"); Console.WriteLine("Now take a 100 basis-point upward shift in FRA quotes and examine NPV\n"); const double BpsShift = 0.01; threeMonthFraQuote[1] = 0.030 + BpsShift; threeMonthFraQuote[2] = 0.031 + BpsShift; threeMonthFraQuote[3] = 0.032 + BpsShift; threeMonthFraQuote[6] = 0.033 + BpsShift; threeMonthFraQuote[9] = 0.034 + BpsShift; fra1x4Rate.setValue(threeMonthFraQuote[1]); fra2x5Rate.setValue(threeMonthFraQuote[2]); fra3x6Rate.setValue(threeMonthFraQuote[3]); fra6x9Rate.setValue(threeMonthFraQuote[6]); fra9x12Rate.setValue(threeMonthFraQuote[9]); for (i = 0; i < monthsToStart.Length; i++) { Date fraValueDate = fraCalendar.advance( settlementDate, monthsToStart[i], TimeUnit.Months, fraBusinessDayConvention); Date fraMaturityDate = fraCalendar.advance( fraValueDate, FraTermMonths, TimeUnit.Months, fraBusinessDayConvention); double fraStrikeRate = threeMonthFraQuote[monthsToStart[i]] - BpsShift; ForwardRateAgreement myFRA = new ForwardRateAgreement(fraValueDate, fraMaturityDate, fraFwdType, fraStrikeRate, fraNotional, euribor3m, discountingTermStructure); Console.WriteLine("3m Term FRA, 100 notional, Months to Start: " + monthsToStart[i]); Console.WriteLine("strike FRA rate: {0:0.00%}", fraStrikeRate); Console.WriteLine("FRA 3m forward rate: {0:0.00%}", myFRA.forwardRate()); Console.WriteLine("FRA market quote: {0:0.00%}", threeMonthFraQuote[monthsToStart[i]]); Console.WriteLine("FRA spot value: " + myFRA.spotValue()); Console.WriteLine("FRA forward value: " + myFRA.forwardValue()); Console.WriteLine("FRA implied Yield: {0:0.00%}", myFRA.impliedYield(myFRA.spotValue(), myFRA.forwardValue(), settlementDate, Compounding.Simple, fraDayCounter)); Console.WriteLine("market Zero Rate: {0:0.00%}", discountingTermStructure.link.zeroRate(fraMaturityDate, fraDayCounter, Compounding.Simple)); Console.WriteLine("FRA NPV [should be positive]: {0}\n", myFRA.NPV()); } Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); Console.WriteLine(); Console.Write("Press any key to continue ..."); Console.ReadKey(); }
public void BasicOisCurveSolving() { var startDate = new DateTime(2016, 05, 20); var depoTenors = new Frequency[] { 3.Months() }; double[] depoPrices = { 0.06 }; string[] FRATenors = { "3x6", "6x9", "9x12" }; double[] FRAPrices = { 0.065, 0.07, 0.075 }; var swapTenors = new Frequency[] { 18.Months(), 2.Years(), 3.Years(), 4.Years(), 5.Years(), 7.Years(), 10.Years(), 15.Years(), 20.Years() }; double[] swapPrices = { 0.075, 0.08, 0.085, 0.09, 0.095, 0.0975, 0.098, 0.099, 0.1 }; var oisTenors = new Frequency[] { 3.Months(), 6.Months(), 1.Years(), 2.Years(), 3.Years(), 4.Years(), 5.Years(), 7.Years(), 10.Years(), 15.Years(), 20.Years() }; var oisPrices = new double[] { 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004 }; var pillarDatesDepo = depoTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var pillarDatesFRA = FRATenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, new Frequency(x.Split('x')[1] + "M"))).ToArray(); var pillarDatesSwap = swapTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var pillarDates3m = pillarDatesDepo.Union(pillarDatesSwap).Union(pillarDatesFRA).Distinct().OrderBy(x => x).ToArray(); var pillarDatesOIS = oisTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var swaps = new IrSwap[swapTenors.Length]; var depos = new IrSwap[depoTenors.Length]; var oisSwaps = new IrBasisSwap[oisTenors.Length]; var FRAs = new ForwardRateAgreement[FRATenors.Length]; var fic = new FundingInstrumentCollection(TestProviderHelper.CurrencyProvider); for (var i = 0; i < FRAs.Length; i++) { FRAs[i] = new ForwardRateAgreement(startDate, FRATenors[i], FRAPrices[i], _zar3m, SwapPayReceiveType.Payer, FraDiscountingType.Isda, "ZAR.JIBAR.3M", "ZAR.OIS.1B"); fic.Add(FRAs[i]); } for (var i = 0; i < oisSwaps.Length; i++) { oisSwaps[i] = new IrBasisSwap(startDate, oisTenors[i], oisPrices[i], true, zaron, _zar3m, "ZAR.JIBAR.3M", "ZAR.OIS.1B", "ZAR.OIS.1B"); fic.Add(oisSwaps[i]); } for (var i = 0; i < swaps.Length; i++) { swaps[i] = new IrSwap(startDate, swapTenors[i], _zar3m, swapPrices[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.OIS.1B"); fic.Add(swaps[i]); } for (var i = 0; i < depos.Length; i++) { depos[i] = new IrSwap(startDate, depoTenors[i], _zar3m, depoPrices[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.OIS.1B"); fic.Add(depos[i]); } var curve3m = new IrCurve(pillarDates3m, new double[pillarDates3m.Length], startDate, "ZAR.JIBAR.3M", Interpolator1DType.LinearFlatExtrap, ccyZar); var curveOIS = new IrCurve(pillarDatesOIS, new double[pillarDatesOIS.Length], startDate, "ZAR.OIS.1B", Interpolator1DType.LinearFlatExtrap, ccyZar); var model = new FundingModel(startDate, new IrCurve[] { curve3m, curveOIS }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var S = new NewtonRaphsonMultiCurveSolver { Tollerance = IsCoverageOnly ? 1 : 0.00000001, MaxItterations = IsCoverageOnly ? 1 : 100, }; S.Solve(model, fic); if (!IsCoverageOnly) { foreach (var ins in fic) { var pv = ins.Pv(model, false); Assert.Equal(0.0, pv, 7); } } }
public void ComplexerCurve() { var startDate = new DateTime(2016, 05, 20); Frequency[] depoTenors = { 3.Months() }; Frequency[] OISdepoTenors = { 1.Bd() }; double[] depoPricesZAR = { 0.06 }; double[] depoPricesUSD = { 0.01 }; double[] OISdepoPricesZAR = { 0.055 }; double[] OISdepoPricesUSD = { 0.009 }; string[] FRATenors = { "3x6", "6x9", "9x12", "12x15", "15x18", "18x21", "21x24" }; double[] FRAPricesZAR = { 0.065, 0.07, 0.075, 0.077, 0.08, 0.081, 0.082 }; double[] FRAPricesUSD = { 0.012, 0.013, 0.014, 0.015, 0.016, 0.017, 0.018 }; Frequency[] swapTenors = { 3.Years(), 4.Years(), 5.Years(), 6.Years(), 7.Years(), 8.Years(), 9.Years(), 10.Years(), 12.Years(), 15.Years(), 20.Years(), 25.Years(), 30.Years() }; double[] swapPricesZAR = { 0.08, 0.083, 0.085, 0.087, 0.089, 0.091, 0.092, 0.093, 0.094, 0.097, 0.099, 0.099, 0.099 }; double[] swapPricesUSD = { 0.017, 0.018, 0.019, 0.020, 0.021, 0.022, 0.023, 0.024, 0.025, 0.026, 0.027, 0.028, 0.03 }; Frequency[] oisTenors = { 3.Months(), 6.Months(), 1.Years(), 18.Months(), 2.Years(), 3.Years(), 4.Years(), 5.Years(), 6.Years(), 7.Years(), 8.Years(), 9.Years(), 10.Years(), 12.Years(), 15.Years(), 20.Years(), 25.Years(), 30.Years() }; double[] oisPricesZAR = { 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004 }; double[] oisPricesUSD = { 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002 }; var fxSpot = 14.0; Frequency[] fxForwardTenors = { 3.Months(), 6.Months(), 1.Years(), 18.Months(), 2.Years(), 3.Years() }; double[] fxForwardPrices = { 14.10, 14.20, 14.40, 14.60, 14.80, 15.20 }; Frequency[] xcySwapTenors = { 4.Years(), 5.Years(), 6.Years(), 7.Years(), 8.Years(), 9.Years(), 10.Years(), 12.Years(), 15.Years(), 20.Years(), 25.Years(), 30.Years() }; double[] xcySwapPrices = { 0.0055, 0.0050, 0.0045, 0.0040, 0.0035, 0.0030, 0.0025, 0.0020, 0.0015, 0.0010, 0.0005, 0.0000 }; var ZARpillarDatesDepo = depoTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var ZARpillarDatesFRA = FRATenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, new Frequency(x.Split('x')[1] + "M"))).ToArray(); var ZARpillarDatesSwap = swapTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var ZARpillarDates3m = ZARpillarDatesDepo.Union(ZARpillarDatesSwap).Union(ZARpillarDatesFRA).Distinct().OrderBy(x => x).ToArray(); var ZARpillarDatesDepoOIS = OISdepoTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var ZARpillarDatesOISSwap = oisTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var ZARpillarDatesOIS = ZARpillarDatesDepoOIS.Union(ZARpillarDatesOISSwap).Distinct().OrderBy(x => x).ToArray(); var USDpillarDatesDepo = depoTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var USDpillarDatesFRA = FRATenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, new Frequency(x.Split('x')[1] + "M"))).ToArray(); var USDpillarDatesSwap = swapTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var USDpillarDates3m = USDpillarDatesDepo.Union(USDpillarDatesSwap).Union(USDpillarDatesFRA).Distinct().OrderBy(x => x).ToArray(); var USDpillarDatesDepoOIS = OISdepoTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var USDpillarDatesOISSwap = oisTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var USDpillarDatesOIS = USDpillarDatesDepoOIS.Union(USDpillarDatesOISSwap).Distinct().OrderBy(x => x).ToArray(); var fxForwardPillarDates = fxForwardTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var xcySwapDates = xcySwapTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var fxPillarDates = fxForwardPillarDates.Union(xcySwapDates).Distinct().OrderBy(x => x).ToArray(); var ZARswaps = new IrSwap[swapTenors.Length]; var ZARdepos = new IrSwap[depoTenors.Length]; var ZARdeposOIS = new IrSwap[OISdepoTenors.Length]; var ZARoisSwaps = new IrBasisSwap[oisTenors.Length]; var ZARFRAs = new ForwardRateAgreement[FRATenors.Length]; var USDswaps = new IrSwap[swapTenors.Length]; var USDdepos = new IrSwap[depoTenors.Length]; var USDdeposOIS = new IrSwap[OISdepoTenors.Length]; var USDoisSwaps = new IrBasisSwap[oisTenors.Length]; var USDFRAs = new ForwardRateAgreement[FRATenors.Length]; var fxForwards = new FxForward[fxForwardTenors.Length]; var xcySwaps = new XccyBasisSwap[xcySwapTenors.Length]; var FIC = new FundingInstrumentCollection(TestProviderHelper.CurrencyProvider); for (var i = 0; i < FRATenors.Length; i++) { ZARFRAs[i] = new ForwardRateAgreement(startDate, FRATenors[i], FRAPricesZAR[i], _zar3m, SwapPayReceiveType.Payer, FraDiscountingType.Isda, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.JIBAR.3M" }; FIC.Add(ZARFRAs[i]); USDFRAs[i] = new ForwardRateAgreement(startDate, FRATenors[i], FRAPricesUSD[i], usd3m, SwapPayReceiveType.Payer, FraDiscountingType.Isda, "USD.LIBOR.3M", "USD.DISC.CSA_USD") { SolveCurve = "USD.LIBOR.3M" }; FIC.Add(USDFRAs[i]); } for (var i = 0; i < oisTenors.Length; i++) { ZARoisSwaps[i] = new IrBasisSwap(startDate, oisTenors[i], oisPricesZAR[i], true, zaron, _zar3m, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.DISC.CSA_ZAR" }; FIC.Add(ZARoisSwaps[i]); USDoisSwaps[i] = new IrBasisSwap(startDate, oisTenors[i], oisPricesUSD[i], true, usdon, usd3m, "USD.LIBOR.3M", "USD.DISC.CSA_USD", "USD.DISC.CSA_USD") { SolveCurve = "USD.DISC.CSA_USD" }; FIC.Add(USDoisSwaps[i]); } for (var i = 0; i < swapTenors.Length; i++) { ZARswaps[i] = new IrSwap(startDate, swapTenors[i], _zar3m, swapPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.JIBAR.3M" }; FIC.Add(ZARswaps[i]); USDswaps[i] = new IrSwap(startDate, swapTenors[i], usd3m, swapPricesUSD[i], SwapPayReceiveType.Payer, "USD.LIBOR.3M", "USD.DISC.CSA_USD") { SolveCurve = "USD.LIBOR.3M" }; FIC.Add(USDswaps[i]); } for (var i = 0; i < depoTenors.Length; i++) { ZARdepos[i] = new IrSwap(startDate, depoTenors[i], _zar3m, depoPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.JIBAR.3M" }; FIC.Add(ZARdepos[i]); USDdepos[i] = new IrSwap(startDate, depoTenors[i], usd3m, depoPricesUSD[i], SwapPayReceiveType.Payer, "USD.LIBOR.3M", "USD.DISC.CSA_USD") { SolveCurve = "USD.LIBOR.3M" }; FIC.Add(USDdepos[i]); } for (var i = 0; i < OISdepoTenors.Length; i++) { ZARdeposOIS[i] = new IrSwap(startDate, OISdepoTenors[i], zaron, OISdepoPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.DISC.CSA_ZAR", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.DISC.CSA_ZAR" }; FIC.Add(ZARdeposOIS[i]); USDdeposOIS[i] = new IrSwap(startDate, OISdepoTenors[i], usdon, OISdepoPricesUSD[i], SwapPayReceiveType.Payer, "USD.DISC.CSA_USD", "USD.DISC.CSA_USD") { SolveCurve = "USD.DISC.CSA_USD" }; FIC.Add(USDdeposOIS[i]); } for (var i = 0; i < fxForwards.Length; i++) { fxForwards[i] = new FxForward { SolveCurve = "ZAR.DISC.CSA_USD", DeliveryDate = fxForwardPillarDates[i], DomesticCCY = ccyUsd, ForeignCCY = ccyZar, DomesticQuantity = 1e6 / fxForwardPrices[i], Strike = fxForwardPrices[i], ForeignDiscountCurve = "ZAR.DISC.CSA_USD", }; FIC.Add(fxForwards[i]); } for (var i = 0; i < xcySwapTenors.Length; i++) { xcySwaps[i] = new XccyBasisSwap(startDate, xcySwapTenors[i], xcySwapPrices[i], true, usd3m, _zar3m, ExchangeType.Both, MTMSwapType.ReceiveNotionalFixed, "USD.LIBOR.3M", "ZAR.JIBAR.3M", "USD.DISC.CSA_USD", "ZAR.DISC.CSA_USD") { SolveCurve = "ZAR.DISC.CSA_USD" }; FIC.Add(xcySwaps[i]); } var ZARcurve3m = new IrCurve(ZARpillarDates3m, new double[ZARpillarDates3m.Length], startDate, "ZAR.JIBAR.3M", Interpolator1DType.LinearFlatExtrap, ccyZar) { SolveStage = 0 }; var ZARcurveOIS = new IrCurve(ZARpillarDatesOIS, new double[ZARpillarDatesOIS.Length], startDate, "ZAR.DISC.CSA_ZAR", Interpolator1DType.LinearFlatExtrap, ccyZar) { SolveStage = 0 }; var USDcurve3m = new IrCurve(USDpillarDates3m, new double[USDpillarDates3m.Length], startDate, "USD.LIBOR.3M", Interpolator1DType.LinearFlatExtrap, ccyUsd) { SolveStage = 1 }; var USDcurveOIS = new IrCurve(USDpillarDatesOIS, new double[USDpillarDatesOIS.Length], startDate, "USD.DISC.CSA_USD", Interpolator1DType.LinearFlatExtrap, ccyUsd) { SolveStage = 1 }; var fxCurve = new IrCurve(fxPillarDates, new double[fxPillarDates.Length], startDate, "ZAR.DISC.CSA_USD", Interpolator1DType.LinearFlatExtrap, ccyZar) { SolveStage = 2 }; var engine = new FundingModel(startDate, new IrCurve[] { ZARcurve3m, ZARcurveOIS, USDcurve3m, USDcurveOIS, fxCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); var spotRates = new Dictionary <Currency, double> { { ccyZar, fxSpot } }; var fxPairs = new List <FxPair> { new FxPair { Domestic = ccyUsd, Foreign = ccyZar, SettlementCalendar = _usd, SpotLag = new Frequency("2b") } }; var discountMap = new Dictionary <Currency, string> { { ccyUsd, "USD.DISC.CSA_USD" }, { ccyZar, "ZAR.DISC.CSA_USD" }, }; fxMatrix.Init(ccyUsd, startDate, spotRates, fxPairs, discountMap); engine.SetupFx(fxMatrix); var S = new NewtonRaphsonMultiCurveSolverStaged() { Tollerance = IsCoverageOnly ? 1 : 0.00000001, MaxItterations = IsCoverageOnly ? 1 : 100, }; S.Solve(engine, FIC); if (!IsCoverageOnly) { foreach (var ins in FIC) { var pv = ins.Pv(engine, false); Assert.Equal(0.0, pv, 7); } } }
public void ComplexCurve() { var startDate = new DateTime(2016, 05, 20); var depoTenors = new Frequency[] { 3.Months() }; var OISdepoTenors = new Frequency[] { 1.Bd() }; double[] depoPricesZAR = { 0.06 }; double[] depoPricesUSD = { 0.01 }; double[] OISdepoPricesZAR = { 0.055 }; double[] OISdepoPricesUSD = { 0.009 }; string[] FRATenors = { "3x6", "6x9", "9x12", "12x15", "15x18", "18x21", "21x24" }; double[] FRAPricesZAR = { 0.065, 0.07, 0.075, 0.077, 0.08, 0.081, 0.082 }; double[] FRAPricesUSD = { 0.012, 0.013, 0.014, 0.015, 0.016, 0.017, 0.018 }; Frequency[] swapTenors = { 3.Years(), 4.Years(), 5.Years(), 6.Years(), 7.Years(), 8.Years(), 9.Years(), 10.Years(), 12.Years(), 15.Years(), 20.Years(), 25.Years(), 30.Years() }; double[] swapPricesZAR = { 0.08, 0.083, 0.085, 0.087, 0.089, 0.091, 0.092, 0.093, 0.094, 0.097, 0.099, 0.099, 0.099 }; double[] swapPricesUSD = { 0.017, 0.018, 0.019, 0.020, 0.021, 0.022, 0.023, 0.024, 0.025, 0.026, 0.027, 0.028, 0.03 }; Frequency[] oisTenors = { 3.Months(), 6.Months(), 1.Years(), 18.Months(), 2.Years(), 3.Years(), 4.Years(), 5.Years(), 6.Years(), 7.Years(), 8.Years(), 9.Years(), 10.Years(), 12.Years(), 15.Years(), 20.Years(), 25.Years(), 30.Years() }; double[] oisPricesZAR = { 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004 }; double[] oisPricesUSD = { 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002 }; var ZARpillarDatesDepo = depoTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var ZARpillarDatesFRA = FRATenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, new Frequency(x.Split('x')[1] + "M"))).ToArray(); var ZARpillarDatesSwap = swapTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var ZARpillarDates3m = ZARpillarDatesDepo.Union(ZARpillarDatesSwap).Union(ZARpillarDatesFRA).Distinct().OrderBy(x => x).ToArray(); var ZARpillarDatesDepoOIS = OISdepoTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var ZARpillarDatesOISSwap = oisTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var ZARpillarDatesOIS = ZARpillarDatesDepoOIS.Union(ZARpillarDatesOISSwap).Distinct().OrderBy(x => x).ToArray(); var USDpillarDatesDepo = depoTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var USDpillarDatesFRA = FRATenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, new Frequency(x.Split('x')[1] + "M"))).ToArray(); var USDpillarDatesSwap = swapTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var USDpillarDates3m = USDpillarDatesDepo.Union(USDpillarDatesSwap).Union(USDpillarDatesFRA).Distinct().OrderBy(x => x).ToArray(); var USDpillarDatesDepoOIS = OISdepoTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var USDpillarDatesOISSwap = oisTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var USDpillarDatesOIS = USDpillarDatesDepoOIS.Union(USDpillarDatesOISSwap).Distinct().OrderBy(x => x).ToArray(); var ZARswaps = new IrSwap[swapTenors.Length]; var ZARdepos = new IrSwap[depoTenors.Length]; var ZARdeposOIS = new IrSwap[OISdepoTenors.Length]; var ZARoisSwaps = new IrBasisSwap[oisTenors.Length]; var ZARFRAs = new ForwardRateAgreement[FRATenors.Length]; var USDswaps = new IrSwap[swapTenors.Length]; var USDdepos = new IrSwap[depoTenors.Length]; var USDdeposOIS = new IrSwap[OISdepoTenors.Length]; var USDoisSwaps = new IrBasisSwap[oisTenors.Length]; var USDFRAs = new ForwardRateAgreement[FRATenors.Length]; var FIC = new FundingInstrumentCollection(TestProviderHelper.CurrencyProvider); for (var i = 0; i < FRATenors.Length; i++) { ZARFRAs[i] = new ForwardRateAgreement(startDate, FRATenors[i], FRAPricesZAR[i], _zar3m, SwapPayReceiveType.Payer, FraDiscountingType.Isda, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.JIBAR.3M" }; FIC.Add(ZARFRAs[i]); USDFRAs[i] = new ForwardRateAgreement(startDate, FRATenors[i], FRAPricesUSD[i], usd3m, SwapPayReceiveType.Payer, FraDiscountingType.Isda, "USD.LIBOR.3M", "USD.DISC.CSA_USD") { SolveCurve = "USD.LIBOR.3M" }; FIC.Add(USDFRAs[i]); } for (var i = 0; i < oisTenors.Length; i++) { ZARoisSwaps[i] = new IrBasisSwap(startDate, oisTenors[i], oisPricesZAR[i], true, zaron, _zar3m, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.DISC.CSA_ZAR" }; FIC.Add(ZARoisSwaps[i]); USDoisSwaps[i] = new IrBasisSwap(startDate, oisTenors[i], oisPricesUSD[i], true, usdon, usd3m, "USD.LIBOR.3M", "USD.DISC.CSA_USD", "USD.DISC.CSA_USD") { SolveCurve = "USD.DISC.CSA_USD" }; FIC.Add(USDoisSwaps[i]); } for (var i = 0; i < swapTenors.Length; i++) { ZARswaps[i] = new IrSwap(startDate, swapTenors[i], _zar3m, swapPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.JIBAR.3M" }; FIC.Add(ZARswaps[i]); USDswaps[i] = new IrSwap(startDate, swapTenors[i], usd3m, swapPricesUSD[i], SwapPayReceiveType.Payer, "USD.LIBOR.3M", "USD.DISC.CSA_USD") { SolveCurve = "USD.LIBOR.3M" }; FIC.Add(USDswaps[i]); } for (var i = 0; i < depoTenors.Length; i++) { ZARdepos[i] = new IrSwap(startDate, depoTenors[i], _zar3m, depoPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.JIBAR.3M" }; FIC.Add(ZARdepos[i]); USDdepos[i] = new IrSwap(startDate, depoTenors[i], usd3m, depoPricesUSD[i], SwapPayReceiveType.Payer, "USD.LIBOR.3M", "USD.DISC.CSA_USD") { SolveCurve = "USD.LIBOR.3M" }; FIC.Add(USDdepos[i]); } for (var i = 0; i < OISdepoTenors.Length; i++) { ZARdeposOIS[i] = new IrSwap(startDate, OISdepoTenors[i], zaron, OISdepoPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.DISC.CSA_ZAR", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.DISC.CSA_ZAR" }; FIC.Add(ZARdeposOIS[i]); USDdeposOIS[i] = new IrSwap(startDate, OISdepoTenors[i], usdon, OISdepoPricesUSD[i], SwapPayReceiveType.Payer, "USD.DISC.CSA_USD", "USD.DISC.CSA_USD") { SolveCurve = "USD.DISC.CSA_USD" }; FIC.Add(USDdeposOIS[i]); } var ZARcurve3m = new IrCurve(ZARpillarDates3m, new double[ZARpillarDates3m.Length], startDate, "ZAR.JIBAR.3M", Interpolator1DType.LinearFlatExtrap, ccyZar) { SolveStage = 0 }; var ZARcurveOIS = new IrCurve(ZARpillarDatesOIS, new double[ZARpillarDatesOIS.Length], startDate, "ZAR.DISC.CSA_ZAR", Interpolator1DType.LinearFlatExtrap, ccyZar) { SolveStage = 0 }; var USDcurve3m = new IrCurve(USDpillarDates3m, new double[USDpillarDates3m.Length], startDate, "USD.LIBOR.3M", Interpolator1DType.LinearFlatExtrap, ccyUsd) { SolveStage = 1 }; var USDcurveOIS = new IrCurve(USDpillarDatesOIS, new double[USDpillarDatesOIS.Length], startDate, "USD.DISC.CSA_USD", Interpolator1DType.LinearFlatExtrap, ccyUsd) { SolveStage = 1 }; var engine = new FundingModel(startDate, new IrCurve[] { ZARcurve3m, ZARcurveOIS, USDcurve3m, USDcurveOIS }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var ZARcurve3m0 = new IrCurve(ZARpillarDates3m, new double[ZARpillarDates3m.Length], startDate, "ZAR.JIBAR.3M", Interpolator1DType.LinearFlatExtrap, ccyZar) { SolveStage = 0 }; var ZARcurveOIS0 = new IrCurve(ZARpillarDatesOIS, new double[ZARpillarDatesOIS.Length], startDate, "ZAR.DISC.CSA_ZAR", Interpolator1DType.LinearFlatExtrap, ccyZar) { SolveStage = 0 }; var USDcurve3m0 = new IrCurve(USDpillarDates3m, new double[USDpillarDates3m.Length], startDate, "USD.LIBOR.3M", Interpolator1DType.LinearFlatExtrap, ccyUsd) { SolveStage = 1 }; var USDcurveOIS0 = new IrCurve(USDpillarDatesOIS, new double[USDpillarDatesOIS.Length], startDate, "USD.DISC.CSA_USD", Interpolator1DType.LinearFlatExtrap, ccyUsd) { SolveStage = 1 }; var engine0 = new FundingModel(startDate, new IrCurve[] { ZARcurve3m0, ZARcurveOIS0, USDcurve3m0, USDcurveOIS0 }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var S = new NewtonRaphsonMultiCurveSolverStagedWithAnalyticJacobian() { Tollerance = IsCoverageOnly ? 1 : 0.00000001, MaxItterations = IsCoverageOnly ? 1 : 100, }; var S0 = new NewtonRaphsonMultiCurveSolverStaged() { Tollerance = IsCoverageOnly ? 1 : 0.00000001, MaxItterations = IsCoverageOnly ? 1 : 100, }; S.Solve(engine, FIC); S0.Solve(engine0, FIC); if (!IsCoverageOnly) { foreach (var ins in FIC) { var pv = ins.Pv(engine, false); Assert.Equal(0.0, pv, 7); } foreach (var curve in engine.Curves) { var otherCurve = engine0.Curves[curve.Key]; Assert.Equal(curve.Value.NumberOfPillars, otherCurve.NumberOfPillars); var otherRates = otherCurve.GetRates(); var rates = curve.Value.GetRates(); for (var i = 0; i < otherRates.Length; i++) { Assert.Equal(otherRates[i], rates[i], 10); } } } }
public static void Setup() { var startDate = new DateTime(2016, 05, 20); var depoTenors = new Frequency[] { 3.Months() }; var OISdepoTenors = new Frequency[] { 1.Bd() }; double[] depoPricesZAR = { 0.06 }; double[] depoPricesUSD = { 0.01 }; double[] OISdepoPricesZAR = { 0.055 }; double[] OISdepoPricesUSD = { 0.009 }; string[] FRATenors = { "3x6", "6x9", "9x12", "12x15", "15x18", "18x21", "21x24" }; double[] FRAPricesZAR = { 0.065, 0.07, 0.075, 0.077, 0.08, 0.081, 0.082 }; double[] FRAPricesUSD = { 0.012, 0.013, 0.014, 0.015, 0.016, 0.017, 0.018 }; Frequency[] swapTenors = { 3.Years(), 4.Years(), 5.Years(), 6.Years(), 7.Years(), 8.Years(), 9.Years(), 10.Years(), 12.Years(), 15.Years(), 20.Years(), 25.Years(), 30.Years() }; double[] swapPricesZAR = { 0.08, 0.083, 0.085, 0.087, 0.089, 0.091, 0.092, 0.093, 0.094, 0.097, 0.099, 0.099, 0.099 }; double[] swapPricesUSD = { 0.017, 0.018, 0.019, 0.020, 0.021, 0.022, 0.023, 0.024, 0.025, 0.026, 0.027, 0.028, 0.03 }; Frequency[] oisTenors = { 3.Months(), 6.Months(), 1.Years(), 18.Months(), 2.Years(), 3.Years(), 4.Years(), 5.Years(), 6.Years(), 7.Years(), 8.Years(), 9.Years(), 10.Years(), 12.Years(), 15.Years(), 20.Years(), 25.Years(), 30.Years() }; double[] oisPricesZAR = { 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004 }; double[] oisPricesUSD = { 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002 }; double[] crossxPrices = { 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002 }; var ZARpillarDatesDepo = depoTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._jhb, x)).ToArray(); var ZARpillarDatesFRA = FRATenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._jhb, new Frequency(x.Split('x')[1] + "M"))).ToArray(); var ZARpillarDatesSwap = swapTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._jhb, x)).ToArray(); var ZARpillarDates3m = ZARpillarDatesDepo.Union(ZARpillarDatesSwap).Union(ZARpillarDatesFRA).Distinct().OrderBy(x => x).ToArray(); var ZARpillarDatesDepoOIS = OISdepoTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._jhb, x)).ToArray(); var ZARpillarDatesOISSwap = oisTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._jhb, x)).ToArray(); var ZARpillarDatesOIS = ZARpillarDatesDepoOIS.Union(ZARpillarDatesOISSwap).Distinct().OrderBy(x => x).ToArray(); var USDpillarDatesDepo = depoTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._usd, x)).ToArray(); var USDpillarDatesFRA = FRATenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._usd, new Frequency(x.Split('x')[1] + "M"))).ToArray(); var USDpillarDatesSwap = swapTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._usd, x)).ToArray(); var USDpillarDates3m = USDpillarDatesDepo.Union(USDpillarDatesSwap).Union(USDpillarDatesFRA).Distinct().OrderBy(x => x).ToArray(); var USDpillarDatesDepoOIS = OISdepoTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._usd, x)).ToArray(); var USDpillarDatesOISSwap = oisTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._usd, x)).ToArray(); var USDpillarDatesOIS = USDpillarDatesDepoOIS.Union(USDpillarDatesOISSwap).Distinct().OrderBy(x => x).ToArray(); var ZARswaps = new IrSwap[swapTenors.Length]; var ZARdepos = new IrSwap[depoTenors.Length]; var ZARdeposOIS = new IrSwap[OISdepoTenors.Length]; var ZARoisSwaps = new IrBasisSwap[oisTenors.Length]; var ZARFRAs = new ForwardRateAgreement[FRATenors.Length]; var USDswaps = new IrSwap[swapTenors.Length]; var USDdepos = new IrSwap[depoTenors.Length]; var USDdeposOIS = new IrSwap[OISdepoTenors.Length]; var USDoisSwaps = new IrBasisSwap[oisTenors.Length]; var USDFRAs = new ForwardRateAgreement[FRATenors.Length]; var ccySwaps = new XccyBasisSwap[oisTenors.Length]; _instruments = new FundingInstrumentCollection(); for (var i = 0; i < FRATenors.Length; i++) { ZARFRAs[i] = new ForwardRateAgreement(startDate, FRATenors[i], FRAPricesZAR[i], CurveDataSetup._zar3m, SwapPayReceiveType.Payer, FraDiscountingType.Isda, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.JIBAR.3M" }; _instruments.Add(ZARFRAs[i]); USDFRAs[i] = new ForwardRateAgreement(startDate, FRATenors[i], FRAPricesUSD[i], CurveDataSetup.usd3m, SwapPayReceiveType.Payer, FraDiscountingType.Isda, "USD.LIBOR.3M", "USD.DISC.CSA_USD") { SolveCurve = "USD.LIBOR.3M" }; _instruments.Add(USDFRAs[i]); } for (var i = 0; i < oisTenors.Length; i++) { ZARoisSwaps[i] = new IrBasisSwap(startDate, oisTenors[i], oisPricesZAR[i], true, CurveDataSetup.zaron, CurveDataSetup._zar3m, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.DISC.CSA_ZAR" }; _instruments.Add(ZARoisSwaps[i]); USDoisSwaps[i] = new IrBasisSwap(startDate, oisTenors[i], oisPricesUSD[i], true, CurveDataSetup.usdon, CurveDataSetup.usd3m, "USD.LIBOR.3M", "USD.DISC.CSA_USD", "USD.DISC.CSA_USD") { SolveCurve = "USD.DISC.CSA_USD" }; _instruments.Add(USDoisSwaps[i]); ccySwaps[i] = new XccyBasisSwap(startDate, oisTenors[i], crossxPrices[i], true, CurveDataSetup.usd3m, CurveDataSetup._zar3m, ExchangeType.Both, MTMSwapType.ReceiveNotionalFixed, "USD.LIBOR.3M", "ZAR.JIBAR.3M", "USD.DISC.CSA_USD", "ZAR.DISC.CSA_USD"); //_instruments.Add(ccySwaps[i]); } for (var i = 0; i < swapTenors.Length; i++) { ZARswaps[i] = new IrSwap(startDate, swapTenors[i], CurveDataSetup._zar3m, swapPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.JIBAR.3M" }; _instruments.Add(ZARswaps[i]); USDswaps[i] = new IrSwap(startDate, swapTenors[i], CurveDataSetup.usd3m, swapPricesUSD[i], SwapPayReceiveType.Payer, "USD.LIBOR.3M", "USD.DISC.CSA_USD") { SolveCurve = "USD.LIBOR.3M" }; _instruments.Add(USDswaps[i]); } for (var i = 0; i < depoTenors.Length; i++) { ZARdepos[i] = new IrSwap(startDate, depoTenors[i], CurveDataSetup._zar3m, depoPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.JIBAR.3M" }; _instruments.Add(ZARdepos[i]); USDdepos[i] = new IrSwap(startDate, depoTenors[i], CurveDataSetup.usd3m, depoPricesUSD[i], SwapPayReceiveType.Payer, "USD.LIBOR.3M", "USD.DISC.CSA_USD") { SolveCurve = "USD.LIBOR.3M" }; _instruments.Add(USDdepos[i]); } for (var i = 0; i < OISdepoTenors.Length; i++) { ZARdeposOIS[i] = new IrSwap(startDate, OISdepoTenors[i], CurveDataSetup.zaron, OISdepoPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.DISC.CSA_ZAR", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.DISC.CSA_ZAR" }; _instruments.Add(ZARdeposOIS[i]); USDdeposOIS[i] = new IrSwap(startDate, OISdepoTenors[i], CurveDataSetup.usdon, OISdepoPricesUSD[i], SwapPayReceiveType.Payer, "USD.DISC.CSA_USD", "USD.DISC.CSA_USD") { SolveCurve = "USD.DISC.CSA_USD" }; _instruments.Add(USDdeposOIS[i]); } var ZARcurve3m = new IrCurve(ZARpillarDates3m, new double[ZARpillarDates3m.Length], startDate, "ZAR.JIBAR.3M", Interpolator1DType.LinearFlatExtrap) { SolveStage = 0 }; var ZARcurveOIS = new IrCurve(ZARpillarDatesOIS, new double[ZARpillarDatesOIS.Length], startDate, "ZAR.DISC.CSA_ZAR", Interpolator1DType.LinearFlatExtrap) { SolveStage = 0 }; var USDcurve3m = new IrCurve(USDpillarDates3m, new double[USDpillarDates3m.Length], startDate, "USD.LIBOR.3M", Interpolator1DType.LinearFlatExtrap) { SolveStage = 1 }; var USDcurveOIS = new IrCurve(USDpillarDatesOIS, new double[USDpillarDatesOIS.Length], startDate, "USD.DISC.CSA_USD", Interpolator1DType.LinearFlatExtrap) { SolveStage = 1 }; // var ZARccyBasisCurve = new IrCurve(USDpillarDatesOIS, new double[USDpillarDatesOIS.Length], startDate, "ZAR.DISC.CSA_USD", Interpolator1DType.LinearFlatExtrap) { SolveStage = 2 }; _fundingModel = new FundingModel(startDate, new IrCurve[] { ZARcurve3m, ZARcurveOIS, USDcurve3m, USDcurveOIS }); }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(ForwardRateAgreement obj) { return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr; }