public void PastStartingFixedRateLoanDepo() { var bd = DateTime.Today; var pillars = new[] { bd, bd.AddDays(1000) }; var flatRate = 0.05; var rates = pillars.Select(p => flatRate).ToArray(); var usd = TestProviderHelper.CurrencyProvider["USD"]; var discoCurve = new IrCurve(pillars, rates, bd, "USD.BLAH", Interpolator1DType.Linear, usd); var fModel = new FundingModel(bd, new[] { discoCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var start = bd.AddDays(-10); var maturity = bd.AddDays(365); var notional = 100e6; var iRate = 0.07; var depo = new FixedRateLoanDeposit(start, maturity, iRate, usd, DayCountBasis.ACT360, notional, "USD.BLAH"); var pv = depo.Pv(fModel, false); var dfEnd = discoCurve.GetDf(bd, maturity); var t = start.CalculateYearFraction(maturity, DayCountBasis.ACT360); var expectedPv = 0.0; //initial notional is in the past expectedPv += -notional * dfEnd; //final notional expectedPv += -notional * (iRate * t) * dfEnd; //final notional Assert.Equal(expectedPv, pv, 8); var loan = new FixedRateLoanDeposit(start, maturity, iRate, usd, DayCountBasis.ACT360, -notional, "USD.BLAH"); pv = loan.Pv(fModel, false); expectedPv = 0.0; //initial notional is in the past expectedPv += notional * dfEnd; //final notional expectedPv += notional * (iRate * t) * dfEnd; //final notional Assert.Equal(expectedPv, pv, 8); }
public void AsianCompoSwap() { ParallelUtils.Instance.MultiThreaded = false; var startDate = new DateTime(2018, 07, 28); var cal = TestProviderHelper.CalendarProvider.Collection["LON"]; var xaf = TestProviderHelper.CurrencyProvider["XAF"]; var usd = TestProviderHelper.CurrencyProvider["USD"]; var curvePillars = new[] { "1W", "1M", "3M", "6M", "1Y" }; var curvePillarDates = curvePillars.Select(l => startDate.AddPeriod(RollType.F, cal, new Frequency(l))).ToArray(); var curvePoints = new[] { 100.0, 100, 100, 100, 100 }; var curve = new BasicPriceCurve(startDate, curvePillarDates, curvePoints, PriceCurveType.LME, TestProviderHelper.CurrencyProvider, curvePillars) { Currency = usd, CollateralSpec = "CURVE", Name = "Coconuts", AssetId = "Coconuts" }; var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); var fxSpot = 7; var rates = new Dictionary <Currency, double> { { xaf, fxSpot } }; var discoMap = new Dictionary <Currency, string> { { xaf, "XAF.CURVE" }, { usd, "USD.CURVE" } }; var fxPair = new FxPair() { Domestic = usd, Foreign = xaf, PrimaryCalendar = cal, SpotLag = new Frequency("2b") }; fxMatrix.Init(usd, startDate, rates, new List <FxPair> { fxPair }, discoMap); var irPillars = new[] { startDate, startDate.AddYears(10) }; var xafRates = new[] { 0.1, 0.1 }; var usdRates = new[] { 0.01, 0.01 }; var xafCurve = new IrCurve(irPillars, xafRates, startDate, "XAF.CURVE", Interpolator1DType.Linear, xaf, "CURVE"); var usdCurve = new IrCurve(irPillars, usdRates, startDate, "USD.CURVE", Interpolator1DType.Linear, usd, "CURVE"); var fModel = new FundingModel(startDate, new[] { xafCurve, usdCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); fModel.SetupFx(fxMatrix); var aModel = new AssetFxModel(startDate, fModel); aModel.AddPriceCurve("Coconuts", curve); var periodCode = "SEP-18"; var(Start, End) = periodCode.ParsePeriod(); var fixingDates = Start.BusinessDaysInPeriod(End, cal).ToArray(); var settleDate = fixingDates.Last().AddPeriod(RollType.F, cal, new Frequency("5b")); var fxFwd = aModel.FundingModel.GetFxAverage(fixingDates, usd, xaf); var assetFwd = curve.GetAveragePriceForDates(fixingDates); var fairStrike = fxFwd * assetFwd; var asianSwap = AssetProductFactory.CreateMonthlyAsianSwap(periodCode, fairStrike, "Coconuts", cal, cal, new Frequency("5b"), xaf, TradeDirection.Long, new Frequency("0b"), 1000, DateGenerationType.BusinessDays); asianSwap.TradeId = "aLovelyBunch"; foreach (var sw in asianSwap.Swaplets) { sw.DiscountCurve = "XAF.CURVE"; sw.FxConversionType = FxConversionType.AverageThenConvert; } var pv = asianSwap.PV(aModel, false); Assert.Equal(0, pv, 8); var portfolio = new Portfolio() { Instruments = new List <IInstrument> { asianSwap } }; var pfPvCube = portfolio.PV(aModel); var pfPv = (double)pfPvCube.GetAllRows().First().Value; Assert.Equal(0.0, pfPv, 8); var deltaCube = portfolio.AssetDelta(aModel); var dAgg = deltaCube.Pivot("TradeId", AggregationAction.Sum); var delta = (double)dAgg.GetAllRows().First().Value; var t0Spot = aModel.FundingModel.GetFxRate(startDate, usd, xaf); var df = xafCurve.GetDf(startDate, settleDate); Assert.Equal(995.361065482776, delta, 7); var fxDeltaCube = portfolio.FxDelta(aModel, usd, TestProviderHelper.CurrencyProvider); var dfxAgg = fxDeltaCube.Pivot("TradeId", AggregationAction.Sum); var fxDelta = (double)dfxAgg.GetAllRows().First().Value; Assert.Equal(-1000 * df * fxFwd * 100 / (t0Spot / fxSpot) / usdCurve.GetDf(startDate, fxPair.SpotDate(startDate)), fxDelta, 4); }
public void ContangoSwap() { var bd = new DateTime(2019, 06, 14); var pillars = new[] { bd, bd.AddDays(1000) }; var flatRateUsd = 0.05; var flatRateXau = 0.01; var spotRate = 1200; var ratesUsd = pillars.Select(p => flatRateUsd).ToArray(); var ratesXau = pillars.Select(p => flatRateXau).ToArray(); var usd = TestProviderHelper.CurrencyProvider["USD"]; var xau = TestProviderHelper.CurrencyProvider["XAU"]; CalendarProvider.Collection.TryGetCalendar("LON", out var cal); var pair = new FxPair() { Domestic = xau, Foreign = usd, SettlementCalendar = cal, SpotLag = 2.Bd() }; var discoCurveUsd = new IrCurve(pillars, ratesUsd, bd, "USD.BLAH", Interpolator1DType.Linear, usd); var discoCurveXau = new IrCurve(pillars, ratesXau, bd, "XAU.BLAH", Interpolator1DType.Linear, xau); var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); fxMatrix.Init(usd, bd, new Dictionary <Currency, double> { { xau, 1.0 / spotRate } }, new List <FxPair> { pair }, new Dictionary <Currency, string> { { usd, "USD.BLAH" }, { xau, "XAU.BLAH" } }); var fModel = new FundingModel(bd, new[] { discoCurveUsd, discoCurveXau }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); fModel.SetupFx(fxMatrix); var maturity = bd.AddDays(365); var spot = bd.SpotDate(2.Bd(), cal, cal); var c = 0.022; var b = new ContangoSwap { CashCCY = usd, MetalCCY = xau, CashDiscountCurve = "USD.BLAH", DeliveryDate = maturity, ContangoRate = c, MetalQuantity = 1, SpotDate = spot }; var t = spot.CalculateYearFraction(maturity, DayCountBasis.Act360); var pv = b.Pv(fModel, false); var fwdA = (1.0 + c * t) * spotRate; var fwdB = fModel.GetFxRate(maturity, xau, usd); var df = discoCurveUsd.GetDf(bd, maturity); var expectedPv = (fwdB - fwdA) * b.MetalQuantity; expectedPv *= df; Assert.Equal(expectedPv, pv, 10); Assert.Equal(maturity, b.LastSensitivityDate); Assert.Equal(usd, b.Currency); var s = b.Sensitivities(fModel); Assert.True(s.Count == 2 && s.Keys.Contains("USD.BLAH") && s.Keys.Contains("XAU.BLAH")); var s2 = b.Dependencies(fModel.FxMatrix); Assert.True(s2.Count == 2 && s2.Contains("USD.BLAH") && s2.Contains("XAU.BLAH")); Assert.Equal(0.0402428426839156, b.CalculateParRate(fModel), 8); var b2 = (ContangoSwap)b.SetParRate(0.05); Assert.Equal(0.05, b2.ContangoRate); }
public void FixedRateLoanDepo() { var bd = DateTime.Today; var pillars = new[] { bd, bd.AddDays(1000) }; var flatRate = 0.05; var rates = pillars.Select(p => flatRate).ToArray(); var usd = TestProviderHelper.CurrencyProvider["USD"]; var discoCurve = new IrCurve(pillars, rates, bd, "USD.BLAH", Interpolator1DType.Linear, usd); var fModel = new FundingModel(bd, new[] { discoCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var maturity = bd.AddDays(365); var notional = 100e6; var iRate = 0.07; var depo = new FixedRateLoanDeposit(bd, maturity, iRate, usd, DayCountBasis.ACT360, notional, "USD.BLAH"); var pv = depo.Pv(fModel, false); var dfEnd = discoCurve.GetDf(bd, maturity); var t = bd.CalculateYearFraction(maturity, DayCountBasis.ACT360); var expectedPv = notional; //initial notional expectedPv += -notional * dfEnd; //final notional expectedPv += -notional * (iRate * t) * dfEnd; //final notional Assert.Equal(expectedPv, pv, 8); Assert.Equal(maturity, depo.LastSensitivityDate); Assert.Empty(depo.AssetIds); Assert.Equal(usd, depo.PaymentCurrency); Assert.Equal(0.0, depo.CalculateParRate(fModel)); Assert.Equal(notional, depo.FlowsT0(fModel)); var fm2 = fModel.DeepClone(maturity); Assert.Equal(-notional * (1 + (iRate * t)), depo.FlowsT0(fm2)); fm2 = fModel.DeepClone(maturity.AddDays(1)); Assert.Equal(0.0, depo.FlowsT0(fm2)); var flows = depo.ExpectedCashFlows(new AssetFxModel(bd, fModel)); Assert.Equal(3, flows.Count); var loan = new FixedRateLoanDeposit(bd, maturity, iRate, usd, DayCountBasis.ACT360, -notional, "USD.BLAH"); pv = loan.Pv(fModel, false); expectedPv = -notional; //initial notional expectedPv += notional * dfEnd; //final notional expectedPv += notional * (iRate * t) * dfEnd; //final notional Assert.Equal(expectedPv, pv, 8); Assert.Throws <NotImplementedException>(() => depo.Sensitivities(fModel)); Assert.Throws <NotImplementedException>(() => depo.SetStrike(0.0)); Assert.Equal("USD.BLAH", depo.Dependencies(fModel.FxMatrix)[0]); Assert.Empty(depo.PastFixingDates(maturity)); Assert.Equal(FxConversionType.None, depo.FxType(null)); Assert.Equal(string.Empty, depo.FxPair(null)); var depo2 = depo.Clone(); Assert.True(depo.Equals(depo2)); Assert.False(depo.Equals(loan)); var depo3 = depo.SetParRate(0.333); Assert.False(depo.Equals(depo3)); }