{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "### Exogenous Example\n", "## Authored by BlockScience, MV Barlin\n", "### Updated July-10-2019 \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Key assumptions and space:\n", "1. Implementation of System Model in cell 2\n", "2. Timestep = day\n", "3. Launch simulation, without intervention from changing governance policies" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Library Imports" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from IPython.display import Image\n", "import pandas as pd\n", "import numpy as np\n", "import matplotlib as mpl\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "import math\n", "#from tabulate import tabulate\n", "from scipy import stats\n", "sns.set_style('whitegrid')\n", "from decimal import Decimal\n", "from datetime import timedelta\n", "\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## cadCAD Setup\n", "#### ----------------cadCAD LIBRARY IMPORTS------------------------" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from cadCAD.engine import ExecutionMode, ExecutionContext, Executor\n", "#from simulations.validation import sweep_config\n", "from cadCAD import configs\n", "from cadCAD.configuration import append_configs\n", "from cadCAD.configuration.utils import proc_trigger, ep_time_step, config_sim" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "#from cadCAD.configuration.utils.parameterSweep import config_sim" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from typing import Dict, List" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### ----------------Random State Seed-----------------------------" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "seed = {\n", "# 'z': np.random.RandomState(1)\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Timestamp" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "ts_format = '%Y-%m-%d %H:%M:%S'\n", "t_delta = timedelta(days=0, minutes=0, seconds=1)\n", "def set_time(_g, step, sL, s, _input):\n", " y = 'timestamp'\n", " x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta)\n", " return (y, x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# ASSUMED PARAMETERS" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### PRICE LIST" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "# dai_xns_conversion = 1.0 # Assumed for static conversion 'PUBLISHED PRICE LIST' DEPRECATED" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Initial Condition State Variables" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "del_stake_pct = 2\n", "\n", "starting_xns = float(10**10) # initial supply of xns tokens\n", "starting_broker_xns = float(1 * 10**8) # inital holding of xns token by broker app\n", "starting_broker_fiat = float(1 * 10**5) # inital holding of xns token by broker app\n", "starting_broker_stable = float(1 * 10**6) # inital holding of stable token by broker app\n", "starting_deposit_acct = float(100) # inital deposit locked for first month of resources TBD: make function of resource*price\n", "starting_entrance = float(1 * 10**4) # TBD: make function of entrance fee % * cost * # of initial apps\n", "starting_app_usage = float(10) # initial fees from app usage \n", "starting_platform = float(100) # initial platform fees \n", "starting_resource_fees = float(10) # initial resource fees usage paid by apps \n", "starting_app_subsidy = float(0.25* 10**9) # initial application subsidy pool\n", "starting_stake = float(4 * 10**7)\n", "starting_stake_pool = starting_stake + ((3*10**7)*(del_stake_pct)) # initial staked pool + ((3*10**7)*(del_stake_pct))\n", "\n", "#starting_block_reward = float(0) # initial block reward MOVED ABOVE TO POLICY\n", "starting_capacity_subsidy = float(7.5 * 10**7) # initial capacity subsidy pool\n", "starting_delegate_holdings = 0.15 * starting_xns\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Initial Condition Composite State Variables" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "# subsidy limit is 30% of the 10B supply\n", "starting_treasury = float(5.5 * 10**9) \n", "starting_app_income = float(0) # initial income to application\n", "starting_resource_income = float(0) # initial income to application\n", "starting_delegate_income = float(0) # initial income to delegate" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Initial Condition Exogoneous State Variables " ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "starting_xns_fiat = float(0.01) # initial xns per fiat signal\n", "starting_fiat_ext = float(1) # initial xns per fiat signal\n", "starting_stable_ext = float(1) # initial stable signal" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exogenous Price Updates" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "def delta_price(mean,sd):\n", " '''Returns normal random variable generated by first two central moments of price change of input ticker'''\n", " rv = np.random.normal(mean, sd)\n", " return rv" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "\n", "def xns_ext_update(_g, step, sL, s, _input):\n", " key = 'XNS_fiat_external'\n", " \n", " value = s['XNS_fiat_external'] * (1 + delta_price(0.000000, 0.005))\n", " \n", " return key, value" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "From Currency Analysis of DAI-USD pair \n", "May-09-2018 through June-10-2019 \n", "Datasource: BitFinex \n", "Analysis of daily return percentage performed by BlockScience" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "DAI_mean = 0.0000719\n", "DAI_sd = 0.006716" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The daily return is computed as: \n", "$$ r = \\frac{Price_n - Price_{n-1}}{Price_{n-1}} $$ \n", "Thus, the modelled current price can be as: \n", "$$ Price_n = Price_{n-1} * r + Price_{n-1} $$" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "\n", "def stable_update(_g, step, sL, s, _input):\n", " key = 'stable_external'\n", " \n", " value = s['stable_external'] * (1 + delta_price(DAI_mean, DAI_sd))\n", " return key, value\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Assumed Parameters" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "apps_deployed = 1 # Make part of test- application deployment model\n", "\n", "starting_deposit_acct = float(100) # inital deposit locked for first month of resources TBD: make function of resource*price\n", "\n", "app_resource_fee_constant = 10**1 # in STABLE, assumed per day per total nodes \n", "platform_fee_constant = 10 # in XNS\n", "# ^^^^^^^^^^^^ MAKE A PERCENTAGE OR FLAT FEE as PART of TESTING" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1000" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "alpha = 100 # Fee Rate\n", "beta = 0.10 # FIXED Too high because multiplied by constant and resource fees\n", "app_platform = alpha * platform_fee_constant\n", "app_platform" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10.0" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "beta_out =beta*100\n", "beta_out" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.15" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "starting_capacity_subsidy / (5 * 10**7) / 10" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "\n", "weight = 0.95 # 0.95 internal weight 5% friction from external markets\n", "\n", "def xns_int_update(_g, step, sL, s, _input):\n", " key = 'XNS_fiat_internal'\n", "\n", " internal = s['XNS_fiat_internal'] * weight\n", " external = s['XNS_fiat_external'] * (1 - weight)\n", " value = internal + external\n", " \n", " return key, value" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### CONFIGURATION DICTIONARY" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "time_step_count = 3652 # days = 10 years\n", "run_count = 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Genesis States" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "#----------STATE VARIABLE Genesis DICTIONARY---------------------------\n", "genesis_states = {\n", " 'XNS_fiat_external' : starting_xns_fiat,\n", " 'XNS_fiat_internal' : starting_xns_fiat,\n", " # 'fiat_external' : starting_fiat_ext,\n", " 'stable_external' : starting_stable_ext,\n", " 'timestamp': '2018-10-01 15:16:24', #es5\n", "}" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "#--------------EXOGENOUS STATE MECHANISM DICTIONARY--------------------\n", "exogenous_states = {\n", " 'XNS_fiat_external' : xns_ext_update,\n", "# 'fiat_external' : starting_fiat_ext,\n", " 'stable_external' : stable_update,\n", " \"timestamp\": set_time,\n", " }\n", "\n", "#--------------ENVIRONMENTAL PROCESS DICTIONARY------------------------\n", "env_processes = {\n", "# \"Poisson\": env_proc_id\n", "}\n", "#----------------------SIMULATION RUN SETUP----------------------------\n", "sim_config = config_sim(\n", " {\n", " \"N\": run_count,\n", " \"T\": range(time_step_count)\n", "# \"M\": g # for parameter sweep\n", "}\n", ")\n", "#----------------------MECHANISM AND BEHAVIOR DICTIONARY---------------\n", "partial_state_update_block = {\n", " \"price\": { \n", " \"policies\": { \n", " },\n", " \"variables\": {\n", " 'XNS_fiat_internal' : xns_int_update\n", "# 'app_income' : app_earn,\n", " }\n", " },\n", "}\n", "\n", "append_configs(\n", " sim_configs=sim_config,\n", " initial_state=genesis_states,\n", " seeds=seed,\n", " raw_exogenous_states= exogenous_states,\n", " env_processes=env_processes,\n", " partial_state_update_blocks=partial_state_update_block\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Running cadCAD" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Simulation Execution: Single Configuration\n", "\n", "single_proc: []\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\mbarl\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\cadCAD\\utils\\__init__.py:89: FutureWarning: The use of a dictionary to describe Partial State Update Blocks will be deprecated. Use a list instead.\n", " FutureWarning)\n" ] } ], "source": [ "exec_mode = ExecutionMode()\n", "\n", "print(\"Simulation Execution: Single Configuration\")\n", "print()\n", "first_config = configs # only contains config1\n", "single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)\n", "run1 = Executor(exec_context=single_proc_ctx, configs=first_config)\n", "run1_raw_result, tensor_field = run1.main()\n", "result = pd.DataFrame(run1_raw_result)\n", "# print()\n", "# print(\"Tensor Field: config1\")\n", "# print(tabulate(tensor_field, headers='keys', tablefmt='psql'))\n", "# print(\"Output:\")\n", "# print(tabulate(result, headers='keys', tablefmt='psql'))\n", "# print()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "df = result" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
XNS_fiat_externalXNS_fiat_internalrunstable_externalsubsteptimestamptimestep
00.0100000.01000011.00000002018-10-01 15:16:240
10.0099440.01000011.00017212018-10-01 15:16:251
20.0098890.00999711.00351612018-10-01 15:16:262
30.0098480.00999210.99065512018-10-01 15:16:273
40.0098140.00998511.00134612018-10-01 15:16:284
50.0097980.00997611.00249512018-10-01 15:16:295
60.0097060.00996710.99491112018-10-01 15:16:306
70.0096250.00995410.99891912018-10-01 15:16:317
80.0096320.00993810.99504712018-10-01 15:16:328
90.0096480.00992210.98078612018-10-01 15:16:339
\n", "
" ], "text/plain": [ " XNS_fiat_external XNS_fiat_internal run stable_external substep \\\n", "0 0.010000 0.010000 1 1.000000 0 \n", "1 0.009944 0.010000 1 1.000172 1 \n", "2 0.009889 0.009997 1 1.003516 1 \n", "3 0.009848 0.009992 1 0.990655 1 \n", "4 0.009814 0.009985 1 1.001346 1 \n", "5 0.009798 0.009976 1 1.002495 1 \n", "6 0.009706 0.009967 1 0.994911 1 \n", "7 0.009625 0.009954 1 0.998919 1 \n", "8 0.009632 0.009938 1 0.995047 1 \n", "9 0.009648 0.009922 1 0.980786 1 \n", "\n", " timestamp timestep \n", "0 2018-10-01 15:16:24 0 \n", "1 2018-10-01 15:16:25 1 \n", "2 2018-10-01 15:16:26 2 \n", "3 2018-10-01 15:16:27 3 \n", "4 2018-10-01 15:16:28 4 \n", "5 2018-10-01 15:16:29 5 \n", "6 2018-10-01 15:16:30 6 \n", "7 2018-10-01 15:16:31 7 \n", "8 2018-10-01 15:16:32 8 \n", "9 2018-10-01 15:16:33 9 " ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.head(10)" ] }, { "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.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }