示例#1
0
        public void Portfolio()
        {
            var bd  = DateTime.Parse("2018-09-13");
            var swp = AssetProductFactory.CreateTermAsianSwap(bd, bd.AddYears(1), 100, "AssetX", CalendarProvider.Collection["USD"], bd.AddYears(2), CcyProvider.GetCurrency("USD"));

            var pf = new Portfolio()
            {
                Instruments = new List <IInstrument>()
            };

            Assert.Empty(PortfolioEx.AssetIds(pf));

            pf.Instruments = new List <IInstrument> {
                swp
            };

            Assert.Equal(swp.LastSensitivityDate, pf.LastSensitivityDate);
            Assert.Equal("AssetX", PortfolioEx.AssetIds(pf).First());
            Assert.Equal(bd.AddYears(2), pf.LastSensitivityDate);

            var deets = PortfolioEx.Details(pf);

            Assert.Throws <NotImplementedException>(() => pf.TradeId);
            Assert.Throws <NotImplementedException>(() => pf.Counterparty);
            Assert.Throws <NotImplementedException>(() => pf.Counterparty = null);
        }
示例#2
0
        public void StripCrackedCurveSimple()
        {
            var buildDate = new DateTime(2018, 07, 28);

            string[] periods = { "AUG18" };
            double[] strikes = { -10 };

            var cal = TestProviderHelper.CalendarProvider.Collection["LON"];
            var usd = TestProviderHelper.CurrencyProvider["USD"];

            var bPillars   = new[] { buildDate, buildDate.AddDays(100) };
            var brentCurve = new PriceCurve(buildDate, bPillars, new[] { 100.0, 100.0 }, PriceCurveType.Linear, TestProviderHelper.CurrencyProvider)
            {
                AssetId = "Brent"
            };

            var instruments = periods.Select((p, ix) =>
                                             (IAssetInstrument)AssetProductFactory.CreateTermAsianBasisSwap(p, strikes[ix], "Brent", "Sing180", cal, cal, cal, 0.Bd(), usd, 0.Bd(), 0.Bd(), 1000, 1000 / 6.35))
                              .ToList();
            var pillars = instruments.Select(x => ((AsianBasisSwap)x).RecSwaplets.Max(sq => sq.AverageEndDate)).ToList();

            DateTime[] dPillars      = { buildDate, buildDate.AddDays(1000) };
            double[]   dRates        = { 0, 0 };
            var        discountCurve = new IrCurve(dPillars, dRates, buildDate, "zeroDiscount", Interpolator1DType.LinearFlatExtrap, usd);

            var s     = new Calibrators.NewtonRaphsonAssetBasisCurveSolver(TestProviderHelper.CurrencyProvider);
            var curve = s.SolveCurve(instruments, pillars, discountCurve, brentCurve, buildDate, PriceCurveType.Linear);

            Assert.Equal((100.0 - 10.0) * 6.35, curve.GetPriceForDate(buildDate));
            Assert.Equal((100.0 - 10.0) * 6.35, curve.GetPriceForDate(buildDate.AddDays(50)));
        }
