dagger-research/analysis/TokenValuation.ipynb

519 lines
19 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Token Valuation Script for Decentralized Cloud Services \n",
"`A script for analyzing future token utility value`\n",
"\n",
"This builds on the work of:\n",
"- https://medium.com/@cburniske/cryptoasset-valuations-ac83479ffca7\n",
"- https://hunter.mirror.xyz/_04DQ0AHbWCZ1tQxokM1b4bgDEpQ2paukOzEI_w_Ktk\n",
"- https://sites.cs.ucsb.edu/~suri/psdir/incentives.pdf\n",
"\n",
"Future Work:\n",
"- Extend usage of this tool to help analyze and model the intersection of incentives and decentralized cloud service system performance to impact better data distribution and minimize economic vulnerability."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from matplotlib import pyplot as plt\n",
"import numpy as np\n",
"from ipywidgets import HBox, VBox, widgets, interactive\n",
"from IPython.display import display, clear_output\n",
"import math\n",
"import decimal\n",
"from datetime import datetime\n",
"%matplotlib inline\n",
"\n",
"# Widget Definitions\n",
"\n",
"ssi0label = widgets.Label(value = \"ssi0 | Max Supply\")\n",
"ssi0text = widgets.FloatText(\n",
" value = 66000000,\n",
" description = 'ssi0 = '\n",
")\n",
"ssi0 = widgets.IntSlider(\n",
" value=66000000,\n",
" min=10000000,\n",
" max=10000000000,\n",
" step=1,\n",
" description='ssi0:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='d'\n",
")\n",
"ssi0link = widgets.jslink((ssi0text, 'value'), (ssi0, 'value'))\n",
"ssi1label = widgets.Label(value = \"ssi1 | Float\")\n",
"ssi1text = widgets.FloatText(\n",
" value = 33394701,\n",
" description = 'ssi1 = '\n",
")\n",
"ssi1 = widgets.IntSlider(\n",
" value=33394701,\n",
" min=10000000,\n",
" max=10000000000,\n",
" step=1000000,\n",
" description='ssi1:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='d'\n",
") \n",
"ssi1link = widgets.jslink((ssi1text, 'value'), (ssi1, 'value'))\n",
"ssi2label = widgets.Label(value = \"ssi2 | Float CAGR\")\n",
"ssi2text = widgets.FloatText(\n",
" value = 0.2201662,\n",
" description = 'ssi2 = '\n",
")\n",
"ssi2 = widgets.FloatSlider(\n",
" value=0.2201662,\n",
" min=0,\n",
" max=1,\n",
" step=0.001,\n",
" description='ssi2:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='.4f'\n",
") \n",
"ssi2link = widgets.jslink((ssi2text, 'value'), (ssi2, 'value'))\n",
"ssi3label = widgets.Label(value = \"ssi3 | Year Max Supply in Possible Float\")\n",
"ssi3text = widgets.FloatText(\n",
" value = 2026,\n",
" description = 'ssi3 = '\n",
")\n",
"ssi3 = widgets.IntSlider(\n",
" value=2026,\n",
" min=2000,\n",
" max=2100,\n",
" step=1,\n",
" description='ssi3:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='d'\n",
") \n",
"ssi3link = widgets.jslink((ssi3text, 'value'), (ssi3, 'value'))\n",
"ssi4label = widgets.Label(value = \"ssi4 | Percent of Tokens Hodl'd\")\n",
"ssi4text = widgets.FloatText(\n",
" value = 0.5,\n",
" description = 'ssi4 = '\n",
")\n",
"ssi4 = widgets.FloatSlider(\n",
" value=0.5,\n",
" min=0,\n",
" max=1,\n",
" step=0.001,\n",
" description='ssi4:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='.4f'\n",
") \n",
"ssi4link = widgets.jslink((ssi4text, 'value'), (ssi4, 'value'))\n",
"ssi5label = widgets.Label(value = \"ssi5 | Decrease in Percent of Tokens Hodl'd Each Year\")\n",
"ssi5text = widgets.FloatText(\n",
" value = 0.01,\n",
" description = 'ssi5 = '\n",
")\n",
"ssi5 = widgets.FloatSlider(\n",
" value=0.01,\n",
" min=0,\n",
" max=1,\n",
" step=0.001,\n",
" description='ssi5:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='.4f'\n",
") \n",
"ssi5link = widgets.jslink((ssi5text, 'value'), (ssi5, 'value'))\n",
"ei0label = widgets.Label(value = \"ei0 | Storage Cost per GB per Year\")\n",
"ei0text = widgets.FloatText(\n",
" value = 3.85,\n",
" description = 'ei0 = '\n",
")\n",
"ei0 = widgets.FloatSlider(\n",
" value=3.85,\n",
" min=0,\n",
" max=10,\n",
" description='ei0:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='.2f'\n",
") \n",
"ei0link = widgets.jslink((ei0text, 'value'), (ei0, 'value'))\n",
"ei1label = widgets.Label(value = \"ei1 | Cost Decline for Data Storage\")\n",
"ei1text = widgets.FloatText(\n",
" value = 0.1430,\n",
" description = 'ei1 = '\n",
")\n",
"ei1 = widgets.FloatSlider(\n",
" value=0.1430,\n",
" min=0,\n",
" max=1,\n",
" step=0.001,\n",
" description='ei1:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='.4f'\n",
") \n",
"ei1link = widgets.jslink((ei1text, 'value'), (ei1, 'value'))\n",
"ei2label = widgets.Label(value = \"ei2 | Datasphere Size (GB)\")\n",
"ei2text = widgets.FloatText(\n",
" value = 93110734434921.6,\n",
" description = 'ei2 = '\n",
")\n",
"ei2 = widgets.IntSlider(\n",
" value=93110734434921.6,\n",
" min=0,\n",
" max=100000000000000000,\n",
" description='ei2:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='d'\n",
") \n",
"ei2link = widgets.jslink((ei2text, 'value'), (ei2, 'value'))\n",
"ei3label = widgets.Label(value = \"ei3 | Datasphere CAGR\")\n",
"ei3text = widgets.FloatText(\n",
" value = 0.262,\n",
" description = 'ei3 = '\n",
")\n",
"ei3 = widgets.FloatSlider(\n",
" value=0.262,\n",
" min=0,\n",
" max=1,\n",
" step=0.001,\n",
" description='ei3:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='.4f'\n",
") \n",
"ei3link = widgets.jslink((ei3text, 'value'), (ei3, 'value'))\n",
"ei4label = widgets.Label(value = \"ei4 | % Total Addressable Market (TAM)\")\n",
"ei4text = widgets.FloatText(\n",
" value = 0.10,\n",
" description = 'ei4 = '\n",
")\n",
"ei4 = widgets.FloatSlider(\n",
" value=0.10,\n",
" min=0,\n",
" max=1,\n",
" step=0.001,\n",
" description='ei4:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='.2f'\n",
") \n",
"ei4link = widgets.jslink((ei4text, 'value'), (ei4, 'value'))\n",
"ei5label = widgets.Label(value = \"ei5 | Velocity\")\n",
"ei5text = widgets.FloatText(\n",
" value = 20,\n",
" description = 'ei5 = '\n",
")\n",
"ei5 = widgets.IntSlider(\n",
" value=20,\n",
" min=0,\n",
" max=100,\n",
" step=1,\n",
" description='ei5:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='d'\n",
") \n",
"ei5link = widgets.jslink((ei5text, 'value'), (ei5, 'value'))\n",
"aci0label = widgets.Label(value = \"aci0 | Launch Year\")\n",
"aci0text = widgets.FloatText(\n",
" value = 2017,\n",
" description = 'aci0 = '\n",
")\n",
"aci0 = widgets.IntSlider(\n",
" value=2017,\n",
" min=2017,\n",
" max=2024,\n",
" step=1,\n",
" description='aci0:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='d'\n",
") \n",
"aci0link = widgets.jslink((aci0text, 'value'), (aci0, 'value'))\n",
"aci1label = widgets.Label(value = \"aci1 | Saturation Percentage\")\n",
"aci1text = widgets.FloatText(\n",
" value = 0.01,\n",
" description = 'aci1 = '\n",
")\n",
"aci1 = widgets.FloatSlider(\n",
" value=0.01,\n",
" min=0,\n",
" max=1,\n",
" step=0.001,\n",
" description='aci1:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='0.2f'\n",
") \n",
"aci1link = widgets.jslink((aci1text, 'value'), (aci1, 'value'))\n",
"aci2label = widgets.Label(value = \"aci2 | Year of Inflection Point\")\n",
"aci2text = widgets.FloatText(\n",
" value = 2024,\n",
" description = 'aci2 = '\n",
")\n",
"aci2 = widgets.IntSlider(\n",
" value=2024,\n",
" min=2000,\n",
" max=2100,\n",
" step=1,\n",
" description='aci2:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='d'\n",
") \n",
"aci2link = widgets.jslink((aci2text, 'value'), (aci2, 'value'))\n",
"aci3label = widgets.Label(value = \"aci3 | Saturation Over Time\")\n",
"aci3text = widgets.FloatText(\n",
" value = 10,\n",
" description = 'aci3 = '\n",
")\n",
"aci3 = widgets.IntSlider(\n",
" value=10,\n",
" min=0,\n",
" max=100,\n",
" step=1,\n",
" description='aci3:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='d'\n",
") \n",
"aci3link = widgets.jslink((aci3text, 'value'), (aci3, 'value'))\n",
"dcmfu0label = widgets.Label(value = \"dcmfu0 | End Year\")\n",
"dcmfu0text = widgets.FloatText(\n",
" value = 2032,\n",
" description = 'dcmfu0 = '\n",
")\n",
"dcmfu0 = widgets.IntSlider(\n",
" value=2032,\n",
" min=2020,\n",
" max=2100,\n",
" step=1,\n",
" description='dcmfu0:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='d'\n",
") \n",
"dcmfu0link = widgets.jslink((dcmfu0text, 'value'), (dcmfu0, 'value')) # calculated output\n",
"dcmfu1label = widgets.Label(value = \"dcmfu1 | Years Between Target and End Year\")\n",
"dcmfu1text = widgets.FloatText(\n",
" value = 10,\n",
" description = 'dcmfu1 = '\n",
")\n",
"dcmfu1 = widgets.IntSlider(\n",
" value=10,\n",
" min=0,\n",
" max=50,\n",
" step=1,\n",
" description='dcmfu1:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='d'\n",
") \n",
"dcmfu1link = widgets.jslink((dcmfu1text, 'value'), (dcmfu1, 'value'))\n",
"dcmfu2label = widgets.Label(value = \"dcmfu2 | Discount Rate\")\n",
"dcmfu2text = widgets.FloatText(\n",
" value = 0.40,\n",
" description = 'dcmfu2 = '\n",
")\n",
"dcmfu2 = widgets.FloatSlider(\n",
" value=0.40,\n",
" min=0,\n",
" max=1,\n",
" step=0.001,\n",
" description='dcmfu2:',\n",
" disabled=False,\n",
" continuous_update=True,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='.2f'\n",
") \n",
"dcmfu2link = widgets.jslink((dcmfu2text, 'value'), (dcmfu2, 'value')) # calculated output\n",
"resultlabel = widgets.Label(value='| Waiting for Result')\n",
"\n",
"### Calculations\n",
"# Inputs\n",
"def calculate():\n",
" ssi = [ssi0.value, ssi1.value, ssi2.value, ssi3.value, ssi4.value, ssi5.value]\n",
" ei = [ei0.value, ei1.value, ei2.value, ei3.value, ei4.value, ei5.value]\n",
" aci = [aci0.value, aci1.value, aci2.value, aci3.value]\n",
" dcmfu = [dcmfu0.value, dcmfu1.value, dcmfu2.value]\n",
" now = datetime.now() # current date and time\n",
" currentyear = int(now.strftime(\"%Y\")) # make slider for this\n",
" # Outputs\n",
" ssolen = 20 # length of output of array containing results\n",
" ssorows = 16 # unique output rows\n",
" euvo = [8] \n",
" acu = [3]\n",
"\n",
" dcmfu[1] = dcmfu[0] - currentyear # the difference between end year and current year\n",
" yearsfromlaunch = (ssolen) * [0] # an array containing 16 zeroed out elements\n",
" sso = [[0] * ssolen for i in range(ssorows)] # list of lists where each sublist contains 10 zeroed out elements\n",
" sso[0][0] = ssi[1] # number of tokens in float\n",
" sso[2][0] = ssi[4] # first element of array containing initial token hodl rate\n",
" sso[4][0] = ei[0]\n",
" sso[5][0] = ei[2]\n",
" sso[7][0] = 0\n",
"\n",
" for i in range(len(sso[0])-1):\n",
" if sso[0][i] * (1 + ssi[2]) < ssi[0]:\n",
" sso[0][i+1] = sso[0][i] * (1 + ssi[2]) # number of tokens in float after each year\n",
" else:\n",
" sso[0][i+1] = ssi[0] # max number of tokens\n",
" sso[1][i+1] = sso[0][i+1] - sso[0][i]\n",
" sso[2][i+1] = sso[2][i] - ssi[5]\n",
" sso[4][i+1] = sso[4][i]/(1 + ei[1])\n",
" sso[5][i+1] = sso[5][i]*(1 + ei[3])\n",
"\n",
" for i in range(len(yearsfromlaunch)):\n",
" yearsfromlaunch[i] = aci[0] + 4 + i # an array containing the years from launch - 2017 to 2034\n",
"\n",
" for i in range(len(sso[0])):\n",
" sso[3][i] = sso[0][i] * (1 - sso[2][i])\n",
" sso[6][i] = sso[5][i] * ei[4]\n",
" sso[12][i] = aci[1]/(1 + 81**((aci[2]+aci[3]/2-yearsfromlaunch[i])/aci[3]))\n",
" sso[13][i] = sso[12][i] - sso[12][0]\n",
" sso[7][i] = sso[13][i]\n",
" sso[8][i] = sso[7][i] * sso[6][i]\n",
" sso[9][i] = sso[4][i] * sso[6][i] * (sso[7][i])\n",
" sso[10][i] = sso[9][i] / ei[5]\n",
" sso[11][i] = sso[10][i] / (sso[3][i])\n",
" sso[14][i] = aci[1]\n",
" sso[15][i] = sso[13][i]*100\n",
" result = round(sso[11][yearsfromlaunch.index(dcmfu[0])] / (1 + dcmfu[2])**dcmfu[1], 2) #lookup current utility value at end year and divide by (1 + discount rate) ^ years between launch year and end year\n",
" return [result, yearsfromlaunch, sso[11], sso[15]]\n",
"\n",
"### Plots\n",
"\n",
"plot1 = widgets.Output()\n",
"plot2 = widgets.Output()\n",
"\n",
"### 'Plot' Button\n",
"button = widgets.Button(description='Plot')\n",
"buttonoutput = widgets.Output()\n",
"\n",
"# On Button Click \n",
"def on_button_clicked(b):\n",
" result = calculate()[0]\n",
" \n",
" with plot1:\n",
" clear_output()\n",
" a = np.array(calculate()[1])\n",
" b = np.array(calculate()[3])\n",
" plt.plot(a,b)\n",
" plt.title(\"Percent Penetration of Token by Year\")\n",
" plt.xlabel(\"Year\")\n",
" plt.ylabel(\"Penetration (%)\")\n",
" plt.show()\n",
"\n",
" with plot2:\n",
" clear_output()\n",
" c = np.array(calculate()[1])\n",
" d = np.array(calculate()[2])\n",
" plt.plot(c,d)\n",
" plt.title(\"Current Utility Value of Token by Year\")\n",
" plt.xlabel(\"Year\")\n",
" plt.ylabel(\"Dollar Value per Token ($)\")\n",
" plt.show() \n",
" \n",
" with buttonoutput:\n",
" clear_output()\n",
" resultlabel.value = '| Future Value: $' + str(result) # Market Value at End Year based on Expectations of Future Utility\n",
" button.description = 'Update'\n",
" display(plotvbox)\n",
" \n",
"button.on_click(on_button_clicked)\n",
"\n",
"### Box and Tabs Layout\n",
"\n",
"# Supply Schedule Inputs\n",
"tab1avbox = widgets.VBox([ssi0label, ssi0text, ssi1label, ssi1text, ssi2label, ssi2text, ssi3label, ssi3text, ssi4label, ssi4text, ssi5label, ssi5text])\n",
"tab1bvbox = widgets.VBox([ssi0, ssi1, ssi2, ssi3, ssi4, ssi5])\n",
"tab1hbox = widgets.HBox([tab1bvbox, tab1avbox])\n",
"tab1 = VBox(children=[tab1hbox])\n",
"\n",
"# Economy Inputs\n",
"tab2avbox = widgets.VBox([ei0label, ei0text, ei1label, ei1text, ei2label, ei2text, ei3label, ei3text, ei4label, ei4text, ei5label, ei5text])\n",
"tab2bvbox = widgets.VBox([ei0, ei1, ei2, ei3, ei4, ei5])\n",
"tab2hbox = widgets.HBox([tab2bvbox, tab2avbox])\n",
"tab2 = VBox(children=[tab2hbox])\n",
"\n",
"# Adoption Curve Inputs\n",
"tab3avbox = widgets.VBox([aci0label, aci0text, aci1label, aci1text, aci2label, aci2text, aci3label, aci3text])\n",
"tab3bvbox = widgets.VBox([aci0, aci1, aci2, aci3])\n",
"tab3hbox = widgets.HBox([tab3bvbox, tab3avbox])\n",
"tab3 = VBox(children=[tab3hbox])\n",
"\n",
"# Current Market Value from Future Utility\n",
"tab4avbox = widgets.VBox([dcmfu0label, dcmfu0text, dcmfu1label, dcmfu1text, dcmfu2label, dcmfu2text])\n",
"tab4bvbox = widgets.VBox([dcmfu0, dcmfu1, dcmfu2])\n",
"tab4hbox = widgets.HBox([tab4bvbox, tab4avbox])\n",
"tab4 = VBox(children=[tab4hbox])\n",
"\n",
"# Button and Plot\n",
"buttonhbox = widgets.HBox([button, resultlabel])\n",
"plotvbox = widgets.VBox([plot1, plot2])\n",
"tab = widgets.Tab(children=[tab1, tab2, tab3, tab4])\n",
"tabhbox = widgets.HBox([tab, plotvbox])\n",
"tab.set_title(0, 'Supply Schedule')\n",
"tab.set_title(1, 'Economy')\n",
"tab.set_title(2, 'Adoption Curve')\n",
"tab.set_title(3, 'Current Market Value')\n",
"VBox(children=[buttonhbox, tabhbox])"
]
}
],
"metadata": {
"language_info": {
"name": "python"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}