Exemple #1
0
        //SOR method
        private void SORmethod()  
        {
            int noits = 0;
            double tol = 0.000001; // 0.0000001;
            double err = 1.0;
            //double[] temp = new double[_v.Count];
            double temp = 0.0;
            bool bAm = (SStyle.ToUpper().Equals("A")) ? true : false;

            while (Math.Sqrt(err) > tol)
            {
            err = 0.0;
            for (int idx = 1; idx < _msteps; idx++)
            {
                temp = (_q[idx] - _superDiagL[idx] * _v[idx + 1] - _subDiagL[idx] * _v[idx - 1]) / _diagL[idx];

                temp = bAm ?  Math.Max(temp, AmPay(idx)) : temp;
                //if (_sPay.ToUpper().Equals("P"))
                //  temp = bAm ?  Math.Max(temp, AmPay(idx)) : temp;

                err += (temp - _v[idx]) * (temp - _v[idx]);
                _v[idx] = temp;
            }
            noits += 1;
            //temp[0] = _v[0];
            //temp[_msteps] = _v[_msteps];
            //for( int idx = 0; idx != _steps; idx++)
            //  _v[idx] = temp[idx];
            }
        }
Exemple #2
0
        private double MakeUpperBC(double tau, double S, double domRbc, double DiscDiv)
        {
            double temp = 0.0; 
            if (UbFlag) return 0.0;
            switch (SPay.ToUpper())
            {
            case "C":
                temp = (S - DiscDiv - Math.Exp(-domRbc * tau) * Strike);
                temp = (SStyle.ToUpper().Equals("A")) ? Math.Max(temp, S - Strike) : temp;
                break;
            case "P":
                break;
            case "A":
                temp = Math.Exp(-domRbc * tau);
                break;
            case "B":       
                break;
            case "T":
                break;
            default:
                break;
            }

            return temp;
        }
Exemple #3
0
        //apply the BC
        private double MakeLowerBC(double tau, double S, double domRbc, double discDiv)
        {
            double temp = 0.0;

            if (LbFlag)
            {
                return(0.0);
            }
            switch (SPay.ToUpper())
            {
            case "C":
                break;

            case "P":
                temp = (SStyle.ToUpper().Equals("E")) ? Math.Exp(-domRbc * tau) * Strike - Math.Max(S - discDiv, 0.0) :
                       Strike - S;
                break;

            case "A":
                break;

            case "B":
                temp = Math.Exp(-domRbc * tau);
                break;

            case "T":
                break;
            }

            return(temp);
        }
Exemple #4
0
        //Apply grid shift for disc divs
        private void ApplyGridShift(double tau, double divPay, double domRbc, double DiscDiv)
        {
            //set up the new list
            List <double> _vn = new List <double>();
            double        temp;

            //for lower boundary, assign the lower bc using the immediate exercise
            temp = MakeLowerBC(tau, Math.Max(Math.Exp(_x[0]) - divPay, 0.0), domRbc, DiscDiv);
            if (SStyle.ToUpper().Equals("A"))
            {
                _vn.Add(Math.Max(temp, AmPay(0)));
            }
            else
            {
                _vn.Add(temp);
            }

            for (int idx = 1; idx < Steps; idx++)
            {
                double xshift = Math.Log(Math.Exp(_x[idx]) - divPay);
                if (xshift >= XL)
                {
                    int    idNew = (int)((xshift - XL) / _dx);
                    double frac  = (xshift - _x[idNew]) / (_x[idNew + 1] - _x[idNew]);
                    temp = (1.0 - frac) * _v[idNew] + frac * _v[idNew + 1];
                    _vn.Add(SStyle.ToUpper().Equals("A") ? Math.Max(temp, AmPay(idx)) : temp);
                }
                else // the new points are still below the grid
                {
                    temp = MakeLowerBC(tau, Math.Max(Math.Exp(_x[idx]) - divPay, 0.0), domRbc, DiscDiv);
                    _vn.Add(SStyle.ToUpper().Equals("A") ? Math.Max(temp, AmPay(idx)) : temp);
                }
            }

            //for upper boundary add the upper
            //_vn.Add(MakeUpperBC(tau, Math.Exp(_x[_steps-1]) - divPay, domRbc, DiscDiv));

            _v = _vn;
        }
