public static (IrCurve curve, double spotPrice) GetMetalCurveForCode(string cmxSettleFwdFilename, string cmxSymbol, FxPair metalPair, string curveName, DateTime valDate, IrCurve baseCurve, ICurrencyProvider currencyProvider, ICalendarProvider calendarProvider) { var blob = CMEFileParser.Instance.GetBlob(cmxSettleFwdFilename); var fwds = blob.Batch.Where(b => b.Instrmt.Sym == cmxSymbol).ToDictionary(x => x.Instrmt.MatDt, x => Convert.ToDouble(x.Full.Where(x => x.Typ == "6").First().Px)); var curveCcy = metalPair.Domestic; var bc = baseCurve.Clone(); bc.SolveStage = -1; var spotDate = metalPair.SpotDate(valDate); var spotRate = Convert.ToDouble(fwds[spotDate]); fwds = Downsample(fwds, spotDate, metalPair.PrimaryCalendar); var fwdObjects = fwds.Select(x => new FxForward { DomesticCCY = metalPair.Foreign, DeliveryDate = x.Key, DomesticQuantity = 1e6, ForeignCCY = metalPair.Domestic, PillarDate = x.Key, SolveCurve = curveName, Strike = Convert.ToDouble(x.Value), ForeignDiscountCurve = baseCurve.Name, }); var fic = new FundingInstrumentCollection(currencyProvider); fic.AddRange(fwdObjects); var pillars = fwds.Keys.OrderBy(x => x).ToArray(); var curve = new IrCurve(pillars, pillars.Select(p => 0.01).ToArray(), valDate, curveName, Interpolator1DType.Linear, curveCcy); var fm = new FundingModel(valDate, new[] { curve, bc }, currencyProvider, calendarProvider); var matrix = new FxMatrix(currencyProvider); var discoMap = new Dictionary <Currency, string> { { curveCcy, curveName }, { baseCurve.Currency, baseCurve.Name } }; matrix.Init(metalPair.Foreign, valDate, new Dictionary <Currency, double> { { metalPair.Domestic, spotRate } }, new List <FxPair> { metalPair }, discoMap); fm.SetupFx(matrix); var solver = new NewtonRaphsonMultiCurveSolverStaged() { InLineCurveGuessing = true }; solver.Solve(fm, fic); return(curve, spotRate); }
public static IrCurve StripFxBasisCurve(string cmeFwdFileName, FxPair ccyPair, string cmePair, Currency curveCcy, string curveName, DateTime valDate, IrCurve baseCurve, ICurrencyProvider currencyProvider, ICalendarProvider calendarProvider) { var fwdsDict = GetFwdFxRatesFromFwdFile(cmeFwdFileName, new Dictionary <string, string> { { ccyPair.ToString(), cmePair } }); var bc = baseCurve.Clone(); bc.SolveStage = -1; var fwds = fwdsDict[ccyPair.ToString()]; var spotDate = ccyPair.SpotDate(valDate); var spotRate = fwds[spotDate]; fwds = Downsample(fwds, spotDate, ccyPair.PrimaryCalendar); var fwdObjects = fwds.Select(x => new FxForward { DomesticCCY = ccyPair.Domestic, DeliveryDate = x.Key, DomesticQuantity = 1e6, ForeignCCY = ccyPair.Foreign, PillarDate = x.Key, SolveCurve = curveName, Strike = x.Value, ForeignDiscountCurve = ccyPair.Foreign == curveCcy ? curveName : baseCurve.Name, }); var fic = new FundingInstrumentCollection(currencyProvider); fic.AddRange(fwdObjects); var pillars = fwds.Keys.OrderBy(x => x).ToArray(); var curve = new IrCurve(pillars, pillars.Select(p => 0.01).ToArray(), valDate, curveName, Interpolator1DType.Linear, curveCcy); var fm = new FundingModel(valDate, new[] { curve, bc }, currencyProvider, calendarProvider); var matrix = new FxMatrix(currencyProvider); var discoMap = new Dictionary <Currency, string> { { curveCcy, curveName }, { baseCurve.Currency, baseCurve.Name } }; matrix.Init(ccyPair.Domestic, valDate, new Dictionary <Currency, double> { { ccyPair.Foreign, spotRate } }, new List <FxPair> { ccyPair }, discoMap); fm.SetupFx(matrix); var solver = new NewtonRaphsonMultiCurveSolverStaged() { InLineCurveGuessing = true }; solver.Solve(fm, fic); return(curve); }
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 object CreateFxSwap( [ExcelArgument(Description = "Object name")] string ObjectName, [ExcelArgument(Description = "Value Date")] DateTime ValDate, [ExcelArgument(Description = "Tenor")] string Tenor, [ExcelArgument(Description = "Spot Price")] double SpotPrice, [ExcelArgument(Description = "Domestic Currency")] string DomesticCcy, [ExcelArgument(Description = "Foreign Currency")] string ForeignCcy, [ExcelArgument(Description = "Domestic Notional")] double DomesticNotional, [ExcelArgument(Description = "Swap Points")] double SwapPoints, [ExcelArgument(Description = "Foreign Discount Curve")] string DiscountCurve, [ExcelArgument(Description = "Solve Curve name ")] string SolveCurve, [ExcelArgument(Description = "Solve Pillar Date")] object SolvePillarDate, [ExcelArgument(Description = "Divisor, defualt 10,000")] object Divisor, [ExcelArgument(Description = "Spot lag, defualt 2b")] object SpotLag) { return(ExcelHelper.Execute(_logger, () => { var spotLag = SpotLag.OptionalExcel("2b"); var divisor = Divisor.OptionalExcel(10000.0); ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(DomesticCcy, out var domesticCal); ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(ForeignCcy, out var foreignCal); var domesticCCY = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(DomesticCcy); var foreignCCY = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(ForeignCcy); var pair = new FxPair() { Domestic = domesticCCY, Foreign = foreignCCY, SpotLag = new Frequency(spotLag), PrimaryCalendar = domesticCal, SecondaryCalendar = foreignCal }; var SettleDate = new DateTime(); var SolveDate = new DateTime(); var fwd = SpotPrice; switch (Tenor.ToUpper()) { case "ON": case "O/N": case "OVERNIGHT": SettleDate = ValDate.AddPeriod(RollType.F, domesticCal, 1.Bd()); SettleDate = SettleDate.IfHolidayRollForward(foreignCal); var swapProduct = new FxSwap(SwapPoints, ValDate, SettleDate, DomesticNotional, ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(DomesticCcy), ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(ForeignCcy)) { SolveCurve = SolveCurve, PillarDate = DateTime.FromOADate(SolvePillarDate.OptionalExcel(SettleDate.ToOADate())), }; return ExcelHelper.PushToCache(swapProduct, ObjectName); case "T/N": case "TN": SettleDate = pair.SpotDate(ValDate).SubtractPeriod(RollType.P, domesticCal, 1.Bd()); var startDate = SettleDate.IfHolidayRollBack(foreignCal); SolveDate = DateTime.FromOADate(SolvePillarDate.OptionalExcel(pair.SpotDate(ValDate).ToOADate())); fwd -= SwapPoints / divisor; break; default: SettleDate = pair.SpotDate(ValDate); var rt = Tenor.EndsWith("M") || Tenor.EndsWith("Y") ? RollType.MF : RollType.F; SettleDate = SettleDate.AddPeriod(rt, domesticCal, new Frequency(Tenor)); SettleDate = SettleDate.IfHolidayRollForward(foreignCal); fwd += SwapPoints / divisor; SolveDate = DateTime.FromOADate(SolvePillarDate.OptionalExcel(SettleDate.ToOADate()));; break; } var product = new FxForward { DomesticCCY = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(DomesticCcy), ForeignCCY = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(ForeignCcy), DomesticQuantity = DomesticNotional, DeliveryDate = SettleDate, ForeignDiscountCurve = DiscountCurve, SolveCurve = SolveCurve, PillarDate = SolveDate, Strike = fwd, TradeId = ObjectName }; return ExcelHelper.PushToCache(product, ObjectName); })); }