///<summary> /// The main function to calculate the adjusted forward. ///</summary> ///<param name="futuresPrice"> Vector of futures prices.</param> ///<param name="volatility"> Vector of futures</param> ///<param name="correlation"> Correlation between forwards. Can be a /// scalar input or a correlation matrix.</param> ///<param name="shift"> The shift parameters from the BGM /// calibration.</param> ///<param name="coverage"> The vector of time intervals between model /// time nodes.</param> ///<param name="timeNodes"> The model time nodes</param> ///<returns> optOut, an array OptimisationOuput types, with one element /// for each time node.</returns> public static OptimisationOutput[] CalculateCashForward(double[] futuresPrice, double[,] volatility, double[, ,] correlation, double[] shift, double[] coverage, double[] timeNodes) { var terminalNode = futuresPrice.Length - 1; var optOut = new OptimisationOutput[terminalNode + 1]; var cashForward = new double[terminalNode + 1]; const double tolerance = 0.000000001; const int maxIterations = 100; const int approximationOrder = 3; Del delObjective = Difference; // This assumes that if vol is input as a column vector (for // terminal node greater than 1) then the vol is meant to be // constant for each time node. if (volatility.GetLength(1) == 1 && volatility.GetLength(0) == terminalNode + 1 && terminalNode > 1) { volatility = Utilities.Transpose(volatility); } for (var j = 1; j <= terminalNode; j++) { var fixingNode = j; double initialValue = j > 1 ? cashForward[j - 1] : futuresPrice[j]; var targetPrice = futuresPrice[j]; optOut[j] = Optimiser.Secant(delObjective, initialValue, tolerance, maxIterations, cashForward, approximationOrder, fixingNode, volatility, correlation, shift, coverage, timeNodes, targetPrice); cashForward[j] = optOut[j].X; } return(optOut); }
public static OptimisationOutput Secant(Del delF, double initialValue, double tolerance, int maxIterations, params object[] list) { // Finds the root of the function F using the secant method. var x = initialValue; var xMinus = 1.005 * x; var count = 0; while (Math.Abs(delF(x, list)) > tolerance && count < maxIterations) { var xPlus = x - (x - xMinus) * delF(x, list) / (delF(x, list) - delF(xMinus, list)); xMinus = x; x = xPlus; count = count + 1; } var result = new OptimisationOutput(count, x, delF(x, list)); return(result); }