{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#import networkx as nx\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import scipy.stats as sts\n",
    "import seaborn as sns\n",
    "\n",
    "%matplotlib inline\n",
    "\n",
    "#import conviction files\n",
    "#from conviction_helpers import *\n",
    "#from conviction_system_logic3 import *\n",
    "from bonding_curve_eq import *"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "System initialization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "hatch_raise = 100000 # fiat units\n",
    "hatch_price = .1 #fiat per tokens\n",
    "theta = .5 #share of funds going to funding pool at launch\n",
    "\n",
    "R0 = hatch_raise*(1-theta)\n",
    "#F0 = hatch_raise*theta\n",
    "S0 = hatch_raise/hatch_price\n",
    "\n",
    "kappa = 2\n",
    "V0 = invariant(R0,S0,kappa)\n",
    "P0 = spot_price(R0, V0, kappa)\n",
    "\n",
    "dust = 10**-8"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "agent initialization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "#phi for exiting funds\n",
    "phi = 0\n",
    "\n",
    "#beta is param for armijo rule\n",
    "beta = .9\n",
    "\n",
    "#param for open loop\n",
    "rules = [\"martin\", \"step\",\"ramp\", \"sin\"] # step or \"ramp\" \"sin\" or \"martin\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "params= {\n",
    "    'kappa': [kappa],\n",
    "#    'lambda': [lam],\n",
    "#    'gains': [g],\n",
    "#    'rates':[1/gamma],\n",
    "#    'population':[n],\n",
    "#   'beta':[beta],\n",
    "#    'phi': [phi],\n",
    "    'invariant': [V0],\n",
    "    'dust' : [dust],\n",
    "    'rule' : rules,\n",
    "    'dP' : ['N/A', P0/4, P0/1000, P0/2],\n",
    "    'sigma': [.005,'N/A','N/A', 'N/A'],\n",
    "    'period': ['N/A', 2000,2000,2000]}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "initial_conditions = {'supply': S0,\n",
    "                      'price': P0,\n",
    "                      'reserve': R0,\n",
    "                      'spot_price': P0,\n",
    "                      'output_price': P0,\n",
    "                      }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'supply': 1000000.0,\n",
       " 'price': 0.09999999999999999,\n",
       " 'reserve': 50000.0,\n",
       " 'spot_price': 0.09999999999999999,\n",
       " 'output_price': 0.09999999999999999}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "initial_conditions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def set_action(params, step, sL, s):\n",
    "    \n",
    "    R = s['reserve']\n",
    "    S = s['supply']\n",
    "    V0 = params['invariant']\n",
    "    P=s['spot_price']\n",
    "    period = params['period']\n",
    "    \n",
    "    if params['rule'] == 'step':\n",
    "        bump = int((s['timestep'] % int(period/2) == 0))*int(s['timestep']>0)\n",
    "        sign = -(-1)**int((2*s['timestep']/period))\n",
    "        new_price = s['price'] + params['dP']*bump*sign\n",
    "    elif params['rule'] == 'ramp':\n",
    "        sign = (-1)**int((2*s['timestep']/period))\n",
    "        new_price = s['price'] + params['dP']*sign\n",
    "    elif params['rule'] == 'sin':\n",
    "        new_price = P0 + params['dP']*np.sin(2*np.pi*s['timestep']/period)\n",
    "    elif params['rule']=='martin' :\n",
    "        rv = np.random.normal(0, params['sigma'])\n",
    "        new_price = s['price']+s['price']*rv\n",
    "    else :\n",
    "        new_price = s['price']\n",
    "    \n",
    "    \n",
    "    #print(params['rule']+': '+str(new_price))\n",
    "    \n",
    "    if P>new_price: #equiv: pbar(0)>phat_a\n",
    "        mech = 'burn'\n",
    "                        \n",
    "        #approx for burn s.t. p=phat\n",
    "        #armijo style\n",
    "        amt = S*(1-params['dust'])\n",
    "\n",
    "        def pbar(amt):\n",
    "            output = withdraw(amt, R,S, V0, params['kappa'])\n",
    "\n",
    "            if not(output[1])>0:\n",
    "                return np.Infinity\n",
    "            elif amt==0:\n",
    "                return P\n",
    "            else:\n",
    "                return output[1]\n",
    "\n",
    "        if amt > params['dust']:\n",
    "            while pbar(amt)< new_price:\n",
    "                amt = amt*beta\n",
    "\n",
    "    else: # P<phat_a; #equiv pbar(0)<phat_a\n",
    "        mech = 'bond'\n",
    "        #approx for buy s.t. p=phat\n",
    "        #armijo style\n",
    "        amt = R*(1-params['dust'])\n",
    "\n",
    "        def pbar(amt):\n",
    "            output = mint(amt, R,S, V0, params['kappa'])\n",
    "            \n",
    "            if not(output[1])>0:\n",
    "                return 0\n",
    "            elif amt==0:\n",
    "                return P\n",
    "            else:\n",
    "                return output[1]\n",
    "\n",
    "        if amt > params['dust']:\n",
    "            while pbar(amt)> new_price:\n",
    "                amt = amt*beta\n",
    "    #print(mech)\n",
    "    #print(amt)\n",
    "    action = {'mech':mech, 'amt':amt,'pin':new_price ,'pbar':pbar(amt),'posterior':{}}\n",
    "    \n",
    "    if action['mech'] == 'bond':\n",
    "\n",
    "        dS, pbar = mint(amt, R,S, V0, params['kappa'])\n",
    "        R = R+amt\n",
    "        S = S+dS\n",
    "        P = spot_price(R, V0, kappa)\n",
    "\n",
    "    elif action['mech'] == 'burn':\n",
    "        dR, pbar = withdraw(amt, R,S, V0, params['kappa'])\n",
    "        R = R-dR\n",
    "        S = S-amt\n",
    "        P = spot_price(R, V0, kappa)\n",
    "\n",
    "    action['posterior'] = {'S':S, 'R':R,'P':P}\n",
    "    \n",
    "    return {'action': action}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def update_S(params, step, sL, s, _input):\n",
    "    \n",
    "    action = _input['action']\n",
    "    S = action['posterior']['S']\n",
    "    \n",
    "    key = 'supply'\n",
    "    value = S\n",
    "    \n",
    "    return (key, value)\n",
    "\n",
    "def update_R(params, step, sL, s, _input):\n",
    "    \n",
    "    action = _input['action']\n",
    "    R = action['posterior']['R']\n",
    "    \n",
    "    key = 'reserve'\n",
    "    value = R\n",
    "    \n",
    "    return (key, value)\n",
    "\n",
    "def update_P(params, step, sL, s, _input):\n",
    "    \n",
    "    action = _input['action']\n",
    "    P = action['posterior']['P']\n",
    "    \n",
    "    key = 'spot_price'\n",
    "    value = P\n",
    "    \n",
    "    return (key, value)\n",
    "\n",
    "def update_Pbar(params, step, sL, s, _input):\n",
    "    \n",
    "    action = _input['action']\n",
    "    pbar = action['pbar']\n",
    "    \n",
    "    key = 'output_price'\n",
    "    value = pbar\n",
    "    \n",
    "    return (key, value)\n",
    "\n",
    "def capture_Pin(params, step, sL, s, _input):\n",
    "    \n",
    "    Pin = _input['action']['pin']\n",
    "    if Pin== 0:\n",
    "        print(_input['action']) \n",
    "    key = 'price'\n",
    "    value = Pin\n",
    "    \n",
    "    return (key, value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n",
    "# The Partial State Update Blocks\n",
    "partial_state_update_blocks = [\n",
    "    {\n",
    "      'policies': {\n",
    "          'act': set_action,\n",
    "        },\n",
    "        'variables': {\n",
    "            'supply': update_S, \n",
    "            'reserve': update_R,\n",
    "            'spot_price': update_P,\n",
    "            'output_price': update_Pbar,\n",
    "            'price': capture_Pin,\n",
    "        }\n",
    "    }\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "time_periods_per_run = 4000\n",
    "monte_carlo_runs = 1\n",
    "\n",
    "from cadCAD.configuration.utils import config_sim\n",
    "simulation_parameters = config_sim({\n",
    "    'T': range(time_periods_per_run),\n",
    "    'N': monte_carlo_runs,\n",
    "    'M': params\n",
    "})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'martin', 'dP': 'N/A', 'sigma': 0.005, 'period': 'N/A'}}, {'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'step', 'dP': 0.024999999999999998, 'sigma': 'N/A', 'period': 2000}}, {'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'ramp', 'dP': 9.999999999999999e-05, 'sigma': 'N/A', 'period': 2000}}, {'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'sin', 'dP': 0.049999999999999996, 'sigma': 'N/A', 'period': 2000}}]\n",
      "[{'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'martin', 'dP': 'N/A', 'sigma': 0.005, 'period': 'N/A'}}, {'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'step', 'dP': 0.024999999999999998, 'sigma': 'N/A', 'period': 2000}}, {'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'ramp', 'dP': 9.999999999999999e-05, 'sigma': 'N/A', 'period': 2000}}, {'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'sin', 'dP': 0.049999999999999996, 'sigma': 'N/A', 'period': 2000}}]\n",
      "[{'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'martin', 'dP': 'N/A', 'sigma': 0.005, 'period': 'N/A'}}, {'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'step', 'dP': 0.024999999999999998, 'sigma': 'N/A', 'period': 2000}}, {'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'ramp', 'dP': 9.999999999999999e-05, 'sigma': 'N/A', 'period': 2000}}, {'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'sin', 'dP': 0.049999999999999996, 'sigma': 'N/A', 'period': 2000}}]\n",
      "[{'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'martin', 'dP': 'N/A', 'sigma': 0.005, 'period': 'N/A'}}, {'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'step', 'dP': 0.024999999999999998, 'sigma': 'N/A', 'period': 2000}}, {'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'ramp', 'dP': 9.999999999999999e-05, 'sigma': 'N/A', 'period': 2000}}, {'N': 1, 'T': range(0, 4000), 'M': {'kappa': 2, 'invariant': 20000000.0, 'dust': 1e-08, 'rule': 'sin', 'dP': 0.049999999999999996, 'sigma': 'N/A', 'period': 2000}}]\n"
     ]
    }
   ],
   "source": [
    "from cadCAD.configuration import append_configs\n",
    "# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\n",
    "# The configurations above are then packaged into a `Configuration` object\n",
    "append_configs(\n",
    "    initial_state=initial_conditions, #dict containing variable names and initial values\n",
    "    partial_state_update_blocks=partial_state_update_blocks, #dict containing state update functions\n",
    "    sim_configs=simulation_parameters #dict containing simulation parameters\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tabulate import tabulate\n",
    "from cadCAD.engine import ExecutionMode, ExecutionContext, Executor\n",
    "from cadCAD import configs\n",
    "import pandas as pd\n",
    "\n",
    "exec_mode = ExecutionMode()\n",
    "multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc)\n",
    "run = Executor(exec_context=multi_proc_ctx, configs=configs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "                            __________   ____ \n",
      "          ________ __ _____/ ____/   |  / __ \\\n",
      "         / ___/ __` / __  / /   / /| | / / / /\n",
      "        / /__/ /_/ / /_/ / /___/ ___ |/ /_/ / \n",
      "        \\___/\\__,_/\\__,_/\\____/_/  |_/_____/  \n",
      "        by BlockScience\n",
      "        \n",
      "Execution Mode: multi_proc: [<cadCAD.configuration.Configuration object at 0x7f737b45ad50>, <cadCAD.configuration.Configuration object at 0x7f737b45aed0>, <cadCAD.configuration.Configuration object at 0x7f737b463050>, <cadCAD.configuration.Configuration object at 0x7f737b463190>]\n",
      "Configurations: [<cadCAD.configuration.Configuration object at 0x7f737b45ad50>, <cadCAD.configuration.Configuration object at 0x7f737b45aed0>, <cadCAD.configuration.Configuration object at 0x7f737b463050>, <cadCAD.configuration.Configuration object at 0x7f737b463190>]\n"
     ]
    }
   ],
   "source": [
    "i = 0\n",
    "verbose = False\n",
    "results = {}\n",
    "for raw_result, tensor_field in run.execute():\n",
    "    result = pd.DataFrame(raw_result)\n",
    "    if verbose:\n",
    "        print()\n",
    "        print(f\"Tensor Field: {type(tensor_field)}\")\n",
    "        print(tabulate(tensor_field, headers='keys', tablefmt='psql'))\n",
    "        print(f\"Output: {type(result)}\")\n",
    "        print(tabulate(result, headers='keys', tablefmt='psql'))\n",
    "        print()\n",
    "    results[i] = {}\n",
    "    results[i]['result'] = result\n",
    "    results[i]['simulation_parameters'] = simulation_parameters[i]\n",
    "    i += 1\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.10015990554705045"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "experiment_index = 0\n",
    "results[experiment_index]['result'].price[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'kappa': 2,\n",
       " 'invariant': 20000000.0,\n",
       " 'dust': 1e-08,\n",
       " 'rule': 'martin',\n",
       " 'dP': 'N/A',\n",
       " 'sigma': 0.005,\n",
       " 'period': 'N/A'}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "results[0]['simulation_parameters']['M']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "def assign_run(df, T = time_periods_per_run):\n",
    "    temp_df = df.reset_index()\n",
    "    temp_df[\"run\"] = temp_df['index'].apply(lambda x: int(np.floor(x/(T+1))))\n",
    "    \n",
    "    return temp_df.drop(\"index\", axis =1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "def append_parameters(result, experiment_index):\n",
    "    sim_params = result['simulation_parameters']\n",
    "    params = sim_params['M']\n",
    "    frame = result['result']\n",
    "    frame[\"experiment_index\"] = experiment_index\n",
    "    for key in params.keys():\n",
    "        frame[key] = params[key]\n",
    "        \n",
    "    return frame"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "def package_results(results):\n",
    "    dataframes =  [ assign_run(append_parameters(results[experiment_index],experiment_index)) for experiment_index in range(i)]\n",
    "    return pd.concat(dataframes)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = package_results(results)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 24152 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 10928 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 24416 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 23980 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df[['timestep','experiment_index','run','price', 'spot_price']].groupby(['run','experiment_index']).plot(x='timestep', y=['price', 'spot_price'])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "df['err'] = df.price-df.spot_price\n",
    "df['abs_err']= df.err.apply(abs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f739caad2d0>"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 9788 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df[df.rule=='step'].err.plot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f739ca43690>"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 17896 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df[df.rule=='step'].iloc[1995:2050].plot(y=['price', 'spot_price'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f739c99de50>"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 24432 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df[df.rule=='step'].iloc[1995:2050].plot(y=['err','abs_err'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f739c5a56d0>"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 32676 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df.abs_err.plot(logy=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "run  experiment_index\n",
       "0    0                   AxesSubplot(0.125,0.125;0.775x0.755)\n",
       "     1                   AxesSubplot(0.125,0.125;0.775x0.755)\n",
       "     2                   AxesSubplot(0.125,0.125;0.775x0.755)\n",
       "     3                   AxesSubplot(0.125,0.125;0.775x0.755)\n",
       "dtype: object"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 26028 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 20700 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 16768 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 18336 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df[['timestep','experiment_index','run','abs_err']].groupby(['run','experiment_index']).plot(x='timestep', y='abs_err', logy=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<seaborn.axisgrid.JointGrid at 0x7f739c4c8650>"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 20320 characters]\n",
      "text/plain": [
       "<Figure size 432x432 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.jointplot(x='price', y='spot_price',kind='kde',data=df[df.rule==\"martin\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<seaborn.axisgrid.JointGrid at 0x7f739b816610>"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 20016 characters]\n",
      "text/plain": [
       "<Figure size 432x432 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.jointplot(x='price', y='spot_price',kind='kde',data=df[df.rule==\"ramp\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<seaborn.axisgrid.JointGrid at 0x7f739b6baa50>"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 25112 characters]\n",
      "text/plain": [
       "<Figure size 432x432 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.jointplot(x='price', y='spot_price',kind='kde',data=df[df.rule==\"sin\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 22644 characters]\n",
      "text/plain": [
       "<Figure size 432x432 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.jointplot(x='price', y='spot_price',kind='kde',data=df[(df.rule==\"step\")])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "gb=df[['timestep','experiment_index','run','abs_err']].groupby(['run','experiment_index'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>supply</th>\n",
       "      <th>price</th>\n",
       "      <th>reserve</th>\n",
       "      <th>spot_price</th>\n",
       "      <th>output_price</th>\n",
       "      <th>run</th>\n",
       "      <th>substep</th>\n",
       "      <th>timestep</th>\n",
       "      <th>experiment_index</th>\n",
       "      <th>kappa</th>\n",
       "      <th>invariant</th>\n",
       "      <th>dust</th>\n",
       "      <th>rule</th>\n",
       "      <th>dP</th>\n",
       "      <th>sigma</th>\n",
       "      <th>period</th>\n",
       "      <th>err</th>\n",
       "      <th>abs_err</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1.000000e+06</td>\n",
       "      <td>0.100000</td>\n",
       "      <td>50000.000000</td>\n",
       "      <td>0.100000</td>\n",
       "      <td>0.100000</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>20000000.0</td>\n",
       "      <td>1.000000e-08</td>\n",
       "      <td>martin</td>\n",
       "      <td>N/A</td>\n",
       "      <td>0.005</td>\n",
       "      <td>N/A</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.003176e+06</td>\n",
       "      <td>0.100160</td>\n",
       "      <td>50318.134269</td>\n",
       "      <td>0.100318</td>\n",
       "      <td>0.100159</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>20000000.0</td>\n",
       "      <td>1.000000e-08</td>\n",
       "      <td>martin</td>\n",
       "      <td>N/A</td>\n",
       "      <td>0.005</td>\n",
       "      <td>N/A</td>\n",
       "      <td>-0.000158</td>\n",
       "      <td>0.000158</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>9.980062e+05</td>\n",
       "      <td>0.100046</td>\n",
       "      <td>49800.814088</td>\n",
       "      <td>0.099801</td>\n",
       "      <td>0.100059</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>20000000.0</td>\n",
       "      <td>1.000000e-08</td>\n",
       "      <td>martin</td>\n",
       "      <td>N/A</td>\n",
       "      <td>0.005</td>\n",
       "      <td>N/A</td>\n",
       "      <td>0.000246</td>\n",
       "      <td>0.000246</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1.008073e+06</td>\n",
       "      <td>0.100305</td>\n",
       "      <td>50810.553452</td>\n",
       "      <td>0.100807</td>\n",
       "      <td>0.100304</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>20000000.0</td>\n",
       "      <td>1.000000e-08</td>\n",
       "      <td>martin</td>\n",
       "      <td>N/A</td>\n",
       "      <td>0.005</td>\n",
       "      <td>N/A</td>\n",
       "      <td>-0.000503</td>\n",
       "      <td>0.000503</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1.005005e+06</td>\n",
       "      <td>0.100645</td>\n",
       "      <td>50501.765321</td>\n",
       "      <td>0.100501</td>\n",
       "      <td>0.100654</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>20000000.0</td>\n",
       "      <td>1.000000e-08</td>\n",
       "      <td>martin</td>\n",
       "      <td>N/A</td>\n",
       "      <td>0.005</td>\n",
       "      <td>N/A</td>\n",
       "      <td>0.000145</td>\n",
       "      <td>0.000145</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         supply     price       reserve  spot_price  output_price  run  \\\n",
       "0  1.000000e+06  0.100000  50000.000000    0.100000      0.100000    0   \n",
       "1  1.003176e+06  0.100160  50318.134269    0.100318      0.100159    0   \n",
       "2  9.980062e+05  0.100046  49800.814088    0.099801      0.100059    0   \n",
       "3  1.008073e+06  0.100305  50810.553452    0.100807      0.100304    0   \n",
       "4  1.005005e+06  0.100645  50501.765321    0.100501      0.100654    0   \n",
       "\n",
       "   substep  timestep  experiment_index  kappa   invariant          dust  \\\n",
       "0        0         0                 0      2  20000000.0  1.000000e-08   \n",
       "1        1         1                 0      2  20000000.0  1.000000e-08   \n",
       "2        1         2                 0      2  20000000.0  1.000000e-08   \n",
       "3        1         3                 0      2  20000000.0  1.000000e-08   \n",
       "4        1         4                 0      2  20000000.0  1.000000e-08   \n",
       "\n",
       "     rule   dP  sigma period       err   abs_err  \n",
       "0  martin  N/A  0.005    N/A  0.000000  0.000000  \n",
       "1  martin  N/A  0.005    N/A -0.000158  0.000158  \n",
       "2  martin  N/A  0.005    N/A  0.000246  0.000246  \n",
       "3  martin  N/A  0.005    N/A -0.000503  0.000503  \n",
       "4  martin  N/A  0.005    N/A  0.000145  0.000145  "
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "df['price_pc']=df.price.pct_change()\n",
    "df['spot_price_pc']=df.spot_price.pct_change()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 20540 characters]\n",
      "text/plain": [
       "<Figure size 429x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.lmplot(x='spot_price_pc', y='price_pc', hue='rule',truncate=True,data=df)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "def response_plot(rdf, title):\n",
    "    plt.subplots(figsize=(10,6))\n",
    "    ax1=subplot(2,1,1)\n",
    "    rdf[[\"spot_price\",\"price\"]].plot(ax=ax1)\n",
    "    plt.legend([\"spot price (output: $P_t$)\", \"price sample (input: $\\hat P_t$)\" ])\n",
    "    #plt.xlabel(\"transaction count (time)\")\n",
    "    plt.ylabel(\"Price, $\\hat P_t$, $P_t$\")\n",
    "    plt.title(title+\" Response Dynamics\")\n",
    "    ax2=subplot(2,1,2)\n",
    "    rdf[[\"abs_err\"]].plot(ax=ax2,logy=True, color='green')\n",
    "    plt.legend([\"$Error: |P_t-\\hat P_t|$\" ])\n",
    "    plt.xlabel(\"transaction count (time)\")\n",
    "    plt.ylabel(\"Absolute Value of Estimation Error\")\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'subplot' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-36-783e7ec4e4dd>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mresponse_plot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mdf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrule\u001b[0m\u001b[0;34m==\u001b[0m\u001b[0;34m'step'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"Step\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m<ipython-input-35-0ec474876cdb>\u001b[0m in \u001b[0;36mresponse_plot\u001b[0;34m(rdf, title)\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mresponse_plot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrdf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtitle\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      2\u001b[0m     \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubplots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfigsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m6\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m     \u001b[0max1\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msubplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      4\u001b[0m     \u001b[0mrdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"spot_price\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\"price\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0max\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0max1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m     \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlegend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"spot price (output: $P_t$)\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"price sample (input: $\\hat P_t$)\"\u001b[0m \u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'subplot' is not defined"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 5832 characters]\n",
      "text/plain": [
       "<Figure size 720x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "response_plot(df[df.rule=='step'], \"Step\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "response_plot(df[df.rule=='ramp'], \"Ramp\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "response_plot(df[df.rule=='sin'], \"Periodic\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "response_plot(df[df.rule=='martin'], \"Martingale\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
