示例#1
0
        [TestMethod] //TODO: fix this one
        public void TestFdAmericanOptionEngine()
        {
            var startDate = new Date(2010, 08, 31);
            var endDate   = new Date(2016, 08, 31);
            var calendar  = CalendarImpl.Get("chn");

            var option = new VanillaOption(startDate,
                                           endDate,
                                           OptionExercise.American,
                                           OptionType.Call,
                                           3.53,
                                           InstrumentType.Stock,
                                           calendar,
                                           new Act365(),
                                           CurrencyCode.CNY,
                                           CurrencyCode.CNY,
                                           calendar.BizDaysBetweenDatesInclEndDay(startDate, endDate).ToArray(),
                                           null,
                                           1.0
                                           );

            var engine = new FdAmericanOptionEngine(100);
            var result = engine.Calculate(option, TestMarket(), PricingRequest.All);

            Assert.AreEqual(result.Pv, 0.4459260143, 1e-8);
            Assert.AreEqual(result.Delta, 0.71918151, 1e-8);
            Assert.AreEqual(result.Gamma, 0.487730202, 1e-8);
            Assert.AreEqual(result.Vega, 0.0177395037, 1e-8);
            Assert.AreEqual(result.Theta, -0.00045427, 1e-8);
        }
示例#2
0
        private Bond ZheBaoBondPart()
        {
            var bond = new Bond(
                "010002",
                new Date(2017, 8, 17),
                new Date(2022, 8, 17),
                100.0,
                CurrencyCode.CNY,
                new StepWiseCoupon(new Dictionary <Date, double>
            {
                { new Date(2017, 8, 17), 0.01 },
                { new Date(2018, 8, 17), 0.01 },
                { new Date(2019, 8, 17), 0.01 },
                { new Date(2020, 8, 17), 0.01 },
                { new Date(2021, 8, 17), 0.01 },
            },
                                   CalendarImpl.Get("chn_ib")
                                   ),
                CalendarImpl.Get("chn_ib"),
                Frequency.Annual,
                Stub.LongEnd,
                new Act365NoLeap(),
                new ModifiedAfb(),
                BusinessDayConvention.None,
                BusinessDayConvention.ModifiedFollowing,
                null,
                TradingMarket.ChinaExShg,
                redemption: new Qdp.Pricing.Library.Common.Utilities.Redemption(1.03, RedemptionType.SeparatePrincipal)
                );

            return(bond);
        }
示例#3
0
        /// <summary>
        /// Return fixing curve by historicalIndexRates
        /// </summary>
        /// <param name="settlementDate"></param>
        /// <param name="historicalIndexRates"></param>
        /// <param name="floatingBondInfo"></param>
        /// <returns></returns>
        public static InstrumentCurveDefinition GetFixingCurve(string settlementDate, Dictionary <string, Dictionary <string, double> > historicalIndexRates, FloatingRateBondInfo floatingBondInfo)
        {
            var resetCalendar = CalendarImpl.Get(floatingBondInfo.Calendar);
            var index         = floatingBondInfo.Index;
            var rates         = historicalIndexRates[index];
            var tradeId       = floatingBondInfo.TradeId;

            var indexDate   = new DayGap(floatingBondInfo.ResetToFixingGap).Get(resetCalendar, settlementDate.ToDate());
            var fixingTuple = rates.TryGetValue(indexDate.ToString(), resetCalendar);
            var indexRate   = rates.GetAverageIndex(fixingTuple.Item1, resetCalendar, floatingBondInfo.ResetAverageDays, floatingBondInfo.ResetRateDigits);

            string fixingCurveName      = "FixingCurve_" + tradeId;
            var    fixingRateDefinition = new[]
            {
                new RateMktData("1D", indexRate, index, "None", fixingCurveName),
                new RateMktData("50Y", indexRate, index, "None", fixingCurveName),
            };
            var curveConvention = new CurveConvention("fixingCurveConvention_" + tradeId,
                                                      "CNY",
                                                      "ModifiedFollowing",
                                                      "Chn_ib",
                                                      index == null ? "Act365" : index.ToIndexType().DayCountEnum(),
                                                      "Continuous",
                                                      "ForwardFlat");

            floatingBondInfo.ValuationParamters.FixingCurveName = fixingCurveName;
            AddTrades(new [] { floatingBondInfo });
            return(new InstrumentCurveDefinition(fixingCurveName, curveConvention, fixingRateDefinition, "ForwardCurve"));
        }
示例#4
0
        private Bond TianJiBondPart()
        {
            var bond = new Bond(
                "010002",
                new Date(2015, 6, 8),
                new Date(2020, 6, 8),
                100,
                CurrencyCode.CNY,
                new StepWiseCoupon(new Dictionary <Date, double>
            {
                { new Date(2015, 6, 8), 0.01 },
                { new Date(2016, 6, 8), 0.01 },
                { new Date(2017, 6, 8), 0.01 },
                { new Date(2018, 6, 8), 0.01 },
                { new Date(2019, 6, 8), 0.01 },
            },
                                   CalendarImpl.Get("chn_ib")
                                   ),
                CalendarImpl.Get("chn_ib"),
                Frequency.Annual,
                Stub.LongEnd,
                new Act365NoLeap(),
                new ModifiedAfb(),
                BusinessDayConvention.None,
                BusinessDayConvention.ModifiedFollowing,
                null,
                TradingMarket.ChinaExShg
                );

            return(bond);
        }
示例#5
0
        private Bond HangXinBondPart()
        {
            var bond = new Bond(
                "010002",
                new Date(2015, 6, 12),
                new Date(2021, 6, 12),
                100,
                CurrencyCode.CNY,
                new StepWiseCoupon(new Dictionary <Date, double>
            {
                { new Date(2015, 6, 12), 0.002 },
                { new Date(2016, 6, 12), 0.005 },
                { new Date(2017, 6, 12), 0.01 },
                { new Date(2018, 6, 12), 0.015 },
                { new Date(2019, 6, 12), 0.015 },
                { new Date(2020, 6, 12), 0.016 },
            },
                                   CalendarImpl.Get("chn_ib")
                                   ),
                CalendarImpl.Get("chn_ib"),
                Frequency.Annual,
                Stub.LongEnd,
                new Act365NoLeap(),
                new ModifiedAfb(),
                BusinessDayConvention.None,
                BusinessDayConvention.ModifiedFollowing,
                null,
                TradingMarket.ChinaExShg,
                redemption: new Redemption(1.07, RedemptionType.SeparatePrincipalWithLastCoupon)
                );

            return(bond);
        }
