C# C语言中基于极值优化的风险平价投资组合优化#

C# C语言中基于极值优化的风险平价投资组合优化#,c#,mathematical-optimization,numerical,nonlinear-optimization,C#,Mathematical Optimization,Numerical,Nonlinear Optimization,我正试图使用极端优化程序在C#中创建一个风险平价投资组合 在我买之前,我主要是试着看看我是否喜欢它们(我是个学生,所以钱很紧) 我的想法是实施这种新的投资组合优化,称为风险平价。它基本上说,为了使你的投资组合多样化,你应该给它的每个组成部分同等的风险 运行np1.Solve()时出现空错误,我不明白为什么。我以为其他一切都是通过极端优化计算出来的。 1.我做错了什么? 2.有没有一种我不知道的更快的优化方法? 3.如果您不了解EO库,但可以使用C#中的其他工具实现此功能,请您对如何解决此问题发表

我正试图使用极端优化程序在C#中创建一个风险平价投资组合

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

我的想法是实施这种新的投资组合优化,称为风险平价。它基本上说,为了使你的投资组合多样化,你应该给它的每个组成部分同等的风险

运行np1.Solve()时出现空错误,我不明白为什么。我以为其他一切都是通过极端优化计算出来的。
1.我做错了什么?
2.有没有一种我不知道的更快的优化方法?
3.如果您不了解EO库,但可以使用C#中的其他工具实现此功能,请您对如何解决此问题发表评论

顺便说一句,如果你感兴趣的话,投资组合构造的细节在距离函数的注释中

致以最诚挚的问候,
爱德华多

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用极端统计;
运用极限数学;
使用极限、数学、优化;
命名空间测试RiskParityOptimization
{
班级计划
{
静态void Main(字符串[]参数)
{
非线性规划np1=新的非线性规划(2);
Func距离=距离函数;
np1.ObjectiveFunction=距离;
np1.InitialGuess=Vector.CreateConstant(2,1.0/((双精度)2));
np1.AddNonlinearConstraint(x=>x[0]+x[1],ConstraintType.GreaterThanOrEqual,0);
向量解=np1.Solve();
WriteLine(“解决方案:{0:F6}”,解决方案);
WriteLine(“最佳值:{0:F6}”,np1.optimizeValue);
WriteLine(“#迭代:{0}”,np1.SolutionReport.iterationneeded);
控制台。写入(“按回车键退出…”);
Console.ReadLine();
}
专用静态双距离函数(向量权重)
{
矩阵西格玛=矩阵。创建(新的双[,]{
{0.1, 0.2},
{0.2, 0.4}
});
//如果VarP=Weights'*CovarMatrix*Weights和VolP=sqrt(VarP)
//那么,资产对风险的边际贡献是
//西格玛*权重*VolP
//因此,对资产风险的贡献只是权重。(西格玛*权重/VarP)
//我们需要找到权重,使得(Sigma*权重/VarP)的权重(i)*行(i)=1/N
//也就是说,我们想要最小化行向量(权重(i)×行(i)(Sigma*权重/VarP))和向量1/N的距离
双方差=向量点积(权重,西格玛*权重);
向量β=西格玛*权重/方差;
for(int i=0;i
如果目标函数计算抛出,我强烈建议您通过调试器运行代码,以确定抛出代码的确切位置。我的第一个赌注是错误是由于向量大小不匹配造成的,例如在矩阵向量乘法中。如果您找到了这个错误的根源,那么优化很可能会顺利运行

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

    微软Lover基金会(MSDN,微软.COM/En/DeVals/HH14500 3.ASPX),微软数学优化平台
  • ,它使用Ipopt作为NLP解算器
  • ,C#COBYLA2算法的端口,一种支持非线性约束的直接搜索算法(C.f.Nelder-Mead)

我想support@extremeoptimization.com是一个更好的地方。乍一看,这个功能看起来还不错。如果你用一个任意向量调用函数本身,它是返回一个双倍值还是抛出?它抛出:/I我做了一些其他的事情,我使用了Nelder mead的算法,我只打算在短期内使用它。。。后来,如果我发现它太慢,我可以随时更改它或编写自己的实现。。。
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));

        }
    }
}