示例#3
0
        private AssetFxMCModel GetSut()
        {
            var buildDate = DateTime.Parse("2018-10-04");
            var usd       = TestProviderHelper.CurrencyProvider["USD"];

            TestProviderHelper.CalendarProvider.Collection.TryGetCalendar("NYC", out var usdCal);
            var dfCurve = new IrCurve(new[] { buildDate, buildDate.AddDays(1000) }, new[] { 0.0, 0.0 }, buildDate, "disco", Interpolator1DType.Linear, usd, "DISCO");

            var comCurve = new BasicPriceCurve(buildDate, new[] { buildDate, buildDate.AddDays(15), buildDate.AddDays(100) }, new[] { 100.0, 100.0, 100.0 }, PriceCurveType.NYMEX, TestProviderHelper.CurrencyProvider)
            {
                Name    = "CL",
                AssetId = "CL"
            };
            var comSurface = new ConstantVolSurface(buildDate, 0.32)
            {
                AssetId = "CL"
            };
            var fModel = new FundingModel(buildDate, new Dictionary <string, IrCurve> {
                { "DISCO", dfCurve }
            }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);
            var fxM = new FxMatrix(TestProviderHelper.CurrencyProvider);

            fxM.Init(usd, buildDate, new Dictionary <Currency, double>(), new List <FxPair>(), new Dictionary <Currency, string> {
                { usd, "DISCO" }
            });
            fModel.SetupFx(fxM);

            var aModel = new AssetFxModel(buildDate, fModel);

            aModel.AddVolSurface("CL", comSurface);
            aModel.AddPriceCurve("CL", comCurve);

            var product = AssetProductFactory.CreateAsianOption(buildDate.AddDays(10), buildDate.AddDays(20), 101, "CL", OptionType.Call, usdCal, buildDate.AddDays(21), usd);

            product.TradeId       = "waaah";
            product.DiscountCurve = "DISCO";


            var pfolio = new Portfolio {
                Instruments = new List <IInstrument> {
                    product
                }
            };
            var settings = new McSettings
            {
                Generator         = RandomGeneratorType.MersenneTwister,
                NumberOfPaths     = (int)System.Math.Pow(2, 13),
                NumberOfTimesteps = 1,
                ReportingCurrency = usd,
                Parallelize       = false,
                CreditSettings    = new CreditSettings
                {
                    ExposureDates = new DateTime[] { buildDate.AddDays(5), buildDate.AddDays(20), buildDate.AddDays(22) }
                },
            };
            var sut = new AssetFxMCModel(buildDate, pfolio, aModel, settings, TestProviderHelper.CurrencyProvider, TestProviderHelper.FutureSettingsProvider, TestProviderHelper.CalendarProvider);

            return(sut);
        }
示例#4
0
        public void TurboPFETest()
        {
            var CI   = 0.95;
            var am   = GetModel();
            var swap = AssetProductFactory.CreateTermAsianSwap(valDate.AddDays(100), valDate.AddDays(100), assetPrice, "CL", null, valDate.AddDays(101), usd);

            swap.DiscountCurve = "USD";

            var pfe = swap.QuickPFE(CI, am);

            var t           = am.BuildDate.CalculateYearFraction(swap.AverageEndDate, Transport.BasicTypes.DayCountBasis.Act365F);
            var pfePrice    = assetPrice * Exp(-assetVol * assetVol * t / 2.0 + assetVol * Sqrt(t) * Statistics.NormInv(CI));
            var expectedPfe = (pfePrice - swap.Strike) * swap.Notional;

            Assert.Equal(expectedPfe, pfe, 6);
        }
示例#5
0
        public void StripCrackedCurve()
        {
            var buildDate = new DateTime(2018, 07, 28);

            string[] futures       = { "COV8", "COX8", "COZ8", "COF9", "COG9" };
            double[] futuresPrices = { 77, 78, 79, 79.5, 79.75 };
            string[] periods       = { "AUG18", "SEP18", "OCT18", "NOV18" };
            double[] strikes       = { -10, -11, -12, -13 };

            var cal = TestProviderHelper.CalendarProvider.Collection["LON"];
            var usd = TestProviderHelper.CurrencyProvider["USD"];

            var bPillars   = futures.Select(x => FutureCode.GetExpiryFromCode(x, TestProviderHelper.FutureSettingsProvider)).ToArray();
            var brentCurve = new PriceCurve(buildDate, bPillars, futuresPrices, PriceCurveType.ICE, TestProviderHelper.CurrencyProvider, futures)
            {
                AssetId = "Brent"
            };


            var instruments = periods.Select((p, ix) =>
                                             (IAssetInstrument)AssetProductFactory.CreateTermAsianBasisSwap(p, strikes[ix], "Brent", "Sing180", cal, cal, cal, 0.Bd(), usd, 0.Bd(), 0.Bd(), 1000, 1000 / 6.35))
                              .ToList();
            var pillars = instruments.Select(x => ((AsianBasisSwap)x).RecSwaplets.Max(sq => sq.AverageEndDate)).ToList();

            DateTime[] dPillars      = { buildDate, buildDate.AddDays(1000) };
            double[]   dRates        = { 0, 0 };
            var        discountCurve = new IrCurve(dPillars, dRates, buildDate, "zeroDiscount", Interpolator1DType.LinearFlatExtrap, usd);

            var s = new Calibrators.NewtonRaphsonAssetBasisCurveSolver(TestProviderHelper.CurrencyProvider);

            if (IsCoverageOnly)
            {
                s.Tollerance = 1.0;
            }

            var curve = s.SolveCurve(instruments, pillars, discountCurve, brentCurve, buildDate, PriceCurveType.ICE);

            if (!IsCoverageOnly)
            {
                for (var i = 0; i < instruments.Count; i++)
                {
                    var resultPV = Calibrators.NewtonRaphsonAssetBasisCurveSolver.BasisSwapPv(curve, instruments[i], discountCurve, brentCurve);
                    Assert.Equal(0, resultPV, 6);
                }
            }
        }
