{ "nbformat_minor": 2, "cells": [ { "execution_count": 2, "cell_type": "code", "metadata": {}, "outputs": [], "source": "#!pip install lxml\n#!pip install --upgrade beautifulsoup4\n#!pip install --version tushare==1.0.5" }, { "execution_count": 1, "cell_type": "code", "metadata": {}, "outputs": [ { "output_type": "stream", "name": "stdout", "text": "1.0.5\n" } ], "source": "import tushare as ts\n\nprint(ts.__version__)" }, { "execution_count": 2, "cell_type": "code", "metadata": {}, "outputs": [ { "output_type": "stream", "name": "stderr", "text": "/usr/local/src/conda3_runtime/home/envs/DSX-Python35-Spark/lib/python3.5/site-packages/statsmodels/compat/pandas.py:56: FutureWarning: The pandas.core.datetools module is deprecated and will be removed in a future version. Please use the pandas.tseries module instead.\n from pandas.core import datetools\n" } ], "source": "import pandas as pd\nimport numpy as np\nimport statsmodels.api as sm #\u7edf\u8ba1\u8fd0\u7b97\nimport scipy.stats as scs #\u79d1\u5b66\u8ba1\u7b97\nimport matplotlib.pyplot as plt #\u7ed8\u56fe\n%matplotlib inline\nfrom IPython.core.pylabtools import figsize" }, { "source": "## 1. \u8bfb\u5165\u6570\u636e\u5c55\u73b0\u8d70\u52bf", "cell_type": "markdown", "metadata": {} }, { "source": "### 1.1 \u9009\u62e9\u4e2a\u80a1\n\u5b9e\u9645\u6295\u8d44\u4e2d\uff0c\u4e2a\u80a1\u9009\u62e9\u6709\u591a\u79cd\u65b9\u6cd5\uff0c\u4f1a\u6839\u636e\u677f\u5757\u3001\u4e2a\u80a1\u7ee9\u6548\u3001\u6295\u8d44\u4eba\u504f\u597d\u3001\u4fe1\u606f\u62ab\u9732\u7b49\u591a\u65b9\u9762\u8fdb\u884c\u6311\u9009\u3002\u4e00\u822c\u65e2\u8003\u8651\u5b9a\u91cf\u56e0\u7d20\uff0c\u4e5f\u8003\u8651\u5b9a\u6027\u56e0\u7d20\uff0c\u7ecf\u5e38\u8fd8\u4f1a\u4f9d\u636e\u6295\u8d44\u4e2d\u7684\u7ecf\u9a8c\u6cd5\u5219\u3002
\n\u8fd9\u91cc\uff0c\u7531\u4e8e\u7bc7\u5e45\u95ee\u9898\uff0c\u968f\u673a\u9009\u62e9\u4e86\u4e00\u4e9b\u4e2a\u80a1\uff0c\u5e76\u672a\u7ecf\u8fc7\u8ba4\u771f\u7b5b\u67e5\u3002", "cell_type": "markdown", "metadata": {} }, { "execution_count": 3, "cell_type": "code", "metadata": {}, "outputs": [], "source": "stocks = [['meidi','000333','\u7f8e\u7684\u96c6\u56e2'], \n ['icbc','601398','\u5de5\u5546\u94f6\u884c'], \n ['5liang','000858','\u4e94\u7cae\u6db2'],\n ['pingan','601318', '\u4e2d\u56fd\u5e73\u5b89']\n ]" }, { "source": "### 1.2 \u4e2a\u80a1\u7684\u5386\u53f2\u6570\u636e\u83b7\u53d6\n\u4f7f\u7528\u5de5\u5177\u4ece\u4e92\u8054\u7f51\u83b7\u53d6\u6bcf\u4e2a\u4e2a\u80a1\u5b9e\u65f6\u6570\u636e\uff0c\u4f7f\u7528\u6bcf\u65e5\u65e5\u7ec8\u4ef7\u683c\u3002", "cell_type": "markdown", "metadata": {} }, { "execution_count": 5, "cell_type": "code", "metadata": {}, "outputs": [], "source": "# \u6caa\u6df1300\nstart_dt = '2017-01-01'\nhis_hs300 = ts.get_hist_data('hs300',start=start_dt)\ndf = his_hs300.filter(['close']).rename(columns={'close':'hs300'})\n\nreturn_label = []\nfor stock in stocks:\n hs_data = ts.get_hist_data(stock[1], start=start_dt)\n df = df.join(hs_data.filter(['close']).rename(columns={'close':stock[0]}))\n return_label.append(stock[0])" }, { "execution_count": 6, "cell_type": "code", "metadata": {}, "outputs": [ { "execution_count": 6, "metadata": {}, "data": { "text/html": "\n | hs300 | \nmeidi | \nicbc | \n5liang | \npingan | \n
---|---|---|---|---|---|
date | \n\n | \n | \n | \n | \n |
2018-03-16 | \n4056.42 | \n59.69 | \n6.37 | \n76.87 | \n70.50 | \n
2018-03-15 | \n4096.16 | \n61.41 | \n6.46 | \n78.00 | \n70.50 | \n
2018-03-14 | \n4073.34 | \n60.40 | \n6.44 | \n75.55 | \n68.80 | \n
2018-03-13 | \n4091.25 | \n61.06 | \n6.50 | \n74.61 | \n69.45 | \n
2018-03-12 | \n4127.67 | \n60.73 | \n6.45 | \n76.15 | \n71.11 | \n
\n | hs300 | \nmeidi | \nicbc | \n5liang | \npingan | \n
---|---|---|---|---|---|
date | \n\n | \n | \n | \n | \n |
2017-01-03 | \nNaN | \nNaN | \nNaN | \nNaN | \nNaN | \n
2017-01-04 | \n0.007773 | \n0.024089 | \n0.000000 | \n0.035151 | \n-0.000841 | \n
2017-01-05 | \n-0.000154 | \n-0.004704 | \n0.002255 | \n0.000835 | \n0.002242 | \n
2017-01-06 | \n-0.005992 | \n-0.010156 | \n0.000000 | \n0.004720 | \n-0.008150 | \n
2017-01-09 | \n0.004836 | \n-0.004775 | \n0.004494 | \n0.009649 | \n-0.000564 | \n
2017-01-10 | \n-0.001675 | \n-0.002396 | \n0.000000 | \n0.001371 | \n-0.005379 | \n
2017-01-11 | \n-0.007103 | \n-0.020077 | \n0.002240 | \n-0.017690 | \n0.000000 | \n
2017-01-12 | \n-0.005075 | \n-0.014085 | \n0.000000 | \n-0.007277 | \n-0.000568 | \n
2017-01-13 | \n0.000690 | \n0.000709 | \n0.004464 | \n0.002525 | \n0.009891 | \n
2017-01-16 | \n-0.000139 | \n0.001063 | \n0.013275 | \n-0.006747 | \n0.017561 | \n
2017-01-17 | \n0.002080 | \n0.023094 | \n-0.004405 | \n0.008707 | \n-0.005820 | \n
2017-01-18 | \n0.003904 | \n0.007924 | \n0.000000 | \n0.032736 | \n0.006372 | \n
2017-01-19 | \n-0.003023 | \n-0.012779 | \n0.000000 | \n-0.002710 | \n-0.004428 | \n
2017-01-20 | \n0.007660 | \n0.015520 | \n-0.002210 | \n0.001627 | \n0.005808 | \n
2017-01-23 | \n0.002736 | \n-0.008938 | \n0.002210 | \n0.012653 | \n-0.001656 | \n
\u98ce\u9669\u8d44\u4ea7\u7684\u6295\u8d44\u6709\u4e24\u4e2a\u4e3b\u8981\u56e0\u7d20\uff1a\u9884\u671f\u6536\u76ca\u548c\u98ce\u9669\uff0c\u800c\u5e73\u8861\u6536\u76ca\u4e0e\u98ce\u9669\u7684\u5173\u7cfb\u662f\u6295\u8d44\u7ec4\u5408\u8003\u8651\u7684\u6838\u5fc3\u4e4b\u4e00\uff0c\u5982\u4f55\u914d\u7f6e\u4e2a\u80a1\u6210\u4e3a\u7ec4\u5408\u4f18\u5316\u7684\u91cd\u70b9\u3002
\n\u8fd9\u91cc\u7684\u6295\u8d44\u7ec4\u5408\u4f18\u5316\u6a21\u578b\u57fa\u4e8e\u9a6c\u79d1\u7ef4\u5179\u7684\u5747\u503c-\u65b9\u5dee\u6a21\u578b\u3002\u6b64\u6a21\u578b\u662f\u5728\u6709\u6548\u5e02\u573a\u5047\u8bbe\u4e0b\uff0c\u7406\u6027\u6295\u8d44\u7684\u65b9\u6cd5\uff0c\u5b83\u901a\u8fc7\u6784\u5efa\u6709\u6548\u6295\u8d44\u7ec4\u5408\u6765\u5206\u6563\u975e\u7cfb\u7edf\u98ce\u9669\uff0c\u5e76\u901a\u8fc7\u6536\u76ca\u3001\u6536\u76ca\u65b9\u5dee\u3001\u6536\u76ca\u95f4\u7684\u534f\u65b9\u5dee\u63ed\u793a\u4e86\u80a1\u7968\u6295\u8d44\u6536\u76ca\u548c\u98ce\u9669\u6210\u6b63\u6bd4\u5173\u7cfb\u3002
\n\u5747\u503c-\u65b9\u5dee\u6a21\u578b\u7684\u6570\u5b66\u8868\u8fbe\uff1a
\n\u5047\u8bbe\u4e00\u4e2a$n$\u652f\u80a1\u7968\u7684\u6295\u8d44\u7ec4\u5408\uff0c\u6bcf\u652f\u80a1\u7968\u7684\u6536\u76ca\u7387\u4e3a$R_i$\uff0c$w_j$\u4e3a\u8be5\u4e2a\u80a1\u5728\u7ec4\u5408\u4e2d\u8d44\u91d1\u5360\u6bd4\uff0c\u5219\u7ec4\u5408\u7684\u6536\u76ca\u7387$\\overline{R_p}$ \u4e3a\uff1a
\n$$ \\overline{R_p} = \\sum_{j=1}^n{w_j*R_j} $$\n\u7ec4\u5408\u7684\u98ce\u9669\u8861\u91cf-\u6807\u51c6\u5dee$\\overline{\\sigma_p}$\u4e3a\uff1a
\n$$ \\overline{\\sigma_p} = \\sqrt{\\sum_{i=1}^{n}{\\sum_{j=1}^n{w_i*w_j*\\sigma_{ij}}}} $$\n\u5176\u4e2d\uff0c$\\sigma_{ij}$\u4e3a\u4e2a\u80a1i\u4e0e\u4e2a\u80a1j\u7684\u534f\u65b9\u5dee\u3002
\n\u4ee5\u4e0a\u5f0f\u5b50\u4e5f\u53ef\u4ee5\u5199\u4e3a$\\overline{\\sigma_p}^2 = W^T\\Sigma W$\uff0c\u5176\u4e2dW\u662f\u4e2a\u80a1\u8d44\u91d1\u5360\u6bd4\u7684\u5411\u91cf\uff0c$\\Sigma$\u662f\u534f\u65b9\u5dee\u77e9\u9635\u3002
\n\u5747\u503c-\u65b9\u5dee\u6a21\u578b\u5c31\u662f\u8981\u505a\u5230\u6700\u5927\u5316\u6536\u76ca\uff0c\u6700\u5c0f\u5316\u98ce\u9669\uff0c\u56e0\u6b64\u53ef\u4ee5\u8868\u793a\u4e3a\uff1a
\n$$ \\begin{cases}\nmin& \\overline{\\sigma_p}^2 = W^T\\Sigma W \\\\\nmax& \\overline{R_p} = W^T * R \\\\\ns.t.& \\sum_{i=1}^n{w_i} = 1\n\\end{cases}$$\n\u8fd9\u662f\u4e00\u4e2a\u51f8\u4f18\u5316\u95ee\u9898\uff0c\u7ed9\u5b9a\u9884\u671f\u6536\u76ca\u7387$\\overline{R_p}$\u6211\u4eec\u53ef\u4ee5\u5199\u6210\u4e8c\u6b21\u89c4\u5212\u6a21\u578b\uff1a\n$$ min\\qquad \\overline{\\sigma_p}^2 = W^T\\Sigma W $$\n$$ s.t. \\qquad \\begin{cases}\n& W^TR \\geqslant \\overline{R_p} \\\\\n& w_i \\geqslant 0 \\\\\n& w_i \\leqslant 1 \\\\\n& \\sum_{i=1}^n{w_i} = 1 \\\\\n& ...\n\\end{cases}\n$$", "cell_type": "markdown", "metadata": {} }, { "source": "\u51f8\u4f18\u5316\u7b97\u6cd5\u6211\u4eec\u4f7f\u7528CPLEX\u6765\u89e3\u51b3\u3002", "cell_type": "markdown", "metadata": { "collapsed": true } }, { "execution_count": 51, "cell_type": "code", "metadata": {}, "outputs": [ { "execution_count": 51, "metadata": {}, "data": { "text/plain": "['meidi', 'icbc', '5liang', 'pingan']" }, "output_type": "execute_result" } ], "source": "return_label" }, { "execution_count": 52, "cell_type": "code", "metadata": {}, "outputs": [], "source": "returns = log_return[return_label]" }, { "execution_count": 53, "cell_type": "code", "metadata": {}, "outputs": [], "source": "returns.columns = return_label\nsec = return_label" }, { "source": "### 3.2 \u51c6\u5907\u8c03\u7528cplex\u670d\u52a1", "cell_type": "markdown", "metadata": {} }, { "source": "\u5728DO Optimization\u670d\u52a1\u4e2d\u67e5\u770b\u670d\u52a1\u51ed\u8bc1\uff0c\u590d\u5236url\u548cclient_id\u7684\u503c\u5206\u522b\u5230\u4e0b\u9762SVC_URL\u548cSVC_KEY\u53d8\u91cf\u8d4b\u503c\u57df\u3002", "cell_type": "markdown", "metadata": {} }, { "execution_count": 55, "cell_type": "code", "metadata": {}, "outputs": [], "source": "# The code was removed by DSX for sharing.\nSVC_URL = \"\"\nSVC_KEY = \"\"" }, { "execution_count": 56, "cell_type": "code", "metadata": {}, "outputs": [], "source": "import sys\ntry:\n import docplex.mp\nexcept:\n if hasattr(sys, 'real_prefix'):\n #we are in a virtual env.\n !pip install docplex\n else:\n !pip install --user docplex" }, { "execution_count": 57, "cell_type": "code", "metadata": {}, "outputs": [], "source": "from docplex.mp.advmodel import AdvModel as Model" }, { "execution_count": 58, "cell_type": "code", "metadata": {}, "outputs": [], "source": "df_s = pd.DataFrame(columns=['stock', 'return'])\ndf_s['stock'] = return_label\ndf_s['return'] = log_return[return_label].mean().values" }, { "execution_count": 59, "cell_type": "code", "metadata": {}, "outputs": [], "source": "df_s.set_index(['stock'], inplace=True)" }, { "source": "### 3.3 \u8ba1\u7b97\u534f\u65b9\u5dee\u77e9\u9635", "cell_type": "markdown", "metadata": {} }, { "execution_count": 60, "cell_type": "code", "metadata": {}, "outputs": [], "source": "dfv = pd.DataFrame(np.cov(np.asmatrix(returns).transpose()), index = sec, columns=sec)" }, { "execution_count": 61, "cell_type": "code", "metadata": {}, "outputs": [ { "execution_count": 61, "metadata": {}, "data": { "text/html": "\n | meidi | \nicbc | \n5liang | \npingan | \n
---|---|---|---|---|
meidi | \n0.000389 | \n0.000026 | \n0.000260 | \n0.000147 | \n
icbc | \n0.000026 | \n0.000164 | \n0.000014 | \n0.000068 | \n
5liang | \n0.000260 | \n0.000014 | \n0.000469 | \n0.000157 | \n
pingan | \n0.000147 | \n0.000068 | \n0.000157 | \n0.000311 | \n
\n | return | \n
---|---|
stock | \n\n |
icbc | \n0.001244 | \n
pingan | \n0.002332 | \n
meidi | \n0.002458 | \n
5liang | \n0.002728 | \n