Esempio n. 1
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);
        }
Esempio n. 2
0
        public void ClnTest()
        {
            var valueDate = new Date(2015, 06, 1);

            var market = new MarketCondition(x => x.ValuationDate.Value = valueDate);

            var fixings = File.ReadAllLines(@"./Data/HistoricalEquityPrices/hsgy.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 cln = new ConstantLeveragedNote(new Date(2015, 5, 28),
                                                new Date(2018, 10, 29),
                                                1000,
                                                3.0,
                                                0.055,
                                                fixings,
                                                new Dictionary <Date, double>()
            {
                { new Date(2015, 05, 28), 0.8002 },
                { new Date(2015, 06, 01), 0.8 }
            }
                                                );
            var engine = new ConstantLeveragedNoteEngine();
            var result = engine.Calculate(cln, market, PricingRequest.All);

            Assert.AreEqual(result.Pv / cln.Notional, 1.022959, 1e-6);
        }
Esempio n. 3
0
        public double ImpliedVolFromPremium(double targetPremium,
                                            VanillaOption option, MarketCondition market)
        {
            var timeIncrement = AnalyticalOptionPricerUtil.optionTimeToMaturityIncrement(option);
            var calculator    = ConfigureCalculator(option, market, timeIncrement: timeIncrement);

            return(calculator.SolveVol(targetPremium));
        }
        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);
        }
Esempio n. 5
0
        public void TestSwapCurveRepricing()
        {
            var          ReferenceDate = "2017-11-15";
            const string t0MarketName  = "Market2017-11-15";
            var          curveName     = "Fr007SwapCurve";

            //Calibrate curve
            var curveDefinitions = GetTestIrsCurveDefinition(curveName);
            var t0MarketInfo     = new MarketInfo(t0MarketName)
            {
                ReferenceDate         = ReferenceDate,
                YieldCurveDefinitions = curveDefinitions.ToArray(),
                HistoricalIndexRates  = HistoricalDataLoadHelper.HistoricalIndexRates
            };

            XlManager.LoadMarket(t0MarketInfo);
            var market  = XlManager.GetXlMarket(t0MarketName).QdpMarket;
            var tCurves = XlManager.GetXlMarket(t0MarketName).MarketInfo.YieldCurveDefinitions.Select(x => x.Name)
                          .Select(x => market.GetData <CurveData>(x).YieldCurve).ToDictionary(x => x.Name, x => x);
            var curve            = tCurves.First().Value;
            var inputInstruments = curve.MarketInstruments;

            inputInstruments.Select(p => p.TargetValue);

            //Repricing curve building instruments
            //Repricing threshold
            var threshold = 1e-7;

            var expected        = inputInstruments.Select(p => p.TargetValue).ToArray();
            var actual          = new double[inputInstruments.Length];
            var marketCondition = new MarketCondition(
                x => x.ValuationDate.Value        = market.ReferenceDate,
                x => x.DiscountCurve.Value        = market.GetData <CurveData>(curveName).YieldCurve,
                x => x.FixingCurve.Value          = market.GetData <CurveData>(curveName).YieldCurve,
                x => x.RiskfreeCurve.Value        = market.GetData <CurveData>(curveName).YieldCurve,
                x => x.HistoricalIndexRates.Value = new Dictionary <IndexType, SortedDictionary <Date, double> >()
                );

            for (int i = 0; i < inputInstruments.Length; i++)
            {
                actual[i] = inputInstruments[i].Instrument.ModelValue(marketCondition, MktInstrumentCalibMethod.Default);
            }
            var diffReport = expected.Zip(actual, (first, second) => Tuple.Create <double, double, double, bool>(first, second, first - second, Math.Abs(first - second) > threshold));

            foreach (Tuple <double, double, double, bool> diffLine in diffReport)
            {
                Console.WriteLine($"Repricing diff : {diffLine}");
            }
            var breaches = diffReport.Where(x => x.Item4 == true).Count();

            Assert.AreEqual(true, breaches == 0);
        }
