Example #1
0
 public static object AmericanFutureOptionImpliedVol(
     [ExcelArgument(Description = "Time-to-expiry")] double T,
     [ExcelArgument(Description = "Strike")] double K,
     [ExcelArgument(Description = "Forward")] double F,
     [ExcelArgument(Description = "Discounting rate")] double R,
     [ExcelArgument(Description = "Option Premium")] double PV,
     [ExcelArgument(Description = "Call or Put")] string CP,
     [ExcelArgument(Description = "Pricing method (Defult Trinomial)")] string Method)
 {
     return(ExcelHelper.Execute(_logger, () =>
     {
         if (!Enum.TryParse(CP, out OptionType optType))
         {
             return $"Could not parse call or put flag - {CP}";
         }
         if (!Enum.TryParse(Method, out AmericanPricingType method))
         {
             return $"Could not parse pricing type - {Method}";
         }
         if (method == AmericanPricingType.Binomial)
         {
             return BinomialTree.AmericanFuturesOptionImpliedVol(F, K, R, T, PV, optType);
         }
         else
         {
             return TrinomialTree.AmericanFuturesOptionImpliedVol(F, K, R, T, PV, optType);
         }
     }));
 }
Example #2
0
        public override Lattice tree( TimeGrid grid)  
        {
            TermStructureFittingParameter phi= new TermStructureFittingParameter(termStructure());

            ShortRateDynamics numericDynamics=
                                    new Dynamics(phi, a(), sigma());

            TrinomialTree trinomial=
                             new TrinomialTree(numericDynamics.process(), grid);
            ShortRateTree numericTree =
                             new ShortRateTree(trinomial, numericDynamics, grid);

            TermStructureFittingParameter.NumericalImpl impl = 
                (TermStructureFittingParameter.NumericalImpl)phi.implementation();
            impl.reset();
            double value = 1.0;
            double vMin = -50.0;
            double vMax = 50.0;
            for (int i=0; i<(grid.size() - 1); i++) {
                double discountBond = termStructure().link.discount(grid[i+1]);
                double xMin = trinomial.underlying(i, 0);
                double dx = trinomial.dx(i);
                Helper finder = new Helper(i, xMin, dx, discountBond, numericTree);
                Brent s1d = new Brent();
                s1d.setMaxEvaluations(1000);
                value = s1d.solve(finder, 1e-7, value, vMin, vMax);
                impl.setvalue(grid[i], value);
                // vMin = value - 10.0;
                // vMax = value + 10.0;
            }
            return numericTree;
        }
Example #3
0
 public override Lattice tree(TimeGrid grid) {
     TermStructureFittingParameter phi = new TermStructureFittingParameter(termStructure());
     ShortRateDynamics numericDynamics = new Dynamics(phi, a(), sigma());
     TrinomialTree trinomial = new TrinomialTree(numericDynamics.process(), grid);
     ShortRateTree numericTree = new ShortRateTree(trinomial, numericDynamics, grid);
     TermStructureFittingParameter.NumericalImpl  impl =
         (TermStructureFittingParameter.NumericalImpl)phi.implementation();
     impl.reset();
     for (int i=0; i<(grid.size() - 1); i++) {
         double discountBond = termStructure().link.discount(grid[i+1]);
         Vector  statePrices = numericTree.statePrices(i);
         int size = numericTree.size(i);
         double dt = numericTree.timeGrid().dt(i);
         double dx = trinomial.dx(i);
         double x = trinomial.underlying(i,0);
         double value = 0.0;
         for (int j=0; j<size; j++) {
             value += statePrices[j]*Math.Exp(-x*dt);
             x += dx;
         }
         value = Math.Log(value/discountBond)/dt;
         impl.setvalue(grid[i], value);
     }
     return numericTree;
 }
    public static void Main()
    {
        // Declare and initialise the parameters
        TrinomialParameters myData;

        // Clewlow p. 55 C = 8.42534 for N = 3
        myData.sigma         = 0.2;
        myData.T             = 1.0; // One year
        myData.r             = 0.06;
        myData.K             = 100;
        myData.div           = 0.03;
        myData.type          = 'C';
        myData.exercise      = false;
        myData.NumberOfSteps = 3;

        Console.WriteLine("How many timesteps: ");
        myData.NumberOfSteps = Convert.ToInt32(Console.ReadLine());

        // Now define option-related calculations and price
        TrinomialTree myTree = new TrinomialTree(myData);

        Console.WriteLine("Price {0}", myTree.Price(100));

        // Clewlow p. 14 check against binomial method C = 10.1457
        myData.sigma    = 0.2;
        myData.T        = 1.0;  // One year
        myData.r        = 0.06;
        myData.K        = 100;
        myData.div      = 0.0;
        myData.type     = 'C';
        myData.exercise = false;
        //myData.NumberOfSteps = 3;

        TrinomialTree myTree2 = new TrinomialTree(myData);

        Console.WriteLine("Price {0}", myTree2.Price(100));

        // Clewlow p. 63 American Put
        myData.sigma    = 0.2;
        myData.T        = 1.0;  // One year
        myData.r        = 0.06;
        myData.K        = 100;
        myData.div      = 0.0;
        myData.type     = 'P';                          // Put
        myData.exercise = true;
        //myData.NumberOfSteps = 3;

        TrinomialTree myTree3 = new TrinomialTree(myData);

        Console.WriteLine("Price {0}", myTree3.Price(100));
    }
