我正在尝试使用极端优化例程在 C# 中创建风险平价投资组合。
在我购买它们之前,我主要是在试穿它们,看看我是否喜欢它们(我是学生,所以钱很紧)。
我的想法是实施这种称为风险平价的新型投资组合优化。它基本上说,为了使您的投资组合多样化,您应该为其每个组成部分赋予相同的风险。
运行 np1.Solve() 时出现空错误,我不明白为什么。我以为其他的一切都是由极限优化计算出来的。
1.我做错了什么?
2. 有没有一种我不知道的更快的方法来进行这种优化?
3. 如果你不知道 EO 库,但可以用 C# 中的其他东西来实现它,你能否就如何解决这个问题发表评论?
顺便说一下,投资组合构建的详细信息在距离函数的注释中,以防您感兴趣。
最好的问候,
爱德华多
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Extreme.Statistics;
using Extreme.Mathematics;
using Extreme.Mathematics.Optimization;
namespace TestingRiskParityOptimization
{
class Program
{
static void Main(string[] args)
{
NonlinearProgram np1 = new NonlinearProgram(2);
Func<Vector, double> distance = DistanceFunction;
np1.ObjectiveFunction = distance;
np1.InitialGuess = Vector.CreateConstant(2, 1.0 / ((double)2));
np1.AddNonlinearConstraint(x => x[0] + x[1], ConstraintType.GreaterThanOrEqual, 0);
Vector solution = np1.Solve();
Console.WriteLine("Solution: {0:F6}", solution);
Console.WriteLine("Optimal value: {0:F6}", np1.OptimalValue);
Console.WriteLine("# iterations: {0}", np1.SolutionReport.IterationsNeeded);
Console.Write("Press Enter key to exit...");
Console.ReadLine();
}
private static double DistanceFunction(Vector Weights)
{
Matrix Sigma = Matrix.Create(new double[,] {
{0.1, 0.2},
{0.2, 0.4}
});
// if VarP = Weights' * CovarMatrix * Weights and VolP = sqrt(VarP)
// Then the marginal contribution to risk of an asset is the i-th number of
// Sigma*Weights*VolP
// And thus the contribution to risk of an asset is simply Weights . (Sigma*Weights/VarP)
// we need to find weights such that Weights (i) * Row(i) of (Sigma*Weights/VarP) = 1/N
// that is we want to minimize the distance of row vector (Weights (i) * Row(i) of (Sigma*Weights/VarP)) and vector 1/N
double Variance = Vector.DotProduct(Weights, Sigma * Weights);
Vector Beta = Sigma * Weights / Variance;
for (int i = 0; i < Beta.Length; i++)
{
// multiplies row of beta by weight to find the percent contribution to risk
Beta[i] = Weights[i] * Beta[i];
}
Vector ObjectiveVector = Vector.CreateConstant(Weights.Length, 1.0 / ((double)Weights.Length));
Vector Distance = Vector.Subtract(Beta, ObjectiveVector);
return Math.Sqrt(Vector.DotProduct(Distance, Distance));
}
}
}