public static void MyDF(object rateSet) { object[] o = (object[])rateSet; RateSet rs = (RateSet)o[0]; RateSet myRateSet = new RateSet((Date)o[1]); foreach (RateSet r in rs) { myRateSet.Add(r.V, r.M.GetPeriodStringFormat(), r.T); } Date dfDate = new Date(2025, 8, 15); double fixing = (double)o[2]; #region building curve SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator> C = new SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator>(myRateSet, fixing); Console.WriteLine("Ref. {0:D}: DF: {1:F5}", myRateSet.refDate.DateValue, C.DF(dfDate)); #endregion building curve }
// More on sensitivities calc public static void MoreOnSensitivities() { #region Inputs // Start input Date refDate = new Date(2010, 10, 11); // I populate market rates set: from file, from real time, ... RateSet mktRates = new RateSet(refDate); // Depos mktRates.Add(1.243e-2, "1m", BuildingBlockType.EURDEPO); mktRates.Add(1.435e-2, "3m", BuildingBlockType.EURDEPO); mktRates.Add(1.720e-2, "6m", BuildingBlockType.EURDEPO); // Swap Vs 6M mktRates.Add(1.869e-2, "1Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.316e-2, "2Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.544e-2, "3Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.745e-2, "4Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.915e-2, "5Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.057e-2, "6Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.175e-2, "7Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.273e-2, "8Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.362e-2, "9Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.442e-2, "10Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.589e-2, "12Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.750e-2, "15Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.835e-2, "20Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.787e-2, "25Y", BuildingBlockType.EURSWAP6M); #endregion end Inputs #region building curve List <ISingleRateCurve> Curves = new List <ISingleRateCurve>(); // initialised each class and add to list. You can add more curves // Setup (a) in Table 15.3 SingleCurveBuilderStandard <OnLogDf, LinearInterpolator> c2 = new SingleCurveBuilderStandard <OnLogDf, LinearInterpolator>(mktRates, OneDimensionInterpolation.Linear); Curves.Add(c2); // Setup (b) in Table 15.3 SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator> c1 = new SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator>(mktRates); Curves.Add(c1); string swapTenor = "11y"; // you can change it #endregion end building curve #region myFunction Func <SwapStyle, IRateCurve, double> NPV = (BB, c) => { #region FixLeg // fixed leg data double[] yfFixLeg = BB.scheduleLeg1.GetYFVect(BB.swapLeg1.DayCount); // fixed is leg 1 // dfs array of fixed lag Date[] dfDates = BB.scheduleLeg1.payDates; // serial date of fixed lag (each dates we should find df) // # of fixed cash flows int n_fix = dfDates.Length; double NPV_fix = 0.0; // calculate df for (int i = 0; i < n_fix; i++) { NPV_fix += c.Df(dfDates[i]) * yfFixLeg[i] * BB.rateValue; // df*yf } // NPV_fix *= BB.rateValue; #endregion #region FloatLeg // fixed leg data double[] yfFloatLeg = BB.scheduleLeg2.GetYFVect(BB.swapLeg2.DayCount); // float is leg 2 // dfs array of fixed lag Date[] dfDatesFloat = BB.scheduleLeg2.payDates; // serial date of float lag (each dates we should find df) Date[] toDateFloat = BB.scheduleLeg2.toDates; // # of fixed cash flows int n_float = dfDatesFloat.Length; double[] fwd = new double[n_float]; fwd[0] = ((1 / c.Df(toDateFloat[0])) - 1) / refDate.YF(toDateFloat[0], Dc._Act_360);; for (int i = 1; i < n_float; i++) { double yf = toDateFloat[i - 1].YF(toDateFloat[i], Dc._Act_360); double df_ini = c.Df(toDateFloat[i - 1]); double df_end = c.Df(toDateFloat[i]); fwd[i] = ((df_ini / df_end) - 1) / yf; } double NPV_float = 0.0; // calculate df for (int i = 0; i < n_float; i++) { NPV_float += c.Df(dfDatesFloat[i]) * yfFloatLeg[i] * fwd[i]; // df*yf } #endregion return(NPV_fix - NPV_float); }; #endregion #region Print results foreach (ISingleRateCurve C in Curves) { double swapRate = C.SwapFwd(refDate, swapTenor); IRateCurve[] cs = C.ShiftedCurveArray(0.0001); IRateCurve csp = C.ParallelShift(0.0001); // initialise some variable used in sensitivities double sens = 0.0; double runSum = 0.0; // standard Console.WriteLine(C.ToString()); SwapStyle y = (SwapStyle) new BuildingBlockFactory().CreateBuildingBlock(refDate, swapRate, swapTenor, BuildingBlockType.EURSWAP6M); double iniMTM = NPV(y, C) * 100000000; Console.WriteLine("{0} swap ATM fwd: {1:f5}", swapTenor, swapRate); Console.WriteLine("Starting P&L {0:f}", iniMTM); int nOfRate = mktRates.Count; for (int i = 0; i < nOfRate; i++) { sens = NPV(y, cs[i]) * 100000000 - iniMTM; Console.WriteLine("{0} BPV: {1:f}", mktRates.Item(i).M.GetPeriodStringFormat(), sens); runSum += sens; } Console.WriteLine("Total: {0:f}", runSum); Console.WriteLine("Parallel Total: {0:f}", NPV(y, csp) * 100000000 - iniMTM); Console.WriteLine("Press a key to continue"); Console.ReadLine(); } #endregion }
// Print on excel forward rate using different curve builder for 3m public static void CheckFwdRatesVs3m() { #region Inputs // Start input Date refDate = (new Date(DateTime.Now)).mod_foll(); // I populate market rates set: from file, from real time, ... RateSet mktRates = new RateSet(refDate); // Depos mktRates.Add(0.434e-2, "3m", BuildingBlockType.EURDEPO); // Swap Vs 3M mktRates.Add(0.813e-2, "1Y", BuildingBlockType.EURSWAP3M); mktRates.Add(1.096e-2, "2Y", BuildingBlockType.EURSWAP3M); mktRates.Add(1.322e-2, "3Y", BuildingBlockType.EURSWAP3M); mktRates.Add(1.529e-2, "4Y", BuildingBlockType.EURSWAP3M); mktRates.Add(1.709e-2, "5Y", BuildingBlockType.EURSWAP3M); mktRates.Add(1.862e-2, "6Y", BuildingBlockType.EURSWAP3M); mktRates.Add(1.991e-2, "7Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.101e-2, "8Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.197e-2, "9Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.285e-2, "10Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.443e-2, "12Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.614e-2, "15Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.711e-2, "20Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.671e-2, "25Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.589e-2, "30Y", BuildingBlockType.EURSWAP3M); #endregion end Inputs #region building curve SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator> C1 = new SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator>(mktRates); double firstFixing = 0.434e-2; SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator> C2 = new SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator>(mktRates, firstFixing); SingleCurveBuilderStandard <OnLogDf, LinearInterpolator> C3 = new SingleCurveBuilderStandard <OnLogDf, LinearInterpolator>(mktRates, OneDimensionInterpolation.Linear); #endregion end building curve List <IRateCurve> CurveList = new List <IRateCurve>(); // list containing curve List <string> CurveString = new List <string>(); // list containing labels // populate lists CurveList.Add(C1); CurveString.Add(C1.ToString()); CurveList.Add(C2); CurveString.Add(C2.ToString()); CurveList.Add(C3); CurveString.Add(C3.ToString()); #region printing output // I get the longer swap SwapStyle LS = (SwapStyle)mktRates.GetArrayOfBB().Last(); Dc dc = Dc._Act_360; Date[] FromDate = LS.scheduleLeg2.fromDates; Date[] ToDate = LS.scheduleLeg2.toDates; int N = FromDate.Length; List <Vector <double> > Fwds = new List <Vector <double> >(); double[] dt = new double[N]; for (int i = 0; i < N; i++) { dt[i] = FromDate[0].YF(ToDate[i], Dc._30_360); } foreach (IRateCurve myC in CurveList) { double[] fwd = new double[N]; for (int i = 0; i < N; i++) { double yf = FromDate[i].YF(ToDate[i], dc); double df_ini = myC.Df(FromDate[i]); double df_end = myC.Df(ToDate[i]); fwd[i] = ((df_ini / df_end) - 1) / yf; } Fwds.Add(new Vector <double>(fwd)); } ExcelMechanisms exl = new ExcelMechanisms(); exl.printInExcel(new Vector <double>(dt), CurveString, Fwds, "Fwd vs 3M", "time", "rate"); // .printInExcel<T> #endregion end printing output }
// Calculate the time for initialise a SingleCurveBuilderInterpBestFit public static void TimeForBestFitVs3m() { #region Inputs // Start input Date refDate = (new Date(DateTime.Now)).mod_foll(); // I populate market rates set: from file, from real time, ... here not real data RateSet mktRates = new RateSet(refDate); // Depos mktRates.Add(1.434e-2, "3m", BuildingBlockType.EURDEPO); // Swap Vs 3M mktRates.Add(2.813e-2, "1Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.096e-2, "2Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.322e-2, "3Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.529e-2, "4Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.709e-2, "5Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.862e-2, "6Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.991e-2, "7Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.101e-2, "8Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.197e-2, "9Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.285e-2, "10Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.443e-2, "12Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.614e-2, "15Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.711e-2, "20Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.671e-2, "25Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.589e-2, "30Y", BuildingBlockType.EURSWAP3M); #endregion end Inputs #region building curve DateTime timer; // initialise the timer timer = DateTime.Now; double firstFixing = 1.434e-2; SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator> C = new SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator>(mktRates, firstFixing); Console.WriteLine("\n{0} \nFitted in {1}", C.ToString(), DateTime.Now - timer); timer = DateTime.Now; SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator> C1 = new SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator>(mktRates); Console.WriteLine("\n{0} \nFitted in {1}", C1.ToString(), DateTime.Now - timer); timer = DateTime.Now; SingleCurveBuilderStandard <OnLogDf, LinearInterpolator> C2 = new SingleCurveBuilderStandard <OnLogDf, LinearInterpolator>(mktRates, OneDimensionInterpolation.Linear); Console.WriteLine("\n{0} \nFitted in {1}", C2.ToString(), DateTime.Now - timer); #endregion building curve }
// Calculate the time for initialise a SingleCurveBuilderInterpBestFit public static void TimeForBestFitVs6m() { #region Inputs // Start input Date refDate = (new Date(DateTime.Now)).mod_foll(); // I populate markets rates set: from file, from real time, ... here not real data RateSet mktRates = new RateSet(refDate); // Depos mktRates.Add(2.243e-2, "1m", BuildingBlockType.EURDEPO); mktRates.Add(2.435e-2, "3m", BuildingBlockType.EURDEPO); mktRates.Add(2.620e-2, "6m", BuildingBlockType.EURDEPO); // Swap Vs 6M mktRates.Add(2.869e-2, "1Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.316e-2, "2Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.544e-2, "3Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.745e-2, "4Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.915e-2, "5Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.057e-2, "6Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.175e-2, "7Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.273e-2, "8Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.362e-2, "9Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.442e-2, "10Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.589e-2, "12Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.750e-2, "15Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.835e-2, "20Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.787e-2, "25Y", BuildingBlockType.EURSWAP6M); #endregion end Inputs #region building curve DateTime timer; timer = DateTime.Now; double firstFixing = 1.62e-2; SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator> C = new SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator>(mktRates, firstFixing); Console.WriteLine("\n{0} \nFitted in {1}", C.ToString(), DateTime.Now - timer); timer = DateTime.Now; SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator> C1 = new SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator>(mktRates); Console.WriteLine("\n{0} \nFitted in {1}", C1.ToString(), DateTime.Now - timer); timer = DateTime.Now; SingleCurveBuilderStandard <OnLogDf, LinearInterpolator> C2 = new SingleCurveBuilderStandard <OnLogDf, LinearInterpolator>(mktRates, OneDimensionInterpolation.Linear); Console.WriteLine("\n{0} \nFitted in {1}", C2.ToString(), DateTime.Now - timer); #endregion building curve }
// Check if the process will match the starting inputs public static void CheckInputsVs3m() { #region Inputs // Start input Date refDate = (new Date(DateTime.Now)).mod_foll(); // I populate markets rates set: from file, from real time, ... RateSet mktRates = new RateSet(refDate); // Depos mktRates.Add(2.243e-2, "1m", BuildingBlockType.EURDEPO); mktRates.Add(2.435e-2, "3m", BuildingBlockType.EURDEPO); // Swap Vs 3M mktRates.Add(2.869e-2, "1Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.316e-2, "2Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.544e-2, "3Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.745e-2, "4Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.915e-2, "5Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.057e-2, "6Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.175e-2, "7Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.273e-2, "8Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.362e-2, "9Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.442e-2, "10Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.589e-2, "12Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.750e-2, "15Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.835e-2, "20Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.787e-2, "25Y", BuildingBlockType.EURSWAP3M); #endregion end Inputs // Uncomment to chose the curve // SingleCurveBuilderStandard<OnLogDf, LinearInterpolator> C = new SingleCurveBuilderStandard<OnLogDf, LinearInterpolator>(mktRates, OneDimensionInterpolation.Linear); double firstFixing = 1.435e-2; SingleCurveBuilderSmoothingFwd <OnLogDf, LinearInterpolator> C = new SingleCurveBuilderSmoothingFwd <OnLogDf, LinearInterpolator>(mktRates, firstFixing); // SingleCurveBuilderInterpBestFit<OnLogDf, LinearInterpolator> C = new SingleCurveBuilderInterpBestFit<OnLogDf, LinearInterpolator>(mktRates); #region print output IEnumerable <BuildingBlock> BBArray = mktRates.GetArrayOfBB(); // Only Given Swap from BBArray IEnumerable <BuildingBlock> OnlyGivenDepo = from c in BBArray where c.GetType().BaseType == typeof(OnePaymentStyle) select c; Console.WriteLine(C.ToString()); Console.WriteLine("Recalc Df at Ref Date: {0}", C.DF(refDate)); foreach (OnePaymentStyle BB in OnlyGivenDepo) { double yf = refDate.YF(BB.endDate, BB.dayCount); double df = C.DF(BB.endDate); double CalcRate = ((1 / df) - 1) / yf; Console.WriteLine("{0} Input Rate: {1} Recalc Rate: {2}", BB.Tenor.GetPeriodStringFormat(), BB.rateValue, CalcRate); } // Only Given Swap from BBArray IEnumerable <BuildingBlock> OnlyGivenSwap = from c in BBArray where c.GetType().BaseType == typeof(SwapStyle) select c; foreach (SwapStyle BB in OnlyGivenSwap) { // fixed leg data double[] yfFixLeg = BB.scheduleLeg1.GetYFVect(BB.swapLeg1.DayCount); // fixed is leg 1 // dfs array of fixed lag Date[] dfDates = BB.scheduleLeg1.payDates; // serial date of fixed lag (each dates we should find df) // initialise array for df double[] dfFixLeg = new double[dfDates.Length]; // calculate df for (int i = 0; i < dfDates.Length; i++) { dfFixLeg[i] = C.DF(dfDates[i]); } // Interpolation Methods for Curve Construction PATRICK S. HAGAN & GRAEME WEST Applied Mathematical Finance,Vol. 13, No. 2, 89–129, June 2006 // Formula 2) page 4 double CalcRate = Formula.ParRate(yfFixLeg, dfFixLeg); // Calculate par rate Console.WriteLine("{0} Input Rate: {1} Recalc Rate: {2}", BB.Tenor.GetPeriodStringFormat(), BB.rateValue, CalcRate); } #endregion end print output }