示例#6
0
        public void BasicBondTest()
        {
            var bond = new Bond(
                id: "bond",
                startDate: new Date(2016, 3, 15),
                maturityDate: new Date(2019, 3, 15),
                notional: 100.0,
                currency: CurrencyCode.CNY,
                coupon: new FixedCoupon(0.05),
                calendar: CalendarImpl.Get("chn"),
                paymentFreq: Frequency.SemiAnnual,
                stub: Stub.ShortEnd,
                accrualDayCount: new Act365(),
                paymentDayCount: new Act365(),
                accrualBizDayRule: BusinessDayConvention.ModifiedFollowing,
                paymentBizDayRule: BusinessDayConvention.ModifiedFollowing,
                settlementGap: new DayGap("+0D"),
                bondTradingMarket: TradingMarket.ChinaInterBank);

            var engine = new BondEngineCn(new BondYieldPricerCn());
            var market = new MarketCondition(
                x => x.ValuationDate.Value = new Date(2018, 8, 1),
                x => x.MktQuote.Value      =
                    new Dictionary <string, Tuple <PriceQuoteType, double> >
            {
                { "bond", Tuple.Create(PriceQuoteType.Clean, 100.0) }
            }
                );
            var result = engine.Calculate(bond, market, PricingRequest.Ytm);
        }
示例#7
0
        public Bond[] CreateBonds()
        {
            var bondPrices       = new Dictionary <string, Tuple <PriceQuoteType, double> >();
            var deliverableBonds = File.ReadAllLines(@"./Data/BondFuture/TF1509DeliverableBondInfo.txt")
                                   .Select(x =>
            {
                var splits            = x.Split(',');
                bondPrices[splits[0]] = Tuple.Create(PriceQuoteType.Dirty, Convert.ToDouble(splits[6]));
                return(new Bond(
                           splits[0],
                           new Date(DateTime.Parse(splits[4])),
                           new Date(DateTime.Parse(splits[5])),
                           100.0,
                           CurrencyCode.CNY,
                           new FixedCoupon(Convert.ToDouble(splits[2])),
                           CalendarImpl.Get("chn_ib"),
                           Convert.ToInt32(splits[3]) == 1 ? Frequency.Annual : Frequency.SemiAnnual,
                           Stub.LongEnd,
                           new ActActIsma(),
                           new ActAct(),
                           BusinessDayConvention.None,
                           BusinessDayConvention.ModifiedFollowing,
                           new DayGap("0D"),
                           TradingMarket.ChinaInterBank
                           ));
            }).ToArray();

            return(deliverableBonds);
        }
示例#8
0
        private static Bond GeliBondPart(String cbTicker)
        {
            var bond = new Bond(
                cbTicker,
                new Date(2014, 12, 25),
                new Date(2019, 12, 25),
                100,
                CurrencyCode.CNY,
                new StepWiseCoupon(new Dictionary <Date, double>
            {
                { new Date(2014, 12, 25), 0.006 },
                { new Date(2015, 12, 25), 0.008 },
                { new Date(2016, 12, 25), 0.01 },
                { new Date(2017, 12, 25), 0.015 },
                { new Date(2018, 12, 25), 0.02 }
            },
                                   CalendarImpl.Get("chn_ib")
                                   ),
                CalendarImpl.Get("chn_ib"),
                Frequency.Annual,
                Stub.LongEnd,
                new Act365NoLeap(),
                new ModifiedAfb(),
                BusinessDayConvention.None,
                BusinessDayConvention.ModifiedFollowing,
                null,
                TradingMarket.ChinaExShg,
                redemption: new Redemption(1.06, RedemptionType.SeparatePrincipalWithLastCoupon)
                );

            return(bond);
        }
示例#9
0
        private void AsianOptionGreekCalc(String ValuationDate = "2015-03-19", Double vol            = 0.28, Double spot     = 1.0, Double strike = 1.03,
                                          string asianType     = "ArithmeticAverage", Boolean isCall = true, Boolean isFixed = true,
                                          double expectedPv    = 0.03368701153344,
                                          double expectedDelta = 0.431553260493781,
                                          double expectedGamma = 4319.00095926793,
                                          double expectedVega  = 0.00146247323594882,
                                          double expectedRho   = -1.62432084616776E-06,
                                          double expectedTheta = -0.000398443365606245
                                          )
        {
            var valuationDate = DateFromStr(ValuationDate);
            var maturityDate  = new Term("176D").Next(valuationDate);
            var calendar      = CalendarImpl.Get("chn");
            var obsDates      = new[] { new Date(2015, 4, 2), new Date(2015, 5, 4), new Date(2015, 6, 2), new Date(2015, 7, 2), new Date(2015, 8, 3), new Date(2015, 9, 2) };

            #region comment
            //var fixings = File.ReadAllLines(@"./Data/HistoricalEquityPrices/hs300.csv")
            //	.Select(x =>
            //	{
            //		var splits = x.Split(',');
            //		return Tuple.Create(new Date(DateTime.Parse(splits[0])), Double.Parse(splits[1]));
            //	}).ToDictionary(x => x.Item1, x => x.Item2);
            //var initialSpot = fixings[startDate];
            //fixings = fixings.Select(x => Tuple.Create(x.Key, x.Value / initialSpot)).Where(x => x.Item1 < startDate).ToDictionary(x => x.Item1, x => x.Item2);
            #endregion comment
            var option = new AsianOption(
                valuationDate,
                maturityDate,
                OptionExercise.European,
                isCall ? OptionType.Call : OptionType.Put,
                ToAsianType(asianType),
                isFixed ? StrikeStyle.Fixed:StrikeStyle.Floating,
                strike,
                InstrumentType.EquityIndex,
                calendar,
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { maturityDate },
                obsDates,
                new Dictionary <Date, double>()
                );
            var market = TestMarket(referenceDate: ValuationDate, vol: vol, spot: spot);

            var analyticalEngine = new AnalyticalAsianOptionEngine();
            var analyticalResult = analyticalEngine.Calculate(option, market, PricingRequest.All);

            //var engine = new GenericMonteCarloEngine(2, 30000);
            //var result = engine.Calculate(option, market, PricingRequest.All);
            //Console.WriteLine("Analytical: {0},{1},{2},{3},{4},{5}", analyticalResult.Pv, analyticalResult.Delta, analyticalResult.Gamma, analyticalResult.Vega, analyticalResult.Rho, analyticalResult.Theta);
            //Console.WriteLine("Monte Carlo: {0},{1},{2},{3},{4},{5}", result.Pv, result.Delta, result.Gamma, result.Vega, result.Rho, result.Theta);

            Assert.AreEqual(analyticalResult.Pv, expectedPv, 1e-1);
            Assert.AreEqual(analyticalResult.Delta, expectedDelta, 1e-1);
            Assert.AreEqual(analyticalResult.Gamma, expectedGamma, 1e4);
            Assert.AreEqual(analyticalResult.Vega, expectedVega, 1e-1);
            Assert.AreEqual(analyticalResult.Rho, expectedRho, 1e-1);
            Assert.AreEqual(analyticalResult.Theta, expectedTheta, 1e-1);
        }
