Exemplo n.º 1
0
        public void C9_9_6_TwoFactor_Spread_European()
        {
            // Declare and initialise the parameters
            var myData = new TwoFactorBinomialParameters
            {
                sigma1   = 0.2,
                sigma2   = 0.3,
                T        = 1.0,
                r        = 0.06,
                K        = 1.0,
                div1     = 0.03,
                div2     = 0.04,
                rho      = 0.5,
                exercise = false
            };

            // Clewlow and Strickland p. 47
            // false;
            var S1 = 100.0;
            var S2 = 100.0;
            var w1 = 1.0;
            var w2 = -1.0;
            var cp = 1;

            myData.pay = new SpreadStrategy(cp, myData.K, w1, w2);

            var myTree = new TwoFactorBinomial(myData, numberOfSteps, S1, S2);
            var price  = myTree.Price();

            Assert.AreEqual(price, 10.13757, 0.001);
        }
Exemplo n.º 2
0
        public void C9_9_6_TwoFactor_Basket_European()
        {
            double Price(double T, double sig1, double sig2)
            {
                var myData = new TwoFactorBinomialParameters
                {
                    sigma1   = sig1,
                    sigma2   = sig2,
                    T        = T,
                    r        = 0.1,
                    K        = 40.0,
                    div1     = 0.0,
                    div2     = 0.0,
                    rho      = 0.5,
                    exercise = false
                };

                var S1 = 18.0;
                var S2 = 20.0;
                var w1 = 1.0;
                var w2 = 1.0;
                var cp = -1; // Weights; put option

                myData.pay = new BasketStrategy(myData.K, cp, w1, w2);

                var myTree = new TwoFactorBinomial(myData, 500, S1, S2);

                return(myTree.Price());
            }

            Assert.AreEqual(Price(0.95, 0.1, 0.1), 0.6032, 0.001);
            Assert.AreEqual(Price(0.95, 0.1, 0.2), 1.2402, 0.001);
            Assert.AreEqual(Price(0.95, 0.1, 0.3), 1.9266, 0.001);
            Assert.AreEqual(Price(0.95, 0.2, 0.1), 1.1597, 0.001);
            Assert.AreEqual(Price(0.95, 0.2, 0.2), 1.7749, 0.001);
            Assert.AreEqual(Price(0.95, 0.2, 0.3), 2.4383, 0.001);
            Assert.AreEqual(Price(0.95, 0.3, 0.1), 1.7639, 0.001);
            Assert.AreEqual(Price(0.95, 0.3, 0.2), 2.355, 0.001);
            Assert.AreEqual(Price(0.95, 0.3, 0.3), 2.9976, 0.001);

            Assert.AreEqual(Price(0.05, 0.1, 0.1), 1.8025, 0.001);
            Assert.AreEqual(Price(0.05, 0.1, 0.2), 1.8332, 0.001);
            Assert.AreEqual(Price(0.05, 0.1, 0.3), 1.9117, 0.001);
            Assert.AreEqual(Price(0.05, 0.2, 0.1), 1.8270, 0.001);
            Assert.AreEqual(Price(0.05, 0.2, 0.2), 1.8859, 0.001);
            Assert.AreEqual(Price(0.05, 0.2, 0.3), 1.9817, 0.001);
            Assert.AreEqual(Price(0.05, 0.3, 0.1), 1.8906, 0.001);
            Assert.AreEqual(Price(0.05, 0.3, 0.2), 1.9682, 0.001);
            Assert.AreEqual(Price(0.05, 0.3, 0.3), 2.0737, 0.001);
        }
    // Accuracy of price on number of steps
    public static Vector <double> Prices(TwoFactorBinomialParameters optionData, Vector <int> meshSizes, double S1,
                                         double S2)
    {
        // Caculates the price for a number of step sizes (usually increasing)

        Vector <double> result = new Vector <double> (meshSizes.Size);
        //print (result);

        // TwoFactorBinomial(TwoFactorBinomialParameters optinData,long NSteps,
        //									double S1, double S2);

        TwoFactorBinomial local;

        for (int j = result.MinIndex; j <= result.MaxIndex; j++)
        {
            local = new TwoFactorBinomial(optionData, meshSizes[j], S1, S2);

            result[j] = local.Price();
            //cout << local.Price() << ";;";
        }

        return(result);
    }
