Пример #1
0
        private Matrix LocVolMatrixFromImpliedVol(CallPriceMarketData Hdataset, IFunction impVol, out Vector locVolMat, out Vector locVolStr)
        {
            int    nmat    = calibrationSettings.LocalVolatilityMaturities;
            int    nstrike = calibrationSettings.LocalVolatilityStrikes;
            double lastMat = Hdataset.Maturity[Range.End];
            double lastStr = Hdataset.Strike[Range.End];

            locVolMat = Vector.Linspace(Hdataset.Maturity[0], lastMat, nmat);
            locVolStr = Vector.Linspace(Hdataset.Strike[0], lastStr, nstrike);
            Matrix locVolMatrix = new Matrix(nmat, nstrike);

            Integrate integrate = new Integrate(this);
            double    sigma, dSigmadk, num, y, den, avgGrowthRate;
            Vector    x = new Vector(2);

            for (int i = 0; i < nmat; i++)
            {
                avgGrowthRate = integrate.AdaptLobatto(0.0, locVolMat[i]);

                int j = 0;
                x[0]               = locVolMat[i];
                x[1]               = locVolStr[j];
                sigma              = impVol.Evaluate(x);
                dSigmadk           = impVol.Partial(x, 1);
                num                = Math.Pow(sigma, 2) + 2.0 * sigma * x[0] * impVol.Partial(x, 0);
                den                = 1.0;
                locVolMatrix[i, j] = Math.Sqrt(num / den);

                // The rest of the cycle.
                for (j = 1; j < nstrike; j++)
                {
                    x[1]     = locVolStr[j];
                    sigma    = impVol.Evaluate(x);
                    dSigmadk = impVol.Partial(x, 1);
                    num      = Math.Pow(sigma, 2) + 2.0 * sigma * x[0] *
                               (impVol.Partial(x, 0) + avgGrowthRate * x[1] * dSigmadk);
                    y   = Math.Log(locVolStr[j] / Hdataset.S0) + avgGrowthRate;
                    den = System.Math.Pow(1.0 - x[1] * y * dSigmadk / sigma, 2) + x[1] * sigma * x[0] *
                          (dSigmadk - 0.25 * x[1] * sigma * x[0] * dSigmadk * dSigmadk + x[1] * impVol.Partial2(x, 1));
                    locVolMatrix[i, j] = Math.Sqrt(num / den);
                }
            }
            return(locVolMatrix);
        }
        private EstimationResult QuantLibEstimate(CurveMarketData discoutingCurve, CallPriceMarketData Hdataset)
        {
            EquityCalibrationData HCalData = new EquityCalibrationData(Hdataset, discoutingCurve);

            bool hasArbitrage = HCalData.HasArbitrageOpportunity(10e-2);
            if (hasArbitrage)
                Console.WriteLine("Market data contains arbitrage opportunity");

            this.r = new DVPLDOM.PFunction(discoutingCurve.Durations,discoutingCurve.Values);
            this.q = HCalData.dyFunc as PFunction;

            //this.r.Parse(null);
            //this.q.Parse(null);

            Hdataset.Volatility = new Matrix(Hdataset.CallPrice.R, Hdataset.CallPrice.C);
            for (int i = 0; i < Hdataset.Volatility.R; i++)
            {
                double m=Hdataset.Maturity[i];
                for (int j = 0; j < Hdataset.Volatility.C; j++)
                {
                    if (Hdataset.CallPrice[i, j] > 0)
                    {
                        var bs = new Fairmat.Finance.BlackScholes(r.Evaluate(m), Hdataset.S0, Hdataset.Strike[j], 0, m, q.Evaluate(m));
                        //Hdataset.Volatility[i, j] = Hdataset.Volatility[i, j] * Hdataset.Volatility[i, j] * Hdataset.Maturity[i];

                        //Hdataset.Volatility[i, j] = bs.ImpliedCallVolatility(Hdataset.CallPrice[i, j]);
                    }
                }
            }

            Console.WriteLine(Hdataset.Volatility);

            IFunction impVol = FitImplVolModel(Hdataset);

            Document doc = new Document();
            ProjectROV prj = new ProjectROV(doc);
            doc.Part.Add(prj);
            prj.Symbols.Add(impVol);
            // doc.WriteToXMLFile("impVol.fair");

            int nmat = calibrationSettings.LocalVolatilityMaturities;
            int nstrike = calibrationSettings.LocalVolatilityStrikes;
            double lastMat = Hdataset.Maturity[SymbolicIntervalExtremes.End];
            double lastStr = Hdataset.Strike[SymbolicIntervalExtremes.End];
            Vector locVolMat = Vector.Linspace(Hdataset.Maturity[0], lastMat, nmat);
            Vector locVolStr = Vector.Linspace(Hdataset.Strike[0], lastStr, nstrike);
            Matrix locVolMatrix = new Matrix(nmat, nstrike);
            double t, dt, forwardValue, y, dy, strike, strikep, strikem, w, wp, wm, dwdy;
            double d2wdy2, den1, den2, den3, strikept, strikemt, wpt, wmt, dwdt;
            Integrate integrate = new Integrate(this);

            for (int i = 0; i < nmat; i++)
            {
                t = locVolMat[i];
                forwardValue = Hdataset.S0 * Math.Exp(integrate.AdaptLobatto(0.0, t));
                for (int j = 0; j < nstrike; j++)
                {
                    strike = locVolStr[j];
                    y = Math.Log(strike / forwardValue);
                    dy = ((Math.Abs(y) > 0.001) ? y * 0.0001 : 0.000001);

                    // strike derivative
                    strikep = strike * Math.Exp(dy);
                    strikem = strike / Math.Exp(dy);
                    w = impVol.Evaluate(t, strike);
                    wp = impVol.Evaluate(t, strikep);
                    wm = impVol.Evaluate(t, strikem);
                    dwdy = (wp - wm) / (2.0 * dy);
                    d2wdy2 = (wp - 2.0 * w + wm) / (dy * dy);

                    // time derivative
                    if (t == 0.0)
                    {
                        dt = 0.0001;
                        strikept = strike * Math.Exp(integrate.AdaptLobatto(0.0, t + dt));
                        wpt = impVol.Evaluate(t + dt, strikept);
                        // if (wpt < w)
                        //    Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t, t + dt);
                        dwdt = (wpt - w) / dt;
                    }
                    else
                    {
                        dt = Math.Min(0.0001, t / 2.0);
                        strikept = strike * Math.Exp(integrate.AdaptLobatto(t, t + dt));
                        strikemt = strike * Math.Exp(-integrate.AdaptLobatto(t - dt, t));
                        wpt = impVol.Evaluate(t + dt, strikept);
                        wmt = impVol.Evaluate(t + dt, strikemt);

                        //if (wpt < w)
                        //    Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t, t + dt);
                        //if (w < wmt)
                        //    Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t-dt, t);
                        dwdt = (wpt - wmt) / (2.0 * dt);
                    }
                    if (dwdy == 0.0 && d2wdy2 == 0.0)
                        locVolMatrix[i, j] = Math.Sqrt(dwdt);
                    else
                    {
                        den1 = 1.0 - y / w * dwdy;
                        den2 = 0.25 * (-0.25 - 1.0 / w + y * y / w / w) * dwdy * dwdy;
                        den3 = 0.5 * d2wdy2;
                        locVolMatrix[i, j] = dwdt / (den1 + den2 + den3);
                        //if (locVolMatrix[i,j] < 0.0)
                        //    Console.WriteLine("Negative local vol^2 at strike {0} and time {1}; " +
                        //        "Black vol surface is not smooth enought.", strike, t);
                    }
                }
            }

            // Create dupire outputs.
            Console.WriteLine(locVolMat);
            PFunction2D.PFunction2D localVol = new PFunction2D.PFunction2D(locVolMat, locVolStr, locVolMatrix);
            localVol.Parse(null);
            string[] names = new string[] { "S0" };
            Vector param = new Vector(1);
            param[0] = Hdataset.S0;
            EstimationResult result = new EstimationResult(names, param);
            //result.Objects = new object[3];
            result.Objects = new object[4];
            result.Objects[0] = this.r;
            result.Objects[1] = this.q;
            result.Objects[2] = localVol;
            result.Objects[3] = impVol;
            //Console.WriteLine("r = " + HCalData.Rate.ToString());
            //Console.WriteLine("q = " + HCalData.DividendYield.ToString());
            return result;
        }