示例#10
0
        //[TestMethod]
        public void AsianArithmeticOptionTest()
        {
            var valuationDate = DateFromStr("2018-03-14");
            var maturityDate  = new Term("176D").Next(valuationDate);
            var calendar      = CalendarImpl.Get("chn");

            //var obsDates = new[] { new Date(2018, 3, 14), new Date(2015, 5, 4), new Date(2015, 6, 2), new Date(2015, 7, 2), new Date(2015, 8, 3), new Date(2015, 9, 2) };
        }
示例#11
0
        public void TestNumberOfBizDates()
        {
            var cny     = CalendarImpl.Get("chn");
            var start   = new Date(2018, 4, 26); // 2 days
            var end     = new Date(2018, 5, 4);  //3 days
            var numDays = cny.NumberBizDaysBetweenDate(start, end, true);

            Assert.AreEqual(4, numDays);
        }
示例#12
0
        public void TestTfDeliverableBondCf()
        {
            var startDates    = new[] { new Date(2016, 04, 06), new Date(2016, 04, 06), new Date(2016, 04, 06), };
            var maturityDates = new[] { new Date(2016, 06, 15), new Date(2016, 09, 14), new Date(2016, 12, 13), };
            var files         = new[] { "QbTF1606CfTest.txt", "QbTF1609CfTest.txt", "QbTF1612CfTest.txt" };
            var futuresNames  = new[] { "TF1606", "TF1609", "TF1612" };

            for (var k = 0; k < startDates.Length; ++k)
            {
                var bondPrices = new Dictionary <string, double>();
                var targetConversionFactors = new List <double>();
                var bonds = File.ReadAllLines(@"./Data/BondFuture/" + files[k])
                            .Select(x =>
                {
                    var splits       = x.Split(',');
                    var startDate    = new Date(DateTime.Parse(splits[3]));
                    var maturityDate = new Date(DateTime.Parse(splits[4]));
                    var rate         = Convert.ToDouble(splits[1]);
                    var frequency    = splits[2] == "Annual" ? Frequency.Annual : Frequency.SemiAnnual;
                    targetConversionFactors.Add(Convert.ToDouble(splits[5]));
                    bondPrices[splits[0]] = Convert.ToDouble(splits[6]);
                    return(new Bond(
                               splits[0],
                               startDate,
                               maturityDate,
                               100.0,
                               CurrencyCode.CNY,
                               new FixedCoupon(rate),
                               CalendarImpl.Get("chn_ib"),
                               frequency,
                               Stub.LongEnd,
                               new Act365(),
                               new Act365(),
                               BusinessDayConvention.None,
                               BusinessDayConvention.ModifiedFollowing,
                               null,
                               TradingMarket.ChinaInterBank));
                }).ToArray();

                var bondfuture = new BondFutures(
                    futuresNames[k],
                    startDates[k],
                    maturityDates[k],
                    maturityDates[k],
                    CalendarImpl.Get("chn"),
                    bonds,
                    new Act365()
                    );
                var market = new BondFutureTests().TestMarket("2016-04-06");
                for (var i = 0; i < bonds.Length; ++i)
                {
                    Assert.AreEqual(bondfuture.GetConversionFactor(bonds[i], market), targetConversionFactors[i]);
                }
            }
        }
        private void CommodityLookbackVanillaComparison(String ValuationDate = "2015-03-19", Double vol = 0.28, Double spot = 240, Double strike = 240,
                                                        Boolean isCall       = true, Boolean isFixed    = true)
        {
            var valuationDate = DateFromStr(ValuationDate);
            var maturityDate  = new Term("176D").Next(valuationDate);
            var calendar      = CalendarImpl.Get("chn");
            var obsDates      = new[] { new Date(2015, 4, 2), new Date(2015, 5, 4), new Date(2015, 6, 2), new Date(2015, 7, 2), new Date(2015, 8, 3), new Date(2015, 9, 2) };

            var option = new LookbackOption(
                valuationDate,
                maturityDate,
                OptionExercise.European,
                isCall ? OptionType.Call : OptionType.Put,
                isFixed ? StrikeStyle.Fixed : StrikeStyle.Floating,
                strike,
                InstrumentType.EquityIndex,
                calendar,
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { maturityDate },
                obsDates,
                new Dictionary <Date, double>(),
                notional: 1
                );

            var vanilla = new VanillaOption(
                valuationDate,
                maturityDate,
                OptionExercise.European,
                isCall ? OptionType.Call : OptionType.Put,
                strike,
                InstrumentType.EquityIndex,
                calendar,
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { maturityDate },
                obsDates,
                notional: 1
                );
            var market1 = TestMarket(referenceDate: ValuationDate, vol: vol, spot: spot);
            var market2 = TestMarket(referenceDate: ValuationDate, vol: vol * 0.8, spot: spot);

            var analyticalEngine = new AnalyticalLookbackOptionEngine();
            var vanillaEngine    = new AnalyticalVanillaEuropeanOptionEngine();
            var analyticalResult = analyticalEngine.Calculate(option, market1, PricingRequest.All);
            var vanillaResult    = vanillaEngine.Calculate(vanilla, market1, PricingRequest.All);
            var volResult        = analyticalEngine.Calculate(option, market2, PricingRequest.All);

            //Floating Lookback Option >= ATM vanilla
            //High volatility Floating >= Low volatility Floating
            Assert.AreEqual(analyticalResult.Pv >= vanillaResult.Pv, true);
            Assert.AreEqual(analyticalResult.Pv >= volResult.Pv, true);
        }
        private void TradeVolLinearInterpCalc(double expectedValue, Date valuationDate, double tradeOpenVol, double tradeCloseVol, DayCountMode dayCountMode)
        {
            var    startDate          = new Date(2018, 3, 21);
            var    maturityDate       = new Date(2018, 5, 21);
            var    numOfSmoothingDays = 30;
            var    calendar           = CalendarImpl.Get("chn");
            double vol = AnalyticalOptionTradeVolInterp.tradeVolLinearInterp(valuationDate, tradeOpenVol, tradeCloseVol, startDate, maturityDate,
                                                                             numOfSmoothingDays, dayCountMode, calendar);

            Assert.AreEqual(expectedValue, vol, 1e-10);
        }
        public void CommodityBinaryEuropeanOptionTest()
        {
            var goldOption = new BinaryOption(
                new Date(2015, 03, 20),
                new Date(2015, 06, 16),
                OptionExercise.European,
                OptionType.Put,
                231.733,
                InstrumentType.Futures,
                BinaryOptionPayoffType.CashOrNothing,
                10.0,
                CalendarImpl.Get("chn"),
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { new Date(2015, 06, 16) },
                new[] { new Date(2015, 06, 16) },
                5.5
                );

            var market = GetMarket();
            IMarketCondition marketCondition = new MarketCondition(
                x => x.ValuationDate.Value  = market.ReferenceDate,
                x => x.DiscountCurve.Value  = market.GetData <CurveData>("Fr007").YieldCurve,
                x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> {
                { "", market.GetData <CurveData>("Fr007").YieldCurve }
            },
                x => x.SpotPrices.Value = new Dictionary <string, double> {
                { "", 240.6 }
            },
                x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> {
                { "", market.GetData <VolSurfMktData>("goldVolSurf").ToImpliedVolSurface(market.ReferenceDate) }
            }
                );

            var engine = new AnalyticalBinaryEuropeanOptionEngine();
            var result = engine.Calculate(goldOption, marketCondition, PricingRequest.All);

            Assert.AreEqual(0.615985804, result.Pv, 1e-8);
            Assert.AreEqual(-0.409184000310747, result.Delta, 1e-8);
            Assert.AreEqual(0.239395655872165, result.Gamma, 1e-8);
            Assert.AreEqual(0.265082040475919, result.Vega, 1e-8);
            Assert.AreEqual(-8.43816170E-07, result.Rho, 1e-8);

            var engine2 = new AnalyticalBinaryEuropeanOptionReplicationEngine(2.0, BinaryOptionReplicationStrategy.Up);

            result = engine2.Calculate(goldOption, marketCondition, PricingRequest.All);
            Assert.AreEqual(1.25655313, result.Pv, 1e-8);
            Assert.AreEqual(-0.745647330608376, result.Delta, 1e-8);
            Assert.AreEqual(0.377738685022888, result.Gamma, 1e-8);
            Assert.AreEqual(0.417379971819684, result.Vega, 1e-8);
            Assert.AreEqual(-1.72130447839702E-06, result.Rho, 1e-8);
        }
