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)