Esempio n. 6
0
        public void DlnTest()
        {
            var valueDate = new Date(2015, 06, 16);

            var market = new MarketCondition(x => x.ValuationDate.Value = valueDate);

            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 dln = new DynamicLeveragedNote(new Date(2015, 1, 5),
                                               new Date(2018, 10, 29),
                                               1000,
                                               2.0,
                                               1.75,
                                               2.25,
                                               0.05,
                                               0.004,
                                               fixings
                                               );
            var engine = new DynamicLeveragedNoteEngine();
            var result = engine.Calculate(dln, market, PricingRequest.All);

            Assert.AreEqual(result.Pv / dln.Notional, 1.793219889635, 1e-10);
            Assert.AreEqual(result.Delta / dln.Notional, 3.695695861697, 1e-10);

            var dln2 = new DynamicLeveragedNote(new Date(2015, 1, 5),
                                                new Date(2018, 10, 29),
                                                1000,
                                                1.0,
                                                0.75,
                                                1.25,
                                                0.05,
                                                0.004,
                                                fixings
                                                );

            result = engine.Calculate(dln2, market, PricingRequest.All);
            Assert.AreEqual(result.Pv / dln2.Notional, 1.39084563124, 1e-10);
            Assert.AreEqual(result.Delta / dln2.Notional, 1.39084563124, 1e-10);
        }
        //Takes too long time
        //[TestMethod]
        public void CommodityBinaryEuropeanOptionMcTest()
        {
            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) },
                1.0
                );

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

            // set first point on dividend curve to 0
            //MC pricing
            var dc = ZeroRateCurve(marketCondition.DividendCurves.Value.Values.First());

            marketCondition = marketCondition.UpdateCondition(new UpdateMktConditionPack <Dictionary <string, IYieldCurve> >(x => x.DividendCurves, new Dictionary <string, IYieldCurve> {
                { "", dc }
            }));
            var engine = new GenericMonteCarloEngine(2, 500000);
            var result = engine.Calculate(goldOption, marketCondition, PricingRequest.All);

            //analytical pricing
            var analyticalResult = new AnalyticalBinaryEuropeanOptionEngine().Calculate(goldOption, marketCondition, PricingRequest.All);

            Console.WriteLine("Pv:{0},{1}", analyticalResult.Pv, result.Pv);
            Console.WriteLine("Delta: {0},{1}", analyticalResult.Delta, result.Delta);
            Console.WriteLine("Gamma: {0},{1}", analyticalResult.Gamma, result.Gamma);
            Console.WriteLine("Vega: {0},{1}", analyticalResult.Vega, result.Vega);
            Console.WriteLine("Rho: {0},{1}", analyticalResult.Rho, result.Rho); //TODO binary option monte carlo rho
            Console.WriteLine("Theta: {0},{1}", analyticalResult.Theta, result.Theta);
            //Assert.AreEqual(analyticalResult.Pv, result.Pv, 0.02);
            //Assert.AreEqual(analyticalResult.Delta, result.Delta, 0.02);
            //Assert.AreEqual(analyticalResult.Gamma, result.Gamma, 0.05);
            //Assert.AreEqual(analyticalResult.Vega, result.Vega, 1e-2);
            //Assert.AreEqual(analyticalResult.Rho, result.Rho, 1e-6);
            //Assert.AreEqual(analyticalResult.Theta, result.Theta, 1e-5);
        }
        public void CommodityBinaryOptionGreekTest(double vol, double spot, double strike, Boolean isCall = true, Boolean isCashOrNothing = true,
                                                   string t0 = "2017-12-01", string t1 = "2017-12-02", double volMove = 0.10, double mktMove = 1e-4, double toleranceInPct = 2)
        {
            var T0      = DateFromStr(t0);
            var T1      = DateFromStr(t1);
            var spotNew = spot + spot * mktMove;
            var volNew  = vol + volMove;


            var expiry          = new Date(2017, 12, 17);
            var valuationDay    = t0;
            var valuationDayNew = t1;
            var option          = new BinaryOption(
                T0,
                expiry,
                OptionExercise.European,
                isCall ? OptionType.Call : OptionType.Put,
                strike,
                InstrumentType.CommodityFutures,
                isCashOrNothing ? BinaryOptionPayoffType.CashOrNothing : BinaryOptionPayoffType.AssetOrNothing,
                2,
                CalendarImpl.Get("chn"),
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { expiry },
                new[] { expiry },
                notional: 1
                );


            var curveName     = "Fr007";
            var volName       = "volSurf";
            var diviCurveName = "diviCurve";
            var market        = GetMarketJinTao(valuationDay, rate: 0.04, vol: vol, dividendRate: 0, curveName: curveName, volName: volName, diviCurveName: diviCurveName);
            IMarketCondition marketCondition = new MarketCondition(
                x => x.ValuationDate.Value  = market.ReferenceDate,
                x => x.DiscountCurve.Value  = market.GetData <CurveData>(curveName).YieldCurve,
                x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> {
                { "", market.GetData <CurveData>(diviCurveName).YieldCurve }
            },
                x => x.SpotPrices.Value = new Dictionary <string, double> {
                { "", spot }
            },
                x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> {
                { "", market.GetData <VolSurfMktData>(volName).ToImpliedVolSurface(market.ReferenceDate) }
            }
                );

            var marketNew = GetMarketJinTao(valuationDayNew, rate: 0.04, vol: volNew, dividendRate: 0, curveName: curveName, volName: volName, diviCurveName: diviCurveName);
            IMarketCondition marketConditionNew = new MarketCondition(
                x => x.ValuationDate.Value  = marketNew.ReferenceDate,
                x => x.DiscountCurve.Value  = marketNew.GetData <CurveData>(curveName).YieldCurve,
                x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> {
                { "", marketNew.GetData <CurveData>(diviCurveName).YieldCurve }
            },
                x => x.SpotPrices.Value = new Dictionary <string, double> {
                { "", spotNew }
            },
                x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> {
                { "", marketNew.GetData <VolSurfMktData>(volName).ToImpliedVolSurface(market.ReferenceDate) }
            }
                );


            IMarketCondition marketConditionPI = new MarketCondition(
                x => x.ValuationDate.Value  = market.ReferenceDate,
                x => x.DiscountCurve.Value  = market.GetData <CurveData>(curveName).YieldCurve,
                x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> {
                { "", market.GetData <CurveData>(diviCurveName).YieldCurve }
            },
                x => x.SpotPrices.Value = new Dictionary <string, double> {
                { "", spotNew }
            },
                x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> {
                { "", market.GetData <VolSurfMktData>(volName).ToImpliedVolSurface(market.ReferenceDate) }
            }
                );

            var marketVI = GetMarketJinTao(valuationDay, rate: 0.04, vol: volNew, dividendRate: 0, curveName: curveName, volName: volName, diviCurveName: diviCurveName);
            IMarketCondition marketConditionVI = new MarketCondition(
                x => x.ValuationDate.Value  = marketVI.ReferenceDate,
                x => x.DiscountCurve.Value  = marketVI.GetData <CurveData>(curveName).YieldCurve,
                x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> {
                { "", marketVI.GetData <CurveData>(diviCurveName).YieldCurve }
            },
                x => x.SpotPrices.Value = new Dictionary <string, double> {
                { "", spot }
            },
                x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> {
                { "", marketVI.GetData <VolSurfMktData>(volName).ToImpliedVolSurface(market.ReferenceDate) }
            }
                );

            var marketPVC = GetMarketJinTao(valuationDay, rate: 0.04, vol: volNew, dividendRate: 0, curveName: curveName, volName: volName, diviCurveName: diviCurveName);
            IMarketCondition marketConditionPVC = new MarketCondition(
                x => x.ValuationDate.Value  = marketPVC.ReferenceDate,
                x => x.DiscountCurve.Value  = marketPVC.GetData <CurveData>(curveName).YieldCurve,
                x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> {
                { "", marketPVC.GetData <CurveData>(diviCurveName).YieldCurve }
            },
                x => x.SpotPrices.Value = new Dictionary <string, double> {
                { "", spotNew }
            },
                x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> {
                { "", marketPVC.GetData <VolSurfMktData>(volName).ToImpliedVolSurface(market.ReferenceDate) }
            }
                );

            var engine    = new AnalyticalBinaryEuropeanOptionEngine();
            var result    = engine.Calculate(option, marketCondition, PricingRequest.All);
            var resultNew = engine.Calculate(option, marketConditionNew, PricingRequest.All);
            var resultPI  = engine.Calculate(option, marketConditionPI, PricingRequest.All);
            var resultVI  = engine.Calculate(option, marketConditionVI, PricingRequest.All);
            var resultPVC = engine.Calculate(option, marketConditionPVC, PricingRequest.All);

            var actualPL = resultNew.Pv - result.Pv;

            //price Impact
            //PI = PV(t-1, priceNew) - Pv(t-1)
            var basePv  = result.Pv;
            var PI      = resultPI.Pv - basePv;
            var thetapl = result.Theta * (T1 - T0);

            //vol impact
            //VI = PV(t-1. volNew) - Pv (t-1)
            var VI = resultVI.Pv - basePv;

            //price vol cross impact
            //PVC = PV(t-1. volNew, PriceNew) - Pv (t-1) - (PI+VI)
            var PVC = resultPVC.Pv - basePv - PI - VI;

            var newEstimate    = PI + VI + PVC + thetapl;
            var newUnexplained = actualPL - newEstimate;

            //Time impact
            //TI = PV(t, all OldInfo) - Pv(t-1)

            //TODO:
            //Time/ price cross Impact
            //TPC = PV(t, priceNew) - pv(t-1) - (TI +PI)

            //Time/vol cross impact
            //TVC = PV(t, volNew) - pv(t-1) -(TI+VI)



            //TODO:
            //in case of big move ( vol and spot), we need high order risk to explain pnl
            //var diff = actualPL - esimstatedPL;
            //Assert.AreEqual(true, Math.Abs(diff / actualPL) * 100.0 < toleranceInPct); //pnl well explained in not too extreme moves
            Assert.AreEqual(true, Math.Abs(newUnexplained / actualPL) * 100.0 < toleranceInPct);



            var engine2    = new AnalyticalBinaryEuropeanOptionReplicationEngine(2.0, BinaryOptionReplicationStrategy.Up);
            var result2    = engine2.Calculate(option, marketCondition, PricingRequest.All);
            var resultNew2 = engine2.Calculate(option, marketConditionNew, PricingRequest.All);
            var resultPI2  = engine2.Calculate(option, marketConditionPI, PricingRequest.All);
            var resultVI2  = engine2.Calculate(option, marketConditionVI, PricingRequest.All);
            var resultPVC2 = engine2.Calculate(option, marketConditionPVC, PricingRequest.All);

            var actualPL2 = resultNew2.Pv - result2.Pv;

            //price Impact
            //PI = PV(t-1, priceNew) - Pv(t-1)
            var basePv2  = result2.Pv;
            var PI2      = resultPI2.Pv - basePv2;
            var thetapl2 = result2.Theta * (T1 - T0);

            //vol impact
            //VI = PV(t-1. volNew) - Pv (t-1)
            var VI2 = resultVI2.Pv - basePv2;

            //price vol cross impact
            //PVC = PV(t-1. volNew, PriceNew) - Pv (t-1) - (PI+VI)
            var PVC2 = resultPVC2.Pv - basePv2 - PI2 - VI2;

            var newEstimate2    = PI2 + VI2 + PVC2 + thetapl2;
            var newUnexplained2 = actualPL2 - newEstimate2;



            Assert.AreEqual(true, Math.Abs(newUnexplained2 / actualPL2) * 100.0 < toleranceInPct);
        }
        public void CommodityBinaryAmericanOptionTest()
        {
            var strike       = 3100.0;
            var spot         = 2900;
            var expiry       = new Date(2018, 04, 16);
            var valuationDay = "2018-03-28";
            var option       = new BinaryOption(
                new Date(2018, 03, 28),
                expiry,
                OptionExercise.European,
                OptionType.Call,
                strike,
                InstrumentType.CommodityFutures,
                BinaryOptionPayoffType.CashOrNothing,
                2,
                CalendarImpl.Get("chn"),
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { expiry },
                new[] { expiry },
                notional: 1000
                );

            var option2 = new BinaryOption(
                new Date(2018, 03, 28),
                expiry,
                OptionExercise.European,
                OptionType.Call,
                strike,
                InstrumentType.CommodityFutures,
                BinaryOptionPayoffType.CashOrNothing,
                2,
                CalendarImpl.Get("chn"),
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { expiry },
                new[] { expiry },
                notional: 1000,
                binaryRebateType: BinaryRebateType.AtEnd
                );



            var curveName     = "Fr007";
            var volName       = "volSurf";
            var diviCurveName = "diviCurve";
            var market        = GetMarketJinTao(valuationDay, rate: 0.05, vol: 0.3, dividendRate: 0, curveName: curveName, volName: volName, diviCurveName: diviCurveName);
            var volsurf       = market.GetData <VolSurfMktData>(volName).ToImpliedVolSurface(market.ReferenceDate);
            IMarketCondition marketCondition = new MarketCondition(
                x => x.ValuationDate.Value  = market.ReferenceDate,
                x => x.DiscountCurve.Value  = market.GetData <CurveData>(curveName).YieldCurve,
                x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> {
                { "", market.GetData <CurveData>(diviCurveName).YieldCurve }
            },
                x => x.SpotPrices.Value = new Dictionary <string, double> {
                { "", spot }
            },
                x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> {
                { "", volsurf }
            }
                );

            var engine  = new AnalyticalBinaryAmericanOptionEngine();
            var result  = engine.Calculate(option, marketCondition, PricingRequest.All);
            var result3 = engine.Calculate(option2, marketCondition, PricingRequest.All);

            Assert.AreEqual(result.Pv != result3.Pv, true);
            Assert.AreEqual(637.071254168821, result.Pv, 1e-8);
            Assert.AreEqual(4.94251151619665, result.Delta, 1e-8);
            Assert.AreEqual(0.0237525887314405, result.Gamma, 1e-8);
            Assert.AreEqual(31.1432441274033, result.Vega, 1e-8);
            Assert.AreEqual(-25.2234472794418, result.Theta, 1e-8);
            Assert.AreEqual(-0.00171280700558327, result.Rho, 1e-8);

            var engine2 = new AnalyticalBinaryEuropeanOptionEngine();
            var result2 = engine2.Calculate(option, marketCondition, PricingRequest.All);

            Assert.AreEqual(result.Pv >= result2.Pv, true);
            Assert.AreEqual(result.Delta >= result2.Delta, true);
            Assert.AreEqual(result.Gamma >= result2.Gamma, true);
            Assert.AreEqual(result.Vega >= result2.Vega, true);
            Assert.AreEqual(Math.Abs(result.Theta) >= Math.Abs(result2.Theta), true);
        }
