private static double GetScaleFactor(IFundingInstrument ins, double parFlat, double parBump, IFundingModel model) { switch (ins) { case FxForward fxf: return(1.0 / (parBump - parFlat)); case STIRFuture st: return(1.0 / ((parBump - parFlat) / 0.01 * st.UnitPV01)); case ForwardRateAgreement fra: return(1.0 / ((parBump - parFlat) * fra.FlowScheduleFra.Flows.First().NotionalByYearFraction)); case ContangoSwap cs: var t360 = (cs.PillarDate - model.BuildDate).TotalDays / 360.0; var spot = model.GetFxRate(model.BuildDate, cs.MetalCCY, cs.CashCCY); var fwdFlat = (1 + parFlat * t360) * spot; var fwdBumped = (1 + parBump * t360) * spot; return(1.0 / (fwdBumped - fwdFlat)); case IrSwap irs: var pv = irs.SetParRate(parBump).Pv(model, true); return(1.0 / pv * irs.Notional); case FloatingRateLoanDepo fld: var pvF = fld.SetParRate(parBump).Pv(model, true); return(1.0 / pvF * fld.Notional); default: return(1.0); } }
private static double GetBumpSize(IFundingInstrument ins) { switch (ins) { case STIRFuture st: case OISFuture oi: return(0.01); default: return(0.0001); } }
private static string GetRiskUnits(IFundingInstrument ins) { switch (ins) { case STIRFuture st: case OISFuture oi: return("Contracts"); case ForwardRateAgreement fra: case FxForward fxf: return("Nominal"); case ContangoSwap cs: return("Oz"); default: return("PnL"); } }
public void FuturesStripWithConvexity() { var volatility = 0.03; var startDate = new DateTime(2017, 01, 17); var nContracts = 24; var currentDate = startDate.GetNextImmDate(); var expiries = new DateTime[nContracts]; var pillars = new DateTime[nContracts]; var instruments = new IFundingInstrument[nContracts]; var nyc = TestProviderHelper.CalendarProvider.Collection["NYC"]; var lon = TestProviderHelper.CalendarProvider.Collection["LON"]; var ccyUsd = TestProviderHelper.CurrencyProvider["USD"]; var usd3m = new FloatRateIndex() { Currency = ccyUsd, DayCountBasis = DayCountBasis.Act_360, DayCountBasisFixed = DayCountBasis.Act_360, ResetTenor = 3.Months(), FixingOffset = 2.Bd(), HolidayCalendars = nyc, RollConvention = RollType.MF }; for (var i = 0; i < nContracts; i++) { var wed3rd = currentDate.ThirdWednesday(); expiries[i] = wed3rd.SubtractPeriod(RollType.P, lon, 2.Bd()); pillars[i] = wed3rd.AddPeriod(usd3m.RollConvention, usd3m.HolidayCalendars, usd3m.ResetTenor); instruments[i] = new STIRFuture() { Currency = ccyUsd, ContractSize = 1e6, ConvexityAdjustment = FuturesConvexityUtils.CalculateConvexityAdjustment(startDate, expiries[i], pillars[i], volatility), DCF = 0.25, Expiry = expiries[i], ForecastCurve = "USD.LIBOR.3M", Index = usd3m, Position = 1.0, Price = 99.50, SolveCurve = "USD.LIBOR.3M" }; currentDate = currentDate.AddMonths(3); } var fic = new FundingInstrumentCollection(TestProviderHelper.CurrencyProvider); fic.AddRange(instruments); var curve = new IrCurve(pillars, new double[nContracts], startDate, "USD.LIBOR.3M", Interpolator1DType.LinearFlatExtrap, ccyUsd); var model = new FundingModel(startDate, new[] { curve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var s = new Calibrators.NewtonRaphsonMultiCurveSolver() { Tollerance = IsCoverageOnly ? 1 : 0.00000001 }; s.Solve(model, fic); if (!IsCoverageOnly) { for (var i = 0; i < nContracts; i++) { var resultPV = instruments[i].Pv(model, false); Assert.Equal(0, resultPV, 6); } } }