workspace.ipynb 8.66 KB
{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import FinanceDataReader as fdr\n",
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "def basicinform(input):\n",
    "    stocks = pd.read_csv('stockcodename.csv',index_col=0)\n",
    "    symbol = ''\n",
    "    for i in enumerate(stocks.Name) :\n",
    "        if i[1] == input:\n",
    "            symbol = (stocks.iloc[i[0]].Symbol)\n",
    "            break\n",
    "    df = fdr.DataReader(symbol)\n",
    "    ror_df = df.Close.pct_change()\n",
    "    volume = df.Volume.iloc[-1]\n",
    "    price = df.Close.iloc[-1]\n",
    "    ror = ror_df[-1]\n",
    "    #print(\"현재가: \", price)\n",
    "    #print(\"거래량: \", volume)\n",
    "    #print(\"전일 대비 수익률:\", ror)\n",
    "    #display(df)\n",
    "    value = {\"현재가\": price ,\n",
    "              \"거래랑\": volume ,\n",
    "              \"전일 대비 수익률:\" : ror\n",
    "            }\n",
    "    return value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'현재가': 79700, '거래랑': 13358073, '전일 대비 수익률:': -0.004993757802746579}\n"
     ]
    }
   ],
   "source": [
    "print(basicinform('삼성전자'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "stocks = fdr.StockListing('KOSPI') # 코스피\n",
    "stocks.to_csv(\"stockcodename.csv\",mode='w', encoding='utf-8-sig')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {},
   "outputs": [],
   "source": [
    "import datetime\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import FinanceDataReader as fdr\n",
    "from scipy.optimize import minimize\n",
    "import json\n",
    "\n",
    "#소숫점 표현\n",
    "pd.options.display.float_format = '{:.3f}'.format\n",
    "np.set_printoptions(precision=3, suppress=True)\n",
    "\n",
    "class c_Models:\n",
    "    #Input 값으로, 자산 list, 사용자 포트폴리오 비중, 시작일, 마지막일\n",
    "    def __init__(self, assets, assets_w, start, end):\n",
    "        self.result = None\n",
    "        self.graph = None\n",
    "    \n",
    "        stocks = pd.read_csv('stockcodename.csv', index_col=0)\n",
    "        symbol = ''\n",
    "        self.asset_name = assets[:]\n",
    "        for k in range(len(assets)):\n",
    "            for i in enumerate(stocks.Name):\n",
    "                if i[1] == assets[k]:\n",
    "                    assets[k] = (stocks.iloc[i[0]].Symbol)\n",
    "                    break\n",
    "\n",
    "        data = pd.DataFrame()\n",
    "        # 전체 자산 data들을 가지고 온 후, 정리함\n",
    "        \n",
    "        for asset in assets: #total_list:\n",
    "            tmp = fdr.DataReader(asset,start,end).Close\n",
    "            if len(data) == 0 :\n",
    "                data = tmp\n",
    "            else:\n",
    "                data = pd.concat([data,tmp], axis=1)\n",
    "   \n",
    "        data.columns = self.asset_name\n",
    "   \n",
    "        if data.isnull().values.any() == True: #불러온 data에 오류가 있다면\n",
    "            return \"No Data\",''\n",
    "\n",
    "        else:\n",
    "            data = data.resample('M').mean() #일별 데이터를 월별 데이터로 만들어줌\n",
    "            data = data.pct_change() #월별 주가 데이터를 이용해 수익률 데이터로 변환\n",
    "            data.dropna(inplace=True) #결측치 제외(첫 row)\n",
    "\n",
    "            self.data = data\n",
    "            self.assets_w = assets_w\n",
    "            self.mu = data.mean() * 12\n",
    "            self.cov = data.cov() * 12\n",
    "\n",
    "    #GMV 최적화 : 제약 조건은 비중합=1, 공매도 불가능\n",
    "    def gmv_opt(self):\n",
    "        n_assets = len(self.data.columns)\n",
    "        w0 = np.ones(n_assets) / n_assets\n",
    "        fun = lambda w: np.dot(w.T, np.dot(self.cov, w))\n",
    "        constraints = ({'type':'eq', 'fun':lambda x: np.sum(x)-1})\n",
    "        bd = ((0,1),) * n_assets\n",
    "        #cov = data.cov() * 12\n",
    "        gmv = minimize(fun, w0, method = 'SLSQP', constraints=constraints, bounds=bd)\n",
    "        result = dict(zip(self.asset_name, np.round(gmv.x,3)))\n",
    "        return result\n",
    "    \n",
    "    #Max Sharp ratio : risk free rate은 0.8%로 지정했고, \n",
    "    def ms_opt(self):\n",
    "        n_assets = len(self.data.columns)\n",
    "        w0 = np.ones(n_assets) / n_assets\n",
    "        fun = lambda w: -(np.dot(w.T, self.mu) - 0.008) / np.sqrt(np.dot(w.T, np.dot(self.cov, w)))\n",
    "        bd = ((0,1),) * n_assets     \n",
    "        constraints = ({'type': 'eq', 'fun': lambda x:  np.sum(x) - 1})\n",
    "        maxsharp = minimize(fun, w0, method ='SLSQP', constraints=constraints, bounds=bd)\n",
    "        result = dict(zip(self.asset_name, np.round(maxsharp.x,3)))\n",
    "        return result\n",
    "    \n",
    "    def rp_opt(self):\n",
    "        def RC(cov, w):\n",
    "            pfo_std = np.sqrt(np.dot(w.T, np.dot(self.cov, w)))\n",
    "            mrc = 1/pfo_std * (np.dot(self.cov, w))\n",
    "            rc = mrc * w\n",
    "            rc = rc / rc.sum()\n",
    "            return rc\n",
    "        \n",
    "        \n",
    "        def RP_objective(x):\n",
    "            pfo_std = np.sqrt(np.dot(x.T, np.dot(self.cov, x)))\n",
    "            mrc = 1/pfo_std * (np.dot(self.cov, x))\n",
    "            rc = mrc * x\n",
    "            rc = rc / rc.sum()\n",
    "\n",
    "            a = np.reshape(rc, (len(rc),1))\n",
    "            differs = a - a.T\n",
    "            objective = np.sum(np.square(differs))\n",
    "\n",
    "            return objective    \n",
    "        \n",
    "        n_assets = len(self.data.columns)\n",
    "        w0 = np.ones(n_assets) / n_assets\n",
    "        constraints = [{'type':'eq', 'fun': lambda x: np.sum(x) -1}]\n",
    "        bd = ((0,1),) * n_assets\n",
    "\n",
    "        rp = minimize(RP_objective, w0,  constraints=constraints, bounds = bd, method='SLSQP')\n",
    "        result = dict(zip(self.asset_name, np.round(rp.x,3)))\n",
    "        return result     #, RC(self.cov, rp.x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'삼성전자': 0.727, 'LG전자': 0.0, '카카오': 0.273}"
      ]
     },
     "execution_count": 122,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#gmv 포트폴리오 -> 해당 종목을 각각 몇 퍼센트로 투자해야 위험이 제일 적은가\n",
    "c_Models(['삼성전자','LG전자','카카오'],[0,0,0],'2015-01-01','2021-04-01').gmv_opt()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'삼성전자': 0.674, 'LG전자': 0.0, '카카오': 0.326}"
      ]
     },
     "execution_count": 124,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#maxsharp ratio -> 위험대비 수익률이 제일 좋은 포트폴리오 비중 , 즉 가성비가 좋다\n",
    "c_Models(['삼성전자','LG전자','카카오'],[0,0,0],'2015-01-01','2021-04-01').ms_opt()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'삼성전자': 0.443, 'LG전자': 0.238, '카카오': 0.319}"
      ]
     },
     "execution_count": 125,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#risk parity -> 포트폴리오에 대한 자산 위험 비중을 동일하게 조정, 즉 삼전,lg,카카오의 포트폴리오 위험 기여도를 0.33으로 하게 만드는 비중\n",
    "c_Models(['삼성전자','LG전자','카카오'],[0,0,0],'2015-01-01','2021-04-01').rp_opt()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}