Esempio n. 10
0
        public void BondForwardTest()
        {
            var bond = new Bond(
                "010000",
                new Date(2013, 2, 25),
                new Date(2015, 2, 25),
                100,
                CurrencyCode.CNY,
                new FixedCoupon(0.0375),
                CalendarImpl.Get("chn_ib"),
                Frequency.SemiAnnual,
                Stub.LongEnd,
                new ActActIsma(),
                new Act365(),
                BusinessDayConvention.None,
                BusinessDayConvention.None,
                null,
                TradingMarket.ChinaInterBank
                );
            var bondForward = new Forward <Bond>(
                new Date(2013, 5, 28),
                new Date(2013, 8, 28),
                100.0,
                98.57947065,
                bond,
                CurrencyCode.CNY
                );

            var referenceDate = new Date(2013, 8, 23);
            var yieldCurve    = new YieldCurve(
                "中债国债收收益率曲线",
                referenceDate,
                new[]
            {
                Tuple.Create((ITerm) new Term("1D"), 0.035),
                Tuple.Create((ITerm) new Term("1Y"), 0.035)
            },
                BusinessDayConvention.ModifiedFollowing,
                new Act365(),
                CalendarImpl.Get("chn_ib"),
                CurrencyCode.CNY,
                Compound.Simple,
                Interpolation.CubicHermiteMonotic,
                YieldCurveTrait.SpotCurve
                );

            var market = new MarketCondition
                         (
                x => x.ValuationDate.Value = referenceDate,
                x => x.MktQuote.Value      = new Dictionary <string, Tuple <PriceQuoteType, double> > {
                { "010000", Tuple.Create(PriceQuoteType.Dirty, 99.71798177) }
            },
                x => x.DiscountCurve.Value           = yieldCurve,
                x => x.FixingCurve.Value             = yieldCurve,
                x => x.RiskfreeCurve.Value           = yieldCurve,
                x => x.UnderlyingDiscountCurve.Value = yieldCurve,
                x => x.HistoricalIndexRates.Value    = new Dictionary <IndexType, SortedDictionary <Date, double> >()
                         );

            var bondengine = new BondEngine();
            var zeroSpread = bondengine.Calculate(bond, market, PricingRequest.ZeroSpread).ZeroSpread;
            var engine     = new ForwardEngine <Bond>();
            var result     = engine.Calculate(bondForward, market, PricingRequest.Pv);

            Assert.AreEqual(-0.68888788, result.Pv, 1e-8);
        }