示例#6
0
        public void QuickPFETest()
        {
            var CI   = 0.95;
            var am   = GetModel();
            var swap = AssetProductFactory.CreateTermAsianSwap(valDate.AddDays(100), valDate.AddDays(100), assetPrice, "CL", null, valDate.AddDays(101), usd);

            swap.DiscountCurve = "USD";
            var pf = new Portfolio {
                Instruments = new List <IInstrument> {
                    swap
                }
            };

            var pfeCube = QuickPFECalculator.Calculate(am, pf, CI, usd, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);
            var pfe     = pfeCube.GetAllRows().Max(x => x.Value);

            var t           = am.BuildDate.CalculateYearFraction(swap.AverageEndDate, Transport.BasicTypes.DayCountBasis.Act365F);
            var pfePrice    = assetPrice * Exp(-assetVol * assetVol * t / 2.0 + assetVol * Sqrt(t) * Statistics.NormInv(CI));
            var expectedPfe = (pfePrice - swap.Strike) * swap.Notional;

            Assert.Equal(expectedPfe, pfe, 6);
        }
示例#7
0
        public void StripCoalSparse()
        {
            var startDate = new DateTime(2018, 07, 28);

            string[] periods = { "AUG18", "SEP18", "Q4-18", "Q1-19", "Q2-19", "H2-19", "CAL-20", "CAL-21" };
            double[] strikes = { 100, 99, 98, 97, 96, 95, 94, 93 };

            var cal = TestProviderHelper.CalendarProvider.Collection["LON"];

            var xaf = TestProviderHelper.CurrencyProvider["XAF"];


            var instruments = periods.Select((p, ix) =>
                                             AssetProductFactory.CreateMonthlyAsianSwap(p, strikes[ix], "coalXXX", cal, cal, 0.Bd(), xaf, TradeDirection.Long, 0.Bd(), 1, DateGenerationType.Fridays)
                                             ).ToList();
            var pillars = instruments.Select(x => x.Swaplets.Max(sq => sq.AverageEndDate)).ToList();

            DateTime[] dPillars      = { startDate, startDate.AddDays(1000) };
            double[]   dRates        = { 0, 0 };
            var        discountCurve = new IrCurve(dPillars, dRates, startDate, "zeroDiscount", Interpolator1DType.LinearFlatExtrap, xaf);

            var s = new NewtonRaphsonAssetCurveSolver()
            {
                Tollerance = IsCoverageOnly ? 1 : 0.00000001
            };
            var curve = s.Solve(instruments, pillars, discountCurve, startDate, TestProviderHelper.CurrencyProvider);

            if (!IsCoverageOnly)
            {
                for (var i = 0; i < instruments.Count; i++)
                {
                    var resultPV = NewtonRaphsonAssetCurveSolver.SwapPv(curve, instruments[i], discountCurve);
                    Assert.Equal(0, resultPV, 6);
                }
            }
        }
