public static double[] ArithmeticAsianOptionPricing(ArithmeticAsianOptionProb prob) { double s = prob.SpotPrice; double k = prob.StrikePrice; double r = prob.InterestRate; double t = prob.Maturity; double sigma = prob.Volatility; int n = prob.ObservationTime; OptionTypeEnum optionType = prob.OptionType; int pathNum = prob.PathNumber; ControlVariateMethod method = prob.VariateMethod; return(GetAAOPrice(s, k, t, r, sigma, optionType, method, pathNum, n)); }
public ArithmeticAsianOptionProb(double?spotPrice, double?volatility, double?interestRate, double?maturity, double?strikePrice, int?observationTime, OptionTypeEnum optionType, int?pathNumber, ControlVariateMethod variateMethod) { SpotPrice = spotPrice ?? default(double); Volatility = volatility ?? default(double); InterestRate = interestRate ?? default(double); Maturity = maturity ?? default(double); StrikePrice = strikePrice ?? default(double); ObservationTime = observationTime ?? default(int); OptionType = optionType; PathNumber = pathNumber ?? default(int); VariateMethod = variateMethod; }
private static double[] GetAAOPrice(double s, double k, double t, double r, double sigma, OptionTypeEnum optionType, ControlVariateMethod method, int pathNum, int n) { const int seed = 11151; double Dt = t / n; double drift = Math.Exp((r - 0.5 * Math.Pow(sigma, 2)) * Dt); Normal normal = new Normal(); normal.RandomSource = new Random(seed); List <Double> arithPayoff = new List <Double>(); List <Double> geoPayoff = new List <Double>(); for (int i = 1; i <= pathNum; i++) { double growthFactor = drift * Math.Exp(sigma * Math.Sqrt(Dt) * normal.Sample()); List <Double> spath = new List <double>(); spath.Add(s * growthFactor); double logSpathSum = Math.Log(spath.ElementAt(0)); for (int j = 2; j <= n; j++) { growthFactor = drift * Math.Exp(sigma * Math.Sqrt(Dt) * normal.Sample()); double tmp = spath.ElementAt(spath.Count - 1) * growthFactor; spath.Add(tmp); logSpathSum += Math.Log(tmp); } double arithMean = GetMeanVarStd(spath)[0]; double geoMean = Math.Exp((1.0 / n) * logSpathSum); if (optionType == OptionTypeEnum.Call) { arithPayoff.Add(Math.Exp(-r * t) * Math.Max(arithMean - k, 0)); geoPayoff.Add(Math.Exp(-r * t) * Math.Max(geoMean - k, 0)); } else { arithPayoff.Add(Math.Exp(-r * t) * Math.Max(k - arithMean, 0)); geoPayoff.Add(Math.Exp(-r * t) * Math.Max(k - geoMean, 0)); } spath.Clear(); } double[] arithPayoffMvs = GetMeanVarStd(arithPayoff); double arithPayoffMean = arithPayoffMvs[0]; double arithPayoffVar = arithPayoffMvs[1]; double arithPayoffStd = arithPayoffMvs[2]; double[] geoPayoffMvs = GetMeanVarStd(geoPayoff); double geoPayoffMean = geoPayoffMvs[0]; double geoPayoffVar = geoPayoffMvs[1]; double geoPayoffStd = geoPayoffMvs[2]; List <double> pointMultiplyList = new List <double>(); for (int iter = 0; iter < arithPayoff.Count; iter++) { pointMultiplyList.Add(arithPayoff[iter] * geoPayoff[iter]); } double covXY = GetMeanVarStd(pointMultiplyList)[0] - arithPayoffMean * geoPayoffMean; double theta = covXY / geoPayoffVar; double geoPrice = getGeoAsianOptionPrice(s, k, r, t, sigma, n, optionType); List <double> controlVar = new List <double>(); for (int iter = 0; iter < arithPayoff.Count; iter++) { double tempVar = arithPayoff[iter] + theta * (geoPrice - geoPayoff[iter]); controlVar.Add(tempVar); } double[] controlVarMvs = GetMeanVarStd(controlVar); double controlVarMaen = controlVarMvs[0]; double controlVarVar = controlVarMvs[1]; double controlVarStd = controlVarMvs[2]; double lbound = 0; double ubound = 0; double[] results = new double[3]; if (method == ControlVariateMethod.None) { lbound = arithPayoffMean - (1.96 * arithPayoffStd) / Math.Sqrt(pathNum); ubound = arithPayoffMean + (1.96 * arithPayoffStd) / Math.Sqrt(pathNum); results[0] = lbound; results[1] = arithPayoffMean; results[2] = ubound; } else { lbound = controlVarMaen - (1.96 * controlVarStd) / Math.Sqrt(pathNum); ubound = controlVarMaen + (1.96 * controlVarStd) / Math.Sqrt(pathNum); results[0] = lbound; results[1] = controlVarMaen; results[2] = ubound; } return(results); }