예제 #1
0
        public void TestBondPriceConversions3()
        {
            var bond = new FixedRateBondInfo("bond1")
            {
                StartDate          = "2010-10-28",
                MaturityDate       = "2020-10-28",
                Notional           = 100.0,
                Currency           = "CNY",
                FixedCoupon        = 0.0367,
                Calendar           = "chn",
                PaymentFreq        = "SemiAnnual",
                PaymentStub        = "ShortStart",
                AccrualDC          = "Act365NoLeap",
                DayCount           = "ModifiedAfb",
                AccrualBD          = "None",
                PaymentBD          = "None",
                TradingMarket      = "ChinaExShg",
                Settlement         = "+0BD",
                ValuationParamters = new SimpleCfValuationParameters("Fr007", null, "Fr007")
            };

            var bondVf = new BondVf(bond);
            var market = TestMarket("2016-08-04", new BondMktData(bond.TradeId, "Dirty", 100.995424657531));

            var result = bondVf.ValueTrade(market, PricingRequest.Ytm);

            Assert.AreEqual(Math.Round(result.Ytm, 15), 0.036663932289318, 1e-13);
        }
예제 #2
0
        public void TestConvertibleBondWhenCallOnMaturity()
        {
            var bond = new FixedRateBondInfo("110030.SH")
            {
                StartDate        = "2014-12-25",
                MaturityDate     = "2019-12-25",
                Notional         = 100.0,
                Currency         = "CNY",
                FixedCoupon      = 0.006,
                Calendar         = "chn",
                PaymentFreq      = "Annual",
                PaymentStub      = "ShortStart",
                AccrualDC        = "Act365NoLeap",
                DayCount         = "ModifiedAfb",
                AccrualBD        = "None",
                PaymentBD        = "None",
                TradingMarket    = "ChinaExShg",
                Settlement       = "+0BD",
                CompensationRate = new Dictionary <int, double>()
                {
                    { 2, 0.002 }, { 3, 0.002 }, { 4, 0.005 }, { 5, 0.005 }
                },
                ValuationParamters          = new SimpleCfValuationParameters("Fr007", null, "Fr007"),
                RedemptionRate              = 1.06,
                RedemptionIncludeLastCoupon = true
            };

            var bondVf = new BondVf(bond);
            var market = TestMarket("2017-10-20", new BondMktData(bond.TradeId, "Dirty", 95.90891));

            //var result = bondVf.ValueTrade(market, PricingRequest.Ytm);
            XlManager.AddTrades(new TradeInfoBase[] { bond });
            var ytm = XlUdf.xl_YieldFromPrice("110030.SH", "2017-10-20", 95.90891);
        }