Пример #3
0
        private Matrix LocVolMatrixFromImpliedVol(CallPriceMarketData Hdataset, IFunction impVol, out Vector locVolMat, out Vector locVolStr)
        {
            int nmat = calibrationSettings.LocalVolatilityMaturities;
            int nstrike = calibrationSettings.LocalVolatilityStrikes;
            double lastMat = Hdataset.Maturity[Range.End];
            double lastStr = Hdataset.Strike[Range.End];
            locVolMat = Vector.Linspace(Hdataset.Maturity[0], lastMat, nmat);
            locVolStr = Vector.Linspace(Hdataset.Strike[0], lastStr, nstrike);
            Matrix locVolMatrix = new Matrix(nmat, nstrike);

            Integrate integrate = new Integrate(this);
            double sigma, dSigmadk, num, y, den, avgGrowthRate;
            Vector x = new Vector(2);
            for (int i = 0; i < nmat; i++)
            {
                avgGrowthRate = integrate.AdaptLobatto(0.0, locVolMat[i]);

                int j = 0;
                x[0] = locVolMat[i];
                x[1] = locVolStr[j];
                sigma = impVol.Evaluate(x);
                dSigmadk = impVol.Partial(x, 1);
                num = Math.Pow(sigma, 2) + 2.0 * sigma * x[0] * impVol.Partial(x, 0);
                den = 1.0;
                locVolMatrix[i, j] = Math.Sqrt(num / den);

                // The rest of the cycle.
                for (j = 1; j < nstrike; j++)
                {
                    x[1] = locVolStr[j];
                    sigma = impVol.Evaluate(x);
                    dSigmadk = impVol.Partial(x, 1);
                    num = Math.Pow(sigma, 2) + 2.0 * sigma * x[0] *
                        (impVol.Partial(x, 0) + avgGrowthRate * x[1] * dSigmadk);
                    y = Math.Log(locVolStr[j] / Hdataset.S0) + avgGrowthRate;
                    den = System.Math.Pow(1.0 - x[1] * y * dSigmadk / sigma, 2) + x[1] * sigma * x[0] *
                        (dSigmadk - 0.25 * x[1] * sigma * x[0] * dSigmadk * dSigmadk + x[1] * impVol.Partial2(x, 1));
                    locVolMatrix[i, j] = Math.Sqrt(num / den);
                }
            }
            return locVolMatrix;
        }
