Exemplo n.º 1
0
        //Fonction Psi(theta_n,Ztilde_n+1) = Y_n+1.
        public double FonctionPSI_(double K, double theta)
        {
            this.K_ = K;
            double        ratio1 = 0.0;
            double        Z      = LoiNormal.random_normal_parBoxMuller(rnd);
            List <double> ST     = new List <double>();

            for (int i = 0; i < S0_.Count; i++)
            {
                ST.Add(S0_[i] * Math.Exp((r_ - Math.Pow(Sigma_[i], 2) / 2) * t_ + Sigma_[i] * Math.Pow(t_, 0.50) * Z));
            }
            if (this.op_ == type_.Call)
            {
                ratio1 = Math.Exp(-r_ * t_) * Math.Pow(Math.Max(ST.Average() - K_, 0.0), 2); //attention Math.Exp(-2*r_ * t_)
            }
            else if (this.op_ == type_.Put)
            {
                ratio1 = Math.Exp(-r_ * t_) * Math.Pow(Math.Max(K_ - ST.Average(), 0.0), 2); //attention Math.Exp(-2*r_ * t_)
            }
            else
            {
                throw new InvalidOperationException("Impossible de traiter le type d'option entrer!!!!: " + this.op_);
            }
            double ratio2 = (theta - Z) * Math.Exp(-0.5 * theta * (2 * Z - theta));
            double Psi    = ratio1 * ratio2;

            return(Psi);
        }
Exemplo n.º 2
0
        /******************************************************************************
        * ************ Valeur d'une option basket avec la méthode de réduction *******
        ****************   de la variance Robbins Monro (Arouna)   *******************
        * ****************************************************************************/
        public double[] MC_RM_ArounaBasketOptionVal(type_ op)
        {
            //RobbinsMonroAlgorithme RM;
            List <double> Payoff_;

            double[,] ST_;
            double[] res = new double[2];           //Tableau résultat
            Payoff_ = new List <double>();
            ST_     = new double[NSim_, S0_.Count];
            double NormBoxMuller;

            switch (op)
            {
            case type_.Call:
                for (int j = 0; j < NSim_; j++)
                {
                    double som = 0;
                    for (int i = 0; i < S0_.Count; i++)
                    {
                        NormBoxMuller = LoiNormal.random_normal_parBoxMuller(rnd);
                        ST_[j, i]     = S0_[i] * Math.Exp((r_ - 0.5 * Math.Pow(Sigma_[i], 2)) * t_ + Sigma_[i] * Math.Sqrt(t_) * NormBoxMuller);
                        if (j < NSim_ - 1)
                        {
                            ST_[j + 1, i] = S0_[i] * Math.Exp((r_ - 0.5 * Math.Pow(Sigma_[i], 2)) * t_ + Sigma_[i] * Math.Sqrt(t_) * NormBoxMuller);
                        }
                        som += ST_[j, i];
                    }
                    j++;
                    Payoff_.Add(Math.Exp(-r_ * t_) * Math.Max((som / S0_.Count - K_), 0.0));
                }
                break;

            case type_.Put:
                for (int j = 0; j < NSim_; j++)
                {
                    double som = 0;
                    for (int i = 0; i < S0_.Count; i++)
                    {
                        NormBoxMuller = LoiNormal.random_normal_parBoxMuller(rnd);
                        ST_[j, i]     = S0_[i] * Math.Exp((r_ - 0.5 * Math.Pow(Sigma_[i], 2)) * t_ + Sigma_[i] * Math.Sqrt(t_) * NormBoxMuller);
                        if (j < NSim_ - 1)
                        {
                            ST_[j + 1, i] = S0_[i] * Math.Exp((r_ - 0.5 * Math.Pow(Sigma_[i], 2)) * t_ + Sigma_[i] * Math.Sqrt(t_) * NormBoxMuller);
                        }
                        som += ST_[j, i];
                    }
                    j++;
                    Payoff_.Add(Math.Exp(-r_ * t_) * Math.Max((K_ - som / S0_.Count), 0.0));
                }
                break;

            default:
                throw new InvalidOperationException("Impossible de traiter le type d'option entrer!!!!: " + op);
            }
            res[0] = Payoff_.Average();                                      //La valeur de l'option, Esperance des payoff actualisés
            res[1] = Math.Sqrt(Variance(Payoff_, res[0], 0, Payoff_.Count)); //L'ecarte type de simulation,
            return(res);
        }