示例#8
0
        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);
        }
示例#9
0
        private AssetFxMCModel GetSut()
        {
            var buildDate = DateTime.Parse("2018-10-04");
            var usd       = TestProviderHelper.CurrencyProvider["USD"];
            var zar       = TestProviderHelper.CurrencyProvider["ZAR"];

            TestProviderHelper.CalendarProvider.Collection.TryGetCalendar("NYC", out var usdCal);
            var pair = new FxPair()
            {
                Domestic = zar, Foreign = usd, PrimaryCalendar = usdCal, SpotLag = 2.Bd()
            };

            var dfCurve = new IrCurve(new[] { buildDate, buildDate.AddDays(1000) }, new[] { 0.0, 0.0 }, buildDate, "disco", Interpolator1DType.Linear, usd, "DISCO");

            var dates    = new[] { buildDate, buildDate.AddDays(32), buildDate.AddDays(60), buildDate.AddDays(90) };
            var times    = dates.Select(d => buildDate.CalculateYearFraction(d, DayCountBasis.Act365F)).ToArray();
            var vols     = new[] { 0.32, 0.30, 0.29, 0.28 };
            var comCurve = new PriceCurve(buildDate, dates, new[] { 100.0, 100.0, 100.0, 100.0 }, PriceCurveType.NYMEX, TestProviderHelper.CurrencyProvider)
            {
                Name    = "CL",
                AssetId = "CL"
            };
            var comSurface = new GridVolSurface(buildDate, new[] { 0.5 }, dates, vols.Select(x => new double[] { x }).ToArray(), StrikeType.ForwardDelta, Interpolator1DType.Linear, Interpolator1DType.LinearInVariance, DayCountBasis.Act365F)
            {
                AssetId = "CL"
            };
            var fxSurface = new ConstantVolSurface(buildDate, 0.16)
            {
                AssetId = "USD/ZAR"
            };
            var correlVector = new CorrelationTimeVector("CL", "USD/ZAR", _correls, times);
            var fModel       = new FundingModel(buildDate, new Dictionary <string, IrCurve> {
                { "DISCO", dfCurve }
            }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);
            var fxM = new FxMatrix(TestProviderHelper.CurrencyProvider);

            fxM.Init(usd, buildDate, new Dictionary <Currency, double>()
            {
                { zar, 14.0 }
            }, new List <FxPair>()
            {
                pair
            }, new Dictionary <Currency, string> {
                { usd, "DISCO" }, { zar, "DISCO" }
            });
            fModel.SetupFx(fxM);
            fModel.VolSurfaces.Add("ZAR/USD", fxSurface);
            fModel.VolSurfaces.Add("USD/ZAR", fxSurface);

            var aModel = new AssetFxModel(buildDate, fModel);

            aModel.AddVolSurface("CL", comSurface);
            aModel.AddPriceCurve("CL", comCurve);
            aModel.CorrelationMatrix = correlVector;

            var product1 = AssetProductFactory.CreateAsianOption(dates[1], dates[1], 1400, "CL", OptionType.Call, usdCal, dates[1], zar);

            product1.TradeId          = "P1";
            product1.DiscountCurve    = "DISCO";
            product1.FxConversionType = FxConversionType.AverageThenConvert;
            var product2 = AssetProductFactory.CreateAsianOption(dates[2], dates[2], 1400, "CL", OptionType.Call, usdCal, dates[2], zar);

            product2.TradeId          = "P2";
            product2.DiscountCurve    = "DISCO";
            product2.FxConversionType = FxConversionType.AverageThenConvert;
            var product3 = AssetProductFactory.CreateAsianOption(dates[3], dates[3], 1400, "CL", OptionType.Call, usdCal, dates[3], zar);

            product3.TradeId          = "P3";
            product3.DiscountCurve    = "DISCO";
            product3.FxConversionType = FxConversionType.AverageThenConvert;

            var pfolio = new Portfolio {
                Instruments = new List <IInstrument> {
                    product1, product2, product3
                }
            };
            var settings = new McSettings
            {
                Generator         = RandomGeneratorType.MersenneTwister,
                NumberOfPaths     = (int)2.0.IntPow(15),
                NumberOfTimesteps = 1,
                ReportingCurrency = zar,
                Parallelize       = false,
                LocalCorrelation  = true,
            };
            var sut = new AssetFxMCModel(buildDate, pfolio, aModel, settings, TestProviderHelper.CurrencyProvider, TestProviderHelper.FutureSettingsProvider, TestProviderHelper.CalendarProvider);

            return(sut);
        }
