public void Should_get_correct_price_range_When_apply_monte_carlo()
        {
            var date        = D20190505;
            var nextDate    = date.AddDays(1);
            int largeNumber = 10000;

            int randomingCount = 0;
            Func <Volatility, Volatility> producer = d =>
            {
                var volatilityRandomizer = new VolatilityRandomizer();
                Interlocked.Increment(ref randomingCount);
                return(volatilityRandomizer.Randomrize(Volatility));
            };

            var monteCarlo = new MonteCarloVolatilityRandomizer(largeNumber, Volatility, producer);

            var pricer = new MiniPricer(new Price(date, InitialPrice), Volatility, new JoursFeriesProvider(), monteCarlo);

            var priceOfNextDay = pricer.GetPriceOf(Instrument, nextDate);

            Check.That(randomingCount).IsEqualTo(largeNumber);
            Check.That(priceOfNextDay.Date).IsEqualTo(nextDate);
            Check.That(priceOfNextDay.Value).IsStrictlyLessThan(120);
            Check.That(priceOfNextDay.Value).IsStrictlyGreaterThan(80);
        }
        public void Should_provide_the_price_for_a_specific_day()
        {
            var today    = D20190501;
            var tomorrow = D20190502;
            var pricer   = new MiniPricer(new Price(today, InitialPrice), Volatility, new JoursFeriesProvider(), new VolatilityRandomizerForTesting());

            var priceOf20190508 = pricer.GetPriceOf(Instrument, tomorrow);

            Check.That(priceOf20190508).IsEqualTo(new Price(tomorrow, InitialPrice + Volatility.Value));
        }
        public void Should_return_current_price_When_requested_date_is_current_date()
        {
            var date = D20190430;

            var pricer = new MiniPricer(new Price(date, InitialPrice), Volatility, new JoursFeriesProvider(), new VolatilityRandomizerForTesting());

            var priceOf20190508 = pricer.GetPriceOf(Instrument, date);

            Check.That(priceOf20190508).IsEqualTo(new Price(date, InitialPrice));
        }
        public void ShouldReturnTodayPrice_Test()
        {
            var today      = DateTime.Today;
            var volatility = 0d;
            var todayPrice = 100d;

            var pricer = new MiniPricer();
            var price  = pricer.CalculatePrice(today, todayPrice, volatility);

            Assert.AreEqual(todayPrice, price);
        }
        [TestCase(11, 4)] // sunday
        public void Should_apply_one_time_per_day_randomrize_volatility_When_the_date_is_neither_weekend_nor_jour_ferie(int day, int randomrizeCalledTimes)
        {
            var mondayFerie = D20190505;

            var date = new DateTime(2019, 5, day);
            var volatilityRandomizer = new VolatilityRandomizerForTesting();
            var pricer = new MiniPricer(new Price(mondayFerie, InitialPrice), Volatility, new JoursFeriesProvider(), volatilityRandomizer);

            pricer.GetPriceOf(Instrument, date);

            Check.That(volatilityRandomizer.CalledTimes).IsEqualTo(randomrizeCalledTimes);
        }
        public void ShouldReturnPriceWhenSaturdayAndSundayAreInTheMiddle_Test()
        {
            Mock <IPublicHolidayProvider> moqPublicHolidayProvider = new Mock <IPublicHolidayProvider>();

            moqPublicHolidayProvider.Setup(p => p.GetPublicHolidays()).Returns(Enumerable.Empty <DateTime>());
            moqPublicHolidayProvider.Setup(p => p.IsPublicHoliday(It.IsAny <DateTime>())).Returns(false);
            var futurDate  = new DateTime(2017, 10, 16);
            var volatility = 50d;
            var todayPrice = 800d;

            var pricer = new MiniPricer(moqPublicHolidayProvider.Object);
            var price  = pricer.CalculatePrice(futurDate, todayPrice, volatility);

            Assert.AreEqual(4050, price);
        }
        public void ShouldReturnMoreThanOneDayFuturPrice_Test()
        {
            Mock <IPublicHolidayProvider> moqPublicHolidayProvider = new Mock <IPublicHolidayProvider>();

            moqPublicHolidayProvider.Setup(p => p.GetPublicHolidays()).Returns(Enumerable.Empty <DateTime>());
            moqPublicHolidayProvider.Setup(p => p.IsPublicHoliday(It.IsAny <DateTime>())).Returns(false);
            var futurDate  = DateTime.Today.AddDays(2);
            var volatility = 50d;
            var todayPrice = 200d;

            var pricer = new MiniPricer(moqPublicHolidayProvider.Object);
            var price  = pricer.CalculatePrice(futurDate, todayPrice, volatility);

            Assert.AreEqual(450, price);
        }
        public void Should_randomize_volatility_to_absoluteValue_or_negativeValue_or_zero()
        {
            var date = D20190501;
            var volatilityRandomizer = new VolatilityRandomizerTestDecorator();
            var pricer = new MiniPricer(new Price(date, InitialPrice), Volatility, new JoursFeriesProvider(), volatilityRandomizer);

            pricer.GetPriceOf(Instrument, date.AddDays(1000));

            var volatilities = volatilityRandomizer.Volatilities.ToArray();

            Check.That(volatilities.All(v => Math.Abs(Math.Abs(v) - InitialPrice) < 0.000000001));
            Assert.That(volatilities.Any(v => v < 0), Is.True, "Should have negative volatility");
            Assert.That(volatilities.Any(v => v > 0), Is.True, "Should have posivite volatility");
            Assert.That(volatilities.Any(v => Math.Abs(v) < 0.000001), Is.True, "Should have null volatility");
        }
        public void ShouldReturnPriceForPublicHolidayEqualSunday_Test()
        {
            Mock <IPublicHolidayProvider> moqPublicHolidayProvider = new Mock <IPublicHolidayProvider>();
            var testDate   = new DateTime(2017, 10, 15);
            var volatility = 50d;
            var todayPrice = 800d;

            moqPublicHolidayProvider.Setup(p => p.GetPublicHolidays()).Returns(new List <DateTime> {
                testDate
            });
            moqPublicHolidayProvider.Setup(p => p.IsPublicHoliday(testDate)).Returns(true);

            var pricer = new MiniPricer(moqPublicHolidayProvider.Object);
            var price  = pricer.CalculatePrice(testDate, todayPrice, volatility);

            Assert.AreEqual(2700, price);
        }
        public void Should_not_apply_volatility_on_jours_feries()
        {
            var initialDate = D20190430;
            var pricer      = new MiniPricer(new Price(initialDate, InitialPrice), Volatility, new JoursFeriesProvider(), new VolatilityRandomizerForTesting());

            var jf1 = pricer.GetPriceOf(Instrument, D20190501);

            Check.That(jf1.Value).IsEqualTo(InitialPrice);

            var jf2 = pricer.GetPriceOf(Instrument, D20190505);

            Check.That(jf2.Value).IsEqualTo(InitialPrice * Math.Pow((InitialPrice + Volatility.Value) / InitialPrice, 2)); // 2 3 4(saturday)

            var jf3 = pricer.GetPriceOf(Instrument, D20190508);

            Check.That(jf3.Value).IsEqualTo(InitialPrice * Math.Pow((InitialPrice + Volatility.Value) / InitialPrice, 4));
        }
        public void ShouldReturnPriceForPublicHoliday_Test()
        {
            Mock <IPublicHolidayProvider> moqPublicHolidayProvider = new Mock <IPublicHolidayProvider>();

            moqPublicHolidayProvider.Setup(p => p.GetPublicHolidays()).Returns(new List <DateTime>()
            {
                DateTime.Today.AddDays(2)
            });
            moqPublicHolidayProvider.Setup(p => p.IsPublicHoliday(DateTime.Today.AddDays(2))).Returns(true);
            DateTime futurDate  = moqPublicHolidayProvider.Object.GetPublicHolidays().FirstOrDefault();
            var      volatility = 50d;
            var      todayPrice = 200d;

            var pricer = new MiniPricer(moqPublicHolidayProvider.Object);
            var price  = pricer.CalculatePrice(futurDate, todayPrice, volatility);

            Assert.AreEqual(300, price);
        }
        public void Should_not_apply_volatility_on_weekend()
        {
            var initialDate = D20190502;

            var pricer = new MiniPricer(new Price(initialDate, InitialPrice), Volatility, new JoursFeriesProvider(), new VolatilityRandomizerForTesting());

            var friday = D20190503;

            var saturday = friday.AddDays(1);
            var sunday   = saturday.AddDays(1);

            var priceOfSaturday = pricer.GetPriceOf(Instrument, saturday);

            Check.That(priceOfSaturday.Value).IsEqualTo(InitialPrice + Volatility.Value);

            var priceOfSunday = pricer.GetPriceOf(Instrument, sunday);

            Check.That(priceOfSunday.Value).IsEqualTo(InitialPrice + Volatility.Value);
        }
        public void Can_apply_random_volatility_using_monte_carlo()
        {
            var date     = D20190505;
            var nextDate = date.AddDays(1);

            var queue = new Queue <double>();

            queue.Enqueue(20);
            queue.Enqueue(4);
            queue.Enqueue(30);

            Func <Volatility, Volatility> volatilityProducer = d => new Volatility(queue.Dequeue());

            var volatilityRandomizer = new MonteCarloVolatilityRandomizer(3, Volatility, volatilityProducer);
            var pricer = new MiniPricer(new Price(date, InitialPrice), Volatility, new JoursFeriesProvider(), volatilityRandomizer);

            var priceOfNextDate = pricer.GetPriceOf(Instrument, nextDate);

            Check.That(priceOfNextDate).IsEqualTo(new Price(nextDate, 100 * (1 + (20d + 4 + 30) / 3 / 100)));
        }
        public void Return_instrument_price_When_instrument_is_correlated_with_a_pivot_within_a_basket()
        {
            var date     = D20190505;
            var nextDate = date.AddDays(1);

            var queue = new Queue <double>();

            queue.Enqueue(20);
            queue.Enqueue(4);
            queue.Enqueue(30);

            Func <Volatility, Volatility> volatilityProducer = d => new Volatility(queue.Dequeue());

            var volatilityRandomizer = new MonteCarloVolatilityRandomizer(3, Volatility, volatilityProducer);

            var instrument = new Instrument("VOD.L");

            var correlation = new Correlation(value: -1);
            var basketItem  = new BasketItem(instrument, true);
            var basketItem2 = new BasketItem(new Instrument("TOT.L"), false);

            var basket = new InstrumentBasket(correlation, new BasketItem[]
            {
                basketItem,
                basketItem2
            });
            var price = new Price(nextDate, 100 * (1 + (20d + 4 + 30) / 3 / 100));

            var pricer = new MiniPricer(new Price(date, InitialPrice), Volatility, new JoursFeriesProvider(), volatilityRandomizer, basket);

            BasketPriceComposition prices = pricer.GetPriceOf(nextDate, basket);

            Check.That(prices).HasSize(2);
            Check.That(prices[basketItem]).IsEqualTo(price);
            Check.That(prices[basketItem2]).IsEqualTo(price * correlation);
        }