diff --git a/notebooks/test.ipynb b/notebooks/test.ipynb index 4b78882..34d5e19 100644 --- a/notebooks/test.ipynb +++ b/notebooks/test.ipynb @@ -4,13 +4,13 @@ "cell_type": "code", "execution_count": 1, "metadata": { - "collapsed": true, "scrolled": false }, "outputs": [], "source": [ "from engine import run\n", "import matplotlib.pyplot as plt\n", + "import numpy as np\n", "\n", "%matplotlib inline" ] @@ -21,10 +21,19 @@ "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Test\n" + "ename": "TypeError", + "evalue": "cannot convert dictionary update sequence element #0 to a sequence", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mrun\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmain\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~/Documents/GitHub/DiffyQ-SimCAD/engine/run.py\u001b[0m in \u001b[0;36mmain\u001b[0;34m()\u001b[0m\n\u001b[1;32m 17\u001b[0m \u001b[0;31m#r = range(5)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 18\u001b[0m \u001b[0;31m# Dimensions: N x r x mechs\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 19\u001b[0;31m \u001b[0ms\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msimulation\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstates_list\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mconfigs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0menv_processes\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mN\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 20\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mDataFrame\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mflatten\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 21\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Test'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/Documents/GitHub/DiffyQ-SimCAD/engine/mechanismExecutor.py\u001b[0m in \u001b[0;36msimulation\u001b[0;34m(states_list, configs, env_processes, time_seq, runs)\u001b[0m\n\u001b[1;32m 72\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mrun\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mruns\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 73\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mrun\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 74\u001b[0;31m \u001b[0mhead\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mtail\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpipeline\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstates_list\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mconfigs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0menv_processes\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtime_seq\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 75\u001b[0m \u001b[0mhead\u001b[0m\u001b[0;34m[\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'mech_step'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhead\u001b[0m\u001b[0;34m[\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'time_step'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 76\u001b[0m \u001b[0msimulation_list\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mhead\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mtail\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/Documents/GitHub/DiffyQ-SimCAD/engine/mechanismExecutor.py\u001b[0m in \u001b[0;36mpipeline\u001b[0;34m(states_list, configs, env_processes, time_seq)\u001b[0m\n\u001b[1;32m 61\u001b[0m \u001b[0msimulation_list\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mstates_list\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 62\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mtime_step\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtime_seq\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 63\u001b[0;31m \u001b[0mpipeline_run\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mblock_gen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msimulation_list\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mconfigs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0menv_processes\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtime_step\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 64\u001b[0m \u001b[0mhead\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mpipeline_run\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpipeline_run\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 65\u001b[0m \u001b[0msimulation_list\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpipeline_run\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/Documents/GitHub/DiffyQ-SimCAD/engine/mechanismExecutor.py\u001b[0m in \u001b[0;36mblock_gen\u001b[0;34m(states_list, configs, env_processes, t_step)\u001b[0m\n\u001b[1;32m 49\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mconfig\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mconfigs\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 50\u001b[0m \u001b[0ms_conf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb_conf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mconfig\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mconfig\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 51\u001b[0;31m \u001b[0mstates_list\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmech_step\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mm_step\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstates_list\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms_conf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb_conf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0menv_processes\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt_step\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 52\u001b[0m \u001b[0mm_step\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 53\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/Documents/GitHub/DiffyQ-SimCAD/engine/mechanismExecutor.py\u001b[0m in \u001b[0;36mmech_step\u001b[0;34m(m_step, sL, state_funcs, behavior_funcs, env_processes, t_step)\u001b[0m\n\u001b[1;32m 27\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 28\u001b[0m \u001b[0;31m# New\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 29\u001b[0;31m \u001b[0mlast_mut_obj\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mm_step\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msL\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlast_mut_obj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_input\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mf\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mstate_funcs\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 30\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 31\u001b[0m \u001b[0mapply_env_proc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0menv_processes\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlast_mut_obj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlast_mut_obj\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'timestamp'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: cannot convert dictionary update sequence element #0 to a sequence" ] } ], @@ -34,32 +43,96 @@ }, { "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\nAAAAAElFTkSuQmCC\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], "source": [ - "d.plot(x='time_step', y='mech_step')" + "names = d.keys()[:4]\n", + "for n in names:\n", + " d[n]=d[n].apply(float)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "d.plot(x=['time_step', 'mech_step'], figsize=(15,10))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "d[d.time_step<10].plot(x=['time_step', 'mech_step'], figsize=(15,10))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "d[\"invar\"]=(d.Pool/d.Supply)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "d.plot(x=['time_step', 'mech_step'], y = \"invar\", figsize=(15,10))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "d.Belief" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "d.tail()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "d.plot(x=['time_step', 'mech_step'], figsize=(15,10))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "d[d.time_step<100].plot(x=['time_step', 'mech_step'], figsize=(15,10))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "d.Pool.diff().apply(np.sign).hist()" ] }, { @@ -69,7 +142,27 @@ "collapsed": true }, "outputs": [], - "source": [] + "source": [ + "d['scale']= d.Supply.apply(np.log10)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "d.invar" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "d.head()" + ] }, { "cell_type": "code", diff --git a/ui/simpleBC_Config.py b/ui/simpleBC_Config.py new file mode 100644 index 0000000..a5eaf20 --- /dev/null +++ b/ui/simpleBC_Config.py @@ -0,0 +1,168 @@ +from engine.utils import bound_norm_random, ep_time_step, env_proc + +import numpy as np +from decimal import Decimal + +alpha = Decimal('.7') #forgetting param +theta = Decimal('.75') #weight param for rational price +beta = Decimal('0.5') #agant response gain +gamma = Decimal('.03') #action friction param +delta = Decimal('.3') #bounds on price change +omega = Decimal('.5') #bound on burn frac per period + +seed = { + 'z': np.random.RandomState(1), + 'a': np.random.RandomState(2), + 'b': np.random.RandomState(3), + 'c': np.random.RandomState(3) +} + +# Behaviors per Mechanism + +#arbit X Bond +def b1m1(step, sL, s): + #returns "delta p" + if s['Price']< s['Pool']/s['Supply']-gamma: + return (s['Pool']/s['Supply']-s['Price'])/s['Price']*s['Pool']*beta + else : + return 0 + + +#invest X Bond +def b2m1(step, sL, s): + #returns "delta p" + if s['Belief']< (alpha*s['Belief']+s['Pool']/s['Supply'])*(1-alpha): + return s['Supply']*((alpha*s['Belief']+s['Pool']/s['Supply'])*(1-alpha)-s['Belief'])*beta + else : + return 0 + +#arbit X Burn +def b1m2(step, sL, s): + #returns "delta s" + if Decimal('1')/s['Price']< s['Supply']/s['Pool']-gamma: + return (s['Supply']/s['Pool']-Decimal('1')/s['Price'])*s['Price']*s['Supply']*beta + else : + return 0 + +#invest X Burn +def b2m2(step, sL, s): + #returns "delta s" + if Decimal('1')/s['Belief']< Decimal('1')/s['Price']: + return np.min([ s['Pool']*(Decimal('1')/s['Price']-Decimal('1')/s['Belief'])*beta, omega*s['Supply']]) + else : + return 0 + +# +#def b1m3(step, sL, s): +# return s['s1'] +#def b2m3(step, sL, s): +# return s['s2'] + + +# Internal States per Mechanism + +#Pool X Bond +def s1m1(step, sL, s, _input): + #_input = "delta p" + s['Pool'] = s['Pool']+_input + +#Supply X Bond +def s2m1(step, sL, s, _input): + #_input = "delta p" + s['Supply'] = s['Supply']+_input*s['Supply']/s['Pool'] + +# Pool X Burn +def s1m2(step, sL, s, _input): + #_input is "delta s" + s['Pool'] = s['Pool']- _input*s['Pool']/s['Supply'] + +# Supply X Burn +def s2m2(step, sL, s, _input): + s['Supply'] = s['Supply'] - _input + +#def s1m3(step, sL, s, _input): +# s['s1'] = s['s1']+Decimal(.25)*(s['s2']-s['s1']) + Decimal(.25)*(_input-s['s1']) +# +#def s2m3(step, sL, s, _input): +# s['s2'] = s['s2']+Decimal(.25)*(s['s1']-s['s2']) + Decimal(.25)*(_input-s['s2']) + +# Exogenous States +proc_one_coef_A = -delta +proc_one_coef_B = delta +def es3p1(step, sL, s, _input): + rv = bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) + s['Price'] = theta*s['Price'] * (Decimal('1')+rv) +(Decimal('1')-theta)*s['Pool']/s['Supply'] +def es4p2(step, sL, s, _input): + s['Belief'] = alpha*s['Belief']+s['Pool']/s['Supply']*(Decimal('1')-alpha) + +def es5p2(step, sL, s, _input): # accept timedelta instead of timedelta params + s['timestamp'] = ep_time_step(s, s['timestamp'], seconds=1) + +# Environment States +#from numpy.random import randn as rn +def env_a(x): + return 3 +def env_b(x): + return 7 +# def what_ever(x): +# return x + 1 + +# Genesis States +state_dict = { + 'Pool': Decimal(10.0), + 'Supply': Decimal(5.0), + 'Price': Decimal(.01), + 'Belief': Decimal(10.0), + 'timestamp': '2018-10-01 15:16:24' +} + +exogenous_states = { + "Price": es3p1, + "Belief": es4p2, + "timestamp": es5p2 +} + +env_processes = { + "Price": env_proc('2018-10-01 15:16:25', env_a), + "Belief": env_proc('2018-10-01 15:16:25', env_b) +} + +# test return vs. non-return functions as lambdas +# test fully defined functions +mechanisms = { + "bond": { + "behaviors": { + "arbit": b1m1, # lambda step, sL, s: s['s1'] + 1, + "invest": b2m1 + }, + "states": { + "Pool": s1m1, + "Supply": s2m1, + } + }, + "burn": { + "behaviors": { + "arbit": b1m2, + "invest": b2m2 + }, + "states": { + "Pool": s1m2, + "Supply": s2m2, + } + }, +# "m3": { +# "behaviors": { +# "b1": b1m3, +# "b2": b2m3 +# }, +# "states": { +# "s1": s1m3, +# "s2": s2m3, +# } +# } +} + +sim_config = { + "N": 1, + "R": 1000 +} \ No newline at end of file