Пример #4
0
        private Matrix LocVolMatrixFromCallPrices(CallPriceMarketData Hdataset, CallPriceSurface CallPrice, out Vector locVolMat, out Vector locVolStr)
        {
            Integrate integrate = new Integrate(this);

            int nmat = calibrationSettings.LocalVolatilityMaturities;
            int nstrike = calibrationSettings.LocalVolatilityStrikes;

            double firstMat = CallPrice.MinMaturity;
            double lastMat = CallPrice.MaxMaturity;

            double firstStr =  CallPrice.MinStrike;
            double lastStr = CallPrice.MaxStrike;
            double delta = (lastStr - firstStr) / nstrike;
            locVolMat = Vector.Linspace(firstMat, lastMat, nmat);
            locVolStr = Vector.Linspace(firstStr + delta, lastStr - delta, nstrike);
            Matrix locVolMatrix = new Matrix(nmat, nstrike);

            // this next matrix is created only for debugging pourpose
            Matrix squaredLocVolMatrix = new Matrix(nmat, nstrike);
            double num, den, call, dCdt, dCdk, d2Cdk2;
            Vector x = new Vector(2);
            double h0 = 0.02*Hdataset.S0;//increment for numerical derivatives (stock)
            double ht = 0.02;// 0.25 * (lastMat - firstMat) / nmat;//increment for numerical derivatives (maturities)
            double hs = h0;
            double d2Threshold=10e-5;
            for (int i = 0; i < nmat; i++)
            {
                double growthRate = integrate.AdaptLobatto(0.0, locVolMat[i]);
                x[0] = locVolMat[i];
                for (int j = 0; j < nstrike; j++)
                {
                    x[1] = locVolStr[j];

                    var support=CallPrice.SupportY(x[0]);
                    //if (x[1] > support[1] && j > 1)
                    if(x[1]<support[0]||x[1]>support[1])
                    {
                        //skip...fill later
                        //squaredLocVolMatrix[i, j] = squaredLocVolMatrix[i, j - 1];
                        //locVolMatrix[i, j] = locVolMatrix[i, j-1];
                    }
                    else
                    {
                        bool fail = false;
                        call = CallPrice.Evaluate(x);
                        dCdt = CallPrice.Partial(x, 0, ht);
                        //do
                       // {

                            dCdk = CallPrice.Partial(x, 1, hs);
                            d2Cdk2 = CallPrice.Partial2(x, 1, hs);
                            //if (Math.Abs(d2Cdk2) > d2Threshold || hs > 0.1 * Hdataset.S0)
                            if (Math.Abs(d2Cdk2) < d2Threshold)
                            {
                                fail = true;
                                //break;
                            }
                        //    hs *= 2;
                        //} while (true);

                        if (!fail)
                        {
                            double qq = this.q.Evaluate(x[0]);
                            num = dCdt + growthRate * x[1] * dCdk + qq * call;
                            den = x[1] * x[1] * d2Cdk2;
                            squaredLocVolMatrix[i, j] = 2.0 * num / den;
                            locVolMatrix[i, j] = Math.Sqrt(Math.Abs(2.0 * num / den));
                        }
                    }
                }
            }

            //Fill missing vol
            for (int i = 0; i < nmat; i++)
            {
                double lastVol=0;
                for (int j = 0; j < nstrike; j++)
                {
                    if (locVolMatrix[i, j] != 0)
                        lastVol = locVolMatrix[i, j];
                    else
                        locVolMatrix[i, j] = lastVol;
                }
                lastVol = 0;
                for (int j = nstrike-1; j >=0; j--)
                {
                    if (locVolMatrix[i, j] != 0)
                        lastVol = locVolMatrix[i, j];
                    else
                        locVolMatrix[i, j] = lastVol;
                }
                //

            }

            return locVolMatrix;
        }
