Skip to content

Commit

Permalink
notebooks
Browse files Browse the repository at this point in the history
  • Loading branch information
tschm committed Jun 21, 2023
1 parent a1bdde1 commit 498250a
Show file tree
Hide file tree
Showing 4 changed files with 283 additions and 328 deletions.
462 changes: 231 additions & 231 deletions book/docs/notebooks/demo.ipynb

Large diffs are not rendered by default.

103 changes: 31 additions & 72 deletions book/docs/notebooks/factormodel.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -39,46 +39,6 @@
"from cvx.risk.factor import FactorModel"
]
},
{
"cell_type": "markdown",
"id": "5acabae2-f859-4512-978c-29e3a9a96cb5",
"metadata": {
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"## An abstract Risk Model\n",
"\n",
"An abstract risk model is the parent for concrete risk models. It serves as the blueprint. No instances of this class can be created.\n",
"Each risk model inherits the interface and all attributes defined in this class. \n",
"\n",
"An optimizer would get a risk model. Since all risk models share the interface it is trivial to change the risk model."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "5699fcfb-b7ce-4018-b20d-62603b27453b",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"from abc import abstractmethod, ABC\n",
"\n",
"\n",
"class RiskModel(ABC):\n",
" @abstractmethod\n",
" def estimate_risk(self, weights, **kwargs):\n",
" \"\"\"\n",
" Estimate the variance of a portfolio given its weights\n",
" The weights may come as a cvxpy Variable or numpy array.\n",
" \"\"\""
]
},
{
"cell_type": "markdown",
"id": "72f447e8-635d-4ff0-b4ec-d2c856078ccd",
Expand All @@ -93,7 +53,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 2,
"id": "feafbc51-f23e-4435-ae09-7d207fcd7136",
"metadata": {
"pycharm": {
Expand All @@ -120,7 +80,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 3,
"id": "f9e3e0a1-d16d-4976-81ed-4ec3815cb5ee",
"metadata": {
"pycharm": {
Expand Down Expand Up @@ -158,7 +118,7 @@
{
"data": {
"text/plain": [
"8.526818368171275e-05"
"0.00923407730537884"
]
},
"execution_count": 5,
Expand All @@ -170,12 +130,11 @@
"model = FactorModel(assets=len(returns.columns), k=10)\n",
"\n",
"# update the model parameters\n",
"model.update_data(cov=factors.cov, exposure=factors.exposure.values, idiosyncratic_risk=factors.idiosyncratic.std().values,\n",
" lower=np.zeros(20), upper=np.ones(20))\n",
"model.update(cov=factors.cov, exposure=factors.exposure.values, idiosyncratic_risk=factors.idiosyncratic.std().values)\n",
"\n",
"# test the risk model with uniform weights\n",
"weights = 0.05 * np.ones(20)\n",
"model.estimate_risk(weights).value"
"model.estimate(weights).value"
]
},
{
Expand All @@ -192,7 +151,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 8,
"id": "2dd75849-e600-4f26-bbac-e63d06eb1335",
"metadata": {
"pycharm": {
Expand All @@ -204,43 +163,43 @@
"name": "stdout",
"output_type": "stream",
"text": [
"GOOG 5.139026e-24\n",
"AAPL 1.307768e-02\n",
"FB 3.414333e-24\n",
"BABA 5.587538e-02\n",
"AMZN 3.332625e-02\n",
"GE 6.494129e-03\n",
"AMD -1.538891e-23\n",
"WMT 4.472814e-02\n",
"BAC -1.993206e-24\n",
"GM -4.055911e-24\n",
"T 1.330519e-01\n",
"UAA -1.008809e-23\n",
"SHLD -8.047317e-23\n",
"XOM 2.498250e-01\n",
"RRC -2.756693e-23\n",
"BBY 1.102160e-02\n",
"MA 6.236276e-02\n",
"PFE 2.407212e-01\n",
"JPM 1.270214e-24\n",
"SBUX 1.495160e-01\n",
"GOOG 0.000841\n",
"AAPL 0.000463\n",
"FB 0.000462\n",
"BABA 0.003246\n",
"AMZN 0.000594\n",
"GE 0.003120\n",
"AMD 0.143065\n",
"WMT 0.001252\n",
"BAC 0.001290\n",
"GM 0.000356\n",
"T 0.000359\n",
"UAA 0.186590\n",
"SHLD 0.534772\n",
"XOM 0.000519\n",
"RRC 0.036929\n",
"BBY 0.082946\n",
"MA 0.000675\n",
"PFE 0.000576\n",
"JPM 0.001600\n",
"SBUX 0.000344\n",
"dtype: float64\n",
"4.6200569833807105e-05\n"
"0.000170523449914986\n"
]
}
],
"source": [
"w = cvx.Variable(20)\n",
"y = cvx.Variable(10)\n",
"\n",
"objective = cvx.Minimize(1e3*model.estimate_risk(w, y=y))\n",
"constraints = [w >= 0, cvx.sum(w) == 1, y == model.exposure @ w, model.lower <= w, w <= model.upper]\n",
"objective = cvx.Minimize(1e3*model.estimate(w, y=y))\n",
"constraints = [w >= 0, cvx.sum(w) == 1] + model.bounds.constraints(w)\n",
"\n",
"problem = cvx.Problem(objective=objective, constraints=constraints)\n",
"problem.solve()\n",
"\n",
"print(pd.Series(data=w.value, index=prices.columns))\n",
"print(model.estimate_risk(w, y=y).value)\n",
"print(model.estimate(w, y=y).value)\n",
"\n",
"# check the solution\n",
"assert np.isclose(w.value.sum(), 1.0)\n",
Expand Down Expand Up @@ -272,7 +231,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.6"
"version": "3.9.7"
}
},
"nbformat": 4,
Expand Down
26 changes: 11 additions & 15 deletions book/docs/notebooks/large.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,12 @@
"w = cvx.Variable(1000)\n",
"y = cvx.Variable(100)\n",
"\n",
"objective = cvx.Minimize(triangle.estimate_risk(w, y=y))\n",
"constraints = [w >= 0, cvx.sum(w) == 1, y==triangle.exposure @ w, triangle.lower <= w, w <= triangle.upper]\n",
"objective = cvx.Minimize(triangle.estimate(w, y=y))\n",
"constraints = [w >= 0, cvx.sum(w) == 1] + triangle.bounds.constraints(w)\n",
"\n",
"triangle.update_data(exposure=beta.values, \n",
"triangle.update(exposure=beta.values, \n",
" cov=factors.cov().values, \n",
" idiosyncratic_risk=pd.DataFrame(data=ret - factors @ beta, index=ret.index, columns=ret.columns).std().values,\n",
" lower=np.zeros(1000),\n",
" upper=np.ones(1000))\n"
" idiosyncratic_risk=pd.DataFrame(data=ret - factors @ beta, index=ret.index, columns=ret.columns).std().values)\n"
]
},
{
Expand All @@ -159,30 +157,28 @@
"name": "stdout",
"output_type": "stream",
"text": [
"237 ms ± 18.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
"495 ms ± 71 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
]
}
],
"source": [
"%%timeit\n",
"for i in range(1):\n",
" objective = cvx.Minimize(triangle.estimate_risk(w, y=y))\n",
" constraints = [w >= 0, cvx.sum(w) == 1, y==triangle.exposure @ w, triangle.lower <= w, w <= triangle.upper]\n",
" objective = cvx.Minimize(triangle.estimate(w, y=y))\n",
" constraints = [w >= 0, cvx.sum(w) == 1] + triangle.bounds.constraints(w)\n",
"\n",
" problem = cvx.Problem(objective=objective, constraints=constraints)\n",
" triangle.update_data(exposure=beta.values, \n",
" triangle.update(exposure=beta.values, \n",
" cov=factors.cov().values, \n",
" idiosyncratic_risk=pd.DataFrame(data=ret - factors @ beta, index=ret.index, columns=ret.columns).std().values,\n",
" lower=np.zeros(1000),\n",
" upper=np.ones(1000))\n",
" idiosyncratic_risk=pd.DataFrame(data=ret - factors @ beta, index=ret.index, columns=ret.columns).std().values)\n",
" \n",
" problem.solve(ignore_dpp=True)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "2878bfd7",
"id": "c534a9db",
"metadata": {
"collapsed": false,
"jupyter": {
Expand Down Expand Up @@ -216,7 +212,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.6"
"version": "3.9.7"
}
},
"nbformat": 4,
Expand Down
20 changes: 10 additions & 10 deletions book/docs/notebooks/sample.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 4,
"metadata": {
"collapsed": false,
"jupyter": {
Expand All @@ -58,16 +58,16 @@
" _riskmodel = SampleCovariance(num=n)\n",
"\n",
" _problem = cp.Problem(\n",
" cp.Minimize(_riskmodel.estimate_risk(weights)),\n",
" [cp.sum(weights) == 1.0, weights >= 0, _riskmodel.lower <= weights, weights <= _riskmodel.upper],\n",
" cp.Minimize(_riskmodel.estimate(weights)),\n",
" [cp.sum(weights) == 1.0, weights >= 0] + _riskmodel.bounds.constraints(weights)\n",
" )\n",
"\n",
" return _problem, _riskmodel"
]
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 5,
"metadata": {
"collapsed": false,
"jupyter": {
Expand All @@ -82,7 +82,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"270 ms ± 15.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
"358 ms ± 15.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
]
}
],
Expand All @@ -94,13 +94,13 @@
"_problem, _riskmodel = problem(n)\n",
"\n",
"for i in range(100):\n",
" _riskmodel.update_data(cov=a, lower=np.zeros(48), upper=np.ones(48))\n",
" _riskmodel.update(cov=a)\n",
" _problem.solve()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 7,
"metadata": {
"collapsed": false,
"jupyter": {
Expand All @@ -115,7 +115,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"6.87 s ± 1.17 s per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
"4.13 s ± 53.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
]
}
],
Expand All @@ -129,7 +129,7 @@
"\n",
"for i in range(100):\n",
" _problem, _riskmodel = problem(a.shape[0])\n",
" _riskmodel.update_data(cov=a, lower=np.zeros(48), upper=np.ones(48))\n",
" _riskmodel.update(cov=a)\n",
" _problem.solve()"
]
},
Expand Down Expand Up @@ -157,7 +157,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.6"
"version": "3.9.7"
}
},
"nbformat": 4,
Expand Down

0 comments on commit 498250a

Please sign in to comment.