예제 #1
0
        public void StrikeForPVFacts()
        {
            var evalDate = DateTime.Today;
            var avgStart = evalDate.AddDays(365);
            var avgEnd   = avgStart.AddDays(32);
            var k        = 110.0;
            var f        = 100.0;
            var vol      = 0.32;
            var rf       = 0.0;

            var volSurface = new ConstantVolSurface(evalDate, vol);


            var pv = TurnbullWakeman.PV(f, 0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.C);

            var strike = TurnbullWakeman.StrikeForPV(pv, f, 0, volSurface, DateTime.Today, avgStart, avgEnd, rf, OptionType.C);

            Assert.Equal(k, strike, 10);

            var fixingDates = avgStart.CalendarDaysInPeriod(avgEnd).ToArray();
            var fwds        = fixingDates.Select(d => f).ToArray();
            var sigmas      = fixingDates.Select(d => vol).ToArray();

            pv     = TurnbullWakeman.PV(fwds, fixingDates, evalDate, avgEnd, sigmas, k, rf, OptionType.C);
            strike = TurnbullWakeman.StrikeForPV(pv, fwds, fixingDates, volSurface, evalDate, avgEnd, rf, OptionType.C);
            Assert.Equal(k, strike, 10);
        }
예제 #2
0
        public void PVFacts()
        {
            var t   = 1.0;
            var t2  = 2.0;
            var k   = 0;
            var f   = 100;
            var vol = 0.32;
            var rf  = 0.05;
            var cp  = OptionType.P;

            //expired is worthless
            var PV = TurnbullWakeman.PV(f, 0, vol, 0, t, 0, rf, OptionType.P);

            Assert.Equal(0, PV, 10);
            PV = TurnbullWakeman.PV(f, 0, vol, 0, t, 0, rf, OptionType.C);
            Assert.Equal(0, PV, 10);

            //zero strike put is worthless
            PV = TurnbullWakeman.PV(f, 0, vol, 0, t, t2, rf, cp);
            Assert.Equal(0, PV, 10);
            PV = TurnbullWakeman.PV(f, 50, vol, 0, -0.1, t2, rf, cp);
            Assert.Equal(0, PV, 10);

            //zero strike call is worth discounted fwd
            cp = OptionType.C;
            PV = TurnbullWakeman.PV(f, 0, vol, 0, t, t2, rf, cp);
            Assert.Equal(System.Math.Exp(-rf * t2) * f, PV, 2);

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

            //put-call parity at f==k
            k   = f;
            vol = 0.32;
            var PVcall = TurnbullWakeman.PV(f, 0, vol, k, t, t2, rf, OptionType.C);
            var PVput  = TurnbullWakeman.PV(f, 0, vol, k, t, t2, rf, OptionType.P);

            Assert.Equal(PVcall, PVput, 2);

            //independent fwds version
            var valDate         = new DateTime(2019, 10, 24);
            var fixingStartDate = new DateTime(2019, 10, 01);
            var fixingEndDate   = new DateTime(2019, 10, 25);
            var fixingDates     = DateExtensions.BusinessDaysInPeriod(fixingStartDate, fixingEndDate, TestProviderHelper.CalendarProvider.Collection["NYC"]).ToArray();
            var fwds            = fixingDates.Select(x => 100.0).ToArray();
            var sigmas          = fixingDates.Select(x => 0.32).ToArray();

            PV = TurnbullWakeman.PV(fwds, fixingDates, valDate, fixingEndDate, sigmas, 1, 0.0, OptionType.C, true);
            var blackPV = BlackFunctions.BlackPV(100.0, 1, 0.0, 1 / 365.0, 0.32, OptionType.C);

            Assert.Equal(blackPV, PV, 4);
        }
