/// <summary> /// Get a point from the implied vol surface /// </summary> /// <param name="t">date in double</param> /// <param name="k">strike</param> /// <returns></returns> public double GetValue(double t, double k) { //check if the point is out of range var axisX1InDouble = RowGrid.Select(item => _dayCount.CalcDayCountFraction(ValuationDate, item)).ToList(); if (t < axisX1InDouble.Min() || t > axisX1InDouble.Max() || k < ColGrid.Min() || k > ColGrid.Max()) { throw new PricingLibraryException(String.Format("Date - strike pair ({0},{1}) is out of range. Extrapolation is not implemented yet", t, k)); } //find the two indices which on the two sides of the input date. If cannot find in the for loop, then i = 0 automatically. int i = 0; for (int j = 0; j < axisX1InDouble.Count - 1; j++) { if ((axisX1InDouble[j] < t) && (t <= axisX1InDouble[j + 1])) { i = j; } } // get the left and right value of the sabr interpolated vol with the same strike s var leftValue = SABRVolFineTune( OptimizerResults[i].BestAlpha, OptimizerResults[i].BestBeta, OptimizerResults[i].BestRho, OptimizerResults[i].BestNu, _spotPrice, k, OptimizerResults[i].Maturity, _useFineTune); var rightValue = SABRVolFineTune( OptimizerResults[i + 1].BestAlpha, OptimizerResults[i + 1].BestBeta, OptimizerResults[i + 1].BestRho, OptimizerResults[i + 1].BestNu, _spotPrice, k, OptimizerResults[i + 1].Maturity, _useFineTune); var w = Weight((OptimizerResults[i + 1].Maturity - t) / (OptimizerResults[i + 1].Maturity - OptimizerResults[i].Maturity)); return(w * leftValue + (1 - w) * rightValue); }
public override double MaxY() { return(ColGrid.Max()); }