Example #1
0
        public virtual void test_trinomialTree_down()
        {
            int nSteps = 133;
            LatticeSpecification lattice = new CoxRossRubinsteinLatticeSpecification();
            DoubleArray          rebate  = DoubleArray.of(nSteps + 1, i => REBATE_AMOUNT);
            double barrierLevel          = 76d;
            double tol = 1.0e-2;

            foreach (bool isCall in new bool[] { true, false })
            {
                foreach (double strike in STRIKES)
                {
                    foreach (double interest in INTERESTS)
                    {
                        foreach (double vol in VOLS)
                        {
                            foreach (double dividend in DIVIDENDS)
                            {
                                OptionFunction function = ConstantContinuousSingleBarrierKnockoutFunction.of(strike, TIME, PutCall.ofPut(!isCall), nSteps, BarrierType.DOWN, barrierLevel, rebate);
                                SimpleConstantContinuousBarrier barrier = SimpleConstantContinuousBarrier.of(BarrierType.DOWN, KnockType.KNOCK_OUT, barrierLevel);
                                double exact    = REBATE_AMOUNT * REBATE_PRICER.price(SPOT, TIME, interest - dividend, interest, vol, barrier.inverseKnockType()) + BARRIER_PRICER.price(SPOT, strike, TIME, interest - dividend, interest, vol, isCall, barrier);
                                double computed = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT, vol, interest, dividend);
                                assertEquals(computed, exact, Math.Max(exact, 1d) * tol);
                            }
                        }
                    }
                }
            }
        }
Example #2
0
        public virtual void test_formula()
        {
            CoxRossRubinsteinLatticeSpecification test = new CoxRossRubinsteinLatticeSpecification();
            DoubleArray computed = test.getParametersTrinomial(VOL, RATE, DT);
            double      u        = Math.Exp(VOL * Math.Sqrt(2.0 * DT));
            double      d        = Math.Exp(-VOL * Math.Sqrt(2.0 * DT));
            double      up       = Math.Pow((Math.Exp(0.5 * RATE * DT) - Math.Exp(-VOL * Math.Sqrt(0.5 * DT))) / (Math.Exp(VOL * Math.Sqrt(0.5 * DT)) - Math.Exp(-VOL * Math.Sqrt(0.5 * DT))), 2);
            double      dp       = Math.Pow((Math.Exp(VOL * Math.Sqrt(0.5 * DT)) - Math.Exp(0.5 * RATE * DT)) / (Math.Exp(VOL * Math.Sqrt(0.5 * DT)) - Math.Exp(-VOL * Math.Sqrt(0.5 * DT))), 2);
            DoubleArray expected = DoubleArray.of(u, 1d, d, up, 1d - up - dp, dp);

            assertTrue(DoubleArrayMath.fuzzyEquals(computed.toArray(), expected.toArray(), 1.0e-14));
        }
Example #3
0
        /// <summary>
        /// Test consistency between price methods, and Greek via finite difference.
        /// </summary>
        public virtual void test_trinomialTree()
        {
            int    nSteps = 135;
            double dt     = TIME / nSteps;
            LatticeSpecification lattice = new CoxRossRubinsteinLatticeSpecification();
            double fdEps = 1.0e-4;

            foreach (bool isCall in new bool[] { true, false })
            {
                foreach (double strike in STRIKES)
                {
                    foreach (double interest in INTERESTS)
                    {
                        foreach (double vol in VOLS)
                        {
                            foreach (double dividend in DIVIDENDS)
                            {
                                OptionFunction function   = EuropeanVanillaOptionFunction.of(strike, TIME, PutCall.ofPut(!isCall), nSteps);
                                double[]       @params    = lattice.getParametersTrinomial(vol, interest - dividend, dt).toArray();
                                DoubleArray    time       = DoubleArray.of(nSteps + 1, i => dt * i);
                                DoubleArray    df         = DoubleArray.of(nSteps, i => Math.Exp(-interest * dt));
                                double[][]     stateValue = new double[nSteps + 1][];
                                stateValue[0] = new double[] { SPOT };
                                IList <DoubleMatrix> prob  = new List <DoubleMatrix>();
                                double[]             probs = new double[] { @params[5], @params[4], @params[3] };
                                for (int i = 0; i < nSteps; ++i)
                                {
                                    int index = i;
                                    stateValue[i + 1] = DoubleArray.of(2 * i + 3, j => SPOT * Math.Pow(@params[2], index + 1 - j) * Math.Pow(@params[1], j)).toArray();
                                    double[][] probMatrix = new double[2 * i + 1][];
                                    Arrays.fill(probMatrix, probs);
                                    prob.Add(DoubleMatrix.ofUnsafe(probMatrix));
                                }
                                RecombiningTrinomialTreeData treeData = RecombiningTrinomialTreeData.of(DoubleMatrix.ofUnsafe(stateValue), prob, df, time);
                                double priceData   = TRINOMIAL_TREE.optionPrice(function, treeData);
                                double priceParams = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT, vol, interest, dividend);
                                assertEquals(priceData, priceParams);
                                ValueDerivatives priceDeriv = TRINOMIAL_TREE.optionPriceAdjoint(function, treeData);
                                assertEquals(priceDeriv.Value, priceData);
                                double priceUp = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT + fdEps, vol, interest, dividend);
                                double priceDw = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT - fdEps, vol, interest, dividend);
                                double fdDelta = 0.5 * (priceUp - priceDw) / fdEps;
                                assertEquals(priceDeriv.getDerivative(0), fdDelta, 3.0e-2);
                            }
                        }
                    }
                }
            }
        }