Skip to content

Commit 638fd2e

Browse files
committed
portfolio optimization using cvxpy notebook
1 parent 81cb11b commit 638fd2e

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "9a8d9072",
6+
"metadata": {},
7+
"source": [
8+
"# Installing the NAG Library and running this notebook\n",
9+
"To run this notebook, you will need to install the NAG Library for Python (Mark 29.3 or newer) and a license key. You can find the software and have a license key (trials are available) from our website here: [Getting Started with the NAG Library](https://www.nag.com/content/getting-started-nag-library?lang=py&os=linux)\n",
10+
"\n",
11+
"We are solving a classic portfolio optimization problem using the NAG Library integration in CVXPY. It can be formulated in the following way:\n",
12+
"\n",
13+
"\\begin{equation*}\n",
14+
" \\begin{aligned}\n",
15+
" &\\min_{x \\in \\mathbb{R}^n} &&\\frac{1}{2} x^T Q_0 x + r^T_0 x\n",
16+
" \\\\\n",
17+
" &\\textrm{subject to } &&\\frac{1}{2} x^T Q_1 x + r^T_1 x \\leq 0,\n",
18+
" \\\\\n",
19+
" & &&e^Tx = 1,\n",
20+
" \\\\\n",
21+
" & && x \\geq 0,\n",
22+
" \\end{aligned}\n",
23+
"\\end{equation*}\n",
24+
"where $e$ refers to the vector of all ones."
25+
]
26+
},
27+
{
28+
"cell_type": "code",
29+
"execution_count": 1,
30+
"id": "dcbfd044",
31+
"metadata": {},
32+
"outputs": [],
33+
"source": [
34+
"# Import modules\n",
35+
"from cvxpy import Minimize, Problem, Variable, quad_form, sum, atoms, OPTIMAL, NAG\n",
36+
"import numpy as np\n",
37+
"import naginterfaces"
38+
]
39+
},
40+
{
41+
"cell_type": "code",
42+
"execution_count": 2,
43+
"id": "4d4bec67-2af9-4d14-932c-ac616f223be8",
44+
"metadata": {},
45+
"outputs": [
46+
{
47+
"data": {
48+
"text/plain": [
49+
"-0.17415932352686342"
50+
]
51+
},
52+
"execution_count": 2,
53+
"metadata": {},
54+
"output_type": "execute_result"
55+
}
56+
],
57+
"source": [
58+
"# Define number of assets\n",
59+
"n = 500 \n",
60+
"\n",
61+
"# Generate random data\n",
62+
"np.random.seed(2)\n",
63+
"r0 = np.matrix(np.random.randn(n, 1))\n",
64+
"r1 = np.matrix(np.random.randn(n, 1))\n",
65+
"q0 = np.matrix(np.random.randn(n, n))\n",
66+
"q0 = q0.T * q0\n",
67+
"q1 = np.matrix(np.random.randn(n, n))\n",
68+
"q1 = q1.T * q1\n",
69+
"\n",
70+
"# Skip psd check due to issues with ARPACK\n",
71+
"q0 = atoms.affine.wraps.psd_wrap(q0)\n",
72+
"q1 = atoms.affine.wraps.psd_wrap(q1)\n",
73+
"\n",
74+
"# Create the cvxpy problem:\n",
75+
"# Define the variables\n",
76+
"x = Variable(len(r1))\n",
77+
"\n",
78+
"# Define the constraints\n",
79+
"constraints = [\n",
80+
" 0 <= x, \n",
81+
" sum(x) == 1,\n",
82+
" 0.5*quad_form(x, q1) + (r1.T @ x) <= 0]\n",
83+
"\n",
84+
"# Define the objective function\n",
85+
"objective = Minimize(0.5*quad_form(x, q0) + r0.T @ x)\n",
86+
"\n",
87+
"# Set up dictionary for option setting\n",
88+
"nag_params = {'SOCP System Formulation':'AS',\n",
89+
" 'SOCP Factorization Method':'MA86'\n",
90+
" }\n",
91+
"\n",
92+
"# Define the problem\n",
93+
"prob = Problem(objective, constraints)\n",
94+
"\n",
95+
"# Solve the problem using NAG\n",
96+
"prob.solve(solver=NAG, nag_params=nag_params)"
97+
]
98+
}
99+
],
100+
"metadata": {
101+
"kernelspec": {
102+
"display_name": "Python 3 (ipykernel)",
103+
"language": "python",
104+
"name": "python3"
105+
},
106+
"language_info": {
107+
"codemirror_mode": {
108+
"name": "ipython",
109+
"version": 3
110+
},
111+
"file_extension": ".py",
112+
"mimetype": "text/x-python",
113+
"name": "python",
114+
"nbconvert_exporter": "python",
115+
"pygments_lexer": "ipython3",
116+
"version": "3.10.8"
117+
}
118+
},
119+
"nbformat": 4,
120+
"nbformat_minor": 5
121+
}

0 commit comments

Comments
 (0)