{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Model Specifications \n",
    "\n",
    "<!-- ![](images/differentialspec.png) -->\n",
    "\n",
    "![](images/SystemStockandFlow.png)\n",
    "\n",
    "![](images/graph.png)\n",
    "\n",
    "## System Definition\n",
    "Reserve $R_t \\in \\mathbb{R}_{++}$ at time $t$ is the total quantity of reserve currency tokens bonded to the bonding curve contract.\n",
    "\n",
    "Supply $S_t \\in \\mathbb{R}_{++}$ at time $t$ is the total quantity of community tokens issued by the bonding curve contract.\n",
    "\n",
    "Spot Price $P_t \\in \\mathbb{R}_{++}$ at time $t$ is the estimate of the value of the community token, in units of $R$ per units of $S$.\n",
    "\n",
    "\n",
    "The system level state is $\\bar x_t := (R_t,S_t,P_t) \\in \\bar{X} \\subset \\mathbb{R}^3_{++}$.\n",
    "\n",
    "The agent level state is $\\hat{x}_{a,t} := (r_{a,t}, s_{a,t}, p_{a,t}) \\in \\hat{X}_a \\subseteq \\mathbb{R}^3_{++}$.\n",
    "\n",
    "The system state is $x_t = (\\hat x_{1,t},\\ldots \\hat x_{n,t}, \\bar x_t) \\in X \\subset \\mathbb{R}^{3(n+1)}_{++}$ and lies in the Cartesian product of the system-level state and the agent-level state.\n",
    "\n",
    "\n",
    "Conservation Function is:\n",
    "\n",
    "\\begin{equation} \\label{vnought}\n",
    "V(R_t,S_t)  := \\frac{S_t^\\kappa}{R_t} \\equiv V_0,\n",
    "\\end{equation}\n",
    "where $V_0 = V(R_0,S_0) := \\frac{S_0^\\kappa}{R_0}$ is a constant defined by initial supply $S_0$ and initial reserve $R_0$. Parameter $\\kappa$ is the curvature of the bonding curve.\n",
    "]\n",
    "\n",
    "\n",
    "Given the conservation function, allows us to assert that the spot price $P_t$ is completely determined by reserve currency and community token supply holdings and the functional form of $V$:\n",
    "\\begin{equation}\\label{spot_price}\n",
    "P_t = P(R_t,S_t) = \\left . \\vphantom{|} -\\frac{\\partial V /\\partial S}{\\partial V /\\partial R} \\right |_{(R_t, S_t)}.\n",
    "\\end{equation}\n",
    "\n",
    "\n",
    "\n",
    "## Burn to Mint\n",
    "The Bond to Mint mechanism takes a system-level state $\\bar x_t = (R_t, S_t, P_t)$ and an agent $a$'s action, given by a bonded quantity $\\Delta R_t := r_{a,t}-r_{a,t+1} \\ge 0$ such that $r_{a,t+1}\\in \\mathbb{R}_{++}$. Quantity $\\Delta R_t$ is reserve currency transferred to the bonding curve, and returns the state $ x_{t+1}$ such that\n",
    "\\begin{equation*}\n",
    "    (R_{t+1},S_{t+1},P_{t+1}) = \\left(R_t + \\Delta R_t,\\sqrt[\\kappa]{V_0(R_t+\\Delta R_t)}, \\frac{\\kappa (R_t+\\Delta R_t)}{\\sqrt[\\kappa]{V_0(R_t+\\Delta R_t)}}  \\right) \n",
    "\\end{equation*}\n",
    "and the associated updates to the agent-level state $\\hat x_{a,t}$ are given by,\n",
    "\\begin{align*}\n",
    "    (r_{a,t+1},s_{a,t+1}, p_{a,t+1}) = \\left(r_t - \\Delta R_t,s_{a,t}+\\sqrt[\\kappa]{V_0(R_t+\\Delta R_t)}, g_a(x_{t+1}, \\varepsilon_t)\\right)\n",
    "\\end{align*}\n",
    "and $(r_{a',t+1}, s_{a',t+1}, p_{a',t+1})= (r_{a',t}, s_{a',t}, g_{a'}(x_{t+1}, \\varepsilon_t)$ for all agents $a'\\not=a$ where $g_a$ is a private mapping for agent $a$ and $\\varepsilon_t$ is an exogenous signal.\n",
    "\n",
    "* Realized Price is: $\\bar{P}(\\Delta R) =\\frac{\\Delta R}{\\Delta S} = \\frac{\\Delta R}{\\sqrt[\\kappa]{V_0(R+\\Delta R)}-\\sqrt[\\kappa]{V_0(R)}} \\rightarrow \\big(\\frac{\\partial S(R)}{\\partial R} \\big)^{-1}$ as $\\Delta R \\rightarrow 0$\n",
    "\n",
    "### Derivation to CIC\n",
    "\n",
    "$$\\textrm{CIC Issued} = S[(1+\\frac{\\text{Added Reserve}}{R})^F-1]$$\n",
    "\n",
    "Where:\n",
    "$$ F = \\frac{1}k$$ \n",
    "\n",
    "Use:\n",
    "$$V_0 = \\frac{S^k}R$$\n",
    " \n",
    "$$\\Delta S = (V_0(R + \\Delta R))^\\frac{1}k - S $$\n",
    "\n",
    "\n",
    "$$ \\Delta S = (\\frac{S^k}R(R + \\Delta R))^\\frac{1}k - S $$\n",
    "$$ \\Delta S = S(1+\\frac{\\Delta R}R)^\\frac{1}k - S$$\n",
    "$$ \\Delta S = S((1 + \\frac{\\Delta R}R)^\\frac{1}k-1$$\n",
    "\n",
    "\n",
    "## Burn to Withdraw\n",
    "The Burn to Withdraw mechanism takes a system-level state $\\bar x_t = (R_t, S_t, P_t)$ and an agent $a$'s action, given by a burned quantity $\\Delta S_t := s_{a,t+1}-s_{a,t}\\le 0$ such that $ s_{a,t+1}\\in \\mathbb{R}_{++}$. Quantity $\\Delta S_t$ is token supply removed from the system, and results in the state $x_{t+1}$ such that\n",
    "\n",
    "\\begin{equation*}\n",
    "    (R_{t+1},S_{t+1},P_{t+1}) = \\left(\\frac{(S_t+\\Delta S_t)^\\kappa}{V_0},S_t+\\Delta S_t, \\frac{\\kappa (S_t+\\Delta S_t)^{\\kappa}}{V_0(S_t+\\Delta S_t)}  \\right) \n",
    "\\end{equation*}\n",
    "and the associated updates to the agent-level state $\\hat x_{a,t}$ are given by,\n",
    "\\begin{align*}\n",
    "    (r_{a,t+1},s_{a,t+1}, p_{a,t+1}) = \\left(r_{a,t}+R_t-\\frac{(S_t+\\Delta S_t)^\\kappa}{V_0},s_{a,t}+\\Delta S_t , g_a(x_{t+1}, \\varepsilon_t)\\right)\n",
    "\\end{align*}\n",
    "and $(r_{a',t+1}, s_{a',t+1}, p_{a',t+1})= (r_{a',t}, s_{a',t}, g_{a'}(x_{t+1}, \\varepsilon_t)$ for all agents $a'\\not=a$ where $g_a$ is a private mapping for agent $a$ and $\\varepsilon_t$ is an exogenous signal.\n",
    "\n",
    "Given these mechanisms, an agent's action set $U({x}_{t},a)$ can be fully determined from both agent-level restrictions and system-level conservation laws:\n",
    "\n",
    "* Realized Price is: $\\bar{P}(\\Delta S) =\\frac{\\Delta R}{\\Delta S} = \\frac{\\frac{S^{\\kappa}}{V_0}-\\frac{(S-\\Delta S)^\\kappa}{V_0}}{\\Delta S} \\rightarrow \\frac{\\partial R(S)}{\\partial S} $ as $\\Delta S \\rightarrow 0$\n",
    "    \n",
    "### Derivation to CIC\n",
    "\n",
    "$$\\textrm{Reserve Redeemed} = R[(1+\\frac{\\text{CIC Redeemed}}{R})^\\frac{1}{F}-1]$$\n",
    "\n",
    "\n",
    "Where:\n",
    "$$ F = \\frac{1}k$$ \n",
    "\n",
    "$$\\Delta R = R - \\frac{(S-\\Delta S)^k}{V_0}$$\n",
    "\n",
    "Use:\n",
    " $$V_0 = \\frac{S^k}R$$\n",
    "\n",
    "$$\\Delta R = R - \\frac{(S-\\Delta S^k)}{S^k})*R$$\n",
    "$$ \\Delta R = R - (\\frac{S- \\Delta S}{S})^k *R $$\n",
    "$$ \\Delta R = R(1-(1-\\frac{\\Delta S}{S})^k)$$\n",
    "\n",
    "## Reference papers by Dr. Zargham and others\n",
    "* https://epub.wu.ac.at/7433/1/zargham_paruch_shorish.pdf\n",
    "* https://epub.wu.ac.at/7385/\n",
    "\n",
    "\n",
    "\n",
    "### Simulation setup\n",
    "\n",
    "#### System Initialization\n",
    "\n",
    "\n",
    "#### Agent Initialization"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Simulation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'N': 1, 'T': range(0, 360), 'M': [{}]}]\n"
     ]
    }
   ],
   "source": [
    "import math\n",
    "import pandas as pd\n",
    "from tabulate import tabulate\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import numpy as np\n",
    "\n",
    "%matplotlib inline\n",
    "from tabulate import tabulate\n",
    "from typing import Dict, List\n",
    "\n",
    "from ipywidgets import interact, interactive, fixed, interact_manual\n",
    "import ipywidgets as widgets\n",
    "from IPython.display import clear_output\n",
    "\n",
    "# The following imports NEED to be in the exact order\n",
    "from cadCAD.engine import ExecutionMode, ExecutionContext, Executor\n",
    "from sim import economyconfig\n",
    "from cadCAD import configs\n",
    "\n",
    "exec_mode = ExecutionMode()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "                            __________   ____ \n",
      "          ________ __ _____/ ____/   |  / __ \\\n",
      "         / ___/ __` / __  / /   / /| | / / / /\n",
      "        / /__/ /_/ / /_/ / /___/ ___ |/ /_/ / \n",
      "        \\___/\\__,_/\\__,_/\\____/_/  |_/_____/  \n",
      "        by BlockScience\n",
      "        \n",
      "Execution Mode: single_proc: [<cadCAD.configuration.Configuration object at 0x7f7f637eb690>]\n",
      "Configurations: [<cadCAD.configuration.Configuration object at 0x7f7f637eb690>]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/aclarkdata/repos/CommunityInclusionCurrencies/v0/sim/parts/functions.py:64: RuntimeWarning: invalid value encountered in double_scalars\n",
      "  realized_price = quantity_recieved/deltaS\n",
      "/home/aclarkdata/repos/CommunityInclusionCurrencies/v0/sim/parts/functions.py:64: RuntimeWarning: divide by zero encountered in double_scalars\n",
      "  realized_price = quantity_recieved/deltaS\n"
     ]
    }
   ],
   "source": [
    "single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)\n",
    "run1 = Executor(exec_context=single_proc_ctx, configs=[configs[0]])\n",
    "run1_raw_result, raw_tensor_field = run1.execute()\n",
    "df = pd.DataFrame(run1_raw_result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "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>native</th>\n",
       "      <th>cic</th>\n",
       "      <th>supply</th>\n",
       "      <th>reserve</th>\n",
       "      <th>spot_price</th>\n",
       "      <th>user_spend</th>\n",
       "      <th>impact</th>\n",
       "      <th>prices</th>\n",
       "      <th>actions</th>\n",
       "      <th>run</th>\n",
       "      <th>substep</th>\n",
       "      <th>timestep</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>[530.9524347906868, 767.4188125782725, 733.768...</td>\n",
       "      <td>[9587.357534446111, 4868.714330437587, 17019.7...</td>\n",
       "      <td>100000.000000</td>\n",
       "      <td>100000.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>[2.595940395058093, 1.4010176731572506, 1.6767...</td>\n",
       "      <td>{}</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>[530.9524347906868, 767.4188125782725, 733.768...</td>\n",
       "      <td>[9587.357534446111, 4868.714330437587, 17019.7...</td>\n",
       "      <td>100000.000000</td>\n",
       "      <td>100000.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>29113.071395</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>[0.7557579805938984, 0.4078792754476903, 0.488...</td>\n",
       "      <td>{}</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>[530.9524347906868, 767.4188125782725, 733.768...</td>\n",
       "      <td>[9587.357534446111, 4868.714330437587, 17019.7...</td>\n",
       "      <td>100000.000000</td>\n",
       "      <td>100000.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>29113.071395</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>[0.7557579805938984, 0.4078792754476903, 0.488...</td>\n",
       "      <td>[{'agent': 6, 'mech': 'burn', 'amt': 8493.3896...</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>[530.9524347906868, 6172.526885259749, 14578.0...</td>\n",
       "      <td>[9587.357534446115, 0.0, 0.0, 0.0, 0.0, 4463.0...</td>\n",
       "      <td>34301.833135</td>\n",
       "      <td>11766.157564</td>\n",
       "      <td>0.686037</td>\n",
       "      <td>29113.071395</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>[0.7557579805938984, 0.4078792754476903, 0.488...</td>\n",
       "      <td>[{'agent': 6, 'mech': 'burn', 'amt': 8493.3896...</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>[530.9524347906868, 6172.526885259749, 14578.0...</td>\n",
       "      <td>[9587.357534446115, 0.0, 0.0, 0.0, 0.0, 4463.0...</td>\n",
       "      <td>34301.833135</td>\n",
       "      <td>11766.157564</td>\n",
       "      <td>0.686037</td>\n",
       "      <td>29113.071395</td>\n",
       "      <td>47064.630256</td>\n",
       "      <td>[0.7557579805938984, 0.4078792754476903, 0.488...</td>\n",
       "      <td>[{'agent': 6, 'mech': 'burn', 'amt': 8493.3896...</td>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                              native  \\\n",
       "0  [530.9524347906868, 767.4188125782725, 733.768...   \n",
       "1  [530.9524347906868, 767.4188125782725, 733.768...   \n",
       "2  [530.9524347906868, 767.4188125782725, 733.768...   \n",
       "3  [530.9524347906868, 6172.526885259749, 14578.0...   \n",
       "4  [530.9524347906868, 6172.526885259749, 14578.0...   \n",
       "\n",
       "                                                 cic         supply  \\\n",
       "0  [9587.357534446111, 4868.714330437587, 17019.7...  100000.000000   \n",
       "1  [9587.357534446111, 4868.714330437587, 17019.7...  100000.000000   \n",
       "2  [9587.357534446111, 4868.714330437587, 17019.7...  100000.000000   \n",
       "3  [9587.357534446115, 0.0, 0.0, 0.0, 0.0, 4463.0...   34301.833135   \n",
       "4  [9587.357534446115, 0.0, 0.0, 0.0, 0.0, 4463.0...   34301.833135   \n",
       "\n",
       "         reserve  spot_price    user_spend        impact  \\\n",
       "0  100000.000000    2.000000      0.000000      0.000000   \n",
       "1  100000.000000    2.000000  29113.071395      0.000000   \n",
       "2  100000.000000    2.000000  29113.071395      0.000000   \n",
       "3   11766.157564    0.686037  29113.071395      0.000000   \n",
       "4   11766.157564    0.686037  29113.071395  47064.630256   \n",
       "\n",
       "                                              prices  \\\n",
       "0  [2.595940395058093, 1.4010176731572506, 1.6767...   \n",
       "1  [0.7557579805938984, 0.4078792754476903, 0.488...   \n",
       "2  [0.7557579805938984, 0.4078792754476903, 0.488...   \n",
       "3  [0.7557579805938984, 0.4078792754476903, 0.488...   \n",
       "4  [0.7557579805938984, 0.4078792754476903, 0.488...   \n",
       "\n",
       "                                             actions  run  substep  timestep  \n",
       "0                                                 {}    1        0         0  \n",
       "1                                                 {}    1        1         1  \n",
       "2  [{'agent': 6, 'mech': 'burn', 'amt': 8493.3896...    1        2         1  \n",
       "3  [{'agent': 6, 'mech': 'burn', 'amt': 8493.3896...    1        3         1  \n",
       "4  [{'agent': 6, 'mech': 'burn', 'amt': 8493.3896...    1        4         1  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = df[df['substep'] == df.substep.max()]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f7f612ffa90>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 36936 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df.user_spend.plot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f7f61168a10>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 45304 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df.spot_price.plot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f7f60a89290>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 46348 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df.supply.plot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f7f609fe790>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 44520 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df.reserve.plot()"
   ]
  }
 ],
 "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
}