示例#10
0
        public void FxDeltaOnUSDTrade()
        {
            ParallelUtils.Instance.MultiThreaded = false;

            var startDate = new DateTime(2018, 07, 28);
            var cal       = TestProviderHelper.CalendarProvider.Collection["LON"];
            var zar       = TestProviderHelper.CurrencyProvider["ZAR"];
            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 PriceCurve(startDate, curvePillarDates, curvePoints, PriceCurveType.LME, TestProviderHelper.CurrencyProvider, curvePillars)
            {
                Currency       = usd,
                CollateralSpec = "CURVE",
                Name           = "Coconuts"
            };

            var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider);
            var fxSpot   = 15;
            var rates    = new Dictionary <Currency, double> {
                { zar, fxSpot }
            };
            var discoMap = new Dictionary <Currency, string> {
                { zar, "ZAR.CURVE" }, { usd, "USD.CURVE" }
            };
            var fxPair = new FxPair()
            {
                Domestic           = usd,
                Foreign            = zar,
                SettlementCalendar = cal,
                SpotLag            = new Frequency("0b")
            };

            fxMatrix.Init(usd, startDate, rates, new List <FxPair> {
                fxPair
            }, discoMap);

            var irPillars = new[] { startDate, startDate.AddYears(10) };
            var zarRates  = new[] { 0.0, 0.0 };
            var usdRates  = new[] { 0.0, 0.0 };
            var zarCurve  = new IrCurve(irPillars, zarRates, startDate, "ZAR.CURVE", Interpolator1DType.Linear, zar, "CURVE");
            var usdCurve  = new IrCurve(irPillars, usdRates, startDate, "USD.CURVE", Interpolator1DType.Linear, usd, "CURVE");

            var fModel = new FundingModel(startDate, new[] { zarCurve, 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, zar);
            var assetFwd    = curve.GetAveragePriceForDates(fixingDates);
            var fairStrike  = assetFwd;
            var strike      = fairStrike - 10;
            var nominal     = 1000;

            var asianSwap = AssetProductFactory.CreateMonthlyAsianSwap(periodCode, strike, "Coconuts", cal, cal, new Frequency("5b"), usd, TradeDirection.Long, new Frequency("0b"), nominal, DateGenerationType.BusinessDays);

            asianSwap.TradeId = "aLovelyBunch";
            foreach (var sw in asianSwap.Swaplets)
            {
                sw.DiscountCurve    = "USD.CURVE";
                sw.FxConversionType = FxConversionType.None;
            }
            var pv         = asianSwap.PV(aModel, false);
            var expectedPV = (fairStrike - strike) * nominal;

            Assert.Equal(expectedPV, pv, 8);

            var portfolio = new Portfolio()
            {
                Instruments = new List <IInstrument> {
                    asianSwap
                }
            };
            var pfPvCube = portfolio.PV(aModel, usd);
            var pfPv     = (double)pfPvCube.GetAllRows().First().Value;

            Assert.Equal(expectedPV, pfPv, 8);

            //expected fx delta is just PV in USD
            var deltaCube = portfolio.FxDelta(aModel, zar, TestProviderHelper.CurrencyProvider);
            var dAgg      = deltaCube.Pivot("TradeId", AggregationAction.Sum);
            var delta     = (double)dAgg.GetAllRows().First().Value;

            Assert.Equal(expectedPV, delta, 4);
        }