예제 #3
0
        public void TestStepWiseCompensationRate()
        {
            //为什么没输入tradedate?应该有tradedate为交易属性
            var bond = new FixedRateBondInfo("bond1")
            {
                StartDate        = "2016-10-28",
                MaturityDate     = "2020-10-28",
                Notional         = 100.0,          //trade
                Currency         = "CNY",
                FixedCoupon      = 0.0367,
                Calendar         = "chn",
                PaymentFreq      = "Annual",                    //付息频率
                PaymentStub      = "ShortStart",                //instrument
                AccrualDC        = "ActActIsma",                // 日期规则,应计利息
                DayCount         = "ModifiedAfb",               // 收益率的日期规则
                AccrualBD        = "None",                      //应计利息 日期调整规则 instrument
                PaymentBD        = "None",                      //支付利息 日期调整规则
                TradingMarket    = "ChinaExShg",                //交易市场
                Settlement       = "+0BD",                      //BD工作日, 后可以拿到交易的东西 instrument
                CompensationRate = new Dictionary <int, double> // :
//补偿利率的意思是有些债券会根据年限的变化增长利息
//2,0.01是指第二年开始利率增加0.01

                {
                    { 2, 0.01 },
                    { 3, 0.015 }
                },
                ValuationParamters = new SimpleCfValuationParameters("Fr007", null, "Fr007")
            };

            var bondVf = new BondVf(bond);
            var market = TestMarket("2016-08-04", new BondMktData(bond.TradeId, "Dirty", 100.995424657531));

            var result    = bondVf.ValueTrade(market, PricingRequest.Cashflow);
            var nettedCfs = result.Cashflows.GroupBy(cf => cf.PaymentDate)
                            .Select(item => new Cashflow(item.Min(x => x.AccrualStartDate), item.Max(x => x.AccrualEndDate), item.Key, item.Sum(entry => entry.PaymentAmount), item.First().PaymentCurrency, CashflowType.Coupon, item.Aggregate(true, (current, v) => current && v.IsFixed), double.NaN, item.Min(x => x.CalculationDetails), item.Min(x => x.RefStartDate), item.Max(x => x.RefEndDate), item.Max(entry => entry.StartPrincipal), item.Sum(entry => entry.CouponRate)))
                            .OrderBy(cf => cf.PaymentDate)
                            .ToArray();

            Assert.AreEqual(nettedCfs[0].PaymentAmount, 3.67, 1e-3);
            Assert.AreEqual(nettedCfs[1].PaymentAmount, 4.67, 1e-3);
            Assert.AreEqual(nettedCfs[2].PaymentAmount, 6.17, 1e-3);
            Assert.AreEqual(nettedCfs[3].PaymentAmount, 106.17, 1e-3);



            //Date tradedate = new Date(2016, 11, 28);
            //Date startdate = new Date(2016, 10, 28);
            //Date maturitydate = new Date(2020, 10, 28);
            //var bond_v2 = new V2.FixedRateBondInfo("bond1",tradedate, startdate,maturitydate, V2.TradeType.Buy, 100, 1000);

            //var bond2s = CreateBonds();
            //var singlebond = bond2s[0];
            //var marketV2 = CreateTestMarket("2016-11-28", singlebond);
            //IPricingResult ipResult = bond_v2.CalculateRisks(marketV2, PricingRequest.Cashflow);

            //var nettedCfs2 = ipResult.Cashflows.GroupBy(cf => cf.PaymentDate)
            //        .Select(item => new Cashflow(item.Min(x => x.AccrualStartDate), item.Max(x => x.AccrualEndDate), item.Key, item.Sum(entry => entry.PaymentAmount), item.First().PaymentCurrency, CashflowType.Coupon, item.Aggregate(true, (current, v) => current && v.IsFixed), double.NaN, item.Min(x => x.CalculationDetails), item.Min(x => x.RefStartDate), item.Max(x => x.RefEndDate), item.Max(entry => entry.StartPrincipal), item.Sum(entry => entry.CouponRate)))
            //        .OrderBy(cf => cf.PaymentDate)
            //        .ToArray();
            //string results = "0:" + nettedCfs2[0].PaymentAmount + "1:" + nettedCfs2[1].PaymentAmount  +"2:" + nettedCfs2[2].PaymentAmount +"3:" + nettedCfs2[3].PaymentAmount; ;
            //System.Diagnostics.Debugger.Log(2, "results", results);
        }
예제 #4
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);
        }
