コード例 #1
0
    // Calculate Yield from dirty price
    public static double YieldFromFullPrice(double fullPrice, double yieldGuess, Date[] CashFlowsDate, double[] CashFlows,
                                            int freq, Dc dc, Date SettlementDate, Compounding compounding, double FaceValue)
    {
        int N = CashFlowsDate.GetLength(0);                              // number of Cash flows dates
        int k = Array.FindIndex(CashFlowsDate, n => n > SettlementDate); // get index of first cash flow after settlement date

        Date[]   Dates = new Date[N - k];                                // array with pay dates after settlement
        double[] Flows = new double[N - k];                              // flows after settlement
        Array.Copy(CashFlowsDate, k, Dates, 0, N - k);                   // fill array with needed data
        Array.Copy(CashFlows, k, Flows, 0, N - k);                       // fill array with needed data

        // define my function: we should find yield that match starting price
        NumMethod.myMethodDelegate fname =
            y_ => fullPrice - FullPriceFromYield(y_, Dates, Flows,
                                                 freq, dc, SettlementDate, compounding, FaceValue);

        // return yield
        return(NumMethod.NewRapNum(fname, yieldGuess));
    }
コード例 #2
0
    public static void SimpleBootstrap20Y()
    {
        #region data
        // We load a set of data (not real)
        DataForCapletExample1 data1 = new DataForCapletExample1();
        double[] df        = data1.df();
        double[] yf        = data1.yf();
        double[] T         = data1.T();
        int      N         = df.Length;
        double[] fwd       = new double[N];
        double[] atmfwd    = new double[N];
        double[] capletVol = new double[N];
        double[] capPrice  = new double[N];
        double   df_ini    = data1.df_ini;
        double[] capVol    = data1.capVol();
        #endregion
        // calculate fwd
        fwd[0] = ((df_ini / df[0]) - 1) / yf[0];
        for (int i = 1; i < df.Length; i++)
        {
            fwd[i] = ((df[i - 1] / df[i]) - 1) / yf[i];
        }

        // calculate ATM strike
        double summ = 0.0;
        for (int i = 0; i < df.Length; i++)
        {
            summ     += yf[i] * df[i];
            atmfwd[i] = (df_ini - df[i]) / summ;
        }

        double shorterCap = 0.0;
        // calculate cap price using flat vol
        for (int i = 0; i < N; i++)
        {
            shorterCap = 0.0;

            for (int j = 0; j <= i; j++)
            {
                capPrice[i] += Formula.CapletBlack(T[j], yf[j], 100, atmfwd[i], capVol[i], df[j], fwd[j]);
            }
            for (int j = 0; j < i; j++)
            {
                shorterCap += Formula.CapletBlack(T[j], yf[j], 100, atmfwd[i], capletVol[j], df[j], fwd[j]);
            }

            NumMethod.myMethodDelegate fname =
                s => capPrice[i] - shorterCap - Formula.CapletBlack(T[i], yf[i], 100, atmfwd[i], s, df[i], fwd[i]);
            capletVol[i] = NumMethod.NewRapNum(fname, 0.20);
        }

        #region print results
        ExcelMechanisms exl = new ExcelMechanisms();

        Vector <double> CapletVol = new Vector <double>(capletVol, 1);
        Vector <double> CapVol    = new Vector <double>(capVol, 1);
        Vector <double> xarr      = new Vector <double>(T, 1);
        List <string>   labels    = new List <string>()
        {
            "CapletVol", "CapVol"
        };
        List <Vector <double> > yarrs = new List <Vector <double> >()
        {
            CapletVol, CapVol
        };

        exl.printInExcel <double>(xarr, labels, yarrs, "Caplet vs Cap Vol", "Term", "Volatility");
        #endregion
    }