示例#16
0
        public void TestQbTfDeliverableBondYield()
        {
            var files = new[] { "QbTF1606CfTest.txt", "QbTF1609CfTest.txt", "QbTF1612CfTest.txt" };

            for (var k = 0; k < files.Length; ++k)
            {
                var bondPrices = new Dictionary <string, Tuple <PriceQuoteType, double> >();
                var targetYtm  = new List <double>();
                var targetAi   = new List <double>();
                var bonds      = File.ReadAllLines(@"./Data/BondFuture/" + files[k])
                                 .Select(x =>
                {
                    var splits       = x.Split(',');
                    var startDate    = new Date(DateTime.Parse(splits[3]));
                    var maturityDate = new Date(DateTime.Parse(splits[4]));
                    var rate         = Convert.ToDouble(splits[1]);
                    var frequency    = splits[2] == "Annual" ? Frequency.Annual : Frequency.SemiAnnual;

                    targetYtm.Add(Convert.ToDouble(splits[8]));
                    targetAi.Add(Convert.ToDouble(splits[6]) - Convert.ToDouble(splits[7]));
                    bondPrices[splits[0]] = Tuple.Create(PriceQuoteType.Dirty, Convert.ToDouble(splits[6]));

                    return(new Bond(
                               splits[0],
                               startDate,
                               maturityDate,
                               100.0,
                               CurrencyCode.CNY,
                               new FixedCoupon(rate),
                               CalendarImpl.Get("chn_ib"),
                               frequency,
                               Stub.LongEnd,
                               new ActActIsma(),
                               new ActActIsma(),
                               BusinessDayConvention.None,
                               BusinessDayConvention.None,
                               null,
                               TradingMarket.ChinaInterBank));
                }).ToArray();

                var market = new BondFutureTests().TestMarket("2016-04-06", bondPrices);
                var engine = new BondEngine();

                for (var i = 0; i < bonds.Length; ++i)
                {
                    var result = engine.Calculate(bonds[i], market, PricingRequest.Ytm | PricingRequest.Ai);
                    Assert.AreEqual(Math.Round(result.Ai, 4), targetAi[i], 1e-5);
                    Assert.AreEqual(Math.Round(result.Ytm, 6), targetYtm[i], 1e-7);
                }
            }
        }
        private void ResetStrikeOptionParityCalc(String ValuationDate = "2017-12-20", Double vol = 0.28, Double spot = 2.0, Double strike = 1.03, Boolean isCall = true, Boolean isPercentage = true)
        {
            var valuationDate    = DateFromStr(ValuationDate);
            var strikefixingDate = valuationDate;
            var exerciseDate     = new Term("176D").Next(valuationDate);
            var calendar         = CalendarImpl.Get("chn");


            var option1 = new ResetStrikeOption(
                valuationDate,
                exerciseDate,
                OptionExercise.European,
                isCall ? OptionType.Call : OptionType.Put,
                isPercentage ? ResetStrikeType.PercentagePayoff : ResetStrikeType.NormalPayoff,
                strike,
                InstrumentType.EquityIndex,
                calendar,
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { exerciseDate },
                new[] { exerciseDate },
                strikefixingDate
                );

            var option2 = new VanillaOption(
                valuationDate,
                exerciseDate,
                OptionExercise.European,
                isCall ? OptionType.Call : OptionType.Put,
                strike,
                InstrumentType.EquityIndex,
                calendar,
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { exerciseDate },
                new[] { exerciseDate }
                );
            var market = TestMarket(referenceDate: ValuationDate, vol: vol, spot: spot);

            var engine        = new AnalyticalResetStrikeOptionEngine();
            var result        = engine.Calculate(option1, market, PricingRequest.All);
            var engineVanilla = new AnalyticalVanillaEuropeanOptionEngine();
            var resultVanilla = engineVanilla.Calculate(option2, market, PricingRequest.All);

            var result1 = (isPercentage) ? result.Pv * strike : result.Pv;

            Assert.AreEqual(result1, resultVanilla.Pv, 1e-8);
        }
