public double[,] FDM(Parameters parameters, Types.OptionType optionType, Types.MethodType methodType) { var pVArray = default(double[, ]); switch (optionType) { case Types.OptionType.Vanilla: pVArray = OptionVanilla.SetInitialCondition( new double[parameters.TNum, parameters.XNum[0]], parameters.BoundaryPrice, parameters.Strike, parameters.IsCall); pVArray = OptionVanilla.SetBoundaryCondition( pVArray, parameters.BoundaryPrice, parameters.Strike, parameters.IsCall); pVArray = MethodTheta.CalculatePVArray( methodType, pVArray, parameters.BoundaryPrice, parameters.Maturity, parameters.DomesticRate, parameters.ForeignRate, parameters.Volatility); break; case Types.OptionType.Barrier: pVArray = OptionBarrier.SetInitialCondition( new double[parameters.TNum, parameters.XNum[0]], parameters.BoundaryPrice, parameters.Strike, parameters.Barrier, parameters.IsCall); pVArray = OptionBarrier.SetBoundaryCondition(pVArray); pVArray = MethodTheta.CalculatePVArray( methodType, pVArray, parameters.BoundaryPrice, parameters.Maturity, parameters.DomesticRate, parameters.ForeignRate, parameters.Volatility); break; } return(pVArray); }
public static Matrix <double> Explicit( Types.MethodType methodType, Types.DifferentialDirection differentialDirection, double[,,] pVArray, double[] boundaryPrice, double maturity, double domesticRate, double[] foreignRate, double[] volatility) { int tNum = pVArray.GetLength(0); int xNum = pVArray.GetLength(1); double dx = boundaryPrice[0] / xNum; double dt = maturity / tNum; var coefficientArray = new double[xNum, xNum]; double theta = DefineTheta.Define(methodType); int bit = differentialDirection == Types.DifferentialDirection.X ? 0 : 1; double a1 = domesticRate - foreignRate[bit] - 0.5 * volatility[bit] * volatility[bit]; double b11 = 0.5 * volatility[bit] * volatility[bit]; double f = -domesticRate; coefficientArray[0, 0] = 1; coefficientArray[bit, 1 - bit] = 0; for (int i = 1; i < xNum - 1; i++) { double a = (1 - theta) * dt * (b11 / (dx * dx) - 0.5 * a1 / dx); double b = 1 + (1 - theta) * dt * (f - 2 * b11 / (dx * dx)); double c = (1 - theta) * dt * (b11 / (dx * dx) + 0.5 * a1 / dx); coefficientArray[i - bit, i + bit - 1] = a; coefficientArray[i, i] = b; coefficientArray[i + bit, i - bit + 1] = c; } coefficientArray[xNum - 1 - bit, xNum - 2 + bit] = 0; coefficientArray[xNum - 1, xNum - 1] = 1; var matrix = Matrix <double> .Build.Dense(xNum, xNum, (i, j) => coefficientArray[i, j]); return(matrix); }
public static double[,] Implicit( Types.MethodType methodType, double[,] pVArray, double[] boundaryPrice, double maturity, double domesticRate, double[] foreignRate, double[] volatility) { int tNum = pVArray.GetLength(0); int xNum = pVArray.GetLength(1); double dx = boundaryPrice[0] / xNum; double dt = maturity / tNum; var coefficientArray = new double[xNum, xNum]; double theta = DefineTheta.Define(methodType); double a1 = domesticRate - foreignRate[0] - 0.5 * volatility[0] * volatility[0]; double b11 = 0.5 * volatility[0] * volatility[0]; double f = -domesticRate; coefficientArray[0, 0] = 1; coefficientArray[0, 1] = 0; for (int i = 1; i < xNum - 1; i++) { double a = theta * dt * (-b11 / (dx * dx) + 0.5 * a1 / dx); double b = 1 + theta * dt * (f + 2 * b11 / (dx * dx)); double c = theta * dt * (-b11 / (dx * dx) - 0.5 * a1 / dx); coefficientArray[i, i - 1] = a; coefficientArray[i, i] = b; coefficientArray[i, i + 1] = c; } coefficientArray[xNum - 1, xNum - 2] = 0; coefficientArray[xNum - 1, xNum - 1] = 1; return(coefficientArray); }
public static double Define(Types.MethodType methodType) { double theta = 0; switch (methodType) { case Types.MethodType.Explicit: theta = 0; break; case Types.MethodType.Implicit: theta = 1; break; case Types.MethodType.CrankNicolson: theta = 0.5; break; case Types.MethodType.ADI: theta = 0.5; break; } return(theta); }
private static void WriteError(StreamWriter file, Types.OptionType optionType, Types.MethodType methodType) { var parameters = ParametersFactory.Original(optionType); var xArray = ParametersFactory.MakeXArray(parameters); int xNum = xArray.GetLength(0); var errorArray = new double[xNum]; file.Write(","); for (int j = 0; j < xNum; j++) { var makePVArray = new MakePVArrayOneAsset(); var analyticArray = makePVArray.Analytic(parameters, optionType); var fDMArray = makePVArray.FDM(parameters, optionType, methodType); errorArray[j] = CalculateErrorOneAsset.AbsoluteArray(fDMArray, analyticArray)[j]; file.Write(errorArray[j] + ","); } file.WriteLine(); }
public static double[,,] CalculatePVArray( Types.MethodType methodType, double[,,] pVArray, double[] boundaryPrice, double maturity, double domesticRate, double[] foreignRate, double[] volatility) { int tNum = pVArray.GetLength(0); var xNum = new int[] { pVArray.GetLength(1), pVArray.GetLength(1) }; var matrixExplicitX = MakeCoefficientMatrixTwoAsset.Explicit( methodType, Types.DifferentialDirection.X, pVArray, boundaryPrice, maturity, domesticRate, foreignRate, volatility); var matrixExplicitY = MakeCoefficientMatrixTwoAsset.Explicit( methodType, Types.DifferentialDirection.Y, pVArray, boundaryPrice, maturity, domesticRate, foreignRate, volatility); var matrixImplicitX = MakeCoefficientMatrixTwoAsset.Implicit( methodType, Types.DifferentialDirection.X, pVArray, boundaryPrice, maturity, domesticRate, foreignRate, volatility); var matrixImplicitY = MakeCoefficientMatrixTwoAsset.Implicit( methodType, Types.DifferentialDirection.Y, pVArray, boundaryPrice, maturity, domesticRate, foreignRate, volatility); var matrix = Matrix <double> .Build.Dense(xNum[0], xNum[1], (i, j) => pVArray[0, i, j]); for (int l = 1; l < tNum; l++) { switch (methodType) { case Types.MethodType.ADI: matrix = matrixExplicitY * matrix; matrix = matrixImplicitX.Solve(matrix); matrix = matrixExplicitX * matrix; matrix = matrixImplicitY.Solve(matrix); break; } for (int i = 0; i < xNum[0]; i++) { for (int j = 0; j < xNum[1]; j++) { pVArray[l, i, j] = matrix[i, j]; } } } return(pVArray); }
public static double[,] CalculatePVArray( Types.MethodType methodType, double[,] pVArray, double[] boundaryPrice, double maturity, double domesticRate, double[] foreignRate, double[] volatility) { int tNum = pVArray.GetLength(0); int xNum = pVArray.GetLength(1); var matrixExplicit = Matrix <double> .Build.DenseOfArray( MakeCoefficientMatrixOneAsset.Explicit( methodType, pVArray, boundaryPrice, maturity, domesticRate, foreignRate, volatility)); var matrixImplicit = Matrix <double> .Build.DenseOfArray( MakeCoefficientMatrixOneAsset.Implicit( methodType, pVArray, boundaryPrice, maturity, domesticRate, foreignRate, volatility)); var vector = Vector <double> .Build.Dense(xNum, i => pVArray[0, i]); for (int l = 1; l < tNum; l++) { switch (methodType) { case Types.MethodType.Explicit: vector = matrixExplicit * vector; break; case Types.MethodType.Implicit: vector = matrixImplicit.Solve(vector); break; case Types.MethodType.CrankNicolson: vector = matrixImplicit.Solve(vector); vector = matrixExplicit * vector; break; } for (int i = 0; i < xNum; i++) { pVArray[l, i] = vector[i]; } } return(pVArray); }
private static void WriteError(StreamWriter file, Types.OptionType optionType, Types.MethodType methodType) { var parameters = ParametersFactory.ForVerification(optionType); var xNumArray = ParametersFactory.MakeXNumArray(); int xNumNum = xNumArray.GetLength(0); file.Write(","); for (int j = 0; j < xNumNum; j++) { var makePVArray = new MakePVArrayOneAsset(); var analyticArray = makePVArray.Analytic(parameters[j], optionType); var fDMArray = makePVArray.FDM(parameters[j], optionType, methodType); double error = CalculateErrorOneAsset.MaxAbsolute(fDMArray, analyticArray); file.Write(error + ","); } file.WriteLine(); }