/// <summary> /// Sets several variables used to solve the optimization problem. /// </summary> /// <param name="callMarketPrice">A matrix containing call option market prices.</param> /// <param name="maturity"> /// Vector of call option maturities relative to callMarketPrice matrix. /// </param> /// <param name="strike"> /// Vector of call option strikes relative to callMarketPrice matrix. /// </param> /// <param name="rate"> /// Vector of zero coupon bond rates calculated relative to maturity vector maturities. /// </param> /// <param name="dividendYield"> /// Vector of dividend yield rates calculated relative to maturity vector maturities. /// </param> /// <param name="s0">Index/Equity value at the time of calibration.</param> /// <param name="matBound"> /// A vector containing the minimum and maximum values /// for maturities to be used in calibration. /// </param> /// <param name="strikeBound"> /// A vector containing the minimum and maximum values /// for strikes to be used in calibration.</param> private void SetVariables(Matrix callMarketPrice, Vector maturity, Vector strike, Vector rate, Vector dividendYield, double s0) { this.s0 = s0; //var rf = new PFunction(maturity, rate); var dy = new PFunction(maturity, dividendYield); //var rfF = new Fairmat.Math.Integrate(x => rf.Evaluate(x)); var dyF = new Fairmat.Math.Integrate(x => dy.Evaluate(x)); this.rate = new Vector(maturity.Length); this.dividendYield = new Vector(maturity.Length); for (int z = 0; z < maturity.Length; z++) { //this.rate[z] = rfF.AdaptLobatto(0, maturity[z]) / maturity[z]; this.dividendYield[z] = dyF.AdaptLobatto(0, maturity[z]) / maturity[z]; } this.rate = rate; this.maturity = maturity; //this.drift = this.rate - this.dividendYield; this.strike = strike; this.callMarketPrice = callMarketPrice; this.numCall = 0; callWeight = new Matrix(this.callMarketPrice.R, this.callMarketPrice.C); putWeight = new Matrix(this.callMarketPrice.R, this.callMarketPrice.C); for (int r = 0; r < this.callMarketPrice.R; r++) { if (this.maturity[r] >= matBound[0] && this.maturity[r]<= matBound[1]) { for (int c = 0; c < this.callMarketPrice.C; c++) { if (this.strike[c] >= s0 * strikeBound[0] && this.strike[c] <= s0 * strikeBound[1]) { if (calibrateOnCallOptions) if (this.callMarketPrice[r, c] > s0 * optionThreshold && this.cpmd.CallVolume[r, c] > 0) { this.callWeight[r, c] = CalculateWeight(this.cpmd.CallVolume[r, c]); this.numCall++; this.totalVolume += CalculateWeight(this.cpmd.CallVolume[r, c]) ; } if (calibrateOnPutOptions) if (this.cpmd.PutPrice != null && this.cpmd.PutPrice[r, c] > s0 * optionThreshold && this.cpmd.PutVolume[r, c] > 0) { this.putWeight[r, c] = CalculateWeight(this.cpmd.PutVolume[r, c]); this.numPut++; this.totalVolume += CalculateWeight(this.cpmd.PutVolume[r, c]); } } } } } //calibrate minVolatility: actually in this.cpmd.Volatility there is sigma not sigma^2 if (this.cpmd.Volatility != null) { //Rows maturities, columns strikes vLastMin = 0.5 * Math.Pow(this.cpmd.Volatility.Min().Min(), 2); v0Min = 0.99 * Math.Pow(this.cpmd.Volatility[0, Range.All].Min().Min(), 2); v0Max = 1.01 * Math.Pow(this.cpmd.Volatility[0, Range.All].Max().Max(), 2); } Console.WriteLine("Options weighting:\t" + weighting); Console.WriteLine("OptionThreshold:\t" + optionThreshold); Console.WriteLine("Strike Bounds:\t" + strikeBound); Console.WriteLine("Maturity Bounds:\t" + matBound); Console.WriteLine("Lb:\t" + Bounds.Lb); Console.WriteLine("Ub:\t" + Bounds.Ub); if(Engine.Verbose>=2) PutCallTest(); }
/// <summary> /// Sets several variables used to solve the optimization problem. /// </summary> /// <param name="callMarketPrice">A matrix containing call option market prices.</param> /// <param name="maturity"> /// Vector of call option maturities relative to callMarketPrice matrix. /// </param> /// <param name="strike"> /// Vector of call option strikes relative to callMarketPrice matrix. /// </param> /// <param name="rate"> /// Vector of zero coupon bond rates calculated relative to maturity vector maturities. /// </param> /// <param name="dividendYield"> /// Vector of dividend yield rates calculated relative to maturity vector maturities. /// </param> /// <param name="s0">Index/Equity value at the time of calibration.</param> /// <param name="matBound"> /// A vector containing the minimum and maximum values /// for maturities to be used in calibration. /// </param> /// <param name="strikeBound"> /// A vector containing the minimum and maximum values /// for strikes to be used in calibration.</param> private void SetVariables(Matrix callMarketPrice, Vector maturity, Vector strike, Vector rate, Vector dividendYield, double s0) { this.s0 = s0; //var rf = new PFunction(maturity, rate); var dy = new PFunction(maturity, dividendYield); //var rfF = new Fairmat.Math.Integrate(x => rf.Evaluate(x)); var dyF = new Fairmat.Math.Integrate(x => dy.Evaluate(x)); this.rate = new Vector(maturity.Length); this.dividendYield = new Vector(maturity.Length); for (int z = 0; z < maturity.Length; z++) { //this.rate[z] = rfF.AdaptLobatto(0, maturity[z]) / maturity[z]; this.dividendYield[z] = dyF.AdaptLobatto(0, maturity[z]) / maturity[z]; } this.rate = rate; this.maturity = maturity; //this.drift = this.rate - this.dividendYield; this.strike = strike; this.callMarketPrice = callMarketPrice; this.numCall = 0; callWeight = new Matrix(this.callMarketPrice.R, this.callMarketPrice.C); putWeight = new Matrix(this.callMarketPrice.R, this.callMarketPrice.C); for (int r = 0; r < this.callMarketPrice.R; r++) { if (this.maturity[r] >= matBound[0] && this.maturity[r] <= matBound[1]) { for (int c = 0; c < this.callMarketPrice.C; c++) { if (this.strike[c] >= s0 * strikeBound[0] && this.strike[c] <= s0 * strikeBound[1]) { if (calibrateOnCallOptions) { if (this.callMarketPrice[r, c] > s0 * optionThreshold && this.cpmd.CallVolume[r, c] > 0) { this.callWeight[r, c] = CalculateWeight(this.cpmd.CallVolume[r, c]); this.numCall++; this.totalVolume += CalculateWeight(this.cpmd.CallVolume[r, c]); } } if (calibrateOnPutOptions) { if (this.cpmd.PutPrice != null && this.cpmd.PutPrice[r, c] > s0 * optionThreshold && this.cpmd.PutVolume[r, c] > 0) { this.putWeight[r, c] = CalculateWeight(this.cpmd.PutVolume[r, c]); this.numPut++; this.totalVolume += CalculateWeight(this.cpmd.PutVolume[r, c]); } } } } } } //calibrate minVolatility: actually in this.cpmd.Volatility there is sigma not sigma^2 if (this.cpmd.Volatility != null) { //Rows maturities, columns strikes vLastMin = 0.5 * Math.Pow(this.cpmd.Volatility.Min().Min(), 2); v0Min = 0.99 * Math.Pow(this.cpmd.Volatility[0, Range.All].Min().Min(), 2); v0Max = 1.01 * Math.Pow(this.cpmd.Volatility[0, Range.All].Max().Max(), 2); } Console.WriteLine("Options weighting:\t" + weighting); Console.WriteLine("OptionThreshold:\t" + optionThreshold); Console.WriteLine("Strike Bounds:\t" + strikeBound); Console.WriteLine("Maturity Bounds:\t" + matBound); Console.WriteLine("Lb:\t" + Bounds.Lb); Console.WriteLine("Ub:\t" + Bounds.Ub); if (Engine.Verbose >= 2) { PutCallTest(); } }