예제 #5
0
        /// <summary>
        /// Return QDP bond qdp object.
        /// </summary>
        /// <param name="tradeId"></param>
        /// <param name="startDate"></param>
        /// <param name="maturityDate"></param>
        /// <param name="notional"></param>
        /// <param name="calendar"></param>
        /// <param name="currency"></param>
        /// <param name="accrualDayCount"></param>
        /// <param name="accrualBusinessDayConvention"></param>
        /// <param name="paymentDayCount"></param>
        /// <param name="paymentFrequency"></param>
        /// <param name="paymentStub"></param>
        /// <param name="paymentBusinessDayConvention"></param>
        /// <param name="settlement"></param>
        /// <param name="settlementCoupon"></param>
        /// <param name="issuePrice"></param>
        /// <param name="firstPaymentDate"></param>
        /// <param name="issueRate"></param>
        /// <param name="amoritzationInIndex"></param>
        /// <param name="renormalizeAfterAmoritzation"></param>
        /// <param name="compensationRate"></param>
        /// <param name="optionToCall"></param>
        /// <param name="optionToPut"></param>
        /// <param name="optionToAssPut"></param>
        /// <param name="fixedCoupon"></param>
        /// <param name="index"></param>
        /// <param name="resetDayCount"></param>
        /// <param name="resetCompound"></param>
        /// <param name="resetStub"></param>
        /// <param name="resetBusinessDayConvention"></param>
        /// <param name="resetToFixingGap"></param>
        /// <param name="resetTerm"></param>
        /// <param name="resetAverageDays"></param>
        /// <param name="resetRateDigits"></param>
        /// <param name="spread"></param>
        /// <param name="floatingRateMultiplier"></param>
        /// <param name="stickToEom"></param>
        /// <returns></returns>
        private static object xl_Bond(
            string tradeId,
            string startDate       = null,
            string maturityDate    = null,
            double notional        = 100,
            string calendar        = "chn_ib",
            string currency        = "CNY",
            string accrualDayCount = "Act365",
            string accrualBusinessDayConvention = "ModifiedFollowing",
            string paymentDayCount              = "Act365",
            string paymentFrequency             = "SemiAnnual",
            string paymentStub                  = "ShortStart",
            string paymentBusinessDayConvention = "ModifiedFollowing",
            string settlement       = "+0D",
            double settlementCoupon = double.NaN,
            double issuePrice       = double.NaN,
            string firstPaymentDate = null,
            double issueRate        = double.NaN,
            Dictionary <int, double> amoritzationInIndex = null,
            bool renormalizeAfterAmoritzation            = false,
            Dictionary <int, double> compensationRate    = null,
            Dictionary <string, double> optionToCall     = null,
            Dictionary <string, double> optionToPut      = null,
            Dictionary <string, double> optionToAssPut   = null,
            double fixedCoupon   = double.NaN,
            string index         = null,
            string resetDayCount = null,
            string resetCompound = null,
            string resetStub     = null,
            string resetBusinessDayConvention = null,
            string resetToFixingGap           = null,
            string resetTerm              = null,
            int resetAverageDays          = 1,
            int resetRateDigits           = 12,
            double spread                 = double.NaN,
            double floatingRateMultiplier = double.NaN,
            bool stickToEom               = false)
        {
            var tradeInfo = XlManager.GetTrade(tradeId);

            if (!(tradeInfo is BondInfoBase))
            {
                startDate    = startDate ?? DateTime.Now.ToString("yyyy-MM-dd");
                maturityDate = maturityDate ?? new Term("1Y").Next(startDate.ToDate()).ToString();
                BondInfoBase bondInfo = null;
                if (string.IsNullOrWhiteSpace(index))
                {
                    bondInfo = new FixedRateBondInfo(tradeId)
                    {
                        FixedCoupon = double.IsNaN(fixedCoupon) ? 0.03 : fixedCoupon
                    };
                }
                else
                {
                    bondInfo = new FloatingRateBondInfo(tradeId)
                    {
                        Index                  = index ?? "Shibor3M",
                        ResetDC                = resetDayCount ?? "Act365",
                        ResetCompound          = resetCompound ?? "Simple",
                        ResetStub              = resetStub ?? "ShortStart",
                        ResetBD                = resetBusinessDayConvention ?? "ModifiedFollowing",
                        ResetToFixingGap       = resetToFixingGap ?? "-1BD",
                        ResetTerm              = resetTerm ?? "3M",
                        Spread                 = double.IsNaN(spread) ? 0.0 : spread,
                        ResetAverageDays       = resetAverageDays,
                        ResetRateDigits        = resetRateDigits,
                        FloatingRateMultiplier = double.IsNaN(floatingRateMultiplier) ? 1.0 : floatingRateMultiplier,
                        FloatingCalc           = "ZzFrn",
                        CapRate                = 100,
                        FloorRate              = -100
                    };
                }
                bondInfo.StartDate        = startDate;
                bondInfo.MaturityDate     = maturityDate;
                bondInfo.Calendar         = calendar;
                bondInfo.PaymentFreq      = paymentFrequency;
                bondInfo.StickToEom       = stickToEom;
                bondInfo.PaymentStub      = paymentStub;
                bondInfo.Notional         = notional;
                bondInfo.Currency         = currency;
                bondInfo.AccrualDC        = accrualDayCount;
                bondInfo.DayCount         = paymentDayCount;
                bondInfo.AccrualBD        = accrualBusinessDayConvention;
                bondInfo.PaymentBD        = paymentBusinessDayConvention;
                bondInfo.Settlement       = settlement;
                bondInfo.SettlementCoupon = settlementCoupon;
                bondInfo.TradingMarket    = calendar == "chn_ib"
                                        ? TradingMarket.ChinaInterBank.ToString()
                                        : TradingMarket.ChinaExShe.ToString();
                bondInfo.IsZeroCouponBond    = !double.IsNaN(issuePrice);
                bondInfo.IssuePrice          = issuePrice;
                bondInfo.FirstPaymentDate    = firstPaymentDate;
                bondInfo.AmortizationType    = "None";
                bondInfo.AmoritzationInIndex = amoritzationInIndex;
                bondInfo.RenormAmortization  = renormalizeAfterAmoritzation;
                bondInfo.CompensationRate    = compensationRate;
                bondInfo.IssueRate           = issueRate;
                bondInfo.OptionToCall        = optionToCall;
                bondInfo.OptionToPut         = optionToPut;
                bondInfo.OptionToAssPut      = optionToAssPut;
                bondInfo.ValuationParamters  = new SimpleCfValuationParameters("中债国债收益率曲线", "", "中债国债收益率曲线");

                XlManager.AddTrades(new[] { bondInfo });
                tradeInfo = bondInfo;
            }
            return(tradeInfo.ToTradeInfoInLabelData(null));
        }