コード例 #3
0
    public static void SimpleBootstrap()
    {
        #region data
        // Array of discount factor
        double[] df = new double[] { 0.994236269575566, 0.991625192926998, 0.989041421054714, 0.986231394133455, 0.983496974873945, 0.980646228901972, 0.977577789248498, 0.974244477497738, 0.97067019775667, 0.966860206840406, 0.96281976156406, 0.958481789220407, 0.953769370400552, 0.948855174348367, 0.94375920324068, 0.93838613470982, 0.93274533960824, 0.926957758932136, 0.92108389607756 };
        // array of yf of each caplet
        double[] yf = new double[] { 0.255555555555556, 0.261111111111111, 0.252777777777778, 0.244444444444444, 0.261111111111111, 0.252777777777778, 0.252777777777778, 0.252777777777778, 0.252777777777778, 0.252777777777778, 0.252777777777778, 0.252777777777778, 0.252777777777778, 0.255555555555556, 0.252777777777778, 0.252777777777778, 0.255555555555556, 0.255555555555556, 0.252777777777778 };
        // array of expiry of each caplet
        double[] T_1       = new double[] { 0.252054794520548, 0.50958904109589, 0.758904109589041, 1, 1.25753424657534, 1.50684931506849, 1.75616438356164, 2.00547945205479, 2.25479452054795, 2.5041095890411, 2.75342465753425, 3.0027397260274, 3.25205479452055, 3.5041095890411, 3.75342465753425, 4.0027397260274, 4.25479452054795, 4.50684931506849, 4.75616438356164 };
        int      N         = df.Length;     // number of elements
        double[] fwd       = new double[N]; // to contain forward rate
        double[] atmfwd    = new double[N]; // to contain ATM forward Cap strike
        double[] capletVol = new double[N]; // to contain each caplet volatilities
        double[] capPrice  = new double[N]; // to contain Cap price
        double   df_ini    = 0.99702;       // first discount factor  on T[0]
        // Cap Volatility from the market
        double[] capVol = new double[] { 0.5458, 0.5458, 0.5458, 0.55289, 0.557646575342466, 0.569168493150685, 0.582581643835616, 0.595015616438357, 0.563876164383561, 0.532736712328767, 0.501597260273972, 0.470798904109589, 0.470699178082192, 0.470598356164384, 0.470498630136986, 0.470348767123288, 0.465635342465753, 0.460921917808219, 0.456259726027397 };
        #endregion
        // calculate fwd
        fwd[0] = ((df_ini / df[0]) - 1) / yf[0];
        for (int i = 1; i < df.Length; i++)
        {
            fwd[i] = ((df[i - 1] / df[i]) - 1) / yf[i];
        }

        // calculate ATM strike
        double summ = 0.0;
        for (int i = 0; i < df.Length; i++)
        {
            summ     += yf[i] * df[i];
            atmfwd[i] = (df_ini - df[i]) / summ;
        }

        double shorterCap = 0.0; // Shorter Cap is the same Cap without last caplet
        // calculate cap price using cal vol
        for (int i = 0; i < N; i++)
        {
            shorterCap = 0.0;

            // Note: here I use cap Vol
            for (int j = 0; j <= i; j++)
            {
                capPrice[i] += Formula.CapletBlack(T_1[j], yf[j], 100, atmfwd[i], capVol[i], df[j], fwd[j]);
            }
            // Note: here I use Caplet vol
            for (int j = 0; j < i; j++)
            {
                shorterCap += Formula.CapletBlack(T_1[j], yf[j], 100, atmfwd[i], capletVol[j], df[j], fwd[j]);
            }
            // Inizialize Newton Raphson solver
            NumMethod.myMethodDelegate fname =
                s => capPrice[i] - shorterCap - Formula.CapletBlack(T_1[i], yf[i], 100, atmfwd[i], s, df[i], fwd[i]);
            capletVol[i] = NumMethod.NewRapNum(fname, 0.20); // the missing caplet volatility
        }
        // Print results
        Console.WriteLine("Time   ATMCapStrike     CapletVol     CapVol");
        for (int i = 0; i < capletVol.Length; i++)
        {
            // Caplet expiry is T_1+yf (expiry + caplet year factor)
            Console.WriteLine("{0:N2}     {1:p5}     {2:p5}   {3:p5}", T_1[i] + yf[i],
                              atmfwd[i], capletVol[i], capVol[i]);
        }
    }