Example #5
0
        public void PVFacts()
        {
            var t   = 1.0;
            var k   = 0;
            var f   = 100;
            var vol = 0.32;
            var rf  = 0.05;
            var cp  = OptionType.P;
            var df  = System.Math.Exp(-rf * t);

            //zero strike put is worthless
            var PV = BinomialTree.AmericanFutureOptionPV(f, k, rf, t, vol, cp);

            Assert.Equal(0, PV, 10);
            PV = TrinomialTree.AmericanFutureOptionPV(f, k, rf, t, vol, cp);
            Assert.Equal(0, PV, 10);

            //zero strike call is worth fwd with no discounting
            cp = OptionType.C;
            PV = BinomialTree.AmericanFutureOptionPV(f, k, rf, t, vol, cp);
            Assert.Equal(f, PV, 10);
            PV = TrinomialTree.AmericanFutureOptionPV(f, k, rf, t, vol, cp);
            Assert.Equal(f, PV, 10);

            //and has delta = 1.0
            var greeks = TrinomialTree.AmericanFutureOption(f, k, rf, t, vol, cp);

            Assert.Equal(1.0, (double)greeks[1, 0], 10);
            greeks = BinomialTree.AmericanFutureOption(f, k, rf, t, vol, cp);
            Assert.Equal(1.0, (double)greeks[1, 0], 10);

            //OTM option with zero vol is worthless
            vol = 0.0;
            k   = f + 1;
            PV  = BinomialTree.AmericanFutureOptionPV(f, k, rf, t, vol, cp);
            Assert.Equal(0, PV, 10);
            PV = TrinomialTree.AmericanFutureOptionPV(f, k, rf, t, vol, cp);
            Assert.Equal(0, PV, 10);

            //option worth >= black in all cases for same inputs
            vol = 0.32;
            k   = f + 20;
            var PVBlack = BlackFunctions.BlackPV(f, k, rf, t, vol, cp);

            PV = BinomialTree.AmericanFutureOptionPV(f, k, rf, t, vol, cp);
            Assert.True(PV >= PVBlack);
            PV = TrinomialTree.AmericanFutureOptionPV(f, k, rf, t, vol, cp);
            Assert.True(PV >= PVBlack);
        }
