在C#中使用极限优化的风险 - 奇偶性投资组合优化

时间:2012-07-15 17:05:54

标签: c# mathematical-optimization numerical nonlinear-optimization

我正在尝试使用Extreme Optimization例程在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 个答案:

答案 0 :(得分:1)

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

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

  • Microsoft Solver Foundation(msdn.microsoft.com/en-us/devlabs/hh145003.aspx),Microsoft的数学优化平台
  • Funclib,它使用Ipopt作为NLP解算器
  • Cscobyla,COBYLA2算法的C#端口,支持非线性约束的直接搜索算法(c.f. Nelder-Mead)