/// <summary> /// Test method, displays a sensitivity on heston call and put prices. /// </summary> private void PutCallTest() { Console.WriteLine("Black-Sholes Calls Market Prices"); Console.WriteLine(this.callMarketPrice); Console.WriteLine("Strikes"); Console.WriteLine(this.strike); Console.WriteLine("Maturities"); Console.WriteLine(this.maturity); var x = new Vector() { 3.18344026504981, 0.0427882999286046, 0.644527074840708, -0.659960749691282, 0.0150455464938991, 0.0211747510984717 }; HestonCall hc = new HestonCall(this, x, this.s0); hc.T = .1; hc.rate = this.rate[0]; Console.WriteLine("Strike\tCall\tPut"); for (int z = 200; z < 6500; z += 1000) { hc.K = z; var call = hc.HestonCallPrice(); var put = hc.HestonPutPrice(); var callPut = hc.HestonCallPutPrice(); Console.WriteLine(z + "\t" + callPut[0] + "\t" + callPut[1]); } }
/// <summary> /// Calculates a single row of the objective function. Basically /// options with the same maturity and different strikes. /// </summary> /// <param name='context'> /// An object of type <see cref="HestonCall"/> containing the context. /// </param> private void CalculateSingleRow(object context) { CalculateSingleRowWithInterpolation(context); return; HestonCall hc = context as HestonCall; int r = hc.row; for (int c = 0; c < this.callMarketPrice.C; c++) { bool callCondition = this.callMarketPrice[r, c] > s0 * optionThreshold && this.cpmd.CallVolume[r, c] > 0; bool putCondition = this.cpmd.PutPrice[r, c] > s0 * optionThreshold && this.cpmd.PutVolume[r, c] > 0; if (callCondition)//||putCondition) { hc.K = this.strike[c]; var callPut = hc.HestonCallPutPrice(); hc.hestonCallPrice[r, c] = callPut[0]; hc.hestonPutPrice[r, c] = callPut[1]; if (callCondition) { if (HestonCallOptimizationProblem.optimizeRelativeError) { double mkt = pricingMin + this.callMarketPrice[r, c]; double model = pricingMin + hc.hestonCallPrice[r, c]; hc.sum += callWeight[r, c] * Math.Pow((model - mkt) / mkt, 2); } else { hc.sum += callWeight[r, c] * Math.Pow(hc.hestonCallPrice[r, c] - this.callMarketPrice[r, c], 2); } } /* * if (putCondition) * { * if (HestonCallOptimizationProblem.optimizeRelativeError) * { * double mkt = pricingMin + this.cpmd.PutPrice[r, c]; * double model = pricingMin + hc.hestonPutPrice[r, c]; * hc.sum += putWeight[r,c] * Math.Pow((model - mkt) / mkt, 2); * } * else * { * hc.sum += putWeight[r,c]* Math.Pow(hc.hestonPutPrice[r, c] - this.cpmd.PutPrice[r, c], 2); * } * } */ } } return; }
/// <summary> /// Test method, displays a sensitivity on heston call and put prices. /// </summary> private void PutCallTest() { Console.WriteLine("Black-Sholes Calls Market Prices"); Console.WriteLine(this.callMarketPrice); Console.WriteLine("Strikes"); Console.WriteLine(this.strike); Console.WriteLine("Maturities"); Console.WriteLine(this.maturity); var x = new Vector() {3.18344026504981, 0.0427882999286046, 0.644527074840708, -0.659960749691282, 0.0150455464938991, 0.0211747510984717}; HestonCall hc = new HestonCall(this, x, this.s0); hc.T = .1; hc.rate = this.rate[0]; Console.WriteLine("Strike\tCall\tPut"); for (int z = 200; z < 6500; z += 1000) { hc.K = z; var call = hc.HestonCallPrice(); var put = hc.HestonPutPrice(); var callPut = hc.HestonCallPutPrice(); Console.WriteLine(z + "\t" + callPut[0] + "\t" + callPut[1]); } }
/// <summary> /// Calculates call put prices for several strikes using controlled interpolation. /// </summary> /// <param name="context"></param> private void CalculateSingleRowWithInterpolation(object context) { HestonCall hc = context as HestonCall; int r = hc.row; hc.sum = 0; // Finds upper extreme for call and put int max_c = 0; for (int c = this.callMarketPrice.C - 1; c > 0; c--) { bool callCondition = this.callMarketPrice[r, c] > s0 * optionThreshold && this.cpmd.CallVolume[r, c] > 0; bool putCondition = this.cpmd.PutPrice != null && this.cpmd.PutPrice[r, c] > s0 * optionThreshold && this.cpmd.PutVolume[r, c] > 0; if (callCondition || putCondition) { max_c = c; break; } } var strikes = new List <double>(); var calls = new List <double>(); var puts = new List <double>(); //Evaluates in strategic points for (int c = 0; c < this.callMarketPrice.C; c++) { bool callCondition = this.callMarketPrice[r, c] > s0 * optionThreshold && this.cpmd.CallVolume[r, c] > 0; bool putCondition = this.cpmd.PutPrice != null && this.cpmd.PutPrice[r, c] > s0 * optionThreshold && this.cpmd.PutVolume[r, c] > 0; if (callCondition || putCondition) { hc.K = this.strike[c]; var callPut = hc.HestonCallPutPrice(); strikes.Add(hc.K); calls.Add(callPut[0]); puts.Add(callPut[1]); if (c == max_c) { break; } c += 1;//skip the subsequent strikes if (c > max_c) { c = max_c; } } } // Builds interpolated call and put values. var callFun = new PFunction((Vector)strikes.ToArray(), (Vector)calls.ToArray()); callFun.m_Function.iType = DVPLUtils.EInterpolationType.SPLINE; var putFun = new PFunction((Vector)strikes.ToArray(), (Vector)puts.ToArray()); putFun.m_Function.iType = DVPLUtils.EInterpolationType.SPLINE; // Evaluates at the requested strikes for (int c = 0; c < this.callMarketPrice.C; c++) { bool callCondition = this.callMarketPrice[r, c] > s0 * optionThreshold && this.cpmd.CallVolume[r, c] > 0; bool putCondition = this.cpmd.PutPrice != null && this.cpmd.PutPrice[r, c] > s0 * optionThreshold && this.cpmd.PutVolume[r, c] > 0; if (callCondition) { hc.hestonCallPrice[r, c] = callFun.Evaluate(this.strike[c]); if (HestonCallOptimizationProblem.optimizeRelativeError) { double mkt = pricingMin + this.callMarketPrice[r, c]; double model = pricingMin + hc.hestonCallPrice[r, c]; hc.sum += callWeight[r, c] * Math.Pow((model - mkt) / mkt, 2); } else { hc.sum += callWeight[r, c] * Math.Pow(hc.hestonCallPrice[r, c] - this.callMarketPrice[r, c], 2); } } if (putCondition) { hc.hestonPutPrice[r, c] = putFun.Evaluate(this.strike[c]); if (HestonCallOptimizationProblem.optimizeRelativeError) { double mkt = pricingMin + this.cpmd.PutPrice[r, c]; double model = pricingMin + hc.hestonPutPrice[r, c]; hc.sum += putWeight[r, c] * Math.Pow((model - mkt) / mkt, 2); } else { hc.sum += putWeight[r, c] * Math.Pow(hc.hestonPutPrice[r, c] - this.cpmd.PutPrice[r, c], 2); } } } return; }