public ADouble GoalFunction_AD(LinearRateModel model, double scaling = 1.0) { ADouble quadraticSum = 0.0; for (int i = 0; i < InputInstruments.Count; i++) { ADouble tempDifference = InputInstruments[i].ValueInstrumentAD(model, Factory) - InputInstruments[i].QuoteValue; quadraticSum = quadraticSum + ADouble.Pow(tempDifference, 2.0) * scaling; } return(quadraticSum); }
public static void FuncPow(ADouble x, double k) { AADTape.ResetTape(); AADTape.Initialize(new ADouble[] { x }); ADouble Out = 3.0 * ADouble.Log(x) + 5.0 * ADouble.Pow(x, k); Console.WriteLine(" "); Console.WriteLine("Testing Adjoint differentiation of a function involving powers"); AADTape.InterpretTape(); AADTape.PrintTape(); AADTape.ResetTape(); }
public static void BlackScholesNoReset(ADouble vol, ADouble spot, ADouble rate, ADouble time, ADouble mat, ADouble strike) { ADouble Help1 = vol * ADouble.Sqrt(mat - time); ADouble d1 = 1.0 / Help1 * (ADouble.Log(spot / strike) + (rate + 0.5 * ADouble.Pow(vol, 2)) * (mat - time)); ADouble d2 = d1 - vol * ADouble.Sqrt(mat - time); ADouble Out = MyMath.NormalCdf(d1) * spot - strike * ADouble.Exp(-rate * (mat - time)) * MyMath.NormalCdf(d2); }
public static void BlackScholes(ADouble vol, ADouble spot, ADouble rate, ADouble time, ADouble mat, ADouble strike) { AADTape.ResetTape(); AADTape.Initialize(new ADouble[] { vol, spot, rate, time, mat, strike }); ADouble Help1 = vol * ADouble.Sqrt(mat - time); ADouble d1 = 1.0 / Help1 * (ADouble.Log(spot / strike) + (rate + 0.5 * ADouble.Pow(vol, 2)) * (mat - time)); ADouble d2 = d1 - vol * ADouble.Sqrt(mat - time); ADouble Out = MyMath.NormalCdf(d1) * spot - strike * ADouble.Exp(-rate * (mat - time)) * MyMath.NormalCdf(d2); Console.WriteLine(""); Console.WriteLine("BLACK-SCHOLES TEST. Value: " + Out.Value); AADTape.InterpretTape(); AADTape.PrintTape(); AADTape.ResetTape(); }
public static ADouble TestingPowInverse(ADouble x) { return(ADouble.Pow(5.0 - x, 2.0)); }
// Testing the pow function public static ADouble TestingPow(ADouble x) { return(ADouble.Pow(x - 5.0, 2.0)); }
public static ADouble InterpolateCurve(double[] xArr, double x, List <ADouble> yArr, InterpMethod method) { // To-do: CATROM interpolation if (xArr.Count() != yArr.Count()) { throw new ArgumentException("Number of dates has to correspond to number of values"); } int n = xArr.Count(); // Extrapolation (flat) if (xArr[0] > x) { return(yArr[0]); } else if (xArr[n - 1] <= x) { return(yArr[n - 1]); } else { // No extrapolation - find relevant index in arrays int i = 0; int j = 0; for (i = 0; i < n; i++) { if (xArr[i] <= x) { j = j + 1; } else { break; } } j = j - 1; switch (method) { case InterpMethod.Constant: return(yArr[j]); case InterpMethod.Linear: ADouble tempLinear = (x - xArr[j]) * yArr[j + 1] + (xArr[j + 1] - x) * yArr[j]; return(tempLinear / (xArr[j + 1] - xArr[j])); case InterpMethod.LogLinear: // Log-Linear interpolation is only valid for positive stuff if (yArr[j + 1] < 0.0 || yArr[j] < 0.0) { return(yArr[j]); } else { ADouble tempLogLinear1 = (x - xArr[j]) / (xArr[j + 1] - xArr[j]); ADouble tempLogLinear2 = (xArr[j + 1] - x) / (xArr[j + 1] - xArr[j]); return(ADouble.Pow(yArr[j + 1], tempLogLinear1) * ADouble.Pow(yArr[j], tempLogLinear2)); } case InterpMethod.Hermite: ADouble bi, bk, hi, mi, ci, di; int k = j + 1; if (j == 0) { bi = (xArr[2] + xArr[1] - 2 * xArr[0]) * (yArr[1] - yArr[0]) / (xArr[1] - xArr[0]); bi += -1 * (xArr[1] - xArr[0]) * (yArr[2] - yArr[1]) / (xArr[2] - xArr[1]); bi *= ADouble.Pow(xArr[2] - xArr[0], -1.0); bk = (xArr[k + 1] - xArr[k]) * (yArr[k] - yArr[k - 1]) / (xArr[k] - xArr[k - 1]); bk += (xArr[k] - xArr[k - 1]) * (yArr[k + 1] - yArr[k]) / (xArr[k + 1] - xArr[k]); bk *= ADouble.Pow(xArr[k + 1] - xArr[k - 1], -1.0); } else if (j == n - 2) { bi = (xArr[j + 1] - xArr[j]) * (yArr[j] - yArr[k - 1]) / (xArr[j] - xArr[j - 1]); bi += (xArr[j] - xArr[j - 1]) * (yArr[j + 1] - yArr[j]) / (xArr[j + 1] - xArr[j]); bi *= ADouble.Pow(xArr[j + 1] - xArr[j - 1], -1.0); bk = -1 * (xArr[n - 1] - xArr[n - 2]) * (yArr[n - 2] - yArr[n - 3]) / (xArr[n - 2] - xArr[n - 3]); bk += -1 * (xArr[n - 1] - xArr[n - 2] - (xArr[n - 1] - xArr[n - 3])) * (yArr[n - 1] - yArr[n - 2]) / (xArr[n - 1] - xArr[n - 2]); bk *= ADouble.Pow(xArr[n - 1] - xArr[n - 3], -1.0); } else { bi = (xArr[j + 1] - xArr[j]) * (yArr[j] - yArr[j - 1]) / (xArr[j] - xArr[j - 1]); bi += (xArr[j] - xArr[j - 1]) * (yArr[j + 1] - yArr[j]) / (xArr[j + 1] - xArr[j]); bi *= ADouble.Pow(xArr[j + 1] - xArr[j - 1], -1.0); bk = (xArr[k + 1] - xArr[k]) * (yArr[k] - yArr[k - 1]) / (xArr[k] - xArr[k - 1]); bk += (xArr[k] - xArr[k - 1]) * (yArr[k + 1] - yArr[k]) / (xArr[k + 1] - xArr[k]); bk *= ADouble.Pow(xArr[k + 1] - xArr[k - 1], -1.0); } hi = xArr[j + 1] - xArr[j]; mi = (yArr[j + 1] - yArr[j]) / hi; ci = (3.0 * mi - bk - 2.0 * bi) / hi; di = (bk + bi - 2.0 * mi) * ADouble.Pow(hi, -2.0); return(yArr[j] + bi * (x - xArr[j]) + ci * ADouble.Pow(x - xArr[j], 2.0) + di * ADouble.Pow(x - xArr[j], 3.0)); default: throw new InvalidOperationException("Interpolation method is not valid"); } } }