ml-finance-python

python scripts for finance machine learning

git clone https://9o.is/git/ml-finance-python.git

lab_123.ipynb

(12205B)


      1 {
      2  "cells": [
      3   {
      4    "cell_type": "markdown",
      5    "metadata": {},
      6    "source": [
      7     "# Interactive Plotting and Monte Carlo Simulations of CPPI"
      8    ]
      9   },
     10   {
     11    "cell_type": "code",
     12    "execution_count": 1,
     13    "metadata": {},
     14    "outputs": [],
     15    "source": [
     16     "import ipywidgets as widgets\n",
     17     "from IPython.display import display\n",
     18     "import pandas as pd\n",
     19     "import edhec_risk_kit_123 as erk\n",
     20     "\n",
     21     "%load_ext autoreload\n",
     22     "%autoreload 2"
     23    ]
     24   },
     25   {
     26    "cell_type": "markdown",
     27    "metadata": {},
     28    "source": [
     29     "## GBM Simulations"
     30    ]
     31   },
     32   {
     33    "cell_type": "code",
     34    "execution_count": 2,
     35    "metadata": {},
     36    "outputs": [],
     37    "source": [
     38     "def show_gbm(n_scenarios, mu, sigma):\n",
     39     "    \"\"\"\n",
     40     "    Draw the results of a stock price evolution under a Geometric Brownian Motion model\n",
     41     "    \"\"\"\n",
     42     "    s_0=100\n",
     43     "    prices = erk.gbm(n_scenarios=n_scenarios, mu=mu, sigma=sigma, s_0=s_0)\n",
     44     "    ax = prices.plot(legend=False, color=\"indianred\", alpha = 0.5, linewidth=2, figsize=(12,5))\n",
     45     "    ax.axhline(y=100, ls=\":\", color=\"black\")\n",
     46     "    # draw a dot at the origin\n",
     47     "    ax.plot(0,s_0, marker='o',color='darkred', alpha=0.2)\n"
     48    ]
     49   },
     50   {
     51    "cell_type": "code",
     52    "execution_count": 3,
     53    "metadata": {},
     54    "outputs": [],
     55    "source": [
     56     "gbm_controls = widgets.interactive(show_gbm, \n",
     57     "                                   n_scenarios=widgets.IntSlider(min=1, max=1000, step=1, value=1), \n",
     58     "                                   mu=(0., +.2,.01),\n",
     59     "                                   sigma=(0, .3, .01)\n",
     60     ")"
     61    ]
     62   },
     63   {
     64    "cell_type": "code",
     65    "execution_count": 4,
     66    "metadata": {},
     67    "outputs": [
     68     {
     69      "data": {
     70       "application/vnd.jupyter.widget-view+json": {
     71        "model_id": "b2cf050bcda641caa2b3ce79cc1b7bf1",
     72        "version_major": 2,
     73        "version_minor": 0
     74       },
     75       "text/plain": [
     76        "interactive(children=(IntSlider(value=1, description='n_scenarios', max=1000, min=1), FloatSlider(value=0.1, d…"
     77       ]
     78      },
     79      "metadata": {},
     80      "output_type": "display_data"
     81     }
     82    ],
     83    "source": [
     84     "display(gbm_controls)"
     85    ]
     86   },
     87   {
     88    "cell_type": "markdown",
     89    "metadata": {},
     90    "source": [
     91     "# Interactive CPPI Monte Carlo Testing"
     92    ]
     93   },
     94   {
     95    "cell_type": "code",
     96    "execution_count": 5,
     97    "metadata": {},
     98    "outputs": [
     99     {
    100      "data": {
    101       "application/vnd.jupyter.widget-view+json": {
    102        "model_id": "f247e88c15cf4ac2bfc0bf670ac394ce",
    103        "version_major": 2,
    104        "version_minor": 0
    105       },
    106       "text/plain": [
    107        "interactive(children=(IntSlider(value=50, description='n_scenarios', max=1000, min=1, step=5), FloatSlider(val…"
    108       ]
    109      },
    110      "metadata": {},
    111      "output_type": "display_data"
    112     }
    113    ],
    114    "source": [
    115     "def show_cppi(n_scenarios=50, mu=0.07, sigma=0.15, m=3, floor=0., riskfree_rate=0.03, y_max=100):\n",
    116     "    \"\"\"\n",
    117     "    Plot the results of a Monte Carlo Simulation of CPPI\n",
    118     "    \"\"\"\n",
    119     "    start = 100\n",
    120     "    sim_rets = erk.gbm(n_scenarios=n_scenarios, mu=mu, sigma=sigma, prices=False, steps_per_year=12)\n",
    121     "    risky_r = pd.DataFrame(sim_rets)\n",
    122     "    # run the \"back\"-test\n",
    123     "    btr = erk.run_cppi(risky_r=pd.DataFrame(risky_r),riskfree_rate=riskfree_rate,m=m, start=start, floor=floor)\n",
    124     "    wealth = btr[\"Wealth\"]\n",
    125     "    y_max=wealth.values.max()*y_max/100\n",
    126     "    ax = wealth.plot(legend=False, alpha=0.3, color=\"indianred\", figsize=(12, 6))\n",
    127     "    ax.axhline(y=start, ls=\":\", color=\"black\")\n",
    128     "    ax.axhline(y=start*floor, ls=\"--\", color=\"red\")\n",
    129     "    ax.set_ylim(top=y_max)\n",
    130     "\n",
    131     "cppi_controls = widgets.interactive(show_cppi, \n",
    132     "                                   n_scenarios=widgets.IntSlider(min=1, max=1000, step=5, value=50), \n",
    133     "                                   mu=(0., +.2, .01),\n",
    134     "                                   sigma=(0, .30, .05),\n",
    135     "                                   floor=(0, 2, .1),\n",
    136     "                                   m=(1, 5, .5),\n",
    137     "                                   riskfree_rate=(0, .05, .01),\n",
    138     "                                   y_max=widgets.IntSlider(min=0, max=100, step=1, value=100,\n",
    139     "                                                          description=\"Zoom Y Axis\")\n",
    140     ")\n",
    141     "display(cppi_controls)"
    142    ]
    143   },
    144   {
    145    "cell_type": "markdown",
    146    "metadata": {},
    147    "source": [
    148     "# Adding a Histogram and Reporting Floor Violations"
    149    ]
    150   },
    151   {
    152    "cell_type": "code",
    153    "execution_count": 6,
    154    "metadata": {},
    155    "outputs": [
    156     {
    157      "data": {
    158       "application/vnd.jupyter.widget-view+json": {
    159        "model_id": "db0278b4b2064464a17c08bf8ccdd2fa",
    160        "version_major": 2,
    161        "version_minor": 0
    162       },
    163       "text/plain": [
    164        "interactive(children=(IntSlider(value=50, description='n_scenarios', max=1000, min=1, step=5), FloatSlider(val…"
    165       ]
    166      },
    167      "metadata": {},
    168      "output_type": "display_data"
    169     }
    170    ],
    171    "source": [
    172     "import matplotlib.pyplot as plt\n",
    173     "\n",
    174     "def show_cppi(n_scenarios=50, mu=0.07, sigma=0.15, m=3, floor=0., riskfree_rate=0.03, y_max=100):\n",
    175     "    \"\"\"\n",
    176     "    Plot the results of a Monte Carlo Simulation of CPPI\n",
    177     "    \"\"\"\n",
    178     "    start = 100\n",
    179     "    sim_rets = erk.gbm(n_scenarios=n_scenarios, mu=mu, sigma=sigma, prices=False, steps_per_year=12)\n",
    180     "    risky_r = pd.DataFrame(sim_rets)\n",
    181     "    # run the \"back\"-test\n",
    182     "    btr = erk.run_cppi(risky_r=pd.DataFrame(risky_r),riskfree_rate=riskfree_rate,m=m, start=start, floor=floor)\n",
    183     "    wealth = btr[\"Wealth\"]\n",
    184     "    # calculate terminal wealth stats\n",
    185     "    y_max=wealth.values.max()*y_max/100\n",
    186     "    terminal_wealth = wealth.iloc[-1]\n",
    187     "    # Plot!\n",
    188     "    fig, (wealth_ax, hist_ax) = plt.subplots(nrows=1, ncols=2, sharey=True, gridspec_kw={'width_ratios':[3,2]}, figsize=(24, 9))\n",
    189     "    plt.subplots_adjust(wspace=0.0)\n",
    190     "    \n",
    191     "    wealth.plot(ax=wealth_ax, legend=False, alpha=0.3, color=\"indianred\")\n",
    192     "    wealth_ax.axhline(y=start, ls=\":\", color=\"black\")\n",
    193     "    wealth_ax.axhline(y=start*floor, ls=\"--\", color=\"red\")\n",
    194     "    wealth_ax.set_ylim(top=y_max)\n",
    195     "    \n",
    196     "    terminal_wealth.plot.hist(ax=hist_ax, bins=50, ec='w', fc='indianred', orientation='horizontal')\n",
    197     "    hist_ax.axhline(y=start, ls=\":\", color=\"black\")\n",
    198     "\n",
    199     "cppi_controls = widgets.interactive(show_cppi, \n",
    200     "                                   n_scenarios=widgets.IntSlider(min=1, max=1000, step=5, value=50), \n",
    201     "                                   mu=(0., +.2, .01),\n",
    202     "                                   sigma=(0, .3, .05),\n",
    203     "                                   floor=(0, 2, .1),\n",
    204     "                                   m=(1, 5, .5),\n",
    205     "                                   riskfree_rate=(0, .05, .01),\n",
    206     "                                   y_max=widgets.IntSlider(min=0, max=100, step=1, value=100,\n",
    207     "                                                          description=\"Zoom Y Axis\")\n",
    208     ")\n",
    209     "display(cppi_controls)"
    210    ]
    211   },
    212   {
    213    "cell_type": "markdown",
    214    "metadata": {},
    215    "source": [
    216     "# Adding Terminal Wealth Statistics"
    217    ]
    218   },
    219   {
    220    "cell_type": "code",
    221    "execution_count": 7,
    222    "metadata": {},
    223    "outputs": [
    224     {
    225      "data": {
    226       "application/vnd.jupyter.widget-view+json": {
    227        "model_id": "86ad8169669145e88ac879e0c5736ffb",
    228        "version_major": 2,
    229        "version_minor": 0
    230       },
    231       "text/plain": [
    232        "interactive(children=(IntSlider(value=50, description='n_scenarios', max=1000, min=1, step=5), FloatSlider(val…"
    233       ]
    234      },
    235      "metadata": {},
    236      "output_type": "display_data"
    237     }
    238    ],
    239    "source": [
    240     "import matplotlib.pyplot as plt\n",
    241     "import numpy as np\n",
    242     "\n",
    243     "def show_cppi(n_scenarios=50, mu=0.07, sigma=0.15, m=3, floor=0., riskfree_rate=0.03, steps_per_year=12, y_max=100):\n",
    244     "    \"\"\"\n",
    245     "    Plot the results of a Monte Carlo Simulation of CPPI\n",
    246     "    \"\"\"\n",
    247     "    start = 100\n",
    248     "    sim_rets = erk.gbm(n_scenarios=n_scenarios, mu=mu, sigma=sigma, prices=False, steps_per_year=steps_per_year)\n",
    249     "    risky_r = pd.DataFrame(sim_rets)\n",
    250     "    # run the \"back\"-test\n",
    251     "    btr = erk.run_cppi(risky_r=pd.DataFrame(risky_r),riskfree_rate=riskfree_rate,m=m, start=start, floor=floor)\n",
    252     "    wealth = btr[\"Wealth\"]\n",
    253     "\n",
    254     "    # calculate terminal wealth stats\n",
    255     "    y_max=wealth.values.max()*y_max/100\n",
    256     "    terminal_wealth = wealth.iloc[-1]\n",
    257     "    \n",
    258     "    tw_mean = terminal_wealth.mean()\n",
    259     "    tw_median = terminal_wealth.median()\n",
    260     "    failure_mask = np.less(terminal_wealth, start*floor)\n",
    261     "    n_failures = failure_mask.sum()\n",
    262     "    p_fail = n_failures/n_scenarios\n",
    263     "\n",
    264     "    e_shortfall = np.dot(terminal_wealth-start*floor, failure_mask)/n_failures if n_failures > 0 else 0.0\n",
    265     "\n",
    266     "    # Plot!\n",
    267     "    fig, (wealth_ax, hist_ax) = plt.subplots(nrows=1, ncols=2, sharey=True, gridspec_kw={'width_ratios':[3,2]}, figsize=(24, 9))\n",
    268     "    plt.subplots_adjust(wspace=0.0)\n",
    269     "    \n",
    270     "    wealth.plot(ax=wealth_ax, legend=False, alpha=0.3, color=\"indianred\")\n",
    271     "    wealth_ax.axhline(y=start, ls=\":\", color=\"black\")\n",
    272     "    wealth_ax.axhline(y=start*floor, ls=\"--\", color=\"red\")\n",
    273     "    wealth_ax.set_ylim(top=y_max)\n",
    274     "    \n",
    275     "    terminal_wealth.plot.hist(ax=hist_ax, bins=50, ec='w', fc='indianred', orientation='horizontal')\n",
    276     "    hist_ax.axhline(y=start, ls=\":\", color=\"black\")\n",
    277     "    hist_ax.axhline(y=tw_mean, ls=\":\", color=\"blue\")\n",
    278     "    hist_ax.axhline(y=tw_median, ls=\":\", color=\"purple\")\n",
    279     "    hist_ax.annotate(f\"Mean: ${int(tw_mean)}\", xy=(.7, .9),xycoords='axes fraction', fontsize=24)\n",
    280     "    hist_ax.annotate(f\"Median: ${int(tw_median)}\", xy=(.7, .85),xycoords='axes fraction', fontsize=24)\n",
    281     "    if (floor > 0.01):\n",
    282     "        hist_ax.axhline(y=start*floor, ls=\"--\", color=\"red\", linewidth=3)\n",
    283     "        hist_ax.annotate(f\"Violations: {n_failures} ({p_fail*100:2.2f}%)\\nE(shortfall)=${e_shortfall:2.2f}\", xy=(.7, .7), xycoords='axes fraction', fontsize=24)\n",
    284     "\n",
    285     "cppi_controls = widgets.interactive(show_cppi,\n",
    286     "                                   n_scenarios=widgets.IntSlider(min=1, max=1000, step=5, value=50), \n",
    287     "                                   mu=(0., +.2, .01),\n",
    288     "                                   sigma=(0, .3, .05),\n",
    289     "                                   floor=(0, 2, .1),\n",
    290     "                                   m=(1, 5, .5),\n",
    291     "                                   riskfree_rate=(0, .05, .01),\n",
    292     "                                   steps_per_year=widgets.IntSlider(min=1, max=12, step=1, value=12,\n",
    293     "                                                          description=\"Rebals/Year\"),\n",
    294     "                                   y_max=widgets.IntSlider(min=0, max=100, step=1, value=100,\n",
    295     "                                                          description=\"Zoom Y Axis\")\n",
    296     ")\n",
    297     "display(cppi_controls)"
    298    ]
    299   },
    300   {
    301    "cell_type": "code",
    302    "execution_count": null,
    303    "metadata": {},
    304    "outputs": [],
    305    "source": []
    306   },
    307   {
    308    "cell_type": "code",
    309    "execution_count": null,
    310    "metadata": {},
    311    "outputs": [],
    312    "source": []
    313   }
    314  ],
    315  "metadata": {
    316   "kernelspec": {
    317    "display_name": "Python 3",
    318    "language": "python",
    319    "name": "python3"
    320   },
    321   "language_info": {
    322    "codemirror_mode": {
    323     "name": "ipython",
    324     "version": 3
    325    },
    326    "file_extension": ".py",
    327    "mimetype": "text/x-python",
    328    "name": "python",
    329    "nbconvert_exporter": "python",
    330    "pygments_lexer": "ipython3",
    331    "version": "3.8.8"
    332   }
    333  },
    334  "nbformat": 4,
    335  "nbformat_minor": 4
    336 }