Esempio n. 1
0
        private Sample <IPath> next(bool antithetic)
        {
            Sample <List <double> > sequence_ =
                antithetic
            ? generator_.lastSequence()
            : generator_.nextSequence();

            if (brownianBridge_)
            {
                bb_.transform(sequence_.value, temp_);
            }
            else
            {
                temp_ = new List <double>(sequence_.value);
            }

            next_.weight = sequence_.weight;

            Path path = (Path)next_.value;

            path.setFront(process_.x0());

            for (int i = 1; i < path.length(); i++)
            {
                double t  = timeGrid_[i - 1];
                double dt = timeGrid_.dt(i - 1);
                path[i] = process_.evolve(t, path[i - 1], dt,
                                          antithetic
                                      ? -temp_[i - 1]
                                      : temp_[i - 1]);
            }
            return(next_);
        }
Esempio n. 2
0
        public TrinomialTree(StochasticProcess1D process,
                             TimeGrid timeGrid,
                             bool isPositive /*= false*/)
            : base(timeGrid.size())
        {
            branchings_ = new List <Branching>();
            dx_         = new InitializedList <double>(1);
            timeGrid_   = timeGrid;
            x0_         = process.x0();

            int nTimeSteps = timeGrid.size() - 1;
            int jMin       = 0;
            int jMax       = 0;

            for (int i = 0; i < nTimeSteps; i++)
            {
                double t  = timeGrid[i];
                double dt = timeGrid.dt(i);

                //Variance must be independent of x
                double v2 = process.variance(t, 0.0, dt);
                double v  = Math.Sqrt(v2);
                dx_.Add(v * Math.Sqrt(3.0));

                Branching branching = new Branching();
                for (int j = jMin; j <= jMax; j++)
                {
                    double x    = x0_ + j * dx_[i];
                    double m    = process.expectation(t, x, dt);
                    int    temp = (int)(Math.Floor((m - x0_) / dx_[i + 1] + 0.5));

                    if (isPositive)
                    {
                        while (x0_ + (temp - 1) * dx_[i + 1] <= 0)
                        {
                            temp++;
                        }
                    }

                    double e  = m - (x0_ + temp * dx_[i + 1]);
                    double e2 = e * e;
                    double e3 = e * Math.Sqrt(3.0);

                    double p1 = (1.0 + e2 / v2 - e3 / v) / 6.0;
                    double p2 = (2.0 - e2 / v2) / 3.0;
                    double p3 = (1.0 + e2 / v2 + e3 / v) / 6.0;

                    branching.add(temp, p1, p2, p3);
                }
                branchings_.Add(branching);

                jMin = branching.jMin();
                jMax = branching.jMax();
            }
        }
Esempio n. 3
0
        private Sample <IPath> next(bool antithetic)
        {
            if (brownianBridge_)
            {
                Utils.QL_FAIL("Brownian bridge not supported");
                return(null);
            }

            Sample <List <double> > sequence_ =
                antithetic
            ? generator_.lastSequence()
            : generator_.nextSequence();

            int m = process_.size();
            int n = process_.factors();

            MultiPath path = (MultiPath)next_.value;

            Vector asset = process_.initialValues();

            for (int j = 0; j < m; j++)
            {
                path[j].setFront(asset[j]);
            }

            Vector temp;

            next_.weight = sequence_.weight;

            TimeGrid timeGrid = path[0].timeGrid();
            double   t, dt;

            for (int i = 1; i < path.pathSize(); i++)
            {
                int offset = (i - 1) * n;
                t  = timeGrid[i - 1];
                dt = timeGrid.dt(i - 1);
                if (antithetic)
                {
                    temp = -1 * new Vector(sequence_.value.GetRange(offset, n));
                }
                else
                {
                    temp = new Vector(sequence_.value.GetRange(offset, n));
                }

                asset = process_.evolve(t, asset, dt, temp);
                for (int j = 0; j < m; j++)
                {
                    path[j][i] = asset[j];
                }
            }
            return(next_);
        }
