Exemple #1
0
 public BinomialLattice(int periods)
 {
     Dimension = periods;
     Nodes     = new BinomialLatticeNode[periods + 1][];
     for (int i = 0; i < periods + 1; i++)
     {
         Nodes[i] = new BinomialLatticeNode[i + 1];
     }
     InterestRates = 0d.Repeat(periods + 1);
 }
Exemple #2
0
        public static void ComputeOption(Option option, double interestRate, int periods)
        {
            var n        = periods;
            var maturity = option.TimeToMaturity;
            var dt       = maturity / n;
            var style    = option.Style;
            var strike   = option.Strike;
            var q        = option.Underlying.YieldRate;
            var r        = interestRate;
            var sig      = option.Underlying.Volatility;

            var lattice = new BinomialLattice(n);

            var node = new BinomialLatticeNode
            {
                Stage           = 0,
                Index           = 0,
                UnderlyingValue = option.Underlying.MarketPrice
            };

            lattice.Root             = node;
            lattice.InterestRates[0] = r;

            // from node to leaves; excludes root node
            for (int stage = 0; stage <= n; stage++)
            {
                var tempIndex = stage == n ? stage - 1 : stage;

                var u = Math.Exp(sig * Math.Sqrt(dt));
                var d = 1 / u;
                var p = (Math.Exp((r - q) * dt) - d) / (u - d);

                var lowerNodeFactor = d / u;

                // compute current stage
                for (int i = 0; i <= stage; i++)
                {
                    lattice[stage][i].Stage     = stage;
                    lattice[stage][i].Index     = i;
                    lattice[stage][i].UpRatio   = u;
                    lattice[stage][i].DownRatio = d;
                    lattice[stage][i].UpRiskNeutralProbability   = p;
                    lattice[stage][i].DownRiskNeutralProbability = 1 - p;
                    lattice.InterestRates[stage] = r;
                }

                if (stage == n)
                {
                    continue;
                }

                // compute next stage
                lattice[stage + 1][0] = new BinomialLatticeNode
                {
                    UnderlyingValue = lattice[stage][0].UnderlyingValue * lattice[stage][0].UpRatio
                };
                for (int i = 1; i <= stage + 1; i++)
                {
                    lattice[stage + 1][i] = new BinomialLatticeNode
                    {
                        UnderlyingValue = lattice[stage + 1][i - 1].UnderlyingValue * lowerNodeFactor
                    };
                }
            }

            // process the leaves
            for (int i = 0; i <= lattice.Dimension; i++)
            {
                node = lattice.Get(lattice.Dimension, i);
                var exerciseValue = option.Type == OptionType.Call
                    ? node.UnderlyingValue - strike
                    : strike - node.UnderlyingValue;
                node.DerivedValue = Math.Max(exerciseValue, 0);
            }

            // from last 2nd level leaves to nodes; includes root node
            for (int stage = n - 1; stage >= 0; stage--)
            {
                var disc  = Math.Exp(-lattice.InterestRates[stage] * dt);
                var pUp   = node.UpRiskNeutralProbability;
                var pDown = node.DownRiskNeutralProbability;
                for (int i = 0; i < lattice[stage].Length; i++)
                {
                    node = lattice[stage][i];
                    var childUp   = lattice[stage + 1][i];     // up child
                    var childDown = lattice[stage + 1][i + 1]; // down child
                    node.DerivedValue = disc * (pUp * childUp.DerivedValue + pDown * childDown.DerivedValue);
                    if (style == OptionStyleType.American)
                    {
                        var exerciseValue = option.Type == OptionType.Call
                            ? node.UnderlyingValue - strike
                            : strike - node.UnderlyingValue;
                        node.DerivedValue = Math.Max(exerciseValue, node.DerivedValue);
                    }
                }
            }

            option.FairPrice = lattice.Root.DerivedValue;
        }