示例#18
0
        private void AsianOptionGTJACalc(String ValuationDate = "2018-06-29", Double vol = 0.12, Double spot = 1820, Double strike = 1850, string asianType = "ArithmeticAverage", Boolean isCall = true, Boolean isFixed = true,
                                         double expectedPv    = 0.03368701153344)
        {
            var valuationDate = DateFromStr(ValuationDate);
            var maturityDate  = DateFromStr("2018-11-01");
            var calendar      = CalendarImpl.Get("chn");
            var obsStartDate  = DateFromStr("2018-10-01");
            var obsDates      = calendar.BizDaysBetweenDatesInclEndDay(obsStartDate, maturityDate).ToArray();

            #region comment
            //var fixings = File.ReadAllLines(@"./Data/HistoricalEquityPrices/hs300.csv")
            //	.Select(x =>
            //	{
            //		var splits = x.Split(',');
            //		return Tuple.Create(new Date(DateTime.Parse(splits[0])), Double.Parse(splits[1]));
            //	}).ToDictionary(x => x.Item1, x => x.Item2);
            //var initialSpot = fixings[startDate];
            //fixings = fixings.Select(x => Tuple.Create(x.Key, x.Value / initialSpot)).Where(x => x.Item1 < startDate).ToDictionary(x => x.Item1, x => x.Item2);
            #endregion comment
            var option = new AsianOption(
                valuationDate,
                maturityDate,
                OptionExercise.European,
                isCall ? OptionType.Call : OptionType.Put,
                ToAsianType(asianType),
                isFixed ? StrikeStyle.Fixed : StrikeStyle.Floating,
                strike,
                InstrumentType.CommodityFutures,
                calendar,
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { maturityDate },
                obsDates,
                new Dictionary <Date, double>(),
                notional: 30000
                );
            var market = TestMarket(referenceDate: ValuationDate, vol: vol, spot: spot);

            var analyticalEngine = new AnalyticalAsianOptionEngine();
            var analyticalResult = analyticalEngine.Calculate(option, market, PricingRequest.All);

            //var engine = new GenericMonteCarloEngine(2, 30000);
            //var result = engine.Calculate(option, market, PricingRequest.All);
            //Console.WriteLine("Analytical: {0},{1},{2},{3},{4},{5}", analyticalResult.Pv, analyticalResult.Delta, analyticalResult.Gamma, analyticalResult.Vega, analyticalResult.Rho, analyticalResult.Theta);
            //Console.WriteLine("Monte Carlo: {0},{1},{2},{3},{4},{5}", result.Pv, result.Delta, result.Gamma, result.Vega, result.Rho, result.Theta);

            Assert.AreEqual(analyticalResult.Pv, expectedPv, 1e-1);
        }
        private void TradeVolLinearInterpSlopeCalc(double tradeOpenVol, double tradeCloseVol, DayCountMode dayCountMode = DayCountMode.TradingDay)
        {
            var    startDate          = new Date(2018, 3, 21);
            var    maturityDate       = new Date(2018, 5, 21);
            var    valuationDate      = new Date[] { new Date(2018, 3, 22), new Date(2018, 3, 23), new Date(2018, 3, 26) };
            var    numOfSmoothingDays = 30;
            var    calendar           = CalendarImpl.Get("chn");
            double vol1 = AnalyticalOptionTradeVolInterp.tradeVolLinearInterp(valuationDate[0], tradeOpenVol, tradeCloseVol, startDate, maturityDate,
                                                                              numOfSmoothingDays, dayCountMode, calendar);
            double vol2 = AnalyticalOptionTradeVolInterp.tradeVolLinearInterp(valuationDate[1], tradeOpenVol, tradeCloseVol, startDate, maturityDate,
                                                                              numOfSmoothingDays, dayCountMode, calendar);
            double vol3 = AnalyticalOptionTradeVolInterp.tradeVolLinearInterp(valuationDate[2], tradeOpenVol, tradeCloseVol, startDate, maturityDate,
                                                                              numOfSmoothingDays, dayCountMode, calendar);

            Assert.AreEqual(vol2 - vol1, vol3 - vol2, 1e-10);
        }
        private void SpreadOptionBjerksundCalc(string spreadType = "TwoAssetsSpread", Boolean isCall = true, string ValuationDate = "2017-12-26", double vol1 = 0.28, double spot1 = 1.0, double vol2 = 0.30, double spot2 = 2.0,
                                               double vol3       = 0.28, double spot3 = 1.0, double vol4 = 0.28, double spot4 = 1.0, double strike = 1.03, double tol = 1e-8)
        {
            var valuationDate = DateFromStr(ValuationDate);
            var maturityDate  = new Term("176D").Next(valuationDate);
            var calendar      = CalendarImpl.Get("chn");

            var asset1 = "asset1";
            var asset2 = "asset2";
            var asset3 = "asset3";
            var asset4 = "asset4";


            var option = new SpreadOption(
                startDate: valuationDate,
                maturityDate: maturityDate,
                exercise: OptionExercise.European,
                optionType: (isCall) ? OptionType.Call : OptionType.Put,
                spreadType: ToSpreadType(spreadType),
                strike: strike,
                weights: new double[] { 1.0, 1.0, 1.0, 1.0 },
                underlyingInstrumentType: InstrumentType.EquityIndex,
                calendar: calendar,
                dayCount: new Act365(),
                payoffCcy: CurrencyCode.CNY,
                settlementCcy: CurrencyCode.CNY,
                exerciseDates: new[] { maturityDate },
                observationDates: new[] { maturityDate },
                underlyingTickers: new[] { asset1, asset2, asset3, asset4 }
                )
            {
                UnderlyingTickers = new string[] { asset1, asset2, asset3, asset4 }
            };


            var market = TestMarket(referenceDate: ValuationDate, vol1: vol1, vol2: vol2, vol3: vol3, vol4: vol4, spot1: spot1, spot2: spot2, spot3: spot3, spot4: spot4,
                                    asset1: asset1, asset2: asset2, asset3: asset3, asset4: asset4);

            var analyticalEngine = new AnalyticalSpreadOptionBjerksundEngine();
            var analyticalResult = analyticalEngine.Calculate(option, market, PricingRequest.All);

            var Engine = new AnalyticalSpreadOptionKirkEngine();
            var Result = Engine.Calculate(option, market, PricingRequest.All);

            Assert.AreEqual(analyticalResult.Pv, Result.Pv, tol);
        }
        private void SpreadOptionGreekCalc(double ExpectedPv, string spreadType = "TwoAssetsSpread", string ValuationDate = "2017-12-26")
        {
            var valuationDate = DateFromStr(ValuationDate);
            var maturityDate  = new Term("176D").Next(valuationDate);
            var calendar      = CalendarImpl.Get("chn");

            var asset1 = "asset1";
            var asset2 = "asset2";
            var asset3 = "asset3";
            var asset4 = "asset4";


            var option = new SpreadOption(
                startDate: valuationDate,
                maturityDate: maturityDate,
                exercise: OptionExercise.European,
                optionType: OptionType.Call,
                spreadType: ToSpreadType(spreadType),
                strike: 1.03,
                weights: new double[] { 1.0, 1.0, 1.0, 1.0 },
                underlyingInstrumentType: InstrumentType.EquityIndex,
                calendar: calendar,
                dayCount: new Act365(),
                payoffCcy: CurrencyCode.CNY,
                settlementCcy: CurrencyCode.CNY,
                exerciseDates: new[] { maturityDate },
                observationDates: new[] { maturityDate },
                underlyingTickers: new[] { asset1, asset2, asset3, asset4 }
                )
            {
                UnderlyingTickers = new string[] { asset1, asset2, asset3, asset4 }
            };


            var market = TestMarket(referenceDate: ValuationDate, asset1: asset1, asset2: asset2, asset3: asset3, asset4: asset4);

            //var analyticalEngine = new AnalyticalSpreadOptionEngine();
            //var analyticalResult = analyticalEngine.Calculate(option, market, PricingRequest.All);

            var Engine = new AnalyticalSpreadOptionKirkEngine();
            var Result = Engine.Calculate(option, market, PricingRequest.All);

            //Assert.AreEqual(ExpectedPv, analyticalResult.Pv, 1e-8);
            Assert.AreEqual(ExpectedPv, Result.Pv, 1e-8);
        }
        private void CommodityLookbackOptionGreekCalc(String ValuationDate = "2015-03-19", Double vol = 0.28, Double spot = 240, Double strike = 240,
                                                      Boolean isCall       = true, Boolean isFixed    = true,
                                                      double expectedPv    = 0.03368701153344,
                                                      double expectedDelta = 0.431553260493781,
                                                      double expectedGamma = 4319.00095926793,
                                                      double expectedVega  = 0.00146247323594882,
                                                      double expectedRho   = -1.62432084616776E-06,
                                                      double expectedTheta = -0.000398443365606245
                                                      )
        {
            var valuationDate = DateFromStr(ValuationDate);
            var maturityDate  = new Term("176D").Next(valuationDate);
            var calendar      = CalendarImpl.Get("chn");
            var obsDates      = new[] { new Date(2015, 4, 2), new Date(2015, 5, 4), new Date(2015, 6, 2), new Date(2015, 7, 2), new Date(2015, 8, 3), new Date(2015, 9, 2) };

            var option = new LookbackOption(
                valuationDate,
                maturityDate,
                OptionExercise.European,
                isCall ? OptionType.Call : OptionType.Put,
                isFixed ? StrikeStyle.Fixed : StrikeStyle.Floating,
                strike,
                InstrumentType.EquityIndex,
                calendar,
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { maturityDate },
                obsDates,
                new Dictionary <Date, double>(),
                notional: 1
                );
            var market = TestMarket(referenceDate: ValuationDate, vol: vol, spot: spot);

            var analyticalEngine = new AnalyticalLookbackOptionEngine();
            var analyticalResult = analyticalEngine.Calculate(option, market, PricingRequest.All);

            Assert.AreEqual(expectedPv, analyticalResult.Pv, 1e-8);
            Assert.AreEqual(expectedDelta, analyticalResult.Delta, 1e-8);
            Assert.AreEqual(expectedGamma, analyticalResult.Gamma, 1e-8);
            Assert.AreEqual(expectedVega, analyticalResult.Vega, 1e-8);
            Assert.AreEqual(expectedRho, analyticalResult.Rho, 1e-8);
            Assert.AreEqual(expectedTheta, analyticalResult.Theta, 1e-8);
        }
