/// <summary>
/// Attempts to solve the Heston optimization problem using
/// <see cref="Heston.HestonOptimizationProblem"/>.
/// </summary>
/// <param name="marketData">Data to be used in order to perform the optimization.</param>
/// <param name="settings">The parameter is not used.</param>
/// <param name="controller">IController.</param>
/// <returns>The results of the optimization.</returns>
public EstimationResult Estimate(List <object> marketData, IEstimationSettings settings = null, IController controller = null, Dictionary <string, object> properties = null)
{
DateTime t0 = DateTime.Now;
var interestDataSet = (CurveMarketData)marketData[0];
CallPriceMarketData callDataSet = (CallPriceMarketData)marketData[1];
EquityCalibrationData equityCalData = new EquityCalibrationData(callDataSet, interestDataSet);
var spotPrice = (DVPLI.MarketDataTypes.Scalar)marketData[2];
Setup(equityCalData, settings);
var calSettings = settings as HestonCalibrationSettings;
// Creates the context.
Document doc = new Document();
ProjectROV prj = new ProjectROV(doc);
doc.Part.Add(prj);
// Optimization problem instance.
Vector matBound = new Vector(2);
Vector strikeBound = new Vector(2);
if (calSettings != null)
{
matBound[0] = calSettings.MinMaturity;
matBound[1] = calSettings.MaxMaturity;
strikeBound[0] = calSettings.MinStrike;
strikeBound[1] = calSettings.MaxStrike;
}
else
{
//use defaults
matBound[0] = 1.0 / 12; // .25;
matBound[1] = 6; // 10; //Up to 6Y maturities
strikeBound[0] = 0.4;
strikeBound[1] = 1.6;
}
Console.WriteLine(callDataSet);
/*
* //CBA TEST
* matBound[0] = 1;// .25;
* matBound[1] = 3.5;// 10; //Up to 6Y maturities
* strikeBound[0] = 0.5;// 0.5;
* strikeBound[1] = 2;//1.5;
*/
HestonCallOptimizationProblem problem = NewOptimizationProblem(equityCalData, matBound, strikeBound);
int totalOpts = problem.numCall + problem.numPut;
Console.WriteLine("Calibration based on " + totalOpts + " options. (" + problem.numCall + " call options and " + problem.numPut + " put options).");
IOptimizationAlgorithm solver = new QADE();
//IOptimizationAlgorithm solver = new MultiLevelSingleLinkage();
IOptimizationAlgorithm solver2 = new SteepestDescent();
DESettings o = new DESettings();
o.controller = controller;
// If true the optimization algorithm will operate in parallel.
o.Parallel = Engine.MultiThread;
o.h = 10e-8;
o.epsilon = 10e-8;
SolutionInfo solution = null;
double minObj = double.MaxValue;
Vector minX = null;
int Z = 1;
//if (problem.GetType() == typeof(Heston.HestonCallSimulationOptimizationProblem))
// Z = 2;
for (int z = 0; z < Z; z++)
{
if (solver.GetType() == typeof(MultiLevelSingleLinkage))
{
o.NP = 50;
o.MaxIter = 25;
o.MaxGamma = 6;
}
else
{
o.NP = 60;
o.MaxIter = 35;
}
o.Verbosity = 1;
Vector x0 = null;// new Vector(new double[] { 0.5, 0.5, 0.8, -0.5, 0.05 });
// GA
solution = solver.Minimize(problem, o, x0);
if (solution.errors)
{
return(null);
}
o.options = "qn";
o.MaxIter = 500;// 1000;
if (solution != null)
{
solution = solver2.Minimize(problem, o, solution.x);
}
else
{
solution = solver2.Minimize(problem, o, x0);
}
if (solution.errors)
{
return(null);
}
if (solution.obj < minObj)
{
minObj = solution.obj;
minX = solution.x.Clone();
}
}
solution.obj = minObj;
solution.x = minX;
//Displays pricing error structure
HestonCallOptimizationProblem.displayObjInfo = true;
problem.Obj(solution.x);
HestonCallOptimizationProblem.displayObjInfo = false;
Console.WriteLine("Calibration Time (s)\t" + (DateTime.Now - t0).TotalSeconds);
return(BuildEstimate(spotPrice, interestDataSet, callDataSet, equityCalData, solution));
}