public static object CreateContangoSwap(
            [ExcelArgument(Description = "Object name")] string ObjectName,
            [ExcelArgument(Description = "Spot Date")] DateTime SpotDate,
            [ExcelArgument(Description = "Settle Date")] DateTime SettleDate,
            [ExcelArgument(Description = "Metal Currency")] string MetalCcy,
            [ExcelArgument(Description = "Cash Currency")] string CashCcy,
            [ExcelArgument(Description = "Metal Notional")] double MetalNotional,
            [ExcelArgument(Description = "Contango")] double Contango,
            [ExcelArgument(Description = "Cash Discount Curve")] string DiscountCurve,
            [ExcelArgument(Description = "Solve Curve name ")] string SolveCurve,
            [ExcelArgument(Description = "Solve Pillar Date")] object SolvePillarDate)
        {
            return(ExcelHelper.Execute(_logger, () =>
            {
                ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(MetalCcy, out var metalCcy);
                ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(CashCcy, out var cashCcy);

                var product = new ContangoSwap
                {
                    MetalCCY = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(MetalCcy),
                    CashCCY = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(CashCcy),
                    MetalQuantity = MetalNotional,
                    DeliveryDate = SettleDate,
                    CashDiscountCurve = DiscountCurve,
                    SolveCurve = SolveCurve,
                    PillarDate = DateTime.FromOADate(SolvePillarDate.OptionalExcel(SettleDate.ToOADate())),
                    ContangoRate = Contango,
                    TradeId = ObjectName,
                    Basis = DayCountBasis.ACT360,
                    SpotDate = SpotDate
                };

                return ExcelHelper.PushToCache(product, ObjectName);
            }));
        }
Example #2
0
        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);
        }