Esempio n. 11
0
        public static object BondEngineCalc(string bondId, string calcDate, PriceQuoteType priceQuote, double quote, PricingRequest request, FixedRateBondInfo fixedBond = null)
        {
            var bond = fixedBond ?? XlManager.GetTrade(bondId);

            if (bond == null)
            {
                return(string.Format("Cannot find bond {0}.", bondId));
            }

            var vf             = new BondVf((BondInfoBase)bond);
            var bondInstrument = vf.GenerateInstrument();

            var valueDate   = calcDate.ToDate();
            var fixingCurve = new YieldCurve(
                "中债国债收收益率曲线",
                valueDate,
                new[]
            {
                new Tuple <Date, double>(valueDate, 0.0),
                new Tuple <Date, double>(new Term("10Y").Next(valueDate), 0.0)
            },
                BusinessDayConvention.ModifiedFollowing,
                new Act365(),
                CalendarImpl.Get("Chn_ib"),
                CurrencyCode.CNY,
                Compound.Continuous,
                Interpolation.ForwardFlat,
                YieldCurveTrait.ForwardCurve
                );
            var market = new MarketCondition(
                x => x.ValuationDate.Value = valueDate,
                x => x.FixingCurve.Value   = fixingCurve,
                x =>
                x.MktQuote.Value =
                    new Dictionary <string, Tuple <PriceQuoteType, double> > {
                { bondId, Tuple.Create(priceQuote, quote) }
            },
                x => x.HistoricalIndexRates.Value = HistoricalIndexRates
                );

            if (bond is FloatingRateBondInfo)
            {
                var fixingTuple = bondInstrument.Coupon.GetPrimeCoupon(HistoricalIndexRates, fixingCurve, valueDate);
                var keyTenors   = new string[fixingCurve.GetKeyTenors().Length];
                fixingCurve.GetKeyTenors().CopyTo(keyTenors, 0);
                for (var i = 0; i < keyTenors.Length; ++i)
                {
                    market = (MarketCondition)market.UpdateCondition(new UpdateMktConditionPack <IYieldCurve>(x => x.FixingCurve, market.FixingCurve.Value.BumpKeyRate(i, fixingTuple.Item2)));
                }
                if (request.Equals(PricingRequest.None))
                {
                    return(fixingTuple);
                }
            }

            var engine = vf.GenerateEngine();
            var result = engine.Calculate(bondInstrument, market, request);

            if (!result.Succeeded)
            {
                return(string.Format("Failed to Calculate bond {0}:{1}", bondId, result.ErrorMessage));
            }

            return(result);
        }
Esempio n. 12
0
        public void BasicVanillaOptionTest()
        {
            var startDate    = new Date(2014, 03, 18);
            var maturityDate = new Date(2015, 03, 18);
            var valueDate    = new Date(2014, 03, 18);

            #region Prepare Market
            // build discount curve and dividend curve
            var fr007CurveName      = "Fr007";
            var fr007RateDefinition = new[]
            {
                new RateMktData("1D", 0.06, "Spot", "None", fr007CurveName),
                new RateMktData("5Y", 0.06, "Spot", "None", fr007CurveName),
            };

            var dividendCurveName      = "Dividend";
            var dividendRateDefinition = new[]
            {
                new RateMktData("1D", 0.03, "Spot", "None", dividendCurveName),
                new RateMktData("5Y", 0.03, "Spot", "None", dividendCurveName),
            };

            var discountCurve = new YieldCurve(
                name: fr007CurveName,
                referenceDate: valueDate,
                keyPoints: fr007RateDefinition.Select(x => Tuple.Create((ITerm) new Term(x.Tenor), x.Rate)).ToArray(),
                bda: BusinessDayConvention.ModifiedFollowing,
                dayCount: new Act365(),
                calendar: CalendarImpl.Get("Chn"),
                currency: CurrencyCode.CNY,
                compound: Compound.Continuous,
                interpolation: Interpolation.CubicHermiteMonotic,
                trait: YieldCurveTrait.SpotCurve);

            var dividendCurve = new YieldCurve(
                name: dividendCurveName,
                referenceDate: valueDate,
                keyPoints: dividendRateDefinition.Select(x => Tuple.Create((ITerm) new Term(x.Tenor), x.Rate)).ToArray(),
                bda: BusinessDayConvention.ModifiedFollowing,
                dayCount: new Act365(),
                calendar: CalendarImpl.Get("Chn"),
                currency: CurrencyCode.CNY,
                compound: Compound.Continuous,
                interpolation: Interpolation.CubicHermiteMonotic,
                trait: YieldCurveTrait.SpotCurve);


            // build vol surface
            var volSurfData = new VolSurfMktData("VolSurf", 0.25);
            var volSurface  = volSurfData.ToImpliedVolSurface(
                valuationDate: valueDate,
                dc: "Act365");

            // construct market
            var market = new MarketCondition(
                x => x.ValuationDate.Value  = valueDate,
                x => x.DiscountCurve.Value  = discountCurve,
                x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> {
                { "", dividendCurve }
            },
                x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> {
                { "", volSurface }
            },
                x => x.SpotPrices.Value = new Dictionary <string, double> {
                { "", 1.0 }
            }
                );

            #endregion

            // construct a put option
            var put = new VanillaOption(startDate,
                                        maturityDate,
                                        OptionExercise.European,
                                        OptionType.Put,
                                        1.0,
                                        InstrumentType.Stock,
                                        CalendarImpl.Get("chn"),
                                        new Act365(),
                                        CurrencyCode.CNY,
                                        CurrencyCode.CNY,
                                        new[] { maturityDate },
                                        new[] { maturityDate });

            var engine = new AnalyticalVanillaEuropeanOptionEngine();

            var result = engine.Calculate(put, market, PricingRequest.All);
        }
Esempio n. 13
0
        public void MoneynessDeltaTest()
        {
            var startDate    = new Date(2018, 03, 02);
            var maturityDate = new Date(2018, 04, 27);

            var call = new VanillaOption(startDate,
                                         maturityDate,
                                         OptionExercise.American,
                                         OptionType.Call,
                                         1.05,
                                         InstrumentType.Stock,
                                         CalendarImpl.Get("chn"),
                                         new Act365(),
                                         CurrencyCode.CNY,
                                         CurrencyCode.CNY,
                                         new[] { maturityDate },
                                         new[] { maturityDate },
                                         12,
                                         null,
                                         null,
                                         0,
                                         true,
                                         8000);

            #region construct market
            var historiclIndexRates = HistoricalDataLoadHelper.HistoricalIndexRates;
            var curveConvention     = new CurveConvention("fr007CurveConvention",
                                                          "CNY",
                                                          "ModifiedFollowing",
                                                          "Chn",
                                                          "Act365",
                                                          "Continuous",
                                                          "CubicHermiteMonotic");

            var fr007CurveName      = "Fr007";
            var fr007RateDefinition = new[]
            {
                new RateMktData("1D", 0.05, "Spot", "None", fr007CurveName),
                new RateMktData("5Y", 0.05, "Spot", "None", fr007CurveName),
            };

            var dividendCurveName      = "Dividend";
            var dividendRateDefinition = new[]
            {
                new RateMktData("1D", 0, "Spot", "None", dividendCurveName),
                new RateMktData("5Y", 0, "Spot", "None", dividendCurveName),
            };

            var curveDefinition = new[]
            {
                new InstrumentCurveDefinition(fr007CurveName, curveConvention, fr007RateDefinition, "SpotCurve"),
                new InstrumentCurveDefinition(dividendCurveName, curveConvention, dividendRateDefinition, "SpotCurve"),
            };

            var       volSurf    = new[] { new VolSurfMktData("VolSurf", 0.3), };
            var       marketInfo = new MarketInfo("tmpMarket", "2018-03-02", curveDefinition, historiclIndexRates, null, null, volSurf);
            QdpMarket qdpMarket;
            MarketFunctions.BuildMarket(marketInfo, out qdpMarket);

            var valuationDate = new Date(2018, 3, 2);

            //flat vol surface

            var surface1 = qdpMarket.GetData <VolSurfMktData>("VolSurf").ToImpliedVolSurface(valuationDate);
            // market with flat vol surface
            var market = new MarketCondition(
                x => x.ValuationDate.Value  = valuationDate,
                x => x.DiscountCurve.Value  = qdpMarket.GetData <CurveData>("Fr007").YieldCurve,
                x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> {
                { "", qdpMarket.GetData <CurveData>("Dividend").YieldCurve }
            },
                x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> {
                { "", surface1 }
            },
                x => x.SpotPrices.Value = new Dictionary <string, double> {
                { "", 8000 }
            }
                );

            //a real vol surface, same as stock 600000 of 2018-03-02 in OTC system
            var maturities = new Date[]
            {
                (new Term("1W")).Next(startDate),
                (new Term("2W")).Next(startDate),
                (new Term("1M")).Next(startDate)
            };

            var strikes = new double[]
            {
                0.9,
                0.95,
                1.0,
                1.05,
                1.1
            };

            var vols = new double[3, 5];
            for (var i = 0; i < vols.GetLength(0); ++i)
            {
                for (var j = 0; j < vols.GetLength(1); ++j)
                {
                    vols[i, j] = 0.3;
                }
            }

            vols[2, 2] = 0.4;


            var surface2 = new ImpliedVolSurface(valuationDate, maturities, strikes, vols, Interpolation2D.BiLinear);
            // market with flat vol surface
            var market2 = new MarketCondition(
                x => x.ValuationDate.Value  = valuationDate,
                x => x.DiscountCurve.Value  = qdpMarket.GetData <CurveData>("Fr007").YieldCurve,
                x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> {
                { "", qdpMarket.GetData <CurveData>("Dividend").YieldCurve }
            },
                x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> {
                { "", surface2 }
            },
                x => x.SpotPrices.Value = new Dictionary <string, double> {
                { "", 8000 }
            }
                );
            #endregion

            var engine = new AnalyticalVanillaEuropeanOptionEngine();

            //result of a flat vol surface of 0.3, which is the same as pricing result in OTC-926
            var result = engine.Calculate(call, market, PricingRequest.All);

            //result of real vol surface, which is the same as scenario analysis in OTC-926
            var result2 = engine.Calculate(call, market2, PricingRequest.All);
        }
