Estoy intentando crear una cartera de riesgo-paridad en C# utilizando las rutinas de Optimización Extrema.
Principalmente los estoy probando para ver si me gustan o no antes de comprarlos (soy estudiante así que el dinero es escaso).
Mi idea era poner en práctica este nuevo tipo de optimización de la cartera llamado riesgo-paridad. Básicamente dice que para diversificar tu cartera debes dar igual riesgo a cada uno de sus componentes.
Estoy recibiendo un error nulo al ejecutar np1.Solve()
y no entiendo por qué. Pensaba que todo lo demás lo calculaba la Optimización Extrema.
-
¿Qué estoy haciendo mal?
-
¿Hay alguna forma más rápida de hacer esta optimización que yo desconozca?
-
Si no conoces las Bibliotecas EO, pero podrías implementar esto con algo más, ¿podrías por favor dejar un comentario sobre cómo harías para resolver esto?
Por cierto, los detalles sobre la construcción de la cartera están en los comentarios de la función de distancia, por si te interesa.
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));
}
}
}