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 BasicPriceCurve(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 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))); }
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); }
public static object CreatePriceCurve( [ExcelArgument(Description = "Object name")] string ObjectName, [ExcelArgument(Description = "Asset Id")] string AssetId, [ExcelArgument(Description = "Build date")] DateTime BuildDate, [ExcelArgument(Description = "Array of pillar dates")] double[] Pillars, [ExcelArgument(Description = "Array of prices values")] double[] Prices, [ExcelArgument(Description = "Type of curve, e.g. LME, ICE, NYMEX etc")] object CurveType, [ExcelArgument(Description = "Array of pillar labels (optional)")] object PillarLabels, [ExcelArgument(Description = "Currency - default USD")] object Currency, [ExcelArgument(Description = "Collateral spec, required for delta calculation - default LIBOR.3M")] object CollateralSpec, [ExcelArgument(Description = "Spot lag, required for theta, default 0b")] object SpotLag, [ExcelArgument(Description = "Spot calendar, required for theta, default USD")] object SpotCalendar) { return(ExcelHelper.Execute(_logger, () => { var curveTypeStr = CurveType.OptionalExcel("Linear"); var ccy = Currency.OptionalExcel("USD"); var colSpec = CollateralSpec.OptionalExcel("LIBOR.3M"); var spotLagStr = SpotLag.OptionalExcel("0b"); var spotCalStr = SpotCalendar.OptionalExcel("USD"); if (!Enum.TryParse(curveTypeStr, out PriceCurveType cType)) { return $"Could not parse price curve type - {curveTypeStr}"; } ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(ccy, out var ccyCal); ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(spotCalStr, out var spotCal); var ccyObj = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>()[ccy]; var labels = (PillarLabels is ExcelMissing) ? null : ((object[, ])PillarLabels).ObjectRangeToVector <string>(); var pDates = Pillars.ToDateTimeArray(); var cObj = new BasicPriceCurve(BuildDate, pDates, Prices, cType, ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>(), labels) { Name = AssetId ?? ObjectName, AssetId = AssetId ?? ObjectName, Currency = ccyObj, CollateralSpec = colSpec, SpotCalendar = spotCal, SpotLag = new Frequency(spotLagStr) }; var cache = ContainerStores.GetObjectCache <IPriceCurve>(); cache.PutObject(ObjectName, new SessionItem <IPriceCurve> { Name = ObjectName, Value = cObj }); return ObjectName + '¬' + cache.GetObject(ObjectName).Version; })); }
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 BasicPriceCurve(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 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 = NewtonRaphsonAssetBasisCurveSolver.BasisSwapPv(curve, instruments[i], discountCurve, brentCurve); Assert.Equal(0, resultPV, 6); } } }
public static BasicPriceCurve GetCurveForCode(string nymexSymbol, string nymexFutureFilename, string qwackCode, IFutureSettingsProvider provider, ICurrencyProvider currency) { var parsed = NYMEXFutureParser.Instance.Parse(nymexFutureFilename).Where(r => r.Symbol == nymexSymbol); var q = parsed.Where(x => x.Settle.HasValue).ToDictionary(x => Year2to1(x.Contract.Replace(nymexSymbol, qwackCode)), x => x.Settle); var datesDict = q.ToDictionary(x => FutureCode.GetExpiryFromCode(x.Key, provider), x => x.Key); var datesVec = datesDict.Keys.OrderBy(x => x).ToArray(); var labelsVec = datesVec.Select(d => datesDict[d]).ToArray(); var pricesVec = labelsVec.Select(l => System.Math.Max(q[l].Value, MinPrice)).ToArray(); var origin = DateTime.ParseExact(parsed.First().TradeDate, "MM/dd/yyyy", CultureInfo.InvariantCulture); var curve = new BasicPriceCurve(origin, datesVec, pricesVec, PriceCurveType.NYMEX, currency, labelsVec) { AssetId = qwackCode, Name = qwackCode, SpotLag = 0.Bd() }; return(curve); }
public static BasicPriceCurve GetFuturesCurveForCode(string cmeSymbol, string cmeFutureFilename, ICurrencyProvider currency) { var parsed = CMEFileParser.Instance.Parse(cmeFutureFilename).Where(r => r.Sym == cmeSymbol && r.SecTyp == "FUT"); var q = parsed.Where(x => x.SettlePrice.HasValue).ToDictionary(x => DateTime.ParseExact(x.MatDt, "yyyy-MM-dd", CultureInfo.InvariantCulture), x => x.SettlePrice); var datesVec = q.Keys.Distinct().OrderBy(x => x).ToArray(); var labelsVec = parsed.Select(x => new Tuple <DateTime, string>(DateTime.ParseExact(x.MatDt, "yyyy-MM-dd", CultureInfo.InvariantCulture), x.MMY)) .Distinct() .OrderBy(x => x.Item1) .Select(x => x.Item2) .ToArray(); var pricesVec = datesVec.Select(l => System.Math.Max(q[l].Value, MinPrice)).ToArray(); var origin = DateTime.ParseExact(parsed.First().BizDt, "yyyy-MM-dd", CultureInfo.InvariantCulture); var curve = new BasicPriceCurve(origin, datesVec, pricesVec, PriceCurveType.NYMEX, currency, labelsVec) { SpotLag = 0.Bd() }; return(curve); }
public void PriceCurveFact() { var origin = new DateTime(2019, 05, 28); var z1 = new BasicPriceCurve(origin, new[] { new DateTime(2019, 05, 31), new DateTime(2019, 06, 30) }, new[] { 100.0, 110.0 }, PriceCurveType.NYMEX, TestProviderHelper.CurrencyProvider); Assert.Equal(2, z1.NumberOfPillars); var z1r = z1.RebaseDate(origin.AddDays(10)); Assert.Single(z1r.PillarDates); Assert.Equal(1, z1r.NumberOfPillars); Assert.Equal(110, z1r.GetPriceForFixingDate(origin)); var z2 = new BasicPriceCurve(origin, new[] { new DateTime(2019, 05, 31), new DateTime(2019, 06, 30) }, new[] { 100.0, 110.0 }, PriceCurveType.ICE, TestProviderHelper.CurrencyProvider); var z2r = z2.RebaseDate(origin.AddDays(10)); Assert.Single(z1r.PillarDates); var z3 = new BasicPriceCurve(origin, new[] { new DateTime(2019, 05, 31), new DateTime(2019, 06, 30) }, new[] { 100.0, 110.0 }, PriceCurveType.LME, TestProviderHelper.CurrencyProvider); var z3r = z3.RebaseDate(origin.AddDays(10)); Assert.Single(z1r.PillarDates); }
public static IAssetFxModel AssetCurveShift(string assetId, double shiftSize, IAssetFxModel model) { var o = model.Clone(); var curve = model.GetPriceCurve(assetId); switch (curve) { case BasicPriceCurve pc: var npc = new BasicPriceCurve(pc.BuildDate, pc.PillarDates, pc.Prices.Select(p => p + shiftSize).ToArray(), pc.CurveType, pc.CurrencyProvider, pc.PillarLabels) { AssetId = pc.AssetId, Name = pc.Name, CollateralSpec = pc.CollateralSpec, Currency = pc.Currency, }; o.AddPriceCurve(assetId, npc); break; default: throw new Exception("Unable to mutate curve type"); } return(o); }
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 static RiskyFlySurface GetSurfaceForCode(string nymexSymbol, string nymexOptionFilename, string qwackCode, BasicPriceCurve priceCurve, ICalendarProvider calendarProvider, ICurrencyProvider currency, IFutureSettingsProvider futureSettingsProvider) { var parsed = NYMEXOptionParser.Instance.Parse(nymexOptionFilename).Where(r => r.Symbol == nymexSymbol); var(optionExerciseType, optionMarginingType) = OptionTypeFromCode(nymexSymbol); var origin = DateTime.ParseExact(parsed.First().TradeDate, "MM/dd/yyyy", CultureInfo.InvariantCulture); var q = parsed.Where(x => x.Settle > 0).Select(x => new ListedOptionSettlementRecord { CallPut = x.PutCall == "C"?OptionType.C:OptionType.P, ExerciseType = optionExerciseType, MarginType = optionMarginingType, PV = x.Settle, Strike = x.Strike, UnderlyingFuturesCode = Year2to1(x.Contract.Split(' ')[0].Replace(nymexSymbol, qwackCode)), ExpiryDate = OptionExpiryFromNymexRecord(x, calendarProvider), ValDate = origin }).Where(z => z.ExpiryDate > origin).ToList(); var priceDict = priceCurve.PillarLabels.ToDictionary(x => x, x => priceCurve.GetPriceForDate(priceCurve.PillarDatesForLabel(x))); ListedSurfaceHelper.ImplyVols(q, priceDict, new ConstantRateIrCurve(0.0, origin, "dummy", currency.GetCurrency("USD"))); var smiles = ListedSurfaceHelper.ToDeltaSmiles(q, priceDict); var allOptionExpiries = new List <DateTime>(); var lastDate = q.Max(x => x.ExpiryDate); var dummyFutureCode = $"{qwackCode}Z{DateExtensions.SingleDigitYear(DateTime.Today.Year + 2)}"; var c = new FutureCode(dummyFutureCode, DateTime.Today.Year - 2, futureSettingsProvider); var contract = c.GetFrontMonth(origin, false); var lastContract = c.GetFrontMonth(lastDate, false); while (contract != lastContract) { var cc = new FutureCode(contract, origin.Year, futureSettingsProvider); var exp = ListedUtils.FuturesCodeToDateTime(contract); var record = new NYMEXOptionRecord { ContractMonth = exp.Month, ContractYear = exp.Year, Symbol = nymexSymbol }; var optExpiry = OptionExpiryFromNymexRecord(record, calendarProvider); if (optExpiry > origin) { allOptionExpiries.Add(optExpiry); } contract = cc.GetNextCode(false); } var surface = ListedSurfaceHelper.ToRiskyFlySurfaceStepFlat(smiles, origin, priceCurve, allOptionExpiries, currency); return(surface); }
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 BasicPriceCurve(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); }
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 BasicPriceCurve(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, PrimaryCalendar = 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); }
public static RiskyFlySurface GetFxSurfaceForCode(string cmeSymbol, string cmeFutureFilename, BasicPriceCurve priceCurve, ICurrencyProvider currency) { var parsed = CMEFileParser.Instance.Parse(cmeFutureFilename).Where(r => r.Sym == cmeSymbol && r.SecTyp == "OOF" && r.SettlePrice.HasValue); var(optionExerciseType, optionMarginingType) = OptionTypeFromCode(cmeSymbol); var origin = DateTime.ParseExact(parsed.First().BizDt, "yyyy-MM-dd", CultureInfo.InvariantCulture); var q = parsed.Where(x => x.SettlePrice > 0).Select(x => new ListedOptionSettlementRecord { CallPut = x.PutCall == 1 ? OptionType.C : OptionType.P, ExerciseType = optionExerciseType, MarginType = optionMarginingType, PV = x.SettlePrice.Value, Strike = x.StrkPx.Value, UnderlyingFuturesCode = x.UndlyMMY, ExpiryDate = DateTime.ParseExact(x.MatDt, "yyyy-MM-dd", CultureInfo.InvariantCulture), ValDate = origin }).Where(z => z.ExpiryDate > origin).ToList(); var priceDict = priceCurve.PillarLabels.ToDictionary(x => x, x => priceCurve.GetPriceForDate(priceCurve.PillarDatesForLabel(x))); ListedSurfaceHelper.ImplyVols(q, priceDict, new ConstantRateIrCurve(0.0, origin, "dummy", currency.GetCurrency("USD"))); var smiles = ListedSurfaceHelper.ToDeltaSmiles(q, priceDict); var expiries = smiles.Keys.OrderBy(x => x).ToArray(); var ulByExpiry = expiries.ToDictionary(x => x, x => q.Where(qq => qq.ExpiryDate == x).First().UnderlyingFuturesCode); var fwdByExpiry = ulByExpiry.ToDictionary(x => x.Key, x => priceCurve.GetPriceForDate(priceCurve.PillarDatesForLabel(x.Value))); var fwds = expiries.Select(e => fwdByExpiry[e]).ToArray(); var surface = ListedSurfaceHelper.ToRiskyFlySurface(smiles, origin, fwds, currency); return(surface); }