16 using System.Collections.Generic;
19 using Accord.Math.Optimization;
20 using Accord.Statistics;
31 private double _lower;
32 private double _upper;
33 private double _targetReturn;
45 _targetReturn = targetReturn;
55 return new LinearConstraint(size)
57 CombinedAs = Vector.Create(size, 1.0),
58 ShouldBe = ConstraintType.EqualTo,
70 for (var i = 0; i < size; i++)
72 yield
return new LinearConstraint(1)
74 VariablesAtIndices =
new[] { i },
75 ShouldBe = ConstraintType.GreaterThanOrEqualTo,
78 yield
return new LinearConstraint(1)
80 VariablesAtIndices =
new[] { i },
81 ShouldBe = ConstraintType.LesserThanOrEqualTo,
94 public double[]
Optimize(
double[,] historicalReturns,
double[] expectedReturns =
null,
double[,] covariance =
null)
96 covariance ??= historicalReturns.Covariance();
97 var size = covariance.GetLength(0);
98 var returns = expectedReturns ?? historicalReturns.Mean(0);
100 var constraints =
new List<LinearConstraint>
105 CombinedAs = returns,
106 ShouldBe = ConstraintType.EqualTo,
107 Value = _targetReturn
117 var optfunc =
new QuadraticObjectiveFunction(covariance, Vector.Create(size, 0.0));
118 var solver =
new GoldfarbIdnani(optfunc, constraints);
121 var x0 = Vector.Create(size, 1.0 / size);
122 var success = solver.Minimize(Vector.Copy(x0));
123 if (!success)
return x0;
126 var solution = solver.Solution
127 .Select(x => x.IsNaNOrInfinity() ? 0 : x).ToArray();
130 var sumOfAbsoluteWeights = solution.Abs().Sum();
131 if (sumOfAbsoluteWeights.IsNaNOrZero())
return x0;
133 return solution.Divide(sumOfAbsoluteWeights);