Esempio n. 14
0
        /// <summary>
        /// for Option version only
        /// </summary>
        /// <param name="prebuiltMarket"></param>
        /// <param name="curveDate"></param>
        /// <param name="curveDefinition"></param>
        /// <returns></returns>
        public static YieldCurve BuildYieldCurve(PrebuiltQdpMarket prebuiltMarket, Date curveDate, InstrumentCurveDefinition curveDefinition)
        {
            IMarketCondition baseMarket;

            baseMarket = new MarketCondition(x => x.ValuationDate.Value = prebuiltMarket.ReferenceDate,
                                             x => x.HistoricalIndexRates.Value = prebuiltMarket.HistoricalIndexRates);

            YieldCurve instrumentCurve = null;

            if (curveDefinition.RateDefinitions.All(
                    x => x.InstrumentType.ToInstrumentType() == InstrumentType.Dummy || x.InstrumentType.ToInstrumentType() == InstrumentType.None))
            {
                if (curveDefinition.RateDefinitions.All(x => x.IsTerm()))
                {
                    instrumentCurve = new YieldCurve(
                        curveDefinition.Name,
                        curveDate,
                        curveDefinition.RateDefinitions.Select(x => Tuple.Create((ITerm) new Term(x.Tenor), x.Rate)).ToArray(),
                        curveDefinition.CurveConvention.BusinessDayConvention.ToBda(),
                        curveDefinition.CurveConvention.DayCount.ToDayCountImpl(),
                        curveDefinition.CurveConvention.Calendar.ToCalendarImpl(),
                        curveDefinition.CurveConvention.Currency.ToCurrencyCode(),
                        curveDefinition.CurveConvention.Compound.ToCompound(),
                        curveDefinition.CurveConvention.Interpolation.ToInterpolation(),
                        curveDefinition.Trait.ToYieldCurveTrait(),
                        null,
                        null,
                        null,
                        null,
                        curveDefinition
                        );
                }
                else
                {
                    instrumentCurve = new YieldCurve(
                        curveDefinition.Name,
                        curveDate,
                        curveDefinition.RateDefinitions.Select(x => Tuple.Create(new Date(DateTime.Parse(x.Tenor)), x.Rate)).ToArray(),
                        curveDefinition.CurveConvention.BusinessDayConvention.ToBda(),
                        curveDefinition.CurveConvention.DayCount.ToDayCountImpl(),
                        curveDefinition.CurveConvention.Calendar.ToCalendarImpl(),
                        curveDefinition.CurveConvention.Currency.ToCurrencyCode(),
                        curveDefinition.CurveConvention.Compound.ToCompound(),
                        curveDefinition.CurveConvention.Interpolation.ToInterpolation(),
                        curveDefinition.Trait.ToYieldCurveTrait(),
                        null,
                        null,
                        null,
                        null,
                        curveDefinition
                        );
                }
            }
            else
            {
                var mktInstruments = new List <MarketInstrument>();
                foreach (var rateDefinition in curveDefinition.RateDefinitions)
                {
                    MktInstrumentCalibMethod calibrationMethod;
                    if (rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.InterestRateSwap)
                    {
                        var swap = CurveBuildHelper.CreateIrsInstrument(curveDate, rateDefinition, out calibrationMethod);
                        mktInstruments.Add(new MarketInstrument(swap, rateDefinition.Rate, calibrationMethod));
                    }
                    else if (rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.Deposit ||
                             rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.Repo ||
                             rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.Ibor)
                    {
                        var deposit = CurveBuildHelper.CreateDepositInstrument(curveDate, rateDefinition, out calibrationMethod);
                        mktInstruments.Add(new MarketInstrument(deposit, rateDefinition.Rate, calibrationMethod));
                    }
                    else if (rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.Dummy ||
                             rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.None)
                    {
                        var dummy = CurveBuildHelper.CreateDummyInstrument(curveDate, rateDefinition);
                        mktInstruments.Add(new MarketInstrument(dummy, rateDefinition.Rate, MktInstrumentCalibMethod.Default));
                    }
                    else if (rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.CreditDefaultSwap)
                    {
                        var cds = CurveBuildHelper.CreateCreditDefaultSwap(curveDate, rateDefinition);
                        mktInstruments.Add(new MarketInstrument(cds, rateDefinition.Rate, MktInstrumentCalibMethod.Default));
                    }
                    else if (rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.CommodityForward)
                    {
                        mktInstruments.Add(new MarketInstrument(CurveBuildHelper.CreateCommodityForward(curveDate, rateDefinition), rateDefinition.Rate, MktInstrumentCalibMethod.Default));
                    }
                    else if (rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.CommoditySpot)
                    {
                        //baseMarket = baseMarket.UpdateCondition(new UpdateMktConditionPack<double>(x => x.SpotPrice, rateDefinition.Rate));
                    }
                    else if (rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.FxSpot)
                    {
                    }
                    else
                    {
                        throw new PricingLibraryException("Unrecognized product type in calibrating curve.");
                    }
                }

                var isSpcCurve        = curveDefinition.RateDefinitions.All(x => x.IndexType != null && x.IndexType.ToIndexType() == IndexType.Spc);
                var isConvenicenYield = curveDefinition.RateDefinitions.All(x => x.IndexType != null && x.IndexType.ToIndexType() == IndexType.ConvenienceYield);


                //Expression<Func<IMarketCondition, object>>[] expression = null;
                //if (isSpcCurve) expression = new Expression<Func<IMarketCondition, object>>[] { x => x.SurvivalProbabilityCurve };
                //if (isConvenicenYield) expression = new Expression<Func<IMarketCondition, object>>[] { x => x.DividendCurve };

                instrumentCurve = new YieldCurve(
                    curveDefinition.Name,
                    curveDate,
                    mktInstruments.ToArray(),
                    curveDefinition.CurveConvention.BusinessDayConvention.ToBda(),
                    curveDefinition.CurveConvention.DayCount.ToDayCountImpl(),
                    curveDefinition.CurveConvention.Calendar.ToCalendarImpl(),
                    curveDefinition.CurveConvention.Currency.ToCurrencyCode(),
                    curveDefinition.CurveConvention.Compound.ToCompound(),
                    curveDefinition.CurveConvention.Interpolation.ToInterpolation(),
                    curveDefinition.Trait.ToYieldCurveTrait(),
                    baseMarket,
                    null,
                    null,
                    null,
                    null,
                    curveDefinition);
            }
            return(instrumentCurve);
        }