Exemple #5
0
            /// <summary>
            /// main pricer
            /// </summary>
            /// <param name="myZero"></param>
            /// <param name="myDiv"></param>
            /// <param name="greeks"></param>
            /// <param name="bGreeks"></param>
            /// <returns></returns>
            public double Pricer(ZeroCurve myZero, DivList myDiv, ref double[] greeks, bool bGreeks)
            {

                _x = new List<double>();
                _v = new List<double>();

                double tTemp = T;  //real time
                double tau = 0.0; //backward time

                double dtnom = T / (double) NTsteps;
                double dt = dtnom;
                double tempInt=0.0;

                //start the pricer

                CreateGrid();
                TerminalCondition();

                while( tau < T)
                {
                //set the increment
                double t1 = tTemp - dtnom;
                t1 = (t1 >= 0.0) ? t1 : 0.0;  //make sure t1 >= 0.0
                double divPay = 0.0;
                dt = CheckBetweenDiv(t1, tTemp, ref divPay, myDiv);


                //compute the real time and backward time tau
                tTemp -= dt;
                tau = T - tTemp;    
       
                //compute the increment forward rate
                _domR = myZero.ForwardRate(tTemp, tTemp + dt);
                _forR = 0.0;

                //compute the forward rate from real time tTemp to expiry for the BC'c
                double domRbc = myZero.ForwardRate(tTemp, T);

                //compute discounted dividends for the bc's
                double DiscDiv = ComputeDiscDiv(tTemp, T, myZero, myDiv);

                //save the value at the spot for use in theta calcuation
                int nKeyInt = (int)((Math.Log(Spot) - XL) / _dx);
                double fracInt = (Math.Log(Spot) - _x[nKeyInt]) / (_x[nKeyInt + 1] - _x[nKeyInt]);
                tempInt = _v[nKeyInt] * (1.0 - fracInt) + _v[nKeyInt + 1] * fracInt;


                //get the fwd
                _lnfwd = Math.Log(GetATMfwd(myZero, myDiv, tTemp));

                //build the matrix
                OneStepSetUp(dt, tTemp);

                //compute the q vec
                MakeQVec();

        
                if (SStyle.ToUpper().Equals("E"))
                {
                    // set the exlicit BC
                    _v[0] = MakeLowerBC(tau, Math.Exp(_x[0]), domRbc, DiscDiv);
                    _v[Steps - 1] = MakeUpperBC(tau, Math.Exp(_x[Steps - 1]), domRbc, DiscDiv);
                    SORmethod();

                    //subract from q(1) and q(_steps-2) for explicit BC
                    //'_q[1] -= _SubDiagL[0] * _v[0];
                    //'_q[_msteps - 1] -= _SuperDiagL[_steps - 1] * _v[_steps - 1];

                    //this commented out info is used for the zero curvature condition
                    //_DiagL[1] += 2.0 * _SubDiagL[1];
                    //_SuperDiagL[1] -= _SubDiagL[1];
                    //_DiagL[_steps - 2] += 2.0 * _SuperDiagL[_steps - 2];
                    //_SubDiagL[_steps - 2] -= _SuperDiagL[_steps - 2];

                    //call LU decomp
                    //LUDecomp();
                    //Call the LU sOlver
                    //LUSolution();

                    //for zero curvature
                    //_v[0] = 2.0 * _v[1] - _v[2];
                    //_v[_steps - 1] = 2.0 * _v[_steps - 2] - _v[_steps - 3];
                }
                else
                {
                    _v[0] = MakeLowerBC(tau, Math.Exp(_x[0]), domRbc, DiscDiv);
                    _v[Steps - 1] = MakeUpperBC(tau, Math.Exp(_x[Steps - 1]), domRbc, DiscDiv);       
                    SORmethod();
                }

                //after having incremented back,  apply a grid shift if needed
                if (divPay != 0.0)
                {
                    ApplyGridShift(tau, divPay, domRbc, DiscDiv);
                }

                }

                int nKey = (int) ((Math.Log(Spot) - XL) / _dx);
                double frac = (Math.Log(Spot) - _x[nKey])/ (_x[nKey+1] - _x[nKey]);
                double temp = _v[nKey] * (1.0 - frac) + _v[nKey+1] * frac;

                if (bGreeks)
                {
        
                double[,] a = new double[4, 4];
                double[] b = new double[4];

                a[0,0] = 1.0;
                a[1,0] = 1.0;
                a[2,0] = 1.0;
                a[3,0] = 1.0;

                a[0, 1] = Math.Exp(_x[nKey-1]);
                a[1, 1] = Math.Exp(_x[nKey]);
                a[2, 1] = Math.Exp(_x[nKey +1]);
                a[3, 1] = Math.Exp(_x[nKey +2]);

                a[0, 2] = Math.Exp(_x[nKey - 1]) * Math.Exp(_x[nKey - 1]);
                a[1, 2] = Math.Exp(_x[nKey]) * Math.Exp(_x[nKey]);
                a[2, 2] = Math.Exp(_x[nKey + 1])*Math.Exp(_x[nKey + 1]);
                a[3, 2] = Math.Exp(_x[nKey + 2]) * Math.Exp(_x[nKey + 1]);

                a[0, 3] = Math.Exp(_x[nKey - 1])*Math.Exp(_x[nKey - 1])*Math.Exp(_x[nKey - 1]);
                a[1, 3] = Math.Exp(_x[nKey]) * Math.Exp(_x[nKey]) * Math.Exp(_x[nKey]);
                a[2, 3] = Math.Exp(_x[nKey + 1]) * Math.Exp(_x[nKey + 1]) * Math.Exp(_x[nKey +1]);
                a[3, 3] = Math.Exp(_x[nKey + 2] )* Math.Exp(_x[nKey + 2] )* Math.Exp(_x[nKey + 2]);

                b[0] = _v[nKey-1];
                b[1] = _v[nKey];
                b[2] = _v[nKey+1];
                b[3] = _v[nKey+2];


                int info = NewtonGauss(4, ref a, ref b);

                greeks[0] = b[1] + 2.0 * b[2] * Spot +3.0 * b[3] * Spot * Spot;
                greeks[1] =2.0*b[2] +6.0* b[3] * Spot ;
                greeks[2] = (tempInt - temp) / (365.0 * dt); 

                /*
                nKey = (int)((Math.Log(_spot) * 1.001 - _xl) / _dx);
                frac = (Math.Log(_spot )* 1.001 - _x[nKey]) / (_x[nKey + 1] - _x[nKey]);
                double tempUp = _v[nKey] * (1.0 - frac) + _v[nKey + 1] * frac;

                nKey = (int)((Math.Log(_spot) * 0.999 - _xl) / _dx);
                frac = (Math.Log(_spot) * 0.999 - _x[nKey]) / (_x[nKey + 1] - _x[nKey]);
                double tempDn = _v[nKey] * (1.0 - frac) + _v[nKey + 1] * frac;

                greeks[0] = (tempUp - tempDn) / (0.002 *Math.Log(spot))/spot ;
                greeks[1] = (tempUp + tempDn - 2.0 * temp) / Math.Pow(0.001 * _spot * Math.Log(_spot), 2.0) - greeks[0]/_spot;
                greeks[2] = (tempInt - temp) / (365.0 * dt); 
                    */
        
                }
        

                return temp;
            }