Пример #5
0
        private Matrix LocVolMatrixFromCallPrices(CallPriceMarketData Hdataset, CallPriceSurface CallPrice, out Vector locVolMat, out Vector locVolStr)
        {
            Integrate integrate = new Integrate(this);

            int nmat    = calibrationSettings.LocalVolatilityMaturities;
            int nstrike = calibrationSettings.LocalVolatilityStrikes;

            double firstMat = CallPrice.MinMaturity;
            double lastMat  = CallPrice.MaxMaturity;

            double firstStr = CallPrice.MinStrike;
            double lastStr  = CallPrice.MaxStrike;
            double delta    = (lastStr - firstStr) / nstrike;

            locVolMat = Vector.Linspace(firstMat, lastMat, nmat);
            locVolStr = Vector.Linspace(firstStr + delta, lastStr - delta, nstrike);
            Matrix locVolMatrix = new Matrix(nmat, nstrike);

            // this next matrix is created only for debugging pourpose
            Matrix squaredLocVolMatrix = new Matrix(nmat, nstrike);
            double num, den, call, dCdt, dCdk, d2Cdk2;
            Vector x  = new Vector(2);
            double h0 = 0.02 * Hdataset.S0; //increment for numerical derivatives (stock)
            double ht = 0.02;               // 0.25 * (lastMat - firstMat) / nmat;//increment for numerical derivatives (maturities)
            double hs = h0;
            double d2Threshold = 10e-5;

            for (int i = 0; i < nmat; i++)
            {
                double growthRate = integrate.AdaptLobatto(0.0, locVolMat[i]);
                x[0] = locVolMat[i];
                for (int j = 0; j < nstrike; j++)
                {
                    x[1] = locVolStr[j];

                    var support = CallPrice.SupportY(x[0]);
                    //if (x[1] > support[1] && j > 1)
                    if (x[1] < support[0] || x[1] > support[1])
                    {
                        //skip...fill later
                        //squaredLocVolMatrix[i, j] = squaredLocVolMatrix[i, j - 1];
                        //locVolMatrix[i, j] = locVolMatrix[i, j-1];
                    }
                    else
                    {
                        bool fail = false;
                        call = CallPrice.Evaluate(x);
                        dCdt = CallPrice.Partial(x, 0, ht);
                        //do
                        // {

                        dCdk   = CallPrice.Partial(x, 1, hs);
                        d2Cdk2 = CallPrice.Partial2(x, 1, hs);
                        //if (Math.Abs(d2Cdk2) > d2Threshold || hs > 0.1 * Hdataset.S0)
                        if (Math.Abs(d2Cdk2) < d2Threshold)
                        {
                            fail = true;
                            //break;
                        }
                        //    hs *= 2;
                        //} while (true);

                        if (!fail)
                        {
                            double qq = this.q.Evaluate(x[0]);
                            num = dCdt + growthRate * x[1] * dCdk + qq * call;
                            den = x[1] * x[1] * d2Cdk2;
                            squaredLocVolMatrix[i, j] = 2.0 * num / den;
                            locVolMatrix[i, j]        = Math.Sqrt(Math.Abs(2.0 * num / den));
                        }
                    }
                }
            }

            //Fill missing vol
            for (int i = 0; i < nmat; i++)
            {
                double lastVol = 0;
                for (int j = 0; j < nstrike; j++)
                {
                    if (locVolMatrix[i, j] != 0)
                    {
                        lastVol = locVolMatrix[i, j];
                    }
                    else
                    {
                        locVolMatrix[i, j] = lastVol;
                    }
                }
                lastVol = 0;
                for (int j = nstrike - 1; j >= 0; j--)
                {
                    if (locVolMatrix[i, j] != 0)
                    {
                        lastVol = locVolMatrix[i, j];
                    }
                    else
                    {
                        locVolMatrix[i, j] = lastVol;
                    }
                }
                //
            }


            return(locVolMatrix);
        }
