Exemplo n.º 1
0
        /// <summary>
        /// Calculates a call option on a bond.
        /// </summary>
        /// <param name="r0">The Zr evaluated in zero.</param>
        /// <param name="t">The valuation date (in years fractions).</param>
        /// <param name="T">The option exercise time to buy a bond with maturity S.</param>
        /// <param name="S">The maturity of the bound to buy.</param>
        /// <param name="X">The strike price.</param>
        /// <param name="cirParameters">
        /// A vector containing CIR model parameters k, theta, sigma.
        /// </param>
        /// <returns>The call option price.</returns>
        public static double BondCall(double r0, double t, double T, double S, double X, Vector cirParameters)
        {
            double k     = cirParameters[0];
            double theta = cirParameters[1];
            double sigma = cirParameters[2];

            double h = Math.Sqrt(k * k + 2.0 * sigma * sigma);

            double dentS = 2.0 * h + (k + h) * (Math.Exp(h * (S - t)) - 1.0);
            double AtS   = Math.Pow(2.0 * h * Math.Exp(0.5 * (k + h) * (S - t)) / dentS, 2.0 * k * theta / (sigma * sigma));
            double BtS   = 2.0 * (Math.Exp(h * (S - t)) - 1.0) / dentS;

            double denTS = 2.0 * h + (k + h) * (Math.Exp(h * (S - T)) - 1.0);
            double ATS   = Math.Pow(2.0 * h * Math.Exp(0.5 * (k + h) * (S - T)) / denTS, 2.0 * k * theta / (sigma * sigma));
            double BTS   = 2.0 * (Math.Exp(h * (S - T)) - 1.0) / denTS;

            double dentT = 2.0 * h + (k + h) * (Math.Exp(h * (T - t)) - 1.0);
            double AtT   = Math.Pow(2.0 * h * Math.Exp(0.5 * (k + h) * (T - t)) / dentT, 2.0 * k * theta / (sigma * sigma));
            double BtT   = 2.0 * (Math.Exp(h * (T - t)) - 1.0) / dentT;

            double PtS = AtS * Math.Exp(-BtS * r0);
            double PtT = AtT * Math.Exp(-BtT * r0);

            double rstar = Math.Log(ATS / X) / BTS;
            double rho   = 2.0 * h / (sigma * sigma * (Math.Exp(h * (T - t)) - 1.0));
            double psi   = (k + h) / (sigma * sigma);

            double v1 = 4.0 * k * theta / (sigma * sigma);
            double v2 = 2.0 * rho * rho * r0 * Math.Exp(h * (T - t)) / (rho + psi + BTS);
            double v3 = 2.0 * rho * rho * r0 * Math.Exp(h * (T - t)) / (rho + psi);

            double x1 = 2.0 * rstar * (rho + psi + BTS);
            double x2 = 2.0 * rstar * (rho + psi);

            double c1 = v1 / 0.5 + Math.Floor(v2 / 0.5) + 1;
            double c2 = v1 / 0.5 + Math.Floor(v3 / 0.5) + 1;

            NonCentralChiSquare ncx21 = new NonCentralChiSquare(v1, v2);
            NonCentralChiSquare ncx22 = new NonCentralChiSquare(v1, v3);

            return(PtS * ncx21.Cdf(x1) - X * PtT * ncx22.Cdf(x2));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Calculates a call option on a bond.
        /// </summary>
        /// <param name="r0">The Zr evaluated in zero.</param>
        /// <param name="t">The valuation date (in years fractions).</param>
        /// <param name="T">The option exercise time to buy a bond with maturity S.</param>
        /// <param name="S">The maturity of the bound to buy.</param>
        /// <param name="X">The strike price.</param>
        /// <param name="cirParameters">
        /// A vector containing CIR model parameters k, theta, sigma.
        /// </param>
        /// <returns>The call option price.</returns>
        public static double BondCall(double r0, double t, double T, double S, double X, Vector cirParameters)
        {
            double k = cirParameters[0];
            double theta = cirParameters[1];
            double sigma = cirParameters[2];

            double h = Math.Sqrt(k * k + 2.0 * sigma * sigma);

            double dentS = 2.0 * h + (k + h) * (Math.Exp(h * (S - t)) - 1.0);
            double AtS = Math.Pow(2.0 * h * Math.Exp(0.5 * (k + h) * (S - t)) / dentS, 2.0 * k * theta / (sigma * sigma));
            double BtS = 2.0 * (Math.Exp(h * (S - t)) - 1.0) / dentS;

            double denTS = 2.0 * h + (k + h) * (Math.Exp(h * (S - T)) - 1.0);
            double ATS = Math.Pow(2.0 * h * Math.Exp(0.5 * (k + h) * (S - T)) / denTS, 2.0 * k * theta / (sigma * sigma));
            double BTS = 2.0 * (Math.Exp(h * (S - T)) - 1.0) / denTS;

            double dentT = 2.0 * h + (k + h) * (Math.Exp(h * (T - t)) - 1.0);
            double AtT = Math.Pow(2.0 * h * Math.Exp(0.5 * (k + h) * (T - t)) / dentT, 2.0 * k * theta / (sigma * sigma));
            double BtT = 2.0 * (Math.Exp(h * (T - t)) - 1.0) / dentT;

            double PtS = AtS * Math.Exp(-BtS * r0);
            double PtT = AtT * Math.Exp(-BtT * r0);

            double rstar = Math.Log(ATS / X) / BTS;
            double rho = 2.0 * h / (sigma * sigma * (Math.Exp(h * (T - t)) - 1.0));
            double psi = (k + h) / (sigma * sigma);

            double v1 = 4.0 * k * theta / (sigma * sigma);
            double v2 = 2.0 * rho * rho * r0 * Math.Exp(h * (T - t)) / (rho + psi + BTS);
            double v3 = 2.0 * rho * rho * r0 * Math.Exp(h * (T - t)) / (rho + psi);

            double x1 = 2.0 * rstar * (rho + psi + BTS);
            double x2 = 2.0 * rstar * (rho + psi);

            double c1 = v1 / 0.5 + Math.Floor(v2 / 0.5) + 1;
            double c2 = v1 / 0.5 + Math.Floor(v3 / 0.5) + 1;

            NonCentralChiSquare ncx21 = new NonCentralChiSquare(v1, v2);
            NonCentralChiSquare ncx22 = new NonCentralChiSquare(v1, v3);

            return PtS * ncx21.Cdf(x1) - X * PtT * ncx22.Cdf(x2);
        }