示例#23
0
        public void Fr007CurveConstructionTest()
        {
            var historiclIndexRates = HistoricalDataLoadHelper.HistoricalIndexRates;

            var fr007CurveName       = "Swap_Fr007";
            var fr007CurveConvention = new CurveConvention("fr007CurveConvention",
                                                           "CNY",
                                                           "ModifiedFollowing",
                                                           "Chn_ib",
                                                           "Act365",
                                                           "Continuous",
                                                           "CubicHermiteMonotic");
            var rateDefinition = new[]
            {
                new RateMktData("1D", 0.0431, "Fr007", "Deposit", fr007CurveName),
                new RateMktData("7D", 0.053, "Fr007", "Deposit", fr007CurveName),
                new RateMktData("3M", 0.0494, "Fr007", "InterestRateSwap", fr007CurveName),
                new RateMktData("6M", 0.0493, "Fr007", "InterestRateSwap", fr007CurveName),
            };

            var curveDefinition = new[]
            {
                new InstrumentCurveDefinition(fr007CurveName, fr007CurveConvention, rateDefinition, "SpotCurve")
            };

            var marketInfo = new MarketInfo("tmpMarket", "2014-02-10", curveDefinition, historiclIndexRates);
            var temp       = CalendarImpl.Get("chn_ib");

            QdpMarket market = null;

            var time1 = DateTime.Now;

            for (var i = 0; i <= 10; ++i)
            {
                var result = MarketFunctions.BuildMarket(marketInfo, out market);
            }
            var time2 = DateTime.Now;

            Console.WriteLine("{0}ms", (time2 - time1).TotalMilliseconds);
            var fr007Curve = market.GetData <CurveData>(fr007CurveName).YieldCurve;

            Assert.AreEqual(fr007Curve.KeyPoints[0].Item2, 0.0430974555290732, 1e-4);            // use IrsFloatingLegPvReal
            Assert.AreEqual(fr007Curve.KeyPoints[3].Item2, 0.048992349561639, 1e-4);             // use IrsFloatingLegPvReal
        }