Exemplo n.º 4
0
    public static void Main()
    {
        // Declare and initialise the parameters
        TwoFactorBinomialParameters myData = new TwoFactorBinomialParameters();

        // Clewlow and Strickland p. 47
        myData.sigma1 = 0.2; myData.sigma2 = 0.3;
        myData.T      = 1.0;     myData.r = 0.06; myData.K = 1.0;
        myData.div1   = 0.03; myData.div2 = 0.04;
        myData.rho    = 0.5; myData.exercise = true; // false;

        double S1 = 100.0;
        double S2 = 100.0;
        double w1 = 1.0; double w2 = -1.0; int cp = 1;

        myData.pay = new SpreadStrategy(cp, myData.K, w1, w2);

        // Min-max option

        /*    myData.sigma1 = 0.3;
         *      myData.sigma2 = 0.3;
         *
         *      myData.T = 10.0;
         *      myData.r = 0.1;
         *      myData.K = 40.0;
         *      myData.div1 = 0.0;
         *      myData.div2 = 0.0;
         *      myData.rho = 0.5;
         *      myData.exercise = true;
         *  double S1 = 40.0;
         *  double S2 = 40.0;
         *
         *
         *  int cp = 1;
         *  int dMinMax = 1; // 1 == Max, else Min
         *  myData.pay = new RainbowStrategy(cp, myData.K, dMinMax);*/


        // Topper 2005 page 198

        /*     myData.sigma1 = 0.1; myData.sigma2 = 0.1;
         *   myData.T = 0.05; myData.r = 0.1; myData.K = 40.0;
         *   myData.div1 = 0.0; myData.div2 = 0.0;
         *   myData.rho = 0.5; myData.exercise = false;
         *
         *   double S1 = 18.0; double S2 = 20.0;
         *   double w1 = 1.0; double w2 = 1.0; int cp = -1; // Weights; put option
         *   myData.pay = new BasketStrategy(myData.K, cp, w1, w2);*/


        /*    myData.sigma1 = 0.2; myData.sigma2 = 0.2;
         *  myData.T = 0.5; myData.r = 0.1; myData.K = 10.0;
         *  myData.div1 = 0.0; myData.div2 = 0.0;
         *  myData.rho = 0.5; myData.exercise = false;*/

        //  double S1 = 122.0; double S2 = 120.0;
        //    int a = 1; int b = -1; int pp = 1;
        // myData.pay = new BasketStrategy(myData.K, pp, a, b);
        //  myData.pay = new  BestofTwoStrategy(myData.K, pp);
        //  myData.pay = new WorstofTwoStrategy(myData.K, -1);
        //   myData.pay = new SpreadStrategy(-pp, myData.K, 1,-1);
        //   cout << "How many timesteps: ";
        int NumberOfSteps = 50;

        //    cin >> NumberOfSteps;

        //      myData.sigma1 = 0.3; myData.sigma2 = 0.2;
        //      myData.T = 0.95; myData.r = Math.Log(1.1);
        //      myData.div1 = Math.Log(1.05); myData.div2 = Math.Log(1.05);
        ////      myData.div1 = 0; myData.div2 = 0;
        //      myData.rho = 0.99; myData.exercise = false;

        //    double S1 = 100; double S2 = 100;
        //      double w1 = 1.0; double w2 = 1.0; int cp = -1; // Weights; put option
        // myData.pay = new BasketStrategy(myData.K, cp, w1, w2); //double strike, int cp,double weight1, double weight2)
        // myData.pay = new WorstofTwoStrategy(myData.K, cp);
        //myData.pay = new RainbowStrategy(cp, myData.K, 1); //(int cp, double strike, int DMinDMax)
        //  myData.pay = new DualStrikeStrategy(110, 100, +1, -1); //(int cp, double strike, int DMinDMax)
        //myData.pay = new ExchangeStrategy();

        //     int n1 = 1; int n2 = 1; myData.K = 40.0;
        //     myData.pay = new PortfolioStrategy(n1, n2, myData.K, -1);
        Console.WriteLine("Computing...");
        TwoFactorBinomial myTree = new TwoFactorBinomial(myData, NumberOfSteps, S1, S2);

        Console.WriteLine("Price is now: {0}", myTree.Price());
        //  Console.WriteLine(myTree.Price());
        // Now examine the convergence of 2-factor Binomial method

        /*    int size = 12;
         *  Vector<int> meshSizes = new Vector<int>(size);
         *  int N = 2;
         *  for (int j = meshSizes.MinIndex; j <=  meshSizes.MaxIndex; j++)
         *  {
         *      meshSizes[j] = N;
         *      N *= 2;
         *
         *  }
         *  //print(meshSizes);
         *
         *  Vector<double> result = TwoFactorBinomial.Prices(myData, meshSizes, S1, S2);
         *  for (int j = meshSizes.MinIndex ; j <=  meshSizes.MaxIndex; j++)
         *  {
         *      Console.WriteLine(result[j]);
         *  }
         */
    }
    public TwoFactorBinomial(TwoFactorBinomialParameters optionData, int NSteps,
                             double S1, double S2)
    { // The most important constuctor
        par = optionData;

        N = NSteps;

        // Mesh sizes, Clewlow (2.43)-(2.44)
        delta_T = par.T / N;                       // DeltaT
        h1      = par.sigma1 * Math.Sqrt(delta_T); // DeltaX1
        h2      = par.sigma2 * Math.Sqrt(delta_T); // DeltaX2

        //cout << "deltas t, S... " << k << ", " << h1 << ", " << h2 << endl;

        // Parameters (prob)
        double nu1 = par.r - par.div1 - (0.5 * par.sigma1 * par.sigma1);
        double nu2 = par.r - par.div2 - (0.5 * par.sigma2 * par.sigma2);

        //cout << "nu1... " << nu1 << ", " << nu2 << endl;

        double a = h1 * h2; double b = h2 * nu1 * delta_T; double c = h1 * nu2 * delta_T;
        double d = par.rho * par.sigma1 * par.sigma2 * delta_T;

        //cout << "a ..." << a << ", " << b << ", " << c << ", " << d << endl;

        double disc = Math.Exp(-(par.r) * delta_T);

        puu = disc * 0.25 * (a + b + c + d) / a; // eq. (2.45)
        pud = disc * 0.25 * (a + b - c - d) / a;
        pdu = disc * 0.25 * (a - b + c - d) / a;
        pdd = disc * 0.25 * (a - b - c + d) / a;

        //cout << "puu ..." << puu << ", " << pud << ", " << pdu << ", " << pdd << endl;

        // Asset arrays
        // Initialise asset prices at *maturity*. Norice that the start index is a negative number
        asset1 = new Vector <double>(2 * N + 1, -N);
        asset2 = new Vector <double>(2 * N + 1, -N);

        asset1[-N] = S1 * Math.Exp(-N * h1);
        asset2[-N] = S2 * Math.Exp(-N * h2);

        double edx1 = Math.Exp(h1);
        double edx2 = Math.Exp(h2);

        //cout << "edx1... disc " << edx1 << ", " << edx2 << ", " << disc << endl;

        for (int n = -N + 1; n <= N; n++)
        {
            asset1[n] = asset1[n - 1] * edx1;
            asset2[n] = asset2[n - 1] * edx2;
        }

        //print(asset1);
        //print(asset2);

        option = new NumericMatrix <double>(2 * N + 1, 2 * N + 1, -N, -N);

        // Calculate option price at the expiry date
        for (int j = option.MinRowIndex; j <= option.MaxRowIndex; j += 2)
        {
            //cout << j << ", ";
            for (int k = option.MinColumnIndex; k <= option.MaxColumnIndex; k += 2)
            {
                option[j, k] = Payoff(asset1[j], asset2[k]);
            }
        }
    }