public double CalculateParRate(IFundingModel model) { var sumTop = 0.0; var sumBottom = 0.0; foreach (var flow in LoanDepoSchedule.Flows) { var n = flow.Notional; var df = model.Curves[DiscountCurve].GetDf(model.BuildDate, flow.SettleDate); var dcf = flow.Dcf; var r = flow.FlowType == FlowType.FloatRate ? flow.GetFloatRate(model.Curves[ForecastCurve], FloatRateIndex.DayCountBasis) : 1.0; sumTop += -n * dcf * df * r; sumBottom += flow.FlowType == FlowType.NotionalExchange ? 0.0 : n * dcf * df; } var parRate = sumTop / sumBottom; return(parRate); //var targetFunc = new Func<double, double>(spd=> //{ // return SetParRate(spd).Pv(model, true); //}); //var par = Math.Solvers.Brent.BrentsMethodSolve(targetFunc, -0.1, 0.5, 0.0001); //return par; }
private void ComputeJacobian(List <IFundingInstrument> instruments, IFundingModel model, List <IIrCurve> curvesForStage, double[] currentGuess, double[] bumpedPvs, double[] currentPvs, ref double[][] jacobian) { var curveIx = 0; var pillarIx = 0; for (var i = 0; i < instruments.Count; i++) { var currentCurve = curvesForStage[curveIx]; model.CurrentSolveCurve = currentCurve.Name; currentGuess[i] = currentCurve.GetRate(pillarIx); currentCurve.BumpRate(pillarIx, JacobianBump, true); ComputePVs(false, instruments, model, bumpedPvs); currentCurve.BumpRate(pillarIx, -JacobianBump, true); for (var j = 0; j < bumpedPvs.Length; j++) { jacobian[i][j] = (bumpedPvs[j] - currentPvs[j]) / JacobianBump; } pillarIx++; if (pillarIx == currentCurve.NumberOfPillars) { pillarIx = 0; curveIx++; } } model.CurrentSolveCurve = null; }
public static IFundingModel RemapBaseCurrency(IFundingModel input, Currency newBaseCurrency, ICurrencyProvider currencyProvider) { if (newBaseCurrency == input.FxMatrix.BaseCurrency) { return(input.Clone()); } var mf = input.DeepClone(null); var homeToBase = mf.FxMatrix.SpotRates[newBaseCurrency]; var ccys = mf.FxMatrix.SpotRates.Keys.ToList() .Concat(new[] { mf.FxMatrix.BaseCurrency }) .Where(x => x != newBaseCurrency); var newRateDict = new Dictionary <Currency, double>(); foreach (var ccy in ccys) { var spotDate = mf.FxMatrix.GetFxPair(newBaseCurrency, ccy).SpotDate(mf.BuildDate); var newRate = mf.GetFxRate(spotDate, newBaseCurrency, ccy); newRateDict.Add(ccy, newRate); } var newFx = new FxMatrix(currencyProvider); newFx.Init(newBaseCurrency, mf.FxMatrix.BuildDate, newRateDict, mf.FxMatrix.FxPairDefinitions, mf.FxMatrix.DiscountCurveMap); mf.SetupFx(newFx); return(mf); }
public double Pv(IFundingModel model, bool updateState) { var updateDF = updateState || model.CurrentSolveCurve == DiscountCurve; var updateEst = updateState || model.CurrentSolveCurve == ForecastCurve; return(Pv(model.Curves[DiscountCurve], model.Curves[ForecastCurve], updateState, updateDF, updateEst)); }
public double Pv(IFundingModel model, bool updateState, bool ignoreTodayFlows) { var discountCurve = model.Curves[DiscountCurve]; var pv = LoanDepoSchedule.PV(discountCurve, discountCurve, updateState, true, false, DayCountBasis.ACT360, ignoreTodayFlows ? model.BuildDate.AddDays(1) : model.BuildDate); return(pv); }
public double Pv(IFundingModel Model, bool updateState) { var fairPrice = CalculateParRate(Model); var PV = (Price - fairPrice) * Position * ContractSize * DCF; return(PV); }
public double CalculateParRate(IFundingModel model) { var farFx = model.GetFxRate(FarDate, DomesticCcy, ForeignCcy); var nearFx = model.GetFxRate(NearDate, DomesticCcy, ForeignCcy); return((farFx - nearFx) * Divisor); }
private void ComputeJacobian(List <IFundingInstrument> instruments, IFundingModel model, List <IIrCurve> curvesForStage) { var nPillars = curvesForStage.Sum(x => x.NumberOfPillars); _jacobian = new double[instruments.Count][]; for (var i = 0; i < _jacobian.Length; i++) { _jacobian[i] = new double[nPillars]; } for (var i = 0; i < instruments.Count; i++) { var sensitivities = instruments[i].Sensitivities(model); var pillarOffset = 0; foreach (var curve in curvesForStage) { if (sensitivities.ContainsKey(curve.Name)) { foreach (var date in sensitivities[curve.Name].Keys) { var s1 = curve.GetSensitivity(date); for (var p = 0; p < s1.Length; p++) { _jacobian[pillarOffset + p][i] += s1[p] * sensitivities[curve.Name][date]; } } } pillarOffset += curve.NumberOfPillars; } } }
public double SuggestPillarValue(IFundingModel model) { var discountCurve = model.Curves[SolveCurve]; var t = discountCurve.Basis.CalculateYearFraction(discountCurve.BuildDate, MaturityDate); return(-System.Math.Log(Price) / t); }
public double CalculateParRate(IFundingModel model) { var dFs = FlowScheduleFloat.Flows.Select(x => x.SettleDate).Select(y => model.Curves[DiscountCurve].GetDf(model.BuildDate, y)); var floatRates = FlowScheduleFloat.Flows.Select(x => x.GetFloatRate(model.Curves[ForecastCurve], BasisFloat)).ToArray(); var parRate = dFs.Select((x, ix) => x * floatRates[ix]).Sum() / dFs.Sum(); return(parRate); }
public AssetFxModel(DateTime buildDate, IFundingModel fundingModel) { _assetCurves = new Dictionary <string, IPriceCurve>(); _assetVols = new Dictionary <VolSurfaceKey, IVolSurface>(); _fixings = new Dictionary <string, IFixingDictionary>(); _buildDate = buildDate; _fundingModel = fundingModel; }
public double Pv(IFundingModel model, bool updateState) { var updateDfPay = updateState || model.CurrentSolveCurve == DiscountCurvePay; var updateDfRec = updateState || model.CurrentSolveCurve == DiscountCurveRec; var updatePayEst = updateState || model.CurrentSolveCurve == ForecastCurvePay; var updateRecEst = updateState || model.CurrentSolveCurve == ForecastCurveRec; return(PV(model, updateState, updateDfPay, updateDfRec, updatePayEst, updateRecEst)); }
public double CalculateParRate(IFundingModel Model) { var forecastCurve = Model.Curves[ForecastCurve]; var fwdRate = forecastCurve.GetForwardRate(AverageStartDate, AverageEndDate, RateType.Linear, Index.DayCountBasis); var fairPrice = 100.0 - fwdRate * 100.0; return(fairPrice); }
public double CalculateParRate(IFundingModel model) { var discountCurve = model.Curves[CashDiscountCurve]; var SpotRate = model.GetFxRate(SpotDate, MetalCCY, CashCCY); var t = SpotDate.CalculateYearFraction(DeliveryDate, Basis); var fwd = model.GetFxRate(DeliveryDate, MetalCCY, CashCCY); var ctgo = (fwd / SpotRate - 1.0) / t; return(ctgo); }
public double CalculateParRate(IFundingModel model) { var discountCurvePay = model.Curves[DiscountCurvePay]; var discountCurveRec = model.Curves[DiscountCurveRec]; var forecastCurvePay = model.Curves[ForecastCurvePay]; var forecastCurveRec = model.Curves[ForecastCurveRec]; var payCCY = MtmSwapType == MTMSwapType.ReceiveNotionalFixed ? CcyRec : CcyPay; var recCCY = MtmSwapType == MTMSwapType.PayNotionalFixed ? CcyPay : CcyRec; var baseCCY = Pvccy ?? payCCY; var fxPayToBase = model.GetFxRate(model.BuildDate, payCCY, baseCCY); var fxRecToBase = model.GetFxRate(model.BuildDate, recCCY, baseCCY); if (ParSpreadPay != 0.0) { var newSched = FlowSchedulePay.Clone(); var recPV = FlowScheduleRec.PV(discountCurveRec, forecastCurveRec, true, true, true, BasisRec, null); recPV *= fxRecToBase; var targetFunc = new Func <double, double>(spread => { foreach (var s in newSched.Flows.Where(x => x.FlowType == FlowType.FloatRate)) { s.FixedRateOrMargin = spread; } var pv = newSched.PV(discountCurvePay, forecastCurvePay, true, true, true, BasisPay, null); pv *= fxPayToBase; return(pv - recPV); } ); var newSpread = Math.Solvers.Newton1D.MethodSolve(targetFunc, 0, 0.000001); return(newSpread); } else { var newSched = FlowScheduleRec.Clone(); var payPV = FlowSchedulePay.PV(discountCurvePay, forecastCurvePay, true, true, true, BasisPay, null); payPV *= fxPayToBase; var targetFunc = new Func <double, double>(spread => { foreach (var s in newSched.Flows.Where(x => x.FlowType == FlowType.FloatRate)) { s.FixedRateOrMargin = spread; } var pv = newSched.PV(discountCurveRec, forecastCurveRec, true, true, true, BasisRec, null); pv *= fxRecToBase; return(pv - payPV); } ); var newSpread = Math.Solvers.Newton1D.MethodSolve(targetFunc, 0, 0.000001); return(newSpread); } }
public double CalculateParRate(IFundingModel Model) { var rateStart = Expiry.AddPeriod(RollType.F, Index.HolidayCalendars, Index.FixingOffset); var rateEnd = rateStart.AddPeriod(Index.RollConvention, Index.HolidayCalendars, Index.ResetTenor); var forecastCurve = Model.Curves[ForecastCurve]; var fwdRate = forecastCurve.GetForwardRate(rateStart, rateEnd, RateType.Linear, Index.DayCountBasis); var fairPrice = 100.0 - (fwdRate + ConvexityAdjustment) * 100.0; return(fairPrice); }
public double Pv(IFundingModel model, bool updateState) { var discName = model.FxMatrix.GetDiscountCurve(ForeignCcy); var discCurve = model.GetCurve(discName); var farFx = model.GetFxRate(FarDate, DomesticCcy, ForeignCcy); var nearFx = model.GetFxRate(NearDate, DomesticCcy, ForeignCcy); var farStrike = nearFx + SwapPoints / Divisor; var farPv = -(farFx - farStrike) * Notional * discCurve.GetDf(model.BuildDate, FarDate); return(farPv); }
public double Pv(IFundingModel model, bool updateState) { var updateDf = updateState || (model.CurrentSolveCurve == DiscountCurve); var updateEst = updateState || (model.CurrentSolveCurve == ForecastCurve); var discountCurve = model.Curves[DiscountCurve]; var forecastCurve = model.Curves[ForecastCurve]; var fixedPv = FlowScheduleFixed.PV(discountCurve, forecastCurve, updateState, updateDf, updateEst, BasisFloat, null); var floatPv = FlowScheduleFloat.PV(discountCurve, forecastCurve, updateState, updateDf, updateEst, BasisFloat, null); return(fixedPv + floatPv); }
public CompositeVolSurface(string name, string assetId, Currency ccy, IVolSurface assetSurface, IFundingModel fundingModel, double correlation, CompositeVolType calculationType) { AssetSurface = assetSurface; FundingModel = fundingModel; Correlation = correlation; CalculationType = calculationType; Name = name; AssetId = assetId; Currency = ccy; _Pair = FundingModel.FxMatrix.GetFxPair(AssetSurface.Currency, Currency); }
public double FlowsT0(IFundingModel Model) { if (DeliveryDate != Model.BuildDate) { return(0.0); } var fwdRate = Model.GetFxRate(DeliveryDate, DomesticCCY, ForeignCCY); var FV = (fwdRate - Strike) * DomesticQuantity; return(FV); }
public double Pv(IFundingModel model, bool updateState) { var discountCurve = model.Curves[CashDiscountCurve]; var SpotRate = model.GetFxRate(SpotDate, MetalCCY, CashCCY); var t = SpotDate.CalculateYearFraction(DeliveryDate, Basis); var strike = SpotRate * (1.0 + ContangoRate * t); var fwd = model.GetFxRate(DeliveryDate, MetalCCY, CashCCY); var FV = (fwd - strike) * MetalQuantity; var PV = discountCurve.Pv(FV, DeliveryDate); return(PV); }
public double FlowsT0(IFundingModel model) { if (StartDate == model.BuildDate) { return(Notional); } else if (EndDate == model.BuildDate) { var dcf = StartDate.CalculateYearFraction(EndDate, Basis); return(-Notional - Notional * dcf * InterestRate); } return(0.0); }
public double SuggestPillarValue(IFundingModel model) { var discountCurve = model.Curves[CashDiscountCurve]; var SpotRate = model.GetFxRate(SpotDate, MetalCCY, CashCCY); var t = SpotDate.CalculateYearFraction(DeliveryDate, Basis); var fwd = SpotRate * (1.0 + ContangoRate * t); var fxr = fwd / SpotRate; var df1 = discountCurve.GetDf(SpotDate, PillarDate); var df2 = df1 / fxr; var rate = -System.Math.Log(df2) / t; return(rate); }
public double Pv(IFundingModel Model, bool updateState, bool ignoreTodayFlows) { if (Model.BuildDate > DeliveryDate || (ignoreTodayFlows && Model.BuildDate == DeliveryDate)) { return(0.0); } var discountCurve = Model.Curves[ForeignDiscountCurve]; var fwdRate = Model.GetFxRate(DeliveryDate, DomesticCCY, ForeignCCY); var FV = (fwdRate - Strike) * DomesticQuantity; var PV = discountCurve.Pv(FV, DeliveryDate); return(PV); }
public double Pv(IFundingModel model, bool updateState) { var updateDF = updateState || model.CurrentSolveCurve == DiscountCurve; var updatePayEst = updateState || model.CurrentSolveCurve == ForecastCurvePay; var updateRecEst = updateState || model.CurrentSolveCurve == ForecastCurveRec; var discountCurve = model.Curves[DiscountCurve]; var forecastCurvePay = model.Curves[ForecastCurvePay]; var forecastCurveRec = model.Curves[ForecastCurveRec]; var payPV = FlowSchedulePay.PV(discountCurve, forecastCurvePay, updateState, updateDF, updatePayEst, BasisPay, null); var recPV = FlowScheduleRec.PV(discountCurve, forecastCurveRec, updateState, updateDF, updateRecEst, BasisRec, null); return(payPV + recPV); }
public Dictionary <string, Dictionary <DateTime, double> > Sensitivities(IFundingModel model) { var foreignCurve = model.FxMatrix.DiscountCurveMap[CashCCY]; var domesticCurve = model.FxMatrix.DiscountCurveMap[MetalCCY]; var discountCurve = model.Curves[CashDiscountCurve]; var df = discountCurve.Pv(1.0, DeliveryDate); var t = discountCurve.Basis.CalculateYearFraction(discountCurve.BuildDate, DeliveryDate); var spotRate = model.GetFxRate(SpotDate, MetalCCY, CashCCY); var strike = spotRate * (1.0 + ContangoRate * t); var fwdRate = model.GetFxRate(DeliveryDate, MetalCCY, CashCCY); var domesticDict = new Dictionary <DateTime, double>() { { DeliveryDate, fwdRate *MetalQuantity *df *t } }; Dictionary <DateTime, double> foreignDict; if (foreignCurve == CashDiscountCurve) { foreignDict = new Dictionary <DateTime, double>() { { DeliveryDate, MetalQuantity *df *(fwdRate * -2 * t + strike * t) } }; return(new Dictionary <string, Dictionary <DateTime, double> >() { { foreignCurve, foreignDict }, { domesticCurve, domesticDict }, }); } else { foreignDict = new Dictionary <DateTime, double>() { { DeliveryDate, fwdRate *MetalQuantity *df * -t } }; var foreignDiscDict = new Dictionary <DateTime, double>() { { DeliveryDate, (fwdRate - strike) * MetalQuantity * df * -t } }; return(new Dictionary <string, Dictionary <DateTime, double> >() { { foreignCurve, foreignDict }, { domesticCurve, domesticDict }, { CashDiscountCurve, foreignDiscDict }, }); } }
public Dictionary <string, Dictionary <DateTime, double> > Sensitivities(IFundingModel model) { //discounting only var discountDict = new Dictionary <DateTime, double>(); var discountCurve = model.Curves[DiscountCurve]; var t = discountCurve.Basis.CalculateYearFraction(discountCurve.BuildDate, MaturityDate); var p = model.Curves[DiscountCurve].GetDf(model.BuildDate, MaturityDate); discountDict.Add(MaturityDate, -t * Notional * p); return(new Dictionary <string, Dictionary <DateTime, double> >() { { DiscountCurve, discountDict }, }); }
public Dictionary <string, Dictionary <DateTime, double> > Sensitivities(IFundingModel model) { var foreignCurve = model.FxMatrix.DiscountCurveMap[ForeignCCY]; var domesticCurve = model.FxMatrix.DiscountCurveMap[DomesticCCY]; var discountCurve = model.Curves[ForeignDiscountCurve]; var df = discountCurve.Pv(1.0, DeliveryDate); var t = discountCurve.Basis.CalculateYearFraction(discountCurve.BuildDate, DeliveryDate); var fwdRate = model.GetFxRate(DeliveryDate, DomesticCCY, ForeignCCY); var domesticDict = new Dictionary <DateTime, double>() { { DeliveryDate, fwdRate *DomesticQuantity *df *t } }; Dictionary <DateTime, double> foreignDict; if (foreignCurve == ForeignDiscountCurve) { foreignDict = new Dictionary <DateTime, double>() { { DeliveryDate, DomesticQuantity *df *(fwdRate * -2 * t + Strike * t) } }; return(new Dictionary <string, Dictionary <DateTime, double> >() { { foreignCurve, foreignDict }, { domesticCurve, domesticDict }, }); } else { foreignDict = new Dictionary <DateTime, double>() { { DeliveryDate, fwdRate *DomesticQuantity *df * -t } }; var foreignDiscDict = new Dictionary <DateTime, double>() { { DeliveryDate, (fwdRate - Strike) * DomesticQuantity * df * -t } }; return(new Dictionary <string, Dictionary <DateTime, double> >() { { foreignCurve, foreignDict }, { domesticCurve, domesticDict }, { ForeignDiscountCurve, foreignDiscDict }, }); } }
public double SuggestPillarValue(IFundingModel model) { var pair = model.FxMatrix.GetFxPair(Pair); var spotDate = pair.SpotDate(model.BuildDate); var fxr = Strike / model.GetFxRate(spotDate, Pair); var df1 = model.GetCurve(model.FxMatrix.GetDiscountCurve(DomesticCCY.Ccy)).GetDf(spotDate, PillarDate); var df2 = df1 / fxr; var discountCurve = model.Curves[SolveCurve]; var t = discountCurve.Basis.CalculateYearFraction(spotDate, PillarDate); var rate = -Log(df2) / t; if (double.IsNaN(rate) || double.IsInfinity(rate)) { rate = 0.05; } return(rate); }
public void Solve(IFundingModel fundingModel, FundingInstrumentCollection instruments) { var maxStage = fundingModel.Curves.Max(x => x.Value.SolveStage); var curvesForStage = new List <IIrCurve>(); var fundingInstruments = new List <IFundingInstrument>(); for (var stage = 0; stage <= maxStage; stage++) { curvesForStage.Clear(); fundingInstruments.Clear(); foreach (var kv in fundingModel.Curves) { if (kv.Value.SolveStage == stage) { curvesForStage.Add(kv.Value); foreach (var inst in instruments) { if (inst.SolveCurve == kv.Value.Name) { fundingInstruments.Add(inst); } } } } var currentGuess = new double[fundingInstruments.Count]; _currentPvs = new double[fundingInstruments.Count]; var bumpedPvs = new double[fundingInstruments.Count]; _jacobian = Math.Matrix.DoubleArrayFunctions.MatrixCreate(fundingInstruments.Count, fundingInstruments.Count); for (var i = 0; i < MaxItterations; i++) { ComputePVs(true, fundingInstruments, fundingModel, _currentPvs); if (_currentPvs.Max(x => System.Math.Abs(x)) < Tollerance) { UsedItterations = i + 1; break; } ComputeJacobian(fundingInstruments, fundingModel, curvesForStage); ComputeNextGuess(currentGuess, fundingInstruments.Count, curvesForStage); } } }