Example #6
0
        public void PVFacts()
        {
            var t   = 1.0;
            var k   = 0.0;
            var f   = 100.0;
            var vol = 0.32;
            var rf  = 0.05;
            var cp  = OptionType.P;

            //zero strike put is worthless
            var PV = TrinomialTree.AmericanAssetOptionPV(f, k, rf, f, t, vol, cp);

            Assert.Equal(0, PV, 10);
            PV = BinomialTree.AmericanPV(t, f, k, rf, vol, cp, rf, 100);
            Assert.Equal(0, PV, 10);
            var flatInterp    = new DummyPointInterpolator(new[] { 1.0 }, new[] { rf });
            var flatFwdInterp = new DummyPointInterpolator(new[] { 1.0 }, new[] { f });

            PV = TrinomialTree.VanillaPV(t, f, k, flatInterp, vol, cp, flatFwdInterp, 100, true);
            Assert.Equal(0, PV, 10);

            //zero strike call is worth fwd with no discounting
            cp = OptionType.C;
            PV = TrinomialTree.AmericanAssetOptionPV(f, k, rf, f, t, vol, cp);
            Assert.Equal(f, PV, 10);
            PV = BinomialTree.AmericanPV(t, f, k, rf, vol, cp, rf, 100);
            Assert.Equal(f, PV, 10);

            //OTM option with zero vol is worthless
            vol = 0.0;
            k   = f + 1.0;
            PV  = BinomialTree.AmericanPV(t, f, k, rf, vol, cp, rf, 100);
            Assert.Equal(0, PV, 10);
            PV = TrinomialTree.AmericanAssetOptionPV(f, k, rf, f, t, vol, cp);
            Assert.Equal(0, PV, 10);

            //option worth >= black in all cases for same inputs
            vol = 0.32;
            k   = f + 20;
            var PVBlack = BlackFunctions.BlackPV(f, k, rf, t, vol, cp);

            PV = BinomialTree.AmericanPV(t, f, k, rf, vol, cp, rf, 100);
            Assert.True(PV >= PVBlack);
            PV = TrinomialTree.AmericanAssetOptionPV(f, k, rf, f, t, vol, cp);
            Assert.True(PV >= PVBlack);
        }
Example #7
0
        public void ImpliedVolFacts()
        {
            var t   = 1.0;
            var k   = 120;
            var f   = 100;
            var vol = 0.32;
            var rf  = 0.05;
            var cp  = OptionType.P;

            var PVbi  = BinomialTree.AmericanFutureOptionPV(f, k, rf, t, vol, cp);
            var PVtri = TrinomialTree.AmericanFutureOptionPV(f, k, rf, t, vol, cp);

            var impliedVolBi  = BinomialTree.AmericanFuturesOptionImpliedVol(f, k, rf, t, PVbi, cp);
            var impliedVolTri = TrinomialTree.AmericanFuturesOptionImpliedVol(f, k, rf, t, PVtri, cp);

            Assert.Equal(vol, impliedVolBi, 10);
            Assert.Equal(vol, impliedVolTri, 10);
        }
Example #8
0
        public void EuropeanOnGridFacts()
        {
            var t   = 1.0;
            var k   = 120;
            var f   = 100;
            var vol = 0.32;
            var rf  = 0.05;
            var cp  = OptionType.P;

            var PVBlack = BlackFunctions.BlackPV(f, k, rf, t, vol, cp);
            var PVbi    = BinomialTree.EuropeanPV(t, f, k, rf, vol, cp, rf, 100);
            var PVtri   = TrinomialTree.EuropeanPV(t, f, k, rf, vol, cp, rf, 100);

            Assert.Equal(PVBlack, PVbi, 1);
            Assert.Equal(PVBlack, PVtri, 1);

            PVbi  = BinomialTree.EuropeanFuturePV(t, f, k, rf, vol, cp, 100);
            PVtri = TrinomialTree.EuropeanFuturePV(t, f, k, rf, vol, cp, 100);

            Assert.Equal(PVBlack, PVbi, 1);
            Assert.Equal(PVBlack, PVtri, 1);
        }
Example #9
0
        /// <summary>
        /// Build a trinomial tree for given yield curve and time grids.
        /// For better pricing, one tree shall be rebuilt for each trade because of different coupon time and call/put dates.
        /// </summary>
        /// <param name="times">The times.</param>
        /// <param name="r0">The r0.</param>
        /// <param name="yieldCurve">The yield curve.</param>
        /// <returns></returns>
        public override NumericTree Tree(double[] times, double r0, IYieldCurve yieldCurve = null)
        {
            var tree = new TrinomialTree(new OrnsteinUhlenbeckProcess(_a, _sigma), times, 0);

            return(new NumericTree(this, tree, yieldCurve));
        }
Example #10
0
 private TrinomialTree(TrinomialTree tritree)
 {// Copy-constructor
     // No body
 }
Example #11
0
 public override Lattice tree(TimeGrid grid){
     TrinomialTree trinomial = new TrinomialTree(dynamics().process(), grid, true);
     return new ShortRateTree(trinomial, dynamics(), grid);
 }