Esempio n. 15
0
        /// <summary>
        /// Calibrate implied bs vol from spot premium of an european option
        /// </summary>
        /// <param name="premium"></param>
        /// <param name="isCall"></param>
        /// <param name="strike"></param>
        /// <param name="spot"></param>
        /// <param name="rate"></param>
        /// <param name="expiryDateStr"></param>
        /// <param name="valuationDateStr"></param>
        /// <param name="underlyingInstrumentType"></param>
        /// <param name="calendarStr"></param>
        /// <param name="dayCountStr"></param>
        /// <param name="commodityFuturesPreciseTimeMode"></param>
        /// <param name="hasNightMarket"></param>
        /// <returns>if succeed then return implied vol, if falied then return error message</returns>
        public static double xl_ImpliedVolFromPremium(double premium, bool isCall, double strike, double spot, double rate,
                                                      string expiryDateStr, string valuationDateStr, string underlyingInstrumentType, string calendarStr, string dayCountStr,
                                                      bool commodityFuturesPreciseTimeMode = false,
                                                      bool hasNightMarket = false)
        {
            var bsEngine       = new AnalyticalVanillaEuropeanOptionEngine();
            var expiryDate     = expiryDateStr.ToDate();
            var valuationDate  = valuationDateStr.ToDate();
            var instrumentType = underlyingInstrumentType.ToInstrumentType();
            var calendar       = calendarStr.ToCalendarImpl();
            var dayCount       = dayCountStr.ToDayCountImpl();

            var trade = new VanillaOption(
                valuationDate,
                expiryDate,
                OptionExercise.European,
                isCall ? OptionType.Call : OptionType.Put,
                strike,
                instrumentType,
                calendar,
                dayCount,
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { expiryDate },
                new[] { expiryDate },
                notional: 1,
                hasNightMarket: hasNightMarket,
                commodityFuturesPreciseTimeMode: commodityFuturesPreciseTimeMode
                );

            var curve = new YieldCurve(
                "riskFreeRate",
                valuationDate,
                new[]
            {
                Tuple.Create((ITerm) new Term("1D"), rate),
                Tuple.Create((ITerm) new Term("1Y"), rate)
            },
                BusinessDayConvention.ModifiedFollowing,
                dayCount,
                calendar,
                CurrencyCode.CNY,
                Compound.Continuous,
                Interpolation.CubicHermiteMonotic,
                YieldCurveTrait.SpotCurve
                );
            var volSurf = new VolSurfMktData("VolSurf", 0.1).ToImpliedVolSurface(valuationDate);
            var market  = new MarketCondition(
                x => x.ValuationDate.Value  = valuationDate,
                x => x.DiscountCurve.Value  = curve,
                x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> {
                { "", curve }
            },                                                                                          //not used by futures option
                x => x.FixingCurve.Value   = curve,
                x => x.RiskfreeCurve.Value = curve,
                x => x.SpotPrices.Value    = new Dictionary <string, double> {
                { "", spot }
            },
                x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> {
                { "", volSurf }
            });                                                                                         //not used by this calibration

            return(bsEngine.ImpliedVolFromPremium(targetPremium: premium, option: trade, market: market));
        }
Esempio n. 16
0
        public void CommodityJinTaoBinaryEuropeanOptionTest()
        {
            var strike       = 3100.0;
            var spot         = 2900;
            var expiry       = new Date(2017, 12, 17);
            var valuationDay = "2017-12-01";
            var option       = new BinaryOption(
                new Date(2017, 12, 1),
                expiry,
                OptionExercise.European,
                OptionType.Call,
                strike,
                InstrumentType.CommodityFutures,
                BinaryOptionPayoffType.CashOrNothing,
                2,
                CalendarImpl.Get("chn"),
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { expiry },
                new[] { expiry },
                notional: 1
                );

            var optionInfo = new BinaryOptionInfo(
                tradeId: "",
                valuationParameter: new OptionValuationParameters("Fr007", "diviCurve", "volSurf", "000300.SH"),
                underlyingTicker: "000300.SH",
                strike: strike,
                underlyingInstrumentType: "CommodityFutures",
                optionType: "Call",
                notional: 1,
                startDate: "2017-12-01",
                exerciseDates: "2017-12-17"
                )
            {
                CashOrNothingAmount             = 2,
                BinaryOptionPayoffType          = "CashOrNothing",
                BinaryOptionReplicationStrategy = "Down",
                ReplicationShiftSize            = 2,
            };



            var curveName     = "Fr007";
            var volName       = "volSurf";
            var diviCurveName = "diviCurve";
            var market        = GetMarketJinTao(valuationDay, rate: 0.04, vol: 0.4, dividendRate: 0, curveName: curveName, volName: volName, diviCurveName: diviCurveName, spot: spot);
            var volsurf       = market.GetData <VolSurfMktData>(volName).ToImpliedVolSurface(market.ReferenceDate);
            IMarketCondition marketCondition = new MarketCondition(
                x => x.ValuationDate.Value  = market.ReferenceDate,
                x => x.DiscountCurve.Value  = market.GetData <CurveData>(curveName).YieldCurve,
                x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> {
                { "", market.GetData <CurveData>(diviCurveName).YieldCurve }
            },
                x => x.SpotPrices.Value = new Dictionary <string, double> {
                { "", spot }
            },
                x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> {
                { "", volsurf }
            }
                );

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

            Assert.AreEqual(0.401208951727572, result.Pv, 1e-8);
            Assert.AreEqual(0.00230806033816866, result.Delta, 1e-8);
            Assert.AreEqual(7.16979364767667E-06, result.Gamma, 1e-8);
            Assert.AreEqual(0.0105751548032081, result.Vega, 1e-8);
            Assert.AreEqual(-0.0149236357909549, result.Theta, 1e-8);
            Assert.AreEqual(-1.75872031726865E-06, result.Rho, 1e-8);



            var engine2 = new AnalyticalBinaryEuropeanOptionReplicationEngine(2.0, BinaryOptionReplicationStrategy.Down);
            var result2 = engine2.Calculate(option, marketCondition, PricingRequest.All);

            Assert.AreEqual(0.403373182249897, result2.Pv, 1e-7);
            Assert.AreEqual(0.00231550673674974, result2.Delta, 1e-7);
            Assert.AreEqual(7.16340764483903E-06, result2.Gamma, 1e-7);
            Assert.AreEqual(0.0105550810113932, result2.Vega, 1e-7);
            Assert.AreEqual(-0.0149004654797067, result2.Theta, 1e-7);
            Assert.AreEqual(-1.74927811613657E-06, result2.Rho, 1e-7);

            var vfResult = new BinaryOptionVf(optionInfo).ValueTrade(market, PricingRequest.Pv);

            Assert.AreEqual(vfResult.Pv, result2.Pv, 1e-7);
            Assert.AreEqual(result2.Pv > result.Pv, true);
        }