예제 #3
0
        public void CanRunPV()
        {
            var sut    = GetSut();
            var usd    = TestProviderHelper.CurrencyProvider["USD"];
            var pvCube = sut.PV(usd);

            var ins = sut.Portfolio.Instruments.First() as AsianOption;

            TestProviderHelper.CalendarProvider.Collection.TryGetCalendar("NYC", out var usdCal);

            var clewlowPV = LME_Clewlow.PV(100, 0, 0.32, 101, sut.Model.BuildDate, ins.AverageStartDate, ins.AverageEndDate, 0.0, OptionType.C, usdCal);
            var tbPV      = TurnbullWakeman.PV(100, 0, 0.32, 101, sut.Model.BuildDate, ins.AverageStartDate, ins.AverageEndDate, 0.0, OptionType.C);
            var tbFutPV   = TurnbullWakeman.PV(ins.FixingDates.Select(x => 100.0).ToArray(), ins.FixingDates, sut.Model.BuildDate, ins.PaymentDate, ins.FixingDates.Select(x => 0.32).ToArray(), ins.Strike, 0.0, OptionType.C);

            Assert.Equal(tbFutPV, pvCube.GetAllRows().First().Value, 1);
        }
예제 #4
0
        public void DeltaFacts()
        {
            var evalDate  = new DateTime(2019, 05, 10);
            var avgStart  = evalDate.AddDays(365);
            var avgEnd    = avgStart.AddDays(32);
            var k         = 100.0;
            var f         = 100.0;
            var vol       = 0.32;
            var rf        = 0.0;
            var deltaBump = 1e-6;
            var pv        = TurnbullWakeman.PV(f, 0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.C);
            var pv2       = TurnbullWakeman.PV(f + deltaBump, 0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.C);
            var delta     = TurnbullWakeman.Delta(f, 0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.C);

            Assert.Equal((pv2 - pv) / deltaBump, delta, 2);

            evalDate = avgStart.AddDays(16);
            pv       = TurnbullWakeman.PV(f, 100.0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.C);
            pv2      = TurnbullWakeman.PV(f + deltaBump, 100.0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.C);
            delta    = TurnbullWakeman.Delta(f, 100.0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.C);

            Assert.Equal((pv2 - pv) / deltaBump, delta, 2);

            pv    = TurnbullWakeman.PV(f, 100.0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.P);
            pv2   = TurnbullWakeman.PV(f + deltaBump, 100.0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.P);
            delta = TurnbullWakeman.Delta(f, 100.0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.P);

            Assert.Equal((pv2 - pv) / deltaBump, delta, 2);

            pv    = TurnbullWakeman.PV(f, 0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.C);
            pv2   = TurnbullWakeman.PV(f + deltaBump, 0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.C);
            delta = TurnbullWakeman.Delta(f, 0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.C);

            Assert.Equal((pv2 - pv) / deltaBump, delta, 2);

            pv    = TurnbullWakeman.PV(f, 100.0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.P);
            pv2   = TurnbullWakeman.PV(f + deltaBump, 100.0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.P);
            delta = TurnbullWakeman.Delta(f, 100.0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.P);

            Assert.Equal((pv2 - pv) / deltaBump, delta, 2);
        }
예제 #5
0
        public void ThetaFacts()
        {
            var originDate  = new DateTime(2019, 05, 10);
            var fixingDates = originDate.AddDays(30).CalendarDaysInPeriod(originDate.AddDays(60)).ToArray();
            var fwds        = fixingDates.Select(d => 100.0).ToArray();
            var vols        = fixingDates.Select(d => 0.32).ToArray();
            var k           = 100.0;
            var pv          = TurnbullWakeman.PV(fwds, fixingDates, originDate, fixingDates.Last(), vols, k, 0.0, OptionType.C);
            var pv2         = TurnbullWakeman.PV(fwds, fixingDates, originDate.AddDays(1), fixingDates.Last(), vols, k, 0.0, OptionType.C);
            var theta       = TurnbullWakeman.Theta(fwds, fixingDates, originDate, fixingDates.Last(), vols, k, 0.0, OptionType.C);

            Assert.Equal((pv2 - pv) * 365, theta, 0);

            theta = TurnbullWakeman.Theta(fwds, fixingDates, fixingDates.Last().AddDays(1), fixingDates.Last(), vols, k, 0.0, OptionType.C);
            Assert.Equal(0, theta);

            theta = TurnbullWakeman.Theta(fwds, fixingDates, fixingDates.Last(), fixingDates.Last(), vols, k, 0.0, OptionType.C);
            Assert.Equal(0, theta);

            Assert.Throws <DataMisalignedException>(() => TurnbullWakeman.Theta(new[] { 1.0 }, fixingDates, originDate, fixingDates.Last(), vols, k, 0.0, OptionType.C));
        }