示例#24
0
        public static Date GetFxSpotDate(Date startDate,
                                         DayGap settlement,
                                         CurrencyCode fgnCcy,
                                         CurrencyCode domCcy,
                                         ICalendar fgnCalendar,
                                         ICalendar domCalendar)
        {
            //中国外汇交易中心产品指引(外汇市场)V1.8 58页
            var foreignSpotDate  = settlement.Get(fgnCalendar, startDate);
            var domesticSpotDate = settlement.Get(domCalendar, startDate);

            var usdCalendar = CalendarImpl.Get(Calendar.Usd);

            if (fgnCcy == CurrencyCode.USD)
            {
                if (!usdCalendar.IsHoliday(domesticSpotDate))
                {
                    return(domesticSpotDate);
                }
            }

            if (domCcy == CurrencyCode.USD)
            {
                if (!usdCalendar.IsHoliday(foreignSpotDate))
                {
                    return(foreignSpotDate);
                }
            }

            var guessSettlementDate = foreignSpotDate > domesticSpotDate ? foreignSpotDate : domesticSpotDate;

            if (usdCalendar.IsHoliday(guessSettlementDate) || fgnCalendar.IsHoliday(guessSettlementDate) || domCalendar.IsHoliday(guessSettlementDate))
            {
                //find next biz day for foreign currency and domestic currency
                while (fgnCalendar.IsHoliday(guessSettlementDate) || domCalendar.IsHoliday(guessSettlementDate))
                {
                    guessSettlementDate = new Term("1D").Next(guessSettlementDate);
                }
                return(guessSettlementDate);
            }

            return(guessSettlementDate);
        }
示例#25
0
        public void TestAsianOptionPvAgainistHaugerExcel()
        {
            var startDate    = new Date(2015, 03, 19);
            var maturityDate = new Term("183D").Next(startDate);
            var calendar     = CalendarImpl.Get("chn");

            var oneWeek = new Term("7D");
            var dates   = new List <Date>()
            {
                new Date(2015, 03, 20)
            };

            for (int i = 1; i < 27; i++)
            {
                dates.Add(oneWeek.Next(dates[i - 1]));
            }

            var option = new AsianOption(
                startDate,
                maturityDate,
                OptionExercise.European,
                OptionType.Call,
                AsianType.DiscreteArithmeticAverage,
                StrikeStyle.Fixed,
                100,
                InstrumentType.EquityIndex,
                calendar,
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { maturityDate },
                dates.ToArray(),
                new Dictionary <Date, double>()
                );
            var market = TestMarket2();

            var analyticalEngine = new AnalyticalAsianOptionEngineLegacy();
            var result           = analyticalEngine.Calculate(option, market, PricingRequest.All);

            Console.WriteLine("{0},{1},{2},{3},{4}", result.Pv, result.Delta, result.Gamma, result.Vega, result.Rho);
            //Note: originally was 1.9622573116
            Assert.AreEqual(2.91746104388858, result.Pv, 1e-8);
        }
示例#26
0
        private VanillaOption CreateOption(Double strike, Date expiry, Date firstConversionDate, Boolean American = true)
        {
            var americanNoticeDates = CalendarImpl.Get("chn").BizDaysBetweenDates(new Date(2015, 06, 30), new Date(2019, 12, 25)).ToArray();
            var exerciseStyle       = American ? OptionExercise.American : OptionExercise.European;
            var noticeDates         = American ? americanNoticeDates : new Date[] { expiry };

            return(new VanillaOption(firstConversionDate,
                                     expiry,
                                     exerciseStyle,
                                     OptionType.Call,
                                     strike,
                                     InstrumentType.Stock,
                                     CalendarImpl.Get("chn"),
                                     new Act365(),
                                     CurrencyCode.CNY,
                                     CurrencyCode.CNY,
                                     noticeDates,
                                     noticeDates
                                     ));
        }
示例#27
0
        public void TestCallableBond()
        {
            var bond = new Bond(
                "010001",
                new Date(2012, 05, 03),
                new Date(2017, 05, 03),
                100,
                CurrencyCode.CNY,
                new FixedCoupon(0.068),
                CalendarImpl.Get("chn_ib"),
                Frequency.Annual,
                Stub.LongEnd,
                new ActActIsma(),
                new ActAct(),
                BusinessDayConvention.None,
                BusinessDayConvention.ModifiedFollowing,
                null,
                TradingMarket.ChinaInterBank
                );

            var option = new VanillaOption(new Date(2012, 05, 03),
                                           new Date(2017, 05, 03),
                                           OptionExercise.European,
                                           OptionType.Put,
                                           106.8,
                                           InstrumentType.Bond,
                                           CalendarImpl.Get("chn_ib"),
                                           new Act365(),
                                           CurrencyCode.CNY,
                                           CurrencyCode.CNY,
                                           new[] { new Date(2015, 05, 03) },
                                           new[] { new Date(2015, 05, 03) }
                                           );

            var callableBond = new CallableBond(bond, new[] { option }, new[] { PriceQuoteType.Dirty });
            var market       = TestMarket();
            var engine       = new CallableBondEngine <HullWhite>(new HullWhite(0.1, 0.01), true, 40);
            var result       = engine.Calculate(callableBond, market, PricingRequest.All);

            Assert.AreEqual(107.0198942139, result.Pv, 1e-8);
        }