Пример #6
0
        private EstimationResult QuantLibEstimate(CurveMarketData discoutingCurve, CallPriceMarketData Hdataset)
        {
            EquityCalibrationData HCalData = new EquityCalibrationData(Hdataset, discoutingCurve);

            bool hasArbitrage = HCalData.HasArbitrageOpportunity(10e-2);

            if (hasArbitrage)
            {
                Console.WriteLine("Market data contains arbitrage opportunity");
            }

            this.r = new DVPLDOM.PFunction(discoutingCurve.Durations, discoutingCurve.Values);
            this.q = HCalData.dyFunc as PFunction;

            //this.r.Parse(null);
            //this.q.Parse(null);

            Hdataset.Volatility = new Matrix(Hdataset.CallPrice.R, Hdataset.CallPrice.C);
            for (int i = 0; i < Hdataset.Volatility.R; i++)
            {
                double m = Hdataset.Maturity[i];
                for (int j = 0; j < Hdataset.Volatility.C; j++)
                {
                    if (Hdataset.CallPrice[i, j] > 0)
                    {
                        var bs = new Fairmat.Finance.BlackScholes(r.Evaluate(m), Hdataset.S0, Hdataset.Strike[j], 0, m, q.Evaluate(m));
                        //Hdataset.Volatility[i, j] = Hdataset.Volatility[i, j] * Hdataset.Volatility[i, j] * Hdataset.Maturity[i];

                        //Hdataset.Volatility[i, j] = bs.ImpliedCallVolatility(Hdataset.CallPrice[i, j]);
                    }
                }
            }

            Console.WriteLine(Hdataset.Volatility);

            IFunction impVol = FitImplVolModel(Hdataset);

            Document   doc = new Document();
            ProjectROV prj = new ProjectROV(doc);

            doc.Part.Add(prj);
            prj.Symbols.Add(impVol);
            // doc.WriteToXMLFile("impVol.fair");

            int       nmat = calibrationSettings.LocalVolatilityMaturities;
            int       nstrike = calibrationSettings.LocalVolatilityStrikes;
            double    lastMat = Hdataset.Maturity[SymbolicIntervalExtremes.End];
            double    lastStr = Hdataset.Strike[SymbolicIntervalExtremes.End];
            Vector    locVolMat = Vector.Linspace(Hdataset.Maturity[0], lastMat, nmat);
            Vector    locVolStr = Vector.Linspace(Hdataset.Strike[0], lastStr, nstrike);
            Matrix    locVolMatrix = new Matrix(nmat, nstrike);
            double    t, dt, forwardValue, y, dy, strike, strikep, strikem, w, wp, wm, dwdy;
            double    d2wdy2, den1, den2, den3, strikept, strikemt, wpt, wmt, dwdt;
            Integrate integrate = new Integrate(this);

            for (int i = 0; i < nmat; i++)
            {
                t            = locVolMat[i];
                forwardValue = Hdataset.S0 * Math.Exp(integrate.AdaptLobatto(0.0, t));
                for (int j = 0; j < nstrike; j++)
                {
                    strike = locVolStr[j];
                    y      = Math.Log(strike / forwardValue);
                    dy     = ((Math.Abs(y) > 0.001) ? y * 0.0001 : 0.000001);

                    // strike derivative
                    strikep = strike * Math.Exp(dy);
                    strikem = strike / Math.Exp(dy);
                    w       = impVol.Evaluate(t, strike);
                    wp      = impVol.Evaluate(t, strikep);
                    wm      = impVol.Evaluate(t, strikem);
                    dwdy    = (wp - wm) / (2.0 * dy);
                    d2wdy2  = (wp - 2.0 * w + wm) / (dy * dy);

                    // time derivative
                    if (t == 0.0)
                    {
                        dt       = 0.0001;
                        strikept = strike * Math.Exp(integrate.AdaptLobatto(0.0, t + dt));
                        wpt      = impVol.Evaluate(t + dt, strikept);
                        // if (wpt < w)
                        //    Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t, t + dt);
                        dwdt = (wpt - w) / dt;
                    }
                    else
                    {
                        dt       = Math.Min(0.0001, t / 2.0);
                        strikept = strike * Math.Exp(integrate.AdaptLobatto(t, t + dt));
                        strikemt = strike * Math.Exp(-integrate.AdaptLobatto(t - dt, t));
                        wpt      = impVol.Evaluate(t + dt, strikept);
                        wmt      = impVol.Evaluate(t + dt, strikemt);

                        //if (wpt < w)
                        //    Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t, t + dt);
                        //if (w < wmt)
                        //    Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t-dt, t);
                        dwdt = (wpt - wmt) / (2.0 * dt);
                    }
                    if (dwdy == 0.0 && d2wdy2 == 0.0)
                    {
                        locVolMatrix[i, j] = Math.Sqrt(dwdt);
                    }
                    else
                    {
                        den1 = 1.0 - y / w * dwdy;
                        den2 = 0.25 * (-0.25 - 1.0 / w + y * y / w / w) * dwdy * dwdy;
                        den3 = 0.5 * d2wdy2;
                        locVolMatrix[i, j] = dwdt / (den1 + den2 + den3);
                        //if (locVolMatrix[i,j] < 0.0)
                        //    Console.WriteLine("Negative local vol^2 at strike {0} and time {1}; " +
                        //        "Black vol surface is not smooth enought.", strike, t);
                    }
                }
            }

            // Create dupire outputs.
            Console.WriteLine(locVolMat);
            PFunction2D.PFunction2D localVol = new PFunction2D.PFunction2D(locVolMat, locVolStr, locVolMatrix);
            localVol.Parse(null);
            string[] names = new string[] { "S0" };
            Vector   param = new Vector(1);

            param[0] = Hdataset.S0;
            EstimationResult result = new EstimationResult(names, param);

            //result.Objects = new object[3];
            result.Objects    = new object[4];
            result.Objects[0] = this.r;
            result.Objects[1] = this.q;
            result.Objects[2] = localVol;
            result.Objects[3] = impVol;
            //Console.WriteLine("r = " + HCalData.Rate.ToString());
            //Console.WriteLine("q = " + HCalData.DividendYield.ToString());
            return(result);
        }