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;
}