2

我正尝试在C#中使用极限优化例程创建风险平价投资组合。在C#中使用极端优化的风险均值投资组合优化

我主要是在我买他们之前先试试他们是否喜欢他们(我是个学生,所以钱很紧)。

我的想法是实施这种称为风险平价的新型投资组合优化。它基本上说,为了使您的投资组合多样化,您应该为每个组件分配相同的风险。

运行np1.Solve()时出现空错误,我不明白为什么。我认为其他一切都是由Extreme Optimization计算的。
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)); 

     } 
    } 
} 
+1

我认为[email protected]对你来说是一个更好的地方。 – 2012-07-15 22:22:55

+0

乍一看,该功能看起来不错。如果您使用任意向量调用函数本身,它会返回一个double值还是抛出? – 2012-07-16 17:01:49

+0

它抛出:/我做了其他的东西,我用了Nelder-mead的算法,我只是想在短期内接受它...后来,如果我觉得它太慢,我总是可以改变它或代码我自己的实现... – 2012-07-16 22:05:27

回答

1

如果目标函数计算抛出,我强烈建议你通过调试运行代码来识别投掷代码的确切位置。我的第一个赌注是,错误是由于矢量大小不匹配而发生的,例如在矩阵向量乘法中。如果你发现这个错误的底部,那么优化将会顺利进行。

如果您想尝试替代算法,您可能需要查看以下解决方案之一。它们都支持(非)线性约束的规范,并且不需要提供目标函数和约束梯度。

  • 微软求解基金会(msdn.microsoft.com/en-us/devlabs/hh145003.aspx),微软的平台,为数学优化
  • Funclib,它采用Ipopt作为NLP求解
  • Cscobyla,C# COBYLA2算法的端口,支持非线性约束的直接搜索算法(cf Nelder-Mead)