Esempio n. 17
0
        public void testBondCurve1()
        {
            var bondIds   = new[] { "1", "2", "3", "4", "5" };
            var maturitys = new[] { "2017-10-28", "2018-10-28", "2019-10-28", "2020-10-28", "2021-10-28" };
            var coupons   = new[] { 0.0367, 0.0378, 0.04, 0.039, 0.041 };
            var yields    = new[] { 0.04, 0.041, 0.0415, 0.0425, 0.044 };

            var bondInfos = bondIds.Select((x, i) =>

                                           new FixedRateBondInfo(bondIds[i])
            {
                StartDate          = "2016-10-28",
                MaturityDate       = maturitys[i],
                Notional           = 100.0,
                Currency           = "CNY",
                FixedCoupon        = coupons[i],
                Calendar           = "chn_ib",
                PaymentFreq        = "SemiAnnual",
                PaymentStub        = "LongEnd",
                AccrualDC          = "ActActIsma",
                DayCount           = "ActActIsma",
                AccrualBD          = "None",
                PaymentBD          = "None",
                TradingMarket      = "ChinaInterBank",
                Settlement         = "+0D",
                ValuationParamters = new SimpleCfValuationParameters("Fr007", null, "Fr007")
            }
                                           ).ToArray();

            var bonds             = bondInfos.Select(x => new BondVf(x).GenerateInstrument()).ToArray();
            var marketInstrumetns =
                bonds.Select((x, i) => new MarketInstrument(bonds[i], yields[i], MktInstrumentCalibMethod.Default)).ToArray();

            var referenceDate = new Date(2017, 03, 23);
            var yieldCurve    = new YieldCurve(
                "中债国债收收益率曲线",
                referenceDate,
                marketInstrumetns.ToArray(),
                BusinessDayConvention.ModifiedFollowing,
                new Act365(),
                CalendarImpl.Get("chn_ib"),
                CurrencyCode.CNY,
                Compound.Continuous,
                Interpolation.ExponentialSpline,
                YieldCurveTrait.DiscountCurve,
                null,
                null,
                null,
                maturitys.Select(x => x.ToDate()).ToArray());

            var term = new Term("1D");

            var targetSpotRates = new[]
            {
                0.0395360864,
                0.0405725835,
                0.0410856649,
                0.0420840373,
                0.0436655798,
            };

            Console.WriteLine("Fitting error is {0}", yieldCurve.fittingError);



            for (var i = 0; i < yieldCurve.KeyPoints.Length; ++i)
            {
                Console.WriteLine("{0},{1},{2},{3}", yieldCurve.KeyPoints[i].Item1, yieldCurve.GetDf(yieldCurve.KeyPoints[i].Item1), yieldCurve.GetSpotRate(yieldCurve.KeyPoints[i].Item1), yieldCurve.ZeroRate(referenceDate, yieldCurve.KeyPoints[i].Item1));
                if (i > 3)
                {
                    Assert.AreEqual(yieldCurve.GetSpotRate(yieldCurve.KeyPoints[i].Item1), targetSpotRates[i - 4], 1e-10);
                }
            }

            Console.WriteLine();
            var baseMarket = new MarketCondition(
                x => x.ValuationDate.Value        = referenceDate,
                x => x.DiscountCurve.Value        = null,
                x => x.FixingCurve.Value          = null,
                x => x.HistoricalIndexRates.Value = new Dictionary <IndexType, SortedDictionary <Date, double> >()
                );
            var bondCfs = marketInstrumetns.Select(x => (x.Instrument as Bond).GetCashflows(baseMarket, true)).ToList();

            var bondPricer = new BondYieldPricer();

            for (var i = 0; i < bondCfs.Count; ++i)
            {
                var pv       = bondCfs[i].Select(cf => cf.PaymentAmount * yieldCurve.GetDf(referenceDate, cf.PaymentDate)).Sum();
                var x        = marketInstrumetns[i].Instrument as Bond;
                var mktPrice = bondPricer.FullPriceFromYield(bondCfs[i], x.PaymentDayCount, x.PaymentFreq, x.StartDate,
                                                             referenceDate, marketInstrumetns[i].TargetValue, x.BondTradeingMarket, x.IrregularPayment);
                Console.WriteLine("{0},{1},{2}", pv, mktPrice, pv - mktPrice);
            }
        }