示例#28
0
        private void RainbowOptionGreekCalc(double ExpectedPv, string rainbowType = "Max", string ValuationDate = "2017-12-18", double vol = 0.28, double spot = 1.0, double volNew = 0.30, double spotNew = 2.0,
                                            double strike1 = 1.03, double strike2 = 1.05, Boolean isCall = true)
        {
            var valuationDate = DateFromStr(ValuationDate);
            var maturityDate  = new Term("176D").Next(valuationDate);
            var calendar      = CalendarImpl.Get("chn");

            var asset1 = "asset1";
            var asset2 = "asset2";

            var option = new RainbowOption(
                startDate: valuationDate,
                maturityDate: maturityDate,
                exercise: OptionExercise.European,
                optionType: isCall ? OptionType.Call : OptionType.Put,
                rainbowType: ToRainbowType(rainbowType),
                strikes: new double[] { strike1, strike2 },
                cashAmount: 1.0,
                underlyingInstrumentType: InstrumentType.EquityIndex,
                calendar: calendar,
                dayCount: new Act365(),
                payoffCcy: CurrencyCode.CNY,
                settlementCcy: CurrencyCode.CNY,
                exerciseDates: new[] { maturityDate },
                observationDates: new[] { maturityDate },
                underlyingTickers: new[] { asset1, asset2 }
                )
            {
                UnderlyingTickers = new string[] { asset1, asset2 }
            };

            var market = TestMarket(referenceDate: ValuationDate, vol: vol, volNew: volNew, spot: spot, spotNew: spotNew, asset1: asset1, asset2: asset2);

            var analyticalEngine = new AnalyticalRainbowOptionEngine();
            var analyticalResult = analyticalEngine.Calculate(option, market, PricingRequest.All);

            Assert.AreEqual(ExpectedPv, analyticalResult.Pv, 1e-8);
        }
        private void ResetStrikeOptionGreekCalc(double expectedPv, double expectedDelta, double expectedGamma, double expectedVega, double expectedTheta, double expectedRho,
                                                String ValuationDate = "2017-12-20", Double vol = 0.28, Double spot = 1.0, Double strike = 1.03, Boolean isCall = true, Boolean isPercentage = true)
        {
            var valuationDate    = DateFromStr(ValuationDate);
            var strikefixingDate = new Term("50D").Next(valuationDate);
            var exerciseDate     = new Term("176D").Next(valuationDate);
            var calendar         = CalendarImpl.Get("chn");


            var option = new ResetStrikeOption(
                valuationDate,
                exerciseDate,
                OptionExercise.European,
                isCall ? OptionType.Call : OptionType.Put,
                isPercentage ? ResetStrikeType.PercentagePayoff : ResetStrikeType.NormalPayoff,
                strike,
                InstrumentType.EquityIndex,
                calendar,
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { exerciseDate },
                new[] { exerciseDate },
                strikefixingDate
                );
            var market = TestMarket(referenceDate: ValuationDate, vol: vol, spot: spot);

            var analyticalEngine = new AnalyticalResetStrikeOptionEngine();
            var analyticalResult = analyticalEngine.Calculate(option, market, PricingRequest.All);

            Assert.AreEqual(expectedPv, analyticalResult.Pv, 1e-8);
            Assert.AreEqual(expectedDelta, analyticalResult.Delta, 1e-8);
            Assert.AreEqual(expectedGamma, analyticalResult.Gamma, 1e-8);
            Assert.AreEqual(expectedVega, analyticalResult.Vega, 1e-8);
            Assert.AreEqual(expectedTheta, analyticalResult.Theta, 1e-8);
            Assert.AreEqual(expectedRho, analyticalResult.Rho, 1e-8);
        }
示例#30
0
        public void TestVanillaEuropeanCallMc()
        {
            var startDate    = new Date(2014, 03, 18);
            var maturityDate = new Date(2015, 03, 18);
            var market       = TestMarket();

            var call = new VanillaOption(startDate,
                                         maturityDate,
                                         OptionExercise.European,
                                         OptionType.Call,
                                         1.0,
                                         InstrumentType.Stock,
                                         CalendarImpl.Get("chn"),
                                         new Act365(),
                                         CurrencyCode.CNY,
                                         CurrencyCode.CNY,
                                         new[] { maturityDate },
                                         new[] { maturityDate });

            var mcengine = new GenericMonteCarloEngine(2, 200000);
            var result   = mcengine.Calculate(call, market, PricingRequest.All);

            var analyticalResult = new AnalyticalVanillaEuropeanOptionEngine().Calculate(call, market, PricingRequest.All);

            Console.WriteLine("{0},{1}", analyticalResult.Pv, result.Pv);
            Console.WriteLine("{0},{1}", analyticalResult.Delta, result.Delta);
            Console.WriteLine("{0},{1}", analyticalResult.Gamma, result.Gamma);
            Console.WriteLine("{0},{1}", analyticalResult.Vega, result.Vega);
            Console.WriteLine("{0},{1}", analyticalResult.Rho, result.Rho);
            Console.WriteLine("{0},{1}", analyticalResult.Theta, result.Theta);
            Assert.AreEqual(analyticalResult.Pv, result.Pv, 0.002);
            Assert.AreEqual(analyticalResult.Delta, result.Delta, 0.02);
            Assert.AreEqual(analyticalResult.Gamma, result.Gamma, 0.05);
            Assert.AreEqual(analyticalResult.Theta, result.Theta, 1e-5);
            Assert.AreEqual(analyticalResult.Rho, result.Rho, 1e-6);
            Assert.AreEqual(analyticalResult.Vega, result.Vega, 1e-4);
        }