Esempio n. 4
0
        public double value(IPath path)
        {
            int n = path.length();

            Utils.QL_REQUIRE(n > 1, () => "the path cannot be empty");

            bool          isOptionActive = false;
            int?          knockNode      = null;
            double        asset_price    = (path as Path).front();
            double        new_asset_price;
            double        x, y;
            double        vol;
            TimeGrid      timeGrid = (path as Path).timeGrid();
            double        dt;
            List <double> u = sequenceGen_.nextSequence().value;
            int           i;

            switch (barrierType_)
            {
            case Barrier.Type.DownIn:
                isOptionActive = false;
                for (i = 0; i < n - 1; i++)
                {
                    new_asset_price = (path as Path)[i + 1];
                    // terminal or initial vol?
                    vol = diffProcess_.diffusion(timeGrid[i], asset_price);
                    dt  = timeGrid.dt(i);

                    x = Math.Log(new_asset_price / asset_price);
                    y = 0.5 * (x - Math.Sqrt(x * x - 2 * vol * vol * dt * Math.Log(u[i])));
                    y = asset_price * Math.Exp(y);
                    if (y <= barrier_)
                    {
                        isOptionActive = true;
                        if (knockNode == null)
                        {
                            knockNode = i + 1;
                        }
                    }
                    asset_price = new_asset_price;
                }
                break;

            case Barrier.Type.UpIn:
                isOptionActive = false;
                for (i = 0; i < n - 1; i++)
                {
                    new_asset_price = (path as Path)[i + 1];
                    // terminal or initial vol?
                    vol = diffProcess_.diffusion(timeGrid[i], asset_price);
                    dt  = timeGrid.dt(i);

                    x = Math.Log(new_asset_price / asset_price);
                    y = 0.5 * (x + Math.Sqrt(x * x - 2 * vol * vol * dt * Math.Log((1 - u[i]))));
                    y = asset_price * Math.Exp(y);
                    if (y >= barrier_)
                    {
                        isOptionActive = true;
                        if (knockNode == null)
                        {
                            knockNode = i + 1;
                        }
                    }
                    asset_price = new_asset_price;
                }
                break;

            case Barrier.Type.DownOut:
                isOptionActive = true;
                for (i = 0; i < n - 1; i++)
                {
                    new_asset_price = (path as Path)[i + 1];
                    // terminal or initial vol?
                    vol = diffProcess_.diffusion(timeGrid[i], asset_price);
                    dt  = timeGrid.dt(i);

                    x = Math.Log(new_asset_price / asset_price);
                    y = 0.5 * (x - Math.Sqrt(x * x - 2 * vol * vol * dt * Math.Log(u[i])));
                    y = asset_price * Math.Exp(y);
                    if (y <= barrier_)
                    {
                        isOptionActive = false;
                        if (knockNode == null)
                        {
                            knockNode = i + 1;
                        }
                    }
                    asset_price = new_asset_price;
                }
                break;

            case Barrier.Type.UpOut:
                isOptionActive = true;
                for (i = 0; i < n - 1; i++)
                {
                    new_asset_price = (path as Path)[i + 1];
                    // terminal or initial vol?
                    vol = diffProcess_.diffusion(timeGrid[i], asset_price);
                    dt  = timeGrid.dt(i);

                    x = Math.Log(new_asset_price / asset_price);
                    y = 0.5 * (x + Math.Sqrt(x * x - 2 * vol * vol * dt * Math.Log((1 - u[i]))));
                    y = asset_price * Math.Exp(y);
                    if (y >= barrier_)
                    {
                        isOptionActive = false;
                        if (knockNode == null)
                        {
                            knockNode = i + 1;
                        }
                    }
                    asset_price = new_asset_price;
                }
                break;

            default:
                Utils.QL_FAIL("unknown barrier type");
                break;
            }

            if (isOptionActive)
            {
                return(payoff_.value(asset_price) * discounts_.Last());
            }
            else
            {
                switch (barrierType_)
                {
                case Barrier.Type.UpIn:
                case Barrier.Type.DownIn:
                    return(rebate_.GetValueOrDefault() * discounts_.Last());

                case Barrier.Type.UpOut:
                case Barrier.Type.DownOut:
                    return(rebate_.GetValueOrDefault() * discounts_[(int)knockNode]);

                default:
                    Utils.QL_FAIL("unknown barrier type");
                    return(-1);
                }
            }
        }