コード例 #4
0
    public static void SimpleBootstrapOneCaplet()
    {
        #region InputData
        double[] yf = new double[] { 0.25278, 0.25556, 0.25556, 0.25 };
        double[] T  = new double[] { 0.25, 0.50, 0.75, 1.0 };
        double[] df = new double[] { 0.99406, 0.99153, 0.98904, 0.98633 };
        // One curve framework: traditional fwd calc
        double[] fwd = new double[4];
        fwd[0] = ((0.99695 / df[0]) - 1) / yf[0];
        for (int i = 1; i < df.Length; i++)
        {
            fwd[i] = ((df[i - 1] / df[i]) - 1) / yf[i];
        }
        double K         = 0.0102;
        double sigma1Y3M = 0.2402;
        double sigma1Y   = 0.2364;
        #endregion

        // Price of 1Y3M (18 months) Cap @ vol = sigma1Y3M
        double pxCap1Y3M = Formula.CapBlack(T, yf, 1, K, sigma1Y3M, df, fwd);

        // Price of 1Y Cap @ vol=sigma1Y
        double pxCap1Y = 0.0;
        for (int i = 0; i < df.Length - 1; i++)
        {
            pxCap1Y += Formula.CapletBlack(T[i], yf[i], 1, K, sigma1Y, df[i], fwd[i]);
        }

        // Price of 3M Caplet starting in 1Y
        double pxCaplet3M = pxCap1Y3M - pxCap1Y;

        // Inizialize Newton-Raphson algorithm to find Caplet implied vol
        NumMethod.myMethodDelegate fname =
            s => pxCaplet3M - Formula.CapletBlack(T[3], yf[3], 1, K, s, df[3], fwd[3]);

        // vol is the implied vol of 3M Caplet starting in 1Y. (0.20 is a starting guess)
        double implVol = NumMethod.NewRapNum(fname, 0.20);

        // array of caplet volatility (PieceWiseConstant under1Y)
        double[] capletVol = new double[] { sigma1Y, sigma1Y, sigma1Y, implVol };

        // printing results
        Console.WriteLine("1Y Cap Vol {0:p5}", sigma1Y);
        Console.WriteLine("1Y3M Cap Vol {0:p5}", sigma1Y3M);
        Console.WriteLine("Calculated Implied 3M Caplet Vol Starting in 1Y: {0:p5}", implVol);

        double pxCaplet = 0.0;
        double pxCap    = 0.0;

        Console.WriteLine("\nUsing Caplet Volatilities");
        for (int i = 0; i < df.Length; i++)
        {
            pxCaplet = Formula.CapletBlack(T[i], yf[i], 1, K, capletVol[i], df[i], fwd[i]);
            pxCap   += pxCaplet;
            Console.WriteLine("Caplet #: {0} CapletVol:{1:p4} Px: {2:n5} Cumulated Price: {3:n7}", i + 1, capletVol[i], pxCaplet, pxCap);
        }
        Console.WriteLine("Price Cap as sum of Caplets using Caplet Vol: {0:n7}", pxCap);

        // reset
        pxCaplet = 0.0;
        pxCap    = 0.0;
        Console.WriteLine("\nUsing Cap Volatilities");
        for (int i = 0; i < df.Length; i++)
        {
            pxCaplet = Formula.CapletBlack(T[i], yf[i], 1, K, sigma1Y3M, df[i], fwd[i]);
            pxCap   += pxCaplet;
            Console.WriteLine("Caplet #: {0} CapletVol:{1:p4} Px: {2:n5} Cumulated Price: {3:n7}", i + 1, sigma1Y3M, pxCaplet, pxCap);
        }

        Console.WriteLine("Price Cap as sum of Caplets using Cap Vol: {0:n7}", pxCap); // pxCap = pxCap1Y3M
    }