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); }
public double PriceToYield() { var bond = new FixedDateCouonAdjustedBondInfo("313100015") { StartDate = "2015-03-23", MaturityDate = "2018-11-17", PaymentFrequency = "Quarterly", Notional = 32000, AccrualDayCount = "Act365", AccrualBusinessDayConvention = "None", DayCount = "Act365", PaymentBusinessDayConvention = "None", FirstPaymentDate = "2015-06-21", Index = "Lrb5Y", FloatingRateMultiplier = 0.9, FixedDateCouponAdjustedStyle = "SpecifiedDates", AdjustMmDd = "11-18", AmoritzationInDate = new Dictionary <string, double> { { "2015-06-20", 0.125 }, //percentage of initial Notional { "2015-12-20", 0.125 }, { "2016-06-20", 0.125 }, { "2016-12-20", 0.125 }, { "2017-06-20", 0.125 }, { "2017-12-20", 0.125 }, { "2018-06-20", 0.125 }, { "2018-11-17", 0.125 }, }, }; var bondVf = new BondVf(bond); var result = bondVf.ValueTrade(_market, PricingRequest.Ytm); return(result.Ytm); }
public void TestBondPriceConversions() { var targetDirtyPrice = new List <double>(); var targetCleanPrice = new List <double>(); var targetYtm = new List <double>(); var fixedBonds = File.ReadAllLines(@"./Data/BondFuture/QbTF1606CfTest.txt") .Select(x => { var splits = x.Split(','); targetDirtyPrice.Add(Convert.ToDouble(splits[6])); targetCleanPrice.Add(Convert.ToDouble(splits[7])); targetYtm.Add(Convert.ToDouble(splits[8])); return(new FixedRateBondInfo(splits[0]) { StartDate = new Date(DateTime.Parse(splits[3])).ToString(), MaturityDate = new Date(DateTime.Parse(splits[4])).ToString(), Notional = 100.0, Currency = "CNY", FixedCoupon = Convert.ToDouble(splits[1]), Calendar = "chn_ib", PaymentFreq = (splits[2] == "Annual" ? Frequency.Annual : Frequency.SemiAnnual).ToString(), PaymentStub = "LongEnd", AccrualDC = "ActActIsma", DayCount = "ActActIsma", AccrualBD = "None", PaymentBD = "None", TradingMarket = "ChinaInterBank", Settlement = "+0D", ValuationParamters = new SimpleCfValuationParameters("Fr007", null, "Fr007") }); }).ToArray(); for (var i = 0; i < fixedBonds.Length; ++i) { var bondVf = new BondVf(fixedBonds[i]); var markets = new[] { TestMarket("2016-04-06", new BondMktData(fixedBonds[i].TradeId, "Dirty", targetDirtyPrice[i])), TestMarket("2016-04-06", new BondMktData(fixedBonds[i].TradeId, "Clean", targetCleanPrice[i])), TestMarket("2016-04-06", new BondMktData(fixedBonds[i].TradeId, "Ytm", targetYtm[i])) }; foreach (var qdpMarket in markets) { var result = bondVf.ValueTrade(qdpMarket, PricingRequest.Ytm); Assert.AreEqual(Math.Round(result.DirtyPrice, 4), targetDirtyPrice[i], 1e-5); Assert.AreEqual(Math.Round(result.CleanPrice, 4), targetCleanPrice[i], 1e-5); Assert.AreEqual(Math.Round(result.Ytm, 6), targetYtm[i], 1e-7); } } }
public void TestFixedDateCouponAdjustedBond1() { var bond = new FixedDateCouonAdjustedBondInfo("313100015") { StartDate = "2015-03-23", MaturityDate = "2018-11-17", PaymentFreq = "Quarterly", Notional = 32000, AccrualDC = "Act365", AccrualBD = "None", DayCount = "Act365", PaymentBD = "None", FirstPaymentDate = "2015-06-21", Index = "Lrb5Y", FloatingRateMultiplier = 0.9, FixedDateCouponAdjustedStyle = "SpecifiedDates", AdjustMmDd = "11-18", AmoritzationInDate = new Dictionary <string, double> { { "2015-06-20", 0.125 }, //percentage of initial Notional { "2015-12-20", 0.125 }, { "2016-06-20", 0.125 }, { "2016-12-20", 0.125 }, { "2017-06-20", 0.125 }, { "2017-12-20", 0.125 }, { "2018-06-20", 0.125 }, { "2018-11-17", 0.125 }, }, //Settlment = "+0BD", //PaymentStub = "ShortEnd", //Calendar = "chn_ib", //Currency = "CNY", //TradingMarket = "ChinaInterBank", //IsZeroCouponBond = false, //IssuePrice = 100, //ValuationParamters = new SimpleCfValuationParameters("Fr007", "", "Fr007") }; var marketInfo = TestMarket("2015-03-23", new BondMktData(bond.TradeId, "Dirty", bond.Notional)); var bondVf = new BondVf(bond); var result = bondVf.ValueTrade(marketInfo, PricingRequest.Cashflow); var expectedResults = new[] { "Coupon 459.9715 CNY@2015-06-20", "Coupon 4.5222 CNY@2015-06-21", "Coupon 416.0416 CNY@2015-09-21", "Coupon 392.6367 CNY@2015-12-20", "Coupon 3.4915 CNY@2015-12-21", "Coupon 317.7271 CNY@2016-03-21", "Coupon 317.7271 CNY@2016-06-20", "Coupon 2.9096 CNY@2016-06-21", "Coupon 267.6822 CNY@2016-09-21", "Coupon 261.863 CNY@2016-12-20", "Coupon 2.3277 CNY@2016-12-21", "Coupon 209.4904 CNY@2017-03-21", "Coupon 211.8181 CNY@2017-06-20", "Coupon 1.7458 CNY@2017-06-21", "Coupon 160.6093 CNY@2017-09-21", "Coupon 157.1178 CNY@2017-12-20", "Coupon 1.1638 CNY@2017-12-21", "Coupon 104.7452 CNY@2018-03-21", "Coupon 105.909 CNY@2018-06-20", "Coupon 0.5819 CNY@2018-06-21", "Coupon 53.5364 CNY@2018-09-21", "Coupon 33.1693 CNY@2018-11-17", "Principal 4000 CNY@2015-06-20", "Principal 4000 CNY@2015-12-20", "Principal 4000 CNY@2016-06-20", "Principal 4000 CNY@2016-12-20", "Principal 4000 CNY@2017-06-20", "Principal 4000 CNY@2017-12-20", "Principal 4000 CNY@2018-06-20", "Principal 4000 CNY@2018-11-17", }; for (var i = 0; i < result.Cashflows.Length; ++i) { Assert.AreEqual(result.Cashflows[i].ToString(), expectedResults[i]); } }
public void TestFloatingBondPriceConversions() { var targetDirtyPrice = new List <double>(); //var targetCleanPrice = new List<double>(); //var targetYtm = new List<double>(); var floatingBonds = File.ReadAllLines(@"./Data/BondFuture/QbTF1606CfTest.txt") .Select(x => { var splits = x.Split(','); targetDirtyPrice.Add(Convert.ToDouble(splits[6])); //targetCleanPrice.Add(Convert.ToDouble(splits[7])); //targetYtm.Add(Convert.ToDouble(splits[8])); return(new FloatingRateBondInfo(splits[0]) { StartDate = new Date(DateTime.Parse(splits[3])).ToString(), MaturityDate = new Date(DateTime.Parse(splits[4])).ToString(), Notional = 100.0, Currency = "CNY", Spread = Convert.ToDouble(splits[1]), Calendar = "chn_ib", PaymentFreq = (splits[2] == "Annual" ? Frequency.Annual : Frequency.SemiAnnual).ToString(), PaymentStub = "LongEnd", AccrualDC = "Act365", DayCount = "Act365", AccrualBD = "None", PaymentBD = "ModifiedFollowing", TradingMarket = "ChinaInterBank", Settlement = "+0BD", ValuationParamters = new SimpleCfValuationParameters("Fr007", "Fr007", "Fr007"), Index = IndexType.Fr007.ToString(), ResetDC = DayCount.Act365.ToString(), ResetAverageDays = 1, ResetTerm = "1W", ResetStub = Stub.LongEnd.ToString(), ResetBD = BusinessDayConvention.ModifiedFollowing.ToString(), ResetToFixingGap = "-1BD", FloatingCalc = "SimpleFrn", ResetCompound = CouponCompound.Simple.ToString() }); }).ToArray(); for (var i = 0; i < floatingBonds.Length; ++i) { var bondVf = new BondVf(floatingBonds[i]); var markets = new[] { TestMarket("2014-10-21", new BondMktData(floatingBonds[i].TradeId, "Dirty", targetDirtyPrice[i])), //TestMarket("2014-10-21", new BondMktData(floatingBonds[i].TradeId, "Clean", targetCleanPrice[i])), //TestMarket("2014-10-21", new BondMktData(floatingBonds[i].TradeId, "Ytm", targetYtm[i])) }; foreach (var qdpMarket in markets) { var result = bondVf.ValueTrade(qdpMarket, PricingRequest.Ytm); Console.WriteLine("DirtyPrice:{0}", result.DirtyPrice); Console.WriteLine("CleanPrice:{0}", result.CleanPrice); Console.WriteLine("Ytm:{0}", result.Ytm); //Assert.AreEqual(targetDirtyPrice[i], Math.Round(result.DirtyPrice, 4), 1e-5); //Assert.AreEqual(targetCleanPrice[i], Math.Round(result.CleanPrice, 4), 1e-5); //Assert.AreEqual(targetYtm[i], Math.Round(result.Ytm, 6), 1e-7); } } }
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); }
public void TestFixedDateCouponAdjustedBond2() { var bond = new FixedDateCouonAdjustedBondInfo("1141100129") { StartDate = "2015-03-23", MaturityDate = "2018-04-24", PaymentFreq = "Quarterly", Notional = 4000, AccrualDC = "Act365", AccrualBD = "None", DayCount = "Act365", PaymentBD = "None", FirstPaymentDate = "2015-06-21", Index = "Lrb5Y", FloatingRateMultiplier = 1.0, FixedDateCouponAdjustedStyle = "Follow", AdjustMmDd = "11-08", AmoritzationInDate = new Dictionary <string, double> { { "2015-05-18", 0.25 }, //percentage of initial Notional { "2015-11-19", 0.25 }, { "2016-05-18", 0.5 } }, //Settlment = "+0BD", //PaymentStub = "ShortEnd", //Calendar = "chn_ib", //Currency = "CNY", //TradingMarket = "ChinaInterBank", //IsZeroCouponBond = false, //IssuePrice = 100, //ValuationParamters = new SimpleCfValuationParameters("Fr007", "", "Fr007") }; var marketInfo = TestMarket("2015-03-23", new BondMktData(bond.TradeId, "Dirty", bond.Notional)); var bondVf = new BondVf(bond); var result = bondVf.ValueTrade(marketInfo, PricingRequest.Cashflow); var expectedResults = new[] { "Coupon 36.2082 CNY@2015-05-18", "Coupon 16.4877 CNY@2015-06-21", "Coupon 44.6137 CNY@2015-09-21", "Coupon 28.611 CNY@2015-11-19", "Coupon 10.3452 CNY@2015-12-21", "Coupon 29.4192 CNY@2016-03-21", "Coupon 18.7507 CNY@2016-05-18", "Coupon 0 CNY@2016-06-21", "Coupon 0 CNY@2016-09-21", "Coupon 0 CNY@2016-12-21", "Coupon 0 CNY@2017-03-21", "Coupon 0 CNY@2017-06-21", "Coupon 0 CNY@2017-09-21", "Coupon 0 CNY@2017-12-21", "Coupon 0 CNY@2018-03-21", "Coupon 0 CNY@2018-04-24", "Principal 1000 CNY@2015-05-18", "Principal 1000 CNY@2015-11-19", "Principal 2000 CNY@2016-05-18", }; for (var i = 0; i < result.Cashflows.Length; ++i) { Assert.AreEqual(result.Cashflows[i].ToString(), expectedResults[i]); } }