Exemplo n.º 3
0
        //Algorithme de robbinsMonro
        public double ThetaOptimalRMArouna(double K, double Theta0, int Niter)
        {
            double        x1     = -2;
            double        x2     = 2;
            List <int>    rho_   = new List <int>();
            List <double> u_     = new List <double>();
            List <double> Theta_ = new List <double>();
            List <double> y_     = new List <double>();
            List <double> gamma_ = new List <double>();

            Theta_.Add(Theta0);
            double x = LoiNormal.random_normal_parBoxMuller(rnd);

            y_.Add(FonctionPSI_(K_, Theta_[0]));
            rho_.Add(0);
            gamma_.Add(1);
            u_.Add(50);

            for (int i = 1; i <= Niter + 1; i++)
            {
                gamma_.Add(1 / (double)(i + 1));                                  //gamma_n = a/(b+n)
                u_.Add(Math.Sqrt((1 / 6) * Math.Log((double)i + 1)) + u_[0]);     //U_n = sqrt(1/6*ln(n))+U_0
            }
            for (int i = 0; i <= Niter; i++)
            {
                rho_.Add(0);
                y_.Add(FonctionPSI_(K, Theta_[i]));
                double xn = 0;
                if (i >= 1)
                {
                    rho_[i] = rho_[i - 1];
                    if (Math.Abs(Theta_[i - 1] - gamma_[i] * y_[i]) > u_[rho_[i - 1]])
                    {
                        rho_[i] = rho_[i] + 1;
                    }
                }
                if (rho_[i] % 2 == 0)
                {
                    xn = x1;
                }
                else
                {
                    xn = x2;
                }

                if (Math.Abs(Theta_[i] - gamma_[i + 1] * y_[i + 1]) <= u_[rho_[i]])
                {
                    Theta_.Add(Theta_[i] - gamma_[i + 1] * y_[i + 1]);
                }
                else
                {
                    Theta_.Add(xn);
                }
            }
            return(Theta_[Niter - 1]);
        }
