public ICube ToCube() { var cube = new ResultCube(); var dataTypes = new Dictionary <string, Type> { { "PointDate", typeof(DateTime) }, { "PointType", typeof(string) }, { "QuoteType", typeof(string) }, { "PointDelta", typeof(double) }, }; cube.Initialize(dataTypes); for (var i = 0; i < Expiries.Length; i++) { var rowF = new Dictionary <string, object> { { "PointDate", Expiries[i] }, { "PointType", "Forward" }, { "QuoteType", string.Empty }, { "PointDelta", 0.5 }, }; cube.AddRow(rowF, Forwards[i]); var rowA = new Dictionary <string, object> { { "PointDate", Expiries[i] }, { "PointType", "ATM" }, { "QuoteType", AtmVolType.ToString() }, { "PointDelta", 0.5 }, }; cube.AddRow(rowA, ATMs[i]); for (var j = 0; j < WingDeltas.Length; j++) { var rowRR = new Dictionary <string, object> { { "PointDate", Expiries[i] }, { "PointType", "RR" }, { "QuoteType", WingQuoteType.ToString() }, { "PointDelta", WingDeltas[j] }, }; cube.AddRow(rowRR, Riskies[i][j]); var rowBF = new Dictionary <string, object> { { "PointDate", Expiries[i] }, { "PointType", "BF" }, { "QuoteType", WingQuoteType.ToString() }, { "PointDelta", WingDeltas[j] }, }; cube.AddRow(rowBF, Flies[i][j]); } } return(cube); }
public SVIVolSurface(DateTime originDate, double[] ATMVols, DateTime[] expiries, double[] wingDeltas, double[][] riskies, double[][] flies, double[] fwds, WingQuoteType wingQuoteType, AtmVolType atmVolType, Interpolator1DType timeInterpType, SviType sviType = SviType.Raw, string[] pillarLabels = null) : base() { if (pillarLabels == null) { PillarLabels = expiries.Select(x => x.ToString("yyyy-MM-dd")).ToArray(); } else { PillarLabels = pillarLabels; } if (ATMVols.Length != expiries.Length || expiries.Length != riskies.Length || riskies.Length != flies.Length) { throw new Exception("Inputs do not have consistent time dimensions"); } if (wingDeltas.Length != riskies[0].Length || riskies[0].Length != flies[0].Length) { throw new Exception("Inputs do not have consistent strike dimensions"); } var atmConstraints = ATMVols.Select(a => new ATMStraddleConstraint { ATMVolType = atmVolType, MarketVol = a }).ToArray(); var needsFlip = wingDeltas.First() > wingDeltas.Last(); var strikes = new double[2 * wingDeltas.Length + 1]; if (needsFlip) { for (var s = 0; s < wingDeltas.Length; s++) { strikes[s] = wingDeltas[wingDeltas.Length - 1 - s]; strikes[strikes.Length - 1 - s] = 1.0 - wingDeltas[wingDeltas.Length - 1 - s]; } } else { for (var s = 0; s < wingDeltas.Length; s++) { strikes[s] = wingDeltas[s]; strikes[strikes.Length - 1 - s] = 1.0 - wingDeltas[s]; } } strikes[wingDeltas.Length] = 0.5; var wingConstraints = new RRBFConstraint[expiries.Length][]; RawParams = new SviRawParameters[expiries.Length]; var f = new AssetSmileSolver(); if (needsFlip) { for (var i = 0; i < wingConstraints.Length; i++) { var offset = wingDeltas.Length - 1; wingConstraints[i] = new RRBFConstraint[wingDeltas.Length]; for (var j = 0; j < wingConstraints[i].Length; j++) { wingConstraints[i][j] = new RRBFConstraint { Delta = wingDeltas[offset - j], FlyVol = flies[i][offset - j], RisykVol = riskies[i][offset - j], WingQuoteType = wingQuoteType, }; } RawParams[i] = f.SolveSviRaw(atmConstraints[i], wingConstraints[i], originDate, expiries[i], fwds[i], true); } } else { for (var i = 0; i < wingConstraints.Length; i++) { wingConstraints[i] = new RRBFConstraint[wingDeltas.Length]; for (var j = 0; j < wingConstraints[i].Length; j++) { wingConstraints[i][j] = new RRBFConstraint { Delta = wingDeltas[j], FlyVol = flies[i][j], RisykVol = riskies[i][j], WingQuoteType = wingQuoteType, }; } RawParams[i] = f.SolveSviRaw(atmConstraints[i], wingConstraints[i], originDate, expiries[i], fwds[i], true); } } OriginDate = originDate; TimeInterpolatorType = timeInterpType; Expiries = expiries; ExpiriesDouble = expiries.Select(x => originDate.CalculateYearFraction(x, TimeBasis)).ToArray(); _interps = new IInterpolator1D[5]; _interps[0] = InterpolatorFactory.GetInterpolator(ExpiriesDouble, RawParams.Select(x => x.A).ToArray(), TimeInterpolatorType); _interps[1] = InterpolatorFactory.GetInterpolator(ExpiriesDouble, RawParams.Select(x => x.B).ToArray(), TimeInterpolatorType); _interps[2] = InterpolatorFactory.GetInterpolator(ExpiriesDouble, RawParams.Select(x => x.M).ToArray(), TimeInterpolatorType); _interps[3] = InterpolatorFactory.GetInterpolator(ExpiriesDouble, RawParams.Select(x => x.Rho).ToArray(), TimeInterpolatorType); _interps[4] = InterpolatorFactory.GetInterpolator(ExpiriesDouble, RawParams.Select(x => x.Sigma).ToArray(), TimeInterpolatorType); _fwdsInterp = InterpolatorFactory.GetInterpolator(ExpiriesDouble, fwds, Interpolator1DType.Linear); }
public RiskyFlySurface(DateTime originDate, double[] ATMVols, DateTime[] expiries, double[] wingDeltas, double[][] riskies, double[][] flies, double[] fwds, WingQuoteType wingQuoteType, AtmVolType atmVolType, Interpolator1DType strikeInterpType, Interpolator1DType timeInterpType, string[] pillarLabels = null) { if (pillarLabels == null) { PillarLabels = expiries.Select(x => x.ToString("yyyy-MM-dd")).ToArray(); } else { PillarLabels = pillarLabels; } if (ATMVols.Length != expiries.Length || expiries.Length != riskies.Length || riskies.Length != flies.Length) { throw new Exception("Inputs do not have consistent time dimensions"); } if (wingDeltas.Length != riskies[0].Length || riskies[0].Length != flies[0].Length) { throw new Exception("Inputs do not have consistent strike dimensions"); } var strikes = new double[2 * wingDeltas.Length + 1]; var vols = new double[expiries.Length][]; if (riskies.SelectMany(x => x).All(x => x == 0) && flies.SelectMany(x => x).All(x => x == 0)) { for (var s = 0; s < wingDeltas.Length; s++) { strikes[s] = wingDeltas[wingDeltas.Length - 1 - s]; strikes[strikes.Length - 1 - s] = 1.0 - wingDeltas[wingDeltas.Length - 1 - s]; } for (var t = 0; t < expiries.Length; t++) { vols[t] = Enumerable.Repeat(ATMVols[t], strikes.Length).ToArray(); } } else { var atmConstraints = ATMVols.Select(a => new ATMStraddleConstraint { ATMVolType = atmVolType, MarketVol = a }).ToArray(); var needsFlip = wingDeltas.First() > wingDeltas.Last(); if (needsFlip) { for (var s = 0; s < wingDeltas.Length; s++) { strikes[s] = wingDeltas[wingDeltas.Length - 1 - s]; strikes[strikes.Length - 1 - s] = 1.0 - wingDeltas[wingDeltas.Length - 1 - s]; } } else { for (var s = 0; s < wingDeltas.Length; s++) { strikes[s] = wingDeltas[s]; strikes[strikes.Length - 1 - s] = 1.0 - wingDeltas[s]; } } strikes[wingDeltas.Length] = 0.5; var wingConstraints = new RRBFConstraint[expiries.Length][]; var f = new AssetSmileSolver(); if (needsFlip) { for (var i = 0; i < wingConstraints.Length; i++) { var offset = wingDeltas.Length - 1; wingConstraints[i] = new RRBFConstraint[wingDeltas.Length]; for (var j = 0; j < wingConstraints[i].Length; j++) { wingConstraints[i][j] = new RRBFConstraint { Delta = wingDeltas[offset - j], FlyVol = flies[i][offset - j], RisykVol = riskies[i][offset - j], WingQuoteType = wingQuoteType, }; } vols[i] = f.Solve(atmConstraints[i], wingConstraints[i], originDate, expiries[i], fwds[i], strikes, strikeInterpType); } } else { for (var i = 0; i < wingConstraints.Length; i++) { wingConstraints[i] = new RRBFConstraint[wingDeltas.Length]; for (var j = 0; j < wingConstraints[i].Length; j++) { wingConstraints[i][j] = new RRBFConstraint { Delta = wingDeltas[j], FlyVol = flies[i][j], RisykVol = riskies[i][j], WingQuoteType = wingQuoteType, }; } vols[i] = f.Solve(atmConstraints[i], wingConstraints[i], originDate, expiries[i], fwds[i], strikes, strikeInterpType); } } } StrikeInterpolatorType = strikeInterpType; TimeInterpolatorType = timeInterpType; Expiries = expiries; ExpiriesDouble = expiries.Select(x => x.ToOADate()).ToArray(); Strikes = strikes; StrikeType = StrikeType.ForwardDelta; ATMs = ATMVols; Riskies = riskies; Flies = flies; WingDeltas = wingDeltas; Forwards = fwds; WingQuoteType = wingQuoteType; AtmVolType = atmVolType; base.Build(originDate, strikes, expiries, vols); }
public SabrVolSurface(DateTime originDate, double[] ATMVols, DateTime[] expiries, double[] wingDeltas, double[][] riskies, double[][] flies, double[] fwds, WingQuoteType wingQuoteType, AtmVolType atmVolType, Interpolator1DType timeInterpType, string[] pillarLabels = null) { if (pillarLabels == null) { PillarLabels = expiries.Select(x => x.ToString("yyyy-MM-dd")).ToArray(); } else { PillarLabels = pillarLabels; } if (ATMVols.Length != expiries.Length || expiries.Length != riskies.Length || riskies.Length != flies.Length) { throw new Exception("Inputs do not have consistent time dimensions"); } if (wingDeltas.Length != riskies[0].Length || riskies[0].Length != flies[0].Length) { throw new Exception("Inputs do not have consistent strike dimensions"); } var atmConstraints = ATMVols.Select(a => new ATMStraddleConstraint { ATMVolType = atmVolType, MarketVol = a }).ToArray(); var needsFlip = wingDeltas.First() > wingDeltas.Last(); var strikes = new double[2 * wingDeltas.Length + 1]; if (needsFlip) { for (var s = 0; s < wingDeltas.Length; s++) { strikes[s] = wingDeltas[wingDeltas.Length - 1 - s]; strikes[strikes.Length - 1 - s] = 1.0 - wingDeltas[wingDeltas.Length - 1 - s]; } } else { for (var s = 0; s < wingDeltas.Length; s++) { strikes[s] = wingDeltas[s]; strikes[strikes.Length - 1 - s] = 1.0 - wingDeltas[s]; } } strikes[wingDeltas.Length] = 0.5; var wingConstraints = new RRBFConstraint[expiries.Length][]; var parameters = new SABRParameters[expiries.Length]; var f = new AssetSmileSolver(); if (needsFlip) { for (var i = 0; i < wingConstraints.Length; i++) { var offset = wingDeltas.Length - 1; wingConstraints[i] = new RRBFConstraint[wingDeltas.Length]; for (var j = 0; j < wingConstraints[i].Length; j++) { wingConstraints[i][j] = new RRBFConstraint { Delta = wingDeltas[offset - j], FlyVol = flies[i][offset - j], RisykVol = riskies[i][offset - j], WingQuoteType = wingQuoteType, }; } parameters[i] = f.SolveSABR(atmConstraints[i], wingConstraints[i], originDate, expiries[i], fwds[i], 1.0); } } else { for (var i = 0; i < wingConstraints.Length; i++) { wingConstraints[i] = new RRBFConstraint[wingDeltas.Length]; for (var j = 0; j < wingConstraints[i].Length; j++) { wingConstraints[i][j] = new RRBFConstraint { Delta = wingDeltas[j], FlyVol = flies[i][j], RisykVol = riskies[i][j], WingQuoteType = wingQuoteType, }; } parameters[i] = f.SolveSABR(atmConstraints[i], wingConstraints[i], originDate, expiries[i], fwds[i], 1.0); } } OriginDate = originDate; TimeInterpolatorType = timeInterpType; Expiries = expiries; ExpiriesDouble = expiries.Select(x => originDate.CalculateYearFraction(x, TimeBasis)).ToArray(); Alphas = parameters.Select(x => x.Alpha).ToArray(); Betas = parameters.Select(x => x.Beta).ToArray(); Nus = parameters.Select(x => x.Nu).ToArray(); Rhos = parameters.Select(x => x.Rho).ToArray(); _alphaInterp = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Alphas, TimeInterpolatorType); _betaInterp = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Betas, TimeInterpolatorType); _rhoInterp = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Rhos, TimeInterpolatorType); _nuInterp = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Nus, TimeInterpolatorType); _fwdsInterp = InterpolatorFactory.GetInterpolator(ExpiriesDouble, fwds, TimeInterpolatorType); }