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
    }