Exemplo n.º 4
0
        //Calcul de la valeur d'une option basket en utilisant l'algorithme de RM pour la réduction de la variance
        public double[] MC_RM_BasketOptionVal(double Theta, double K)
        {
            List <double> Payoff_;

            double[,] ST_;
            List <double> Z;
            double        Ztilde = LoiNormal.random_normal_parBoxMuller(rnd) + Theta;

            Payoff_ = new List <double>();          //Payoff de l'option à chaque trajectoire
            ST_     = new double[NSim_, S0_.Count]; //ST simulées
            Z       = new List <double>();          //
            double[] res = new double[2];           //Tableau résultat

            if (this.op_ == type_.Call)
            {
                for (int j = 0; j < NSim_; j++)
                {
                    double som = 0;
                    for (int i = 0; i < S0_.Count; i++)
                    {
                        Ztilde    = LoiNormal.random_normal_parBoxMuller(rnd) + Theta;
                        ST_[j, i] = S0_[i] * Math.Exp((r_ - 0.5 * Math.Pow(Sigma_[i], 2)) * t_ + Sigma_[i] * Math.Sqrt(t_) * Ztilde);
                        som      += ST_[j, i];
                    }
                    Payoff_.Add(Math.Max((som / S0_.Count - K_), 0.0));
                    Z.Add(Math.Exp(-r_ * t_) * (Math.Exp(0.5 * Math.Pow(Theta, 2) - Theta * Ztilde)) * Payoff_[j]);
                }
            }
            else if (this.op_ == type_.Put)
            {
                for (int j = 0; j < NSim_; j++)
                {
                    double som = 0;
                    for (int i = 0; i < S0_.Count; i++)
                    {
                        Ztilde    = LoiNormal.random_normal_parBoxMuller(rnd) + Theta;
                        ST_[j, i] = S0_[i] * Math.Exp((r_ - 0.5 * Math.Pow(Sigma_[i], 2)) * t_ + Sigma_[i] * Math.Sqrt(t_) * Ztilde);
                        som      += ST_[j, i];
                    }
                    Payoff_.Add(Math.Max((K_ - som / S0_.Count), 0.0));
                    Z.Add(Math.Exp(-r_ * t_) * (Math.Exp(0.5 * Math.Pow(Theta, 2) - Theta * Ztilde)) * Payoff_[j]);
                }
            }
            else
            {
                throw new InvalidOperationException("Impossible de traiter le type d'option entrer!!!!: ");
            }
            res[0] = Z.Average();                                     //La valeur de l'option, Esperance des payoff actualisés
            res[1] = Math.Sqrt(Variance(Z, Z.Average(), 0, Z.Count)); //L'ecarte type de simulation,
            return(res);
        }
        /*********************************************************************************************************
         * Fonction return à la valeur d'une option européenne type=Call ou Put
         * return à une vecteur de taille 2: première composante de la table contenant la valeur de l'option
         * Deuxième composante: l'erreur de la simulation MC
         **********************************************************************************************************/
        public double[] MCEuropOptionVal(type_ op)
        {
            List <double> ST_, Payoff_, SquareEsperance;
            double        mu  = (r_ - 0.5 * Math.Pow(Sigma_, 2)) * t_;
            double        sig = Sigma_ * Math.Sqrt(t_);
            double        NormBoxMuller;           //Variable Normale centrée reduite

            ST_             = new List <double>(); //Tableau pour stocker les valeurs de ST simuler
            Payoff_         = new List <double>(); //Tableau des PayOff
            SquareEsperance = new List <double>(); //Esperance des crées
            double[] res = new double[2];          //Tableau résultat

            for (int i = 0; i < NSim_; i++)
            {
                NormBoxMuller = LoiNormal.random_normal_parBoxMuller(rnd);
                ST_.Add(S0_ * Math.Exp(mu + sig * NormBoxMuller));
                if (i < NSim_ - 1)
                {
                    ST_.Add(S0_ * Math.Exp(mu - (sig * NormBoxMuller)));
                }
                i++;
            }
            switch (op)
            {
            case type_.Call:
                for (int i = 0; i < NSim_; i++)
                {
                    Payoff_.Add(Math.Exp(-r_ * t_) * Math.Max((ST_[i] - K_), 0.0));
                    SquareEsperance.Add(Math.Pow(Payoff_[i], 2));
                }
                break;

            case type_.Put:
                for (int i = 0; i < NSim_; i++)
                {
                    Payoff_.Add(Math.Exp(-r_ * t_) * Math.Max((K_ - ST_[i]), 0.0));
                    SquareEsperance.Add(Math.Pow(Payoff_[i], 2));
                }
                break;

            default:
                throw new InvalidOperationException("Impossible de traiter le type d'option entrer!!!!: " + op);
            }
            res[0] = Payoff_.Average();                                      //La valeur de l'option, Esperance des payoff actualisés
            res[1] = Math.Sqrt(Variance(Payoff_, res[0], 0, Payoff_.Count)); //L'ecarte type de simulation,
            return(res);
        }
        //Calcul de la valeur d'une option européenne en utilisant l'algorithme de RM pour la réduction de la variance
        public double[] MCEurValeurISLemairePages(double Theta, double K)
        {
            double[] PrixSimul = new double[NSim_];
            double   Ztilde    = LoiNormal.random_normal_parBoxMuller(rnd) + Theta; //Variable Normale: moyenne =tetha* , variance = 1;
            double   mu        = (r_ - 0.5 * Math.Pow(Sigma_, 2)) * T_;
            double   sig       = Sigma_ * Math.Sqrt(T_);

            List <double> Payoff_   = new List <double>();
            List <double> Z         = new List <double>();;
            List <double> NormalVar = new List <double>();
            List <double> Zcarre    = new List <double>();

            double[] res = new double[2];
            this.K_ = K;

            for (int i = 0; i < NSim_; i++)
            {
                Ztilde       = LoiNormal.random_normal_parBoxMuller(rnd) + Theta;
                PrixSimul[i] = S0_ * Math.Exp(mu + sig * Ztilde);
                NormalVar.Add(Math.Pow(Ztilde, 2));
                if (this.op_ == type_.Call)
                {
                    Payoff_.Add(Math.Max(PrixSimul[i] - K_, 0.0));
                }
                else if (this.op_ == type_.Put)
                {
                    Payoff_.Add(Math.Max(K_ - PrixSimul[i], 0.0));
                }
                else
                {
                    throw new InvalidOperationException("Impossible de traiter le type d'option entrer!!!!: " + this.op_);
                }

                Z.Add(Math.Exp(-r_ * T_) * (Math.Exp(0.5 * Math.Pow(Theta, 2) - Theta * Ztilde)) * Payoff_[i]);
                Zcarre.Add((Math.Pow(Z[i], 2)));
            }
            res[0] = Z.Average();                                     //La moyenne des PayOff actulisés
            res[1] = Math.Sqrt(Variance(Z, Z.Average(), 0, Z.Count)); //L'ecarte type de simulation,
            return(res);
        }
        public double ThetaOptimalPL(double K, double Theta0, double lamda, int Niter)
        {
            List <double> Theta_ = new List <double>();
            List <double> gamma_ = new List <double>();
            List <double> y_     = new List <double>();
            double        Z      = LoiNormal.random_normal_parBoxMuller(rnd);

            this.K_ = K;
            Theta_.Add(Theta0);
            gamma_.Add(1);
            y_.Add(Math.Exp(-2 * lamda * Theta_[0]) * FonctionFCaree(K_, Theta_[0]) * (2 * Theta_[0] - Z));

            for (int i = 1; i <= Niter + 1; i++)
            {
                gamma_.Add(1 / (double)(i + 1));    //gamma_n = a/(b+n)
            }
            for (int i = 0; i < Niter; i++)
            {
                Z = LoiNormal.random_normal_parBoxMuller(rnd);
                Theta_.Add(Theta_[i] - gamma_[i + 1] * y_[i]);
                y_.Add(Math.Exp(-2 * lamda * Theta_[i + 1]) * FonctionFCaree(K_, Theta_[i + 1]) * (2 * Theta_[i + 1] - Z));
            }
            return(Theta_[Niter - 1]);
        }
        //Fonction F^2(Xn+1 - theta)
        public double FonctionFCaree(double K, double theta)
        {
            this.K_ = K;
            double ratio1 = 0.0;
            double Z      = LoiNormal.random_normal_parBoxMuller(rnd) - theta;
            double ST     = S0_ * Math.Exp((r_ - Math.Pow(Sigma_, 2) / 2) * T_ + Sigma_ * Math.Pow(T_, 0.50) * Z);

            if (this.op_ == type_.Call)
            {
                ratio1 = Math.Pow(Math.Max(ST - K_, 0.0), 2);
            }
            else if (this.op_ == type_.Put)
            {
                ratio1 = Math.Pow(Math.Max(K_ - ST, 0.0), 2);
            }
            else
            {
                throw new InvalidOperationException("Impossible de traiter le type d'option entrer!!!!: " + this.op_);
            }
            double ratio2 = 1;
            double Psi    = ratio1 * ratio2;

            return(Psi);
        }
        static void Main(string[] args)
        {
            Random rnd = new Random();

            BSEurOption            Eur;
            RobbinsMonroAlgorithme RM_Put;
            RobbinsMonroAlgorithme RM_Call;
            MCEuropOption          MCEur;
            RMAlgoPagesLemaire     PL_Call;
            RMAlgoPagesLemaire     PL_Put;

            double S0     = 100;
            double K      = 95;
            double r      = 0.05;
            int    T      = 1;
            double sigma  = 0.15;
            double theta0 = 1.5;
            double lamda  = 30;
            long   Nsim   = 2000;
            int    Ntier  = 500000;

            Eur     = new BSEurOption(S0, K, r, T, sigma);
            RM_Put  = new RobbinsMonroAlgorithme(S0, K, T, sigma, r, Nsim, type_.Put);
            RM_Call = new RobbinsMonroAlgorithme(S0, K, T, sigma, r, Nsim, type_.Call);
            PL_Call = new RMAlgoPagesLemaire(S0, K, T, sigma, r, Nsim, type_.Call);
            PL_Put  = new RMAlgoPagesLemaire(S0, K, T, sigma, r, Nsim, type_.Put);
            MCEur   = new MCEuropOption(S0, K, T, sigma, r, Nsim);
            double z = LoiNormal.random_normal_parBoxMuller(rnd);
            double thetaOptArouna;
            double thetaPL;

            /***********************************************
             * ********** Valeur d'un call Européen ********
             * **********************************************/
            Console.WriteLine("============================================================");
            Console.WriteLine("====================Call Européen===========================");
            Console.WriteLine("============================================================");
            Console.WriteLine("Valeur exacte d'un Call (avec formules de BS)= " + Eur.callBlackScholes());
            Console.WriteLine("\nValeur d'un Call avec réduction de la variance par var ANti= " + MCEur.MCEuropOptionVal(type_.Call)[0]);
            Console.WriteLine("\nVariance IS(Variables Antithetique)= " + MCEur.MCEuropOptionVal(type_.Call)[1]);
            thetaOptArouna = RM_Call.ThetaOptimalRMArouna(K, theta0, Ntier);
            Console.WriteLine("\nTheta optimal avec Robbins Monro [Arouna]=  " + thetaOptArouna);
            Console.WriteLine("\nValeur d'un Call avec réduction de la variance IS= " + +RM_Call.MCEurValeurImportanceSampling(thetaOptArouna, K)[0]);
            Console.WriteLine("\nVariance IS(Anouna RM algo)= " + +RM_Call.MCEurValeurImportanceSampling(thetaOptArouna, K)[1]);
            thetaPL = PL_Call.ThetaOptimalPL(105, 0.3, 30, 10);
            Console.WriteLine("\nTheta RMPagesLemaire =  " + thetaPL);
            Console.WriteLine("\nValeur d'un Call avec (Algo RM PagesLemaire) =  " + PL_Call.MCEurValeurISLemairePages(thetaPL, K)[0]);
            Console.WriteLine("\nVariance IS(PagesLemaire RM algo) =  " + PL_Call.MCEurValeurISLemairePages(thetaPL, K)[1]);


            /***************************************
            ********* Test options basket *********
            ***************************************/
            Console.WriteLine("\n\n============================================================");
            Console.WriteLine("====================Options Basket===========================");
            Console.WriteLine("============================================================");
            List <double> S0_    = new List <double>();
            List <double> Sigma_ = new List <double>();

            for (int i = 0; i < 3; i++)
            {
                S0_.Add(94 + i * 4);
                Sigma_.Add(0.25 + i * 0.02);
            }
            MCBasketOption   bsket  = new MCBasketOption(S0_, K, T, Sigma_, r, Nsim);
            MCRMBasketOption rmbask = new MCRMBasketOption(S0_, K, T, Sigma_, r, Nsim, type_.Call);

            Console.WriteLine("\n\n prix Basket Call MC_ Var Anti= " + bsket.MC_AntitBasketOptionVal(type_.Call)[0]);
            Console.WriteLine("\n\n prix Basket Put MC_ Var Anti= " + bsket.MC_AntitBasketOptionVal(type_.Put)[0]);

            double thetarmBasket = rmbask.ThetaOptimalRMArouna(105, 1.5, 100000);

            Console.WriteLine("\n\n Theta optimal avec RM de l'option Basket = " + thetarmBasket);

            Console.ReadLine();
        }