Esempio n. 18
0
        private GuidObject CurveBuiltFromDependents(DependentObject fatherNode, DependentObject[] childrenNodes)
        {
            IMarketCondition baseMarket;


            if (childrenNodes.Any(x => x is InstrumentCurveObject))
            {
                var baseCurve = (CurveData)childrenNodes.First().Value;
                baseMarket = new MarketCondition(x => x.ValuationDate.Value = Market.ReferenceDate,
                                                 x => x.HistoricalIndexRates.Value = Market.HistoricalIndexRates,
                                                 x => x.DiscountCurve.Value        = baseCurve.YieldCurve,
                                                 x => x.FixingCurve.Value          = baseCurve.YieldCurve,
                                                 x => x.FgnDiscountCurve.Value     = baseCurve.YieldCurve);
            }
            else
            {
                baseMarket = new MarketCondition(x => x.ValuationDate.Value = Market.ReferenceDate,
                                                 x => x.HistoricalIndexRates.Value = Market.HistoricalIndexRates);
            }

            var rateDefinitions  = childrenNodes.Where(x => x.Value is RateMktData).Select(x => (RateMktData)x.Value).ToArray();
            var fxSpotDefinition = rateDefinitions.Where(x => x.InstrumentType.ToInstrumentType() == InstrumentType.FxSpot).ToArray();

            if (fxSpotDefinition.Count() > 1)
            {
                throw new PricingBaseException("A yield curve cannot have more than 2 fx rates against its base curve's currency");
            }
            if (fxSpotDefinition.Any())
            {
                baseMarket = baseMarket.UpdateCondition(
                    new UpdateMktConditionPack <FxSpot[]>(x => x.FxSpots, new[] { CreateFxSpot(fxSpotDefinition[0]) }));
            }

            var curveConvention = childrenNodes.Last().Value as CurveConvention;

            if (curveConvention == null)
            {
                Logger.ErrorFormat("Curve conventions are missing!");
                return(null);
            }

            var isRegridded = rateDefinitions.All(x => x.IndexType != null && x.IndexType.ToIndexType() == IndexType.Regridded);

            if (isRegridded)
            {
                var yieldCurve          = baseMarket.DiscountCurve.Value;
                var tempRateDefinitions = new List <RateMktData>();
                foreach (var tenor in Definition.RegriddedTenors)
                {
                    var date = new Term(tenor).Next(yieldCurve.ReferenceDate);
                    if (date > yieldCurve.KeyPoints.Last().Item1)
                    {
                        date = yieldCurve.KeyPoints.Last().Item1;
                    }
                    tempRateDefinitions.Add(new RateMktData(date.ToString(), GetParRate(date, yieldCurve), "SwapParRate", "InterestRateSwap", Definition.Name));
                }
                rateDefinitions = tempRateDefinitions.ToArray();
            }

            YieldCurve instrumentCurve;

            //This branch is for bond pnl calculation
            if (rateDefinitions.All(
                    x => x.InstrumentType.ToInstrumentType() == InstrumentType.Dummy || x.InstrumentType.ToInstrumentType() == InstrumentType.None))
            {
                if (rateDefinitions.All(x => x.IsTerm()))
                {
                    instrumentCurve = new YieldCurve(
                        Definition.Name,
                        Market.ReferenceDate,
                        rateDefinitions.Select(x => Tuple.Create((ITerm) new Term(x.Tenor), x.Rate)).ToArray(),
                        curveConvention.BusinessDayConvention.ToBda(),
                        curveConvention.DayCount.ToDayCountImpl(),
                        curveConvention.Calendar.ToCalendarImpl(),
                        curveConvention.Currency.ToCurrencyCode(),
                        curveConvention.Compound.ToCompound(),
                        curveConvention.Interpolation.ToInterpolation(),
                        Definition.Trait.ToYieldCurveTrait(),
                        baseMarket
                        );
                }
                else
                {
                    instrumentCurve = new YieldCurve(
                        Definition.Name,
                        Market.ReferenceDate,
                        rateDefinitions.Select(x => Tuple.Create(new Date(DateTime.Parse(x.Tenor)), x.Rate)).ToArray(),
                        curveConvention.BusinessDayConvention.ToBda(),
                        curveConvention.DayCount.ToDayCountImpl(),
                        curveConvention.Calendar.ToCalendarImpl(),
                        curveConvention.Currency.ToCurrencyCode(),
                        curveConvention.Compound.ToCompound(),
                        curveConvention.Interpolation.ToInterpolation(),
                        Definition.Trait.ToYieldCurveTrait(),
                        baseMarket
                        );
                }
            }
            else
            {
                var mktInstruments = new List <MarketInstrument>();
                foreach (var rateDefinition in rateDefinitions)
                {
                    MktInstrumentCalibMethod calibrationMethod;
                    var instType = rateDefinition.InstrumentType.ToInstrumentType();

                    switch (instType)
                    {
                    case InstrumentType.InterestRateSwap:
                        var swap = CreateIrsInstrument(rateDefinition, out calibrationMethod);
                        mktInstruments.Add(new MarketInstrument(swap, rateDefinition.Rate, calibrationMethod));
                        break;

                    case InstrumentType.Deposit:
                    case InstrumentType.Repo:
                    case InstrumentType.Ibor:
                        var deposit = CreateDepositInstrument(rateDefinition, out calibrationMethod);
                        mktInstruments.Add(new MarketInstrument(deposit, rateDefinition.Rate, calibrationMethod));
                        break;

                    case InstrumentType.Dummy:
                    case InstrumentType.None:
                        var dummy = CreateDummyInstrument(rateDefinition);
                        mktInstruments.Add(new MarketInstrument(dummy, rateDefinition.Rate, MktInstrumentCalibMethod.Default));
                        break;

                    case InstrumentType.CreditDefaultSwap:
                        var cds = CreateCreditDefaultSwap(rateDefinition);
                        mktInstruments.Add(new MarketInstrument(cds, rateDefinition.Rate, MktInstrumentCalibMethod.Default));
                        break;

                    case InstrumentType.CommodityForward:
                        mktInstruments.Add(new MarketInstrument(CreateCommodityForward(rateDefinition), rateDefinition.Rate, MktInstrumentCalibMethod.Default));
                        break;

                    case InstrumentType.CommoditySpot:
                        //baseMarket = baseMarket.UpdateCondition(new UpdateMktConditionPack<double>(x => x.SpotPrices, rateDefinition.Rate));
                        baseMarket = baseMarket.UpdateCondition(new UpdateMktConditionPack <Dictionary <string, double> >(x => x.SpotPrices, new Dictionary <string, double> {
                            { "", rateDefinition.Rate }
                        }));
                        break;

                    case InstrumentType.FxSpot:
                        break;

                    default:
                        throw new PricingLibraryException("Unrecognized product type in calibrating curve.");
                    }
                    #region legacy code

                    //               if (rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.InterestRateSwap)
                    //{
                    //	var swap = CreateIrsInstrument(rateDefinition, out calibrationMethod);
                    //	mktInstruments.Add(new MarketInstrument(swap, rateDefinition.Rate, calibrationMethod));
                    //}
                    //else if ( instType == InstrumentType.Deposit
                    //	|| rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.Repo
                    //	|| rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.Ibor)
                    //{
                    //	var deposit = CreateDepositInstrument(rateDefinition, out calibrationMethod);
                    //	mktInstruments.Add(new MarketInstrument(deposit, rateDefinition.Rate, calibrationMethod));
                    //}
                    //else if (rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.Dummy ||
                    //				 rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.None)
                    //{
                    //	var dummy = CreateDummyInstrument(rateDefinition);
                    //	mktInstruments.Add(new MarketInstrument(dummy, rateDefinition.Rate, MktInstrumentCalibMethod.Default));
                    //}
                    //else if (rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.CreditDefaultSwap)
                    //{
                    //	var cds = CreateCreditDefaultSwap(rateDefinition);
                    //	mktInstruments.Add(new MarketInstrument(cds, rateDefinition.Rate, MktInstrumentCalibMethod.Default));
                    //}
                    //else if (rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.CommodityForward)
                    //{
                    //	mktInstruments.Add(new MarketInstrument(CreateCommodityForward(rateDefinition), rateDefinition.Rate, MktInstrumentCalibMethod.Default));
                    //}
                    //else if (rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.CommoditySpot)
                    //{
                    //                   //baseMarket = baseMarket.UpdateCondition(new UpdateMktConditionPack<double>(x => x.SpotPrices, rateDefinition.Rate));
                    //                   baseMarket = baseMarket.UpdateCondition(new UpdateMktConditionPack<Dictionary<string, double>>(x => x.SpotPrices, new Dictionary<string, double> { {"", rateDefinition.Rate } }));
                    //               }
                    //else if (rateDefinition.InstrumentType.ToInstrumentType() == InstrumentType.FxSpot)
                    //{

                    //}
                    //else
                    //{
                    //	throw new PricingLibraryException("Unrecognized product type in calibrating curve.");
                    //}
                    #endregion legacy code
                }

                var isSpcCurve        = rateDefinitions.All(x => x.IndexType != null && x.IndexType.ToIndexType() == IndexType.Spc);
                var isConvenicenYield = rateDefinitions.All(x => x.IndexType != null && x.IndexType.ToIndexType() == IndexType.ConvenienceYield);


                Expression <Func <IMarketCondition, object> >[] expression = null;
                if (isSpcCurve)
                {
                    expression = new Expression <Func <IMarketCondition, object> >[] { x => x.SurvivalProbabilityCurve }
                }
                ;
                if (isConvenicenYield)
                {
                    expression = new Expression <Func <IMarketCondition, object> >[] { x => x.DividendCurves }
                }
                ;

                instrumentCurve = new YieldCurve(
                    Definition.Name,
                    Market.ReferenceDate,
                    mktInstruments.ToArray(),
                    curveConvention.BusinessDayConvention.ToBda(),
                    curveConvention.DayCount.ToDayCountImpl(),
                    curveConvention.Calendar.ToCalendarImpl(),
                    curveConvention.Currency.ToCurrencyCode(),
                    curveConvention.Compound.ToCompound(),
                    curveConvention.Interpolation.ToInterpolation(),
                    Definition.Trait.ToYieldCurveTrait(),
                    baseMarket,
                    expression,
                    null
                    );
            }
            return(new CurveData(instrumentCurve));
        }