我正在尝试在 C# 中编写一个 markowitz 优化类,但优化结果不够好。投资组合权重与 matlab 和 excel 的解决方案平均相差 0.2%。我检查了我的协方差矩阵计算和其他计算,发现它们是正确的。有没有办法校准模型的公差或其他方法以获得更好的结果?有我的代码。
public List<OptimalWeight> CalcOptimalWeights(bool isNegativeAllowed,string method)
{
List<OptimalWeight> weightsResult = new List<OptimalWeight>();
List<List<CovarItem>> covariances = new List<List<CovarItem>>();
covariances = CalcCovariances();
int n = this.AssetReturnList.Count();
SolverContext solver = SolverContext.GetContext();
Model model = solver.CreateModel();
if(isNegativeAllowed == false)
{
Decision[] weights = new Decision[n];
for (int i = 0; i < n; i++)
{
model.AddDecision(weights[i] = new Decision(Domain.RealNonnegative, null));
}
model.AddConstraint("SumWeights", Model.Sum(weights) == 1);
if(this.Constraints.Count() == 0)
{
if (method == "MinVar")
{
Term portVar = 0.0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
portVar += weights[j] * covariances[j][i].Covar * weights[i];
}
}
model.AddGoal("MinVarPort", GoalKind.Minimize, portVar);
Solution solution = solver.Solve();
var report = solution.GetReport();
var decisions = solution.Decisions;
List<double> d = decisions.Select(x => x.GetDouble()).ToList();
for(int i = 0 ; i < n; i++)
{
weightsResult.Add(new OptimalWeight {AssetId = AssetReturnList[i].AssetId,
Symbol = AssetReturnList[i].Symbol,
Weight = d[i] });
}
double pvar = solution.Goals.First().ToDouble();
}
}
}
return weightsResult;
}