From cdcc20787170f9722013d61258e7f565ce46c7cc Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Mon, 7 Jan 2019 18:15:15 -0500 Subject: [PATCH 1/5] pre clean for az pt. 2.5 --- simulations/sim_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simulations/sim_test.py b/simulations/sim_test.py index ef1daa7..bb75134 100644 --- a/simulations/sim_test.py +++ b/simulations/sim_test.py @@ -18,7 +18,7 @@ single_proc_ctx = ExecutionContext(context=exec_mode.single_proc) run1 = Executor(exec_context=single_proc_ctx, configs=first_config) run1_raw_result, tensor_field = run1.main() result = pd.DataFrame(run1_raw_result) -# result.to_csv('~/Projects/DiffyQ-SimCAD/results/config4.csv', sep=',') +# result.to_csv('~/Projects/DiffyQ-SimCAD/results/config.csv', sep=',') print() print("Tensor Field:") print(tabulate(tensor_field, headers='keys', tablefmt='psql')) From fe7c5a53fc4b18d3832a1c4f8e277e0d2c2e854e Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Mon, 7 Jan 2019 20:31:05 -0500 Subject: [PATCH 2/5] blah --- .gitignore | 10 +- simulations/scrapbox/config7c.py | 494 +++++++++++++++++++++++++ simulations/scrapbox/config8c.py | 443 ++++++++++++++++++++++ simulations/validation/base_config1.py | 171 +++++++++ simulations/validation/base_config2.py | 180 +++++++++ simulations/validation/config_1.py | 178 +++++++++ simulations/validation/config_2.py | 180 +++++++++ 7 files changed, 1647 insertions(+), 9 deletions(-) create mode 100644 simulations/scrapbox/config7c.py create mode 100644 simulations/scrapbox/config8c.py create mode 100644 simulations/validation/base_config1.py create mode 100644 simulations/validation/base_config2.py create mode 100644 simulations/validation/config_1.py create mode 100644 simulations/validation/config_2.py diff --git a/.gitignore b/.gitignore index c8cd963..e25ca00 100644 --- a/.gitignore +++ b/.gitignore @@ -8,12 +8,4 @@ __pycache__ Pipfile Pipfile.lock results -.mypy_cache -notebooks -simulations/validation/base_config1.py -simulations/validation/base_config2.py -simulations/validation/config_1.py -simulations/validation/config_2.py -simulations/barlin -simulations/scrapbox -simulations/zx \ No newline at end of file +.mypy_cache \ No newline at end of file diff --git a/simulations/scrapbox/config7c.py b/simulations/scrapbox/config7c.py new file mode 100644 index 0000000..1374e1b --- /dev/null +++ b/simulations/scrapbox/config7c.py @@ -0,0 +1,494 @@ +from decimal import Decimal +import numpy as np + +from SimCAD import Configuration, configs +from SimCAD.configuration import exo_update_per_ts, bound_norm_random, \ + ep_time_step + +seed = { + 'z': np.random.RandomState(1) + # 'a': np.random.RandomState(2), + # 'b': np.random.RandomState(3), + # 'c': np.random.RandomState(3) +} + +#Signals +# Pr_signal +#if s['P_Ext_Markets'] != 0: +#Pr_signal = s['Z']/s['P_Ext_Markets'] +#else Pr_signal = 0 +# if Pr_signal < s['Z']/s['Buy_Log']: +beta = Decimal('0.25') #agent response gain +beta_LT = Decimal('0.1') #LT agent response gain +alpha = Decimal('0.091') #21 day EMA forgetfullness between 0 and 1, closer to 1 discounts older obs quicker, should be 2/(N+1) +max_withdraw_factor = Decimal('0.9') +external_draw = Decimal('0.01') # between 0 and 1 to draw Buy_Log to external + +# Stochastic process factors +correction_factor = Decimal('0.01') +volatility = Decimal('5.0') + + +# Buy_Log_signal = +# Z_signal = +# Price_signal = +# TDR_draw_signal = +# P_Ext_Markets_signal = + +# Behaviors per Mechanism + +# BEHAVIOR 1: EMH Trader +EMH_portion = Decimal('0.250') +EMH_Ext_Hold = Decimal('42000.0') + +def b1m1(step, sL, s): + # y = 'P_Ext_Markets' + # Psignal_ext = s['P_Ext_Markets'] / s['Z'] + # Psignal_int = s['Buy_Log'] / s['Z'] + # if Psignal_ext < Psignal_int: + # return beta*(Psignal_int - Psignal_ext) * s['Z'] # Deposited amount in TDR + # else: + # return 0 # Decimal(0.000001) + # return (y,x) + theta = (s['Z']*EMH_portion*s['Price'])/(s['Z']*EMH_portion*s['Price'] + EMH_Ext_Hold * s['P_Ext_Markets']) + if s['Price'] < (theta*EMH_Ext_Hold * s['P_Ext_Markets'])/(s['Z']*EMH_portion*(1-theta)): + return beta * theta*EMH_Ext_Hold * s['P_Ext_Markets']/(s['Price']*EMH_portion*(1-theta)) + elif s['Price'] > (theta*EMH_Ext_Hold * s['P_Ext_Markets'])/(s['Z']*EMH_portion*(1-theta)): + return 0 + else: + return 0 + +def b1m2(step, sL, s): + theta = (s['Z']*EMH_portion*s['Price'])/(s['Z']*EMH_portion*s['Price'] + EMH_Ext_Hold * s['P_Ext_Markets']) + if s['Price'] < (theta*EMH_Ext_Hold * s['P_Ext_Markets'])/(s['Z']*EMH_portion*(1-theta)): + return 0 + elif s['Price'] > (theta*EMH_Ext_Hold * s['P_Ext_Markets'])/(s['Z']*EMH_portion*(1-theta)): + return beta * theta*EMH_Ext_Hold * s['P_Ext_Markets']/(s['Price']*EMH_portion*(1-theta)) + else: + return 0 + +# BEHAVIOR 3: Herding + + +# BEHAVIOR 4: HODLers +HODL_belief = Decimal('10.0') +HODL_portion = Decimal('0.250') +HODL_Ext_Hold = Decimal('4200.0') + +def b4m2(step, sL, s): + theta = (s['Z']*HODL_portion*s['Price'])/(s['Z']*HODL_portion*s['Price'] + HODL_Ext_Hold * s['P_Ext_Markets']) + if s['Price'] < 1/HODL_belief*(theta*HODL_Ext_Hold * s['P_Ext_Markets'])/(s['Z']*HODL_portion*(1-theta)): + return beta * theta*HODL_Ext_Hold * s['P_Ext_Markets']/(s['Price']*HODL_portion*(1-theta)) + elif s['Price'] > (theta*HODL_Ext_Hold * s['P_Ext_Markets'])/(s['Z']*HODL_portion*(1-theta)): + return 0 + else: + return 0 + + +# BEHAVIOR 2: Withdraw TDR and burn Zeus +# Selling Agent- Arbitrage on TDR ext v TDR int signals +# def b2m1(step, sL, s): +# Psignal_ext = s['P_Ext_Markets'] / s['Z'] +# Psignal_int = s['Buy_Log'] / s['Z'] +# if Psignal_ext > Psignal_int: +# # withdrawn amount in TDR, subject to TDR limit +# return - np.minimum(beta*(Psignal_ext - Psignal_int) * s['Z'],s['Buy_Log']*max_withdraw_factor) +# else: +# return 0 #- Decimal(0.000001) + # return 0 + +# BEHAVIOR 1: Deposit TDR and mint Zeus +# Buying Agent- Arbitrage on Price and Z signals +# def b1m2(step, sL, s): +# # Psignal_ext = s['P_Ext_Markets'] / s['Z'] +# # Psignal_int = s['Buy_Log'] / s['Z'] +# # if Psignal_ext > Psignal_int: +# # # withdrawn amount in TDR, subject to TDR limit +# # return - np.minimum(beta*(Psignal_ext - Psignal_int) * s['Z'],s['Buy_Log']*max_withdraw_factor) +# # else: +# # return 0 #- Decimal(0.000001) +# # +# # LT more valuable than ST = deposit TDR and mint Z +# Psignal_LT = s['Price'] / s['Z'] +# if Psignal_LT > 1: +# return beta_LT*(Psignal_LT - 1) * s['Z'] +# else: +# return 0 + +# Behavior will go here- b2m2, putting in mech 3: b1m3 for debugging +# def b2m2(step, sL, s): +# # Psignal_LT = s['Price'] / s['Z'] +# # if Psignal_LT > 1: +# test = np.arange(1,10) +# return test + +# Selling Agent- Arbitrage on Price and Z signals +# def b1m3(step, sL, s): +# Psignal_LT = s['Price'] / s['Z'] +# if Psignal_LT < 1: +# return - np.minimum(beta_LT*(Psignal_LT - 1) * s['Z'], s['Z']*max_withdraw_factor) +# else: +# return 0 + + +# def b2m3(step, sL, s): +# return 0 + +def dummy_behavior(step, sL, s): + return 0 +def s1_dummy(step, sL, s, _input): + y = 'Z' + x = s['Z'] + return (y, x) +def s2_dummy(step, sL, s, _input): + y = 'Price' + x = s['Price'] + return (y, x) +def s3_dummy(step, sL, s, _input): + y = 'Buy_Log' + x = s['Buy_Log'] + return (y, x) +def s4_dummy(step, sL, s, _input): + y = 'Sell_Log' + x = s['Sell_Log'] + return (y, x) +def s5_dummy(step, sL, s, _input): + y = 'Trans' + x = s['Trans'] + return (y, x) +def s6_dummy(step, sL, s, _input): + y = 'P_Ext_Markets' + x = s['P_Ext_Markets'] + return (y, x) +# Internal States per Mechanism +# Deposit TDR/Mint Zeus +# def s1m1(step, sL, s, _input): +# s['Z'] = s['Z'] + _input + + +# STATES + +# ZEUS Fixed Supply +def s1m1(step, sL, s, _input): + y = 'Z' + x = s['Z'] #+ _input # / Psignal_int + return (y, x) + +def s2m1(step, sL, s, _input): + y = 'Price' + x = (s['P_Ext_Markets'] - _input) /s['Z'] *10000 + #x= alpha * s['Z'] + (1 - alpha)*s['Price'] + return (y, x) + +def s3m1(step, sL, s, _input): + y = 'Buy_Log' + x = _input # / Psignal_int + return (y, x) + +def s4m2(step, sL, s, _input): + y = 'Sell_Log' + x = _input # / Psignal_int + print('s4m2 ',type(_input)) + return (y, x) + +def s3m3(step, sL, s, _input): + y = 'Buy_Log' + x = s['Buy_Log'] + _input # / Psignal_int + return (y, x) + +# Price Update +def s2m3(step, sL, s, _input): + print('s2m3 ') + print(type(s['Sell_Log'])) + print(type(s['Z'])) + + y = 'Price' + x = s['Price'] + s['Buy_Log']/s['Z'] - s['Sell_Log']/s['Z'] + #+ np.divide(s['Buy_Log'],s['Z']) - np.divide() # / Psignal_int + return (y, x) + + + +def s6m1(step, sL, s, _input): + y = 'P_Ext_Markets' + x = s['P_Ext_Markets'] - _input + #x= alpha * s['Z'] + (1 - alpha)*s['Price'] + return (y, x) + +def s2m2(step, sL, s, _input): + y = 'Price' + x = (s['P_Ext_Markets'] - _input) /s['Z'] *10000 + #x= alpha * s['Z'] + (1 - alpha)*s['Price'] + return (y, x) + +# def s1m1(step, sL, s, _input): +# Psignal_int = s['Buy_Log'] / s['Z'] +# y = 'Z' +# x = s['Z'] + _input / Psignal_int +# return (y, x) + +# def s2m1(step, sL, s, _input): +# y = 'Price' +# x= alpha * s['Z'] + (1 - alpha)*s['Price'] +# return (y, x) + +# def s3m1(step, sL, s, _input): +# y = 'Buy_Log' +# x = s['Buy_Log'] + _input # Input already in TDR * s['Z'] +# return (y, x) + +# # Withdraw TDR/Burn Zeus +# def s1m2(step, sL, s, _input): +# Psignal_int = s['Buy_Log'] / s['Z'] +# y = 'Z' +# x = s['Z'] #+ _input / Psignal_int +# return (y, x) + +# def s2m2(step, sL, s, _input): +# y = 'Price' +# x= alpha * s['Z'] + (1 - alpha)*s['Price'] +# return (y, x) + +# def s3m2(step, sL, s, _input): +# y = 'Buy_Log' +# x = s['Buy_Log'] + _input #* s['Z'] +# # y = 'Buy_Log' +# # x = s['Buy_Log'] + _input +# return (y, x) + +# def s1m3(step, sL, s, _input): +# Psignal_int = s['Buy_Log'] / s['Z'] +# y = 'Z' +# x = s['Z'] #+ _input / Psignal_int +# return (y, x) + +# def s2m3(step, sL, s, _input): +# y = 'Price' +# x= alpha * s['Z'] + (1 - alpha)*s['Price'] +# return (y, x) + +# def s3m3(step, sL, s, _input): +# y = 'Buy_Log' +# x = s['Buy_Log'] #+ _input #* s['Z'] +# # y = 'Buy_Log' +# # x = s['Buy_Log'] + _input +# return (y, x) + +# def s3m4(step, sL, s, _input): +# y = 'Buy_Log' +# x = s['Buy_Log']*(1-external_draw) + s['Sell_Log']*external_draw # _input #* s['Z'] +# # y = 'Buy_Log' +# # x = s['Buy_Log'] + _input +# return (y, x) + +# def s1m3(step, sL, s, _input): +# s['Z'] = s['Z'] + _input +# def s2m3(step, sL, s, _input): +# s['Price'] = s['Price'] + _input + +# Exogenous States +proc_one_coef_A = -125 +proc_one_coef_B = 125 +# def es3p1(step, sL, s, _input): +# s['s3'] = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) +# def es4p2(step, sL, s, _input): +# s['P_Ext_Markets'] = s['P_Ext_Markets'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) +# def es5p2(step, sL, s, _input): # accept timedelta instead of timedelta params +# s['timestamp'] = ep_time_step(s, s['timestamp'], seconds=1) +def es3p1(step, sL, s, _input): + y = 's3' + x = s['s3'] + 1 + return (y, x) +# def es4p2(step, sL, s, _input): +# y = 'P_Ext_Markets' +# # bound_norm_random defined in utils.py + +# #x = s['P_Ext_Markets'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) +# expected_change = correction_factor*(s['P_Ext_Markets']-s['Buy_Log']) +# vol = np.random.randint(1,volatility) +# change = expected_change * vol +# # change_float = (np.random.normal(expected_change,volatility*expected_change) #Decimal('1.0') +# #change = Decimal.from_float(change_float) +# x = s['P_Ext_Markets'] + change + +# return (y, x) + +# A change in belief of actual price, passed onto behaviors to make action +def es4p2(step, sL, s, _input): + y = 'P_Ext_Markets' + x = s['P_Ext_Markets'] + bound_norm_random(seed['z'], proc_one_coef_A, proc_one_coef_B) + + return (y,x) + + +def es5p2(step, sL, s, _input): # accept timedelta instead of timedelta params + y = 'timestamp' + x = ep_time_step(s, s['timestamp'], seconds=1) + return (y, x) +#Environment States +# def stochastic(reference, seed, correction = 0.01): +# series = np.zeros(len(reference)) +# series[0] = reference[0] +# for i in range(1,len(reference)): +# expected_change = correction*(reference[i]-series[i-1]) +# normalized_expected_change = np.abs(expected_change)*(reference[i])/(reference[i-1]) +# seed_int = seed.randint(1,10) +# change = np.random.normal(expected_change,seed_int*normalized_expected_change) + +# series[i] = series[i-1]+change +# # avoid negative series returns +# if series[i] <= 0: +# series[i] = .01 +# #series[i] = series[i-1]+change + +# return [series,seed_int] +# ref3 = np.arange(1,1000)*.1 +# test = stochastic(ref3,seed['b']) + +# def env_a(ref3,seed['b']): +# return stochastic(ref3,seed['b']) +def env_a(x): + return 100 +def env_b(x): + return 21000000 +# def what_ever(x): +# return x + 1 + +# Genesis States +state_dict = { + 'Z': Decimal(21000000.0), + 'Price': Decimal(100.0), # Initialize = Z for EMA + 'Buy_Log': Decimal(0.0), + 'Sell_Log': Decimal(0.0), + 'Trans': Decimal(0.0), + 'P_Ext_Markets': Decimal(25000.0), + + # 's2': Decimal(0.0), + # 's3': Decimal(0.0), + # 's4': Decimal(0.0), + 'timestamp': '2018-10-01 15:16:24' +} + +# exogenous_states = { +# # "s3": es3p1, +# "P_Ext_Markets": es4p2, +# "timestamp": es5p2 +# } + +exogenous_states = exo_update_per_ts( + { + # "s3": es3p1, + "P_Ext_Markets": es4p2, + "timestamp": es5p2 + } +) + +env_processes = { + # "s3": env_proc('2018-10-01 15:16:25', env_a), +# "P_Ext_Markets": env_proc('2018-10-01 15:16:25', env_b) +} + +# test return vs. non-return functions as lambdas +# test fully defined functions +mechanisms = { + "m1": { + "behaviors": { + "b1": b1m1, # lambda step, sL, s: s['s1'] + 1, +# "b2": b2m1 + }, + "states": { + "Z": s1m1, + "Price": s2_dummy, + "Buy_Log": s3m1, + "Sell_Log":s4_dummy, + "Trans": s5_dummy, + "P_Ext_Markets": s6_dummy + } + }, + "m2": { + "behaviors": { + "b1": b1m2, + "b4": b4m2 + }, + "states": { + "Z": s1_dummy, + "Price": s2_dummy, + "Buy_Log": s3_dummy, + "Sell_Log":s4m2, + "Trans": s5_dummy, + "P_Ext_Markets": s6_dummy + } + }, + "m3": { + "behaviors": { +# "b1": b1m2, +# "b4": b4m2 + }, + "states": { + "Z": s1_dummy, + "Price": s2m3, + "Buy_Log": s3_dummy, + "Sell_Log":s4_dummy, + "Trans": s5_dummy, + "P_Ext_Markets": s6_dummy + } + }, +# "m3": { +# "behaviors": { +# "b1": b1m3, +# "b2": b2m3 +# }, +# "states": { +# "Z": s1m3, +# "Price": s2m3, +# "Buy_Log": s3m3, +# "Sell_Log": s4_dummy, +# "Trans": s5_dummy, +# "P_Ext_Markets": s6_dummy +# } +# }, +# "m4": { +# "behaviors": { +# "dummy": dummy_behavior +# }, +# "states": { +# "Z": s1_dummy, +# "Price": s2_dummy, +# "Buy_Log": s3m4, +# "Sell_Log": s4_dummy, +# "Trans": s5_dummy, +# "P_Ext_Markets": s6_dummy +# } +# }, + # "m3": { + # "behaviors": { + # "b1": b1m3, + # "b2": b2m3 + # }, + # "states": { + # "Z": s1m3, + # "Price": s2m3, + # } + # } + #treat environmental processes as a mechanism + "ep": { + "behaviors": { + "dummy": dummy_behavior + }, + "states": { + "Z": s1_dummy, + "Price": s2_dummy, + "Buy_Log": s3_dummy, + "Sell_Log": s4_dummy, + "Trans": s5_dummy, + "P_Ext_Markets": es4p2 + } + } +} + +sim_config = { + "N": 1, + "T": range(1000) +} + +configs.append(Configuration(sim_config, state_dict, seed, exogenous_states, env_processes, mechanisms)) diff --git a/simulations/scrapbox/config8c.py b/simulations/scrapbox/config8c.py new file mode 100644 index 0000000..2eecf45 --- /dev/null +++ b/simulations/scrapbox/config8c.py @@ -0,0 +1,443 @@ +from decimal import Decimal +import numpy as np + +from SimCAD import Configuration, configs +from SimCAD.configuration import exo_update_per_ts, bound_norm_random, \ + ep_time_step + +# behavior_ops = [] +# behavior_ops = [foldr(dict_elemwise_sum())] + +seed = { + 'z': np.random.RandomState(1) + # 'a': np.random.RandomState(2), + # 'b': np.random.RandomState(3), + # 'c': np.random.RandomState(3) +} + +#Signals +# Pr_signal +#if s['P_Ext_Markets'] != 0: +#Pr_signal = s['Z']/s['P_Ext_Markets'] +#else Pr_signal = 0 +# if Pr_signal < s['Z']/s['Buy_Log']: +beta = Decimal('0.25') #agent response gain +beta_LT = Decimal('0.1') #LT agent response gain +alpha = Decimal('0.091') #21 day EMA forgetfullness between 0 and 1, closer to 1 discounts older obs quicker, should be 2/(N+1) +max_withdraw_factor = Decimal('0.9') +external_draw = Decimal('0.01') # between 0 and 1 to draw Buy_Log to external + +# Stochastic process factors +correction_factor = Decimal('0.01') +volatility = Decimal('5.0') + + +# Buy_Log_signal = +# Z_signal = +# Price_signal = +# TDR_draw_signal = +# P_Ext_Markets_signal = + +# Behaviors per Mechanism + +# BEHAVIOR 1: EMH Trader +EMH_portion = Decimal('0.250') +EMH_Ext_Hold = Decimal('42000.0') + +def b1m1(step, sL, s): + print('b1m1') + # y = 'P_Ext_Markets' + # Psignal_ext = s['P_Ext_Markets'] / s['Z'] + # Psignal_int = s['Buy_Log'] / s['Z'] + # if Psignal_ext < Psignal_int: + # return beta*(Psignal_int - Psignal_ext) * s['Z'] # Deposited amount in TDR + # else: + # return 0 # Decimal(0.000001) + # return (y,x) + theta = (s['Z']*EMH_portion*s['Price'])/(s['Z']*EMH_portion*s['Price'] + EMH_Ext_Hold * s['P_Ext_Markets']) + if s['Price'] < (theta*EMH_Ext_Hold * s['P_Ext_Markets'])/(s['Z']*EMH_portion*(1-theta)): + buy = beta * theta*EMH_Ext_Hold * s['P_Ext_Markets']/(s['Price']*EMH_portion*(1-theta)) + return {'buy_order1': buy} + elif s['Price'] > (theta*EMH_Ext_Hold * s['P_Ext_Markets'])/(s['Z']*EMH_portion*(1-theta)): + return {'buy_order1': 0} + else: + return {'buy_order1': 0} + +def b1m2(step, sL, s): + print('b1m2') + theta = (s['Z']*EMH_portion*s['Price'])/(s['Z']*EMH_portion*s['Price'] + EMH_Ext_Hold * s['P_Ext_Markets']) + if s['Price'] < (theta*EMH_Ext_Hold * s['P_Ext_Markets'])/(s['Z']*EMH_portion*(1-theta)): + return {'sell_order1': 0} + elif s['Price'] > (theta*EMH_Ext_Hold * s['P_Ext_Markets'])/(s['Z']*EMH_portion*(1-theta)): + sell = beta * theta*EMH_Ext_Hold * s['P_Ext_Markets']/(s['Price']*EMH_portion*(1-theta)) + return {'sell_order1': sell} + else: + return {'sell_order1': 0} + +# BEHAVIOR 3: Herding + + +# BEHAVIOR 4: HODLers +HODL_belief = Decimal('10.0') +HODL_portion = Decimal('0.250') +HODL_Ext_Hold = Decimal('4200.0') + +def b4m2(step, sL, s): + print('b4m2') + theta = (s['Z']*HODL_portion*s['Price'])/(s['Z']*HODL_portion*s['Price'] + HODL_Ext_Hold * s['P_Ext_Markets']) + if s['Price'] < 1/HODL_belief*(theta*HODL_Ext_Hold * s['P_Ext_Markets'])/(s['Z']*HODL_portion*(1-theta)): + sell = beta * theta*HODL_Ext_Hold * s['P_Ext_Markets']/(s['Price']*HODL_portion*(1-theta)) + return {'sell_order2': sell} + elif s['Price'] > (theta*HODL_Ext_Hold * s['P_Ext_Markets'])/(s['Z']*HODL_portion*(1-theta)): + return {'sell_order2': 0} + else: + return {'sell_order2': 0} + + +# BEHAVIOR 2: Withdraw TDR and burn Zeus +# Selling Agent- Arbitrage on TDR ext v TDR int signals +# def b2m1(step, sL, s): +# Psignal_ext = s['P_Ext_Markets'] / s['Z'] +# Psignal_int = s['Buy_Log'] / s['Z'] +# if Psignal_ext > Psignal_int: +# # withdrawn amount in TDR, subject to TDR limit +# return - np.minimum(beta*(Psignal_ext - Psignal_int) * s['Z'],s['Buy_Log']*max_withdraw_factor) +# else: +# return 0 #- Decimal(0.000001) + # return 0 + +# BEHAVIOR 1: Deposit TDR and mint Zeus +# Buying Agent- Arbitrage on Price and Z signals +# def b1m2(step, sL, s): +# # Psignal_ext = s['P_Ext_Markets'] / s['Z'] +# # Psignal_int = s['Buy_Log'] / s['Z'] +# # if Psignal_ext > Psignal_int: +# # # withdrawn amount in TDR, subject to TDR limit +# # return - np.minimum(beta*(Psignal_ext - Psignal_int) * s['Z'],s['Buy_Log']*max_withdraw_factor) +# # else: +# # return 0 #- Decimal(0.000001) +# # +# # LT more valuable than ST = deposit TDR and mint Z +# Psignal_LT = s['Price'] / s['Z'] +# if Psignal_LT > 1: +# return beta_LT*(Psignal_LT - 1) * s['Z'] +# else: +# return 0 + +# Behavior will go here- b2m2, putting in mech 3: b1m3 for debugging +# def b2m2(step, sL, s): +# # Psignal_LT = s['Price'] / s['Z'] +# # if Psignal_LT > 1: +# test = np.arange(1,10) +# return test + +# Selling Agent- Arbitrage on Price and Z signals +# def b1m3(step, sL, s): +# Psignal_LT = s['Price'] / s['Z'] +# if Psignal_LT < 1: +# return - np.minimum(beta_LT*(Psignal_LT - 1) * s['Z'], s['Z']*max_withdraw_factor) +# else: +# return 0 + + +# def b2m3(step, sL, s): +# return 0 + +# Internal States per Mechanism +# Deposit TDR/Mint Zeus +# def s1m1(step, sL, s, _input): +# s['Z'] = s['Z'] + _input + + +# STATES + +# ZEUS Fixed Supply +def s1m1(step, sL, s, _input): + y = 'Z' + x = s['Z'] #+ _input # / Psignal_int + return (y, x) + +def s2m1(step, sL, s, _input): + y = 'Price' + x = (s['P_Ext_Markets'] - _input['buy_order1']) /s['Z'] *10000 + #x= alpha * s['Z'] + (1 - alpha)*s['Price'] + return (y, x) + +def s3m1(step, sL, s, _input): + y = 'Buy_Log' + x = _input['buy_order1'] # / Psignal_int + return (y, x) + +def s4m2(step, sL, s, _input): + y = 'Sell_Log' + x = _input['sell_order1'] + _input['sell_order2'] # / Psignal_int + return (y, x) + +def s3m3(step, sL, s, _input): + y = 'Buy_Log' + x = s['Buy_Log'] + _input # / Psignal_int + return (y, x) + +# Price Update +def s2m3(step, sL, s, _input): + + y = 'Price' + #var1 = Decimal.from_float(s['Buy_Log']) + x = s['Price'] + s['Buy_Log'] * 1/s['Z'] - s['Sell_Log']/s['Z'] + #+ np.divide(s['Buy_Log'],s['Z']) - np.divide() # / Psignal_int + return (y, x) + + + +def s6m1(step, sL, s, _input): + y = 'P_Ext_Markets' + x = s['P_Ext_Markets'] - _input + #x= alpha * s['Z'] + (1 - alpha)*s['Price'] + return (y, x) + +def s2m2(step, sL, s, _input): + y = 'Price' + x = (s['P_Ext_Markets'] - _input) /s['Z'] *10000 + #x= alpha * s['Z'] + (1 - alpha)*s['Price'] + return (y, x) + +# def s1m1(step, sL, s, _input): +# Psignal_int = s['Buy_Log'] / s['Z'] +# y = 'Z' +# x = s['Z'] + _input / Psignal_int +# return (y, x) + +# def s2m1(step, sL, s, _input): +# y = 'Price' +# x= alpha * s['Z'] + (1 - alpha)*s['Price'] +# return (y, x) + +# def s3m1(step, sL, s, _input): +# y = 'Buy_Log' +# x = s['Buy_Log'] + _input # Input already in TDR * s['Z'] +# return (y, x) + +# # Withdraw TDR/Burn Zeus +# def s1m2(step, sL, s, _input): +# Psignal_int = s['Buy_Log'] / s['Z'] +# y = 'Z' +# x = s['Z'] #+ _input / Psignal_int +# return (y, x) + +# def s2m2(step, sL, s, _input): +# y = 'Price' +# x= alpha * s['Z'] + (1 - alpha)*s['Price'] +# return (y, x) + +# def s3m2(step, sL, s, _input): +# y = 'Buy_Log' +# x = s['Buy_Log'] + _input #* s['Z'] +# # y = 'Buy_Log' +# # x = s['Buy_Log'] + _input +# return (y, x) + +# def s1m3(step, sL, s, _input): +# Psignal_int = s['Buy_Log'] / s['Z'] +# y = 'Z' +# x = s['Z'] #+ _input / Psignal_int +# return (y, x) + +# def s2m3(step, sL, s, _input): +# y = 'Price' +# x= alpha * s['Z'] + (1 - alpha)*s['Price'] +# return (y, x) + +# def s3m3(step, sL, s, _input): +# y = 'Buy_Log' +# x = s['Buy_Log'] #+ _input #* s['Z'] +# # y = 'Buy_Log' +# # x = s['Buy_Log'] + _input +# return (y, x) + +# def s3m4(step, sL, s, _input): +# y = 'Buy_Log' +# x = s['Buy_Log']*(1-external_draw) + s['Sell_Log']*external_draw # _input #* s['Z'] +# # y = 'Buy_Log' +# # x = s['Buy_Log'] + _input +# return (y, x) + +# def s1m3(step, sL, s, _input): +# s['Z'] = s['Z'] + _input +# def s2m3(step, sL, s, _input): +# s['Price'] = s['Price'] + _input + +# Exogenous States +proc_one_coef_A = -125 +proc_one_coef_B = 125 +# def es3p1(step, sL, s, _input): +# s['s3'] = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) +# def es4p2(step, sL, s, _input): +# s['P_Ext_Markets'] = s['P_Ext_Markets'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) +# def es5p2(step, sL, s, _input): # accept timedelta instead of timedelta params +# s['timestamp'] = ep_time_step(s, s['timestamp'], seconds=1) +def es3p1(step, sL, s, _input): + y = 's3' + x = s['s3'] + 1 + return (y, x) +# def es4p2(step, sL, s, _input): +# y = 'P_Ext_Markets' +# # bound_norm_random defined in utils.py + +# #x = s['P_Ext_Markets'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) +# expected_change = correction_factor*(s['P_Ext_Markets']-s['Buy_Log']) +# vol = np.random.randint(1,volatility) +# change = expected_change * vol +# # change_float = (np.random.normal(expected_change,volatility*expected_change) #Decimal('1.0') +# #change = Decimal.from_float(change_float) +# x = s['P_Ext_Markets'] + change + +# return (y, x) + +# A change in belief of actual price, passed onto behaviors to make action +def es4p2(step, sL, s, _input): + y = 'P_Ext_Markets' + x = s['P_Ext_Markets'] + bound_norm_random(seed['z'], proc_one_coef_A, proc_one_coef_B) + + return (y,x) + + +def es5p2(step, sL, s, _input): # accept timedelta instead of timedelta params + y = 'timestamp' + x = ep_time_step(s, s['timestamp'], seconds=1) + return (y, x) +#Environment States +# def stochastic(reference, seed, correction = 0.01): +# series = np.zeros(len(reference)) +# series[0] = reference[0] +# for i in range(1,len(reference)): +# expected_change = correction*(reference[i]-series[i-1]) +# normalized_expected_change = np.abs(expected_change)*(reference[i])/(reference[i-1]) +# seed_int = seed.randint(1,10) +# change = np.random.normal(expected_change,seed_int*normalized_expected_change) + +# series[i] = series[i-1]+change +# # avoid negative series returns +# if series[i] <= 0: +# series[i] = .01 +# #series[i] = series[i-1]+change + +# return [series,seed_int] +# ref3 = np.arange(1,1000)*.1 +# test = stochastic(ref3,seed['b']) + +# def env_a(ref3,seed['b']): +# return stochastic(ref3,seed['b']) +def env_a(x): + return 100 +def env_b(x): + return 21000000 +# def what_ever(x): +# return x + 1 + +# Genesis States +state_dict = { + 'Z': Decimal(21000000.0), + 'Price': Decimal(100.0), # Initialize = Z for EMA + 'Buy_Log': Decimal(0.0), + 'Sell_Log': Decimal(0.0), + 'Trans': Decimal(0.0), + 'P_Ext_Markets': Decimal(25000.0), + + # 's2': Decimal(0.0), + # 's3': Decimal(0.0), + # 's4': Decimal(0.0), + 'timestamp': '2018-10-01 15:16:24' +} + +# exogenous_states = { +# # "s3": es3p1, +# "P_Ext_Markets": es4p2, +# "timestamp": es5p2 +# } + +exogenous_states = exo_update_per_ts( + { + # "s3": es3p1, + "P_Ext_Markets": es4p2, + "timestamp": es5p2 + } +) + +env_processes = { + # "s3": env_proc('2018-10-01 15:16:25', env_a), +# "P_Ext_Markets": env_proc('2018-10-01 15:16:25', env_b) +} + +# test return vs. non-return functions as lambdas +# test fully defined functions +mechanisms = { + "m1": { + "behaviors": { + "b1": b1m1, # lambda step, sL, s: s['s1'] + 1, +# "b2": b2m1 + }, + "states": { + "Z": s1m1, +# "Price": s2_dummy, + "Buy_Log": s3m1, + } + }, + "m2": { + "behaviors": { + "b1": b1m2, + "b4": b4m2 + }, + "states": { + "Sell_Log":s4m2, + } + }, + "m3": { + "behaviors": { + }, + "states": { + "Price": s2m3, + } + }, +# "m3": { +# "behaviors": { +# "b1": b1m3, +# "b2": b2m3 +# }, +# "states": { +# "Z": s1m3, +# "Price": s2m3, +# "Buy_Log": s3m3, +# } +# }, +# "m4": { +# "behaviors": { +# }, +# "states": { +# } +# }, + # "m3": { + # "behaviors": { + # "b1": b1m3, + # "b2": b2m3 + # }, + # "states": { + # "Z": s1m3, + # "Price": s2m3, + # } + # } + #treat environmental processes as a mechanism + "ep": { + "behaviors": { + }, + "states": { + "P_Ext_Markets": es4p2 + } + } +} + +sim_config = { + "N": 1, + "T": range(1000) +} + +configs.append(Configuration(sim_config, state_dict, seed, exogenous_states, env_processes, mechanisms)) \ No newline at end of file diff --git a/simulations/validation/base_config1.py b/simulations/validation/base_config1.py new file mode 100644 index 0000000..3bf83ba --- /dev/null +++ b/simulations/validation/base_config1.py @@ -0,0 +1,171 @@ +from decimal import Decimal +import numpy as np +from datetime import timedelta + +from SimCAD import configs +from SimCAD.configuration import Configuration +from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ + ep_time_step + +seed = { + 'z': np.random.RandomState(1), + 'a': np.random.RandomState(2), + 'b': np.random.RandomState(3), + 'c': np.random.RandomState(3) +} + +# Behaviors per Mechanism +# Different return types per mechanism ?? *** No *** +def b1m1(step, sL, s): + return {'param1': 1} +def b2m1(step, sL, s): + return {'param1': 1} + +def b1m2(step, sL, s): + return {'param1': 1, 'param2': 2} +def b2m2(step, sL, s): + return {'param1': 1, 'param2': 4} + +def b1m3(step, sL, s): + return {'param1': 1, 'param2': np.array([10, 100])} +def b2m3(step, sL, s): + return {'param1': 1, 'param2': np.array([20, 200])} + +# deff not more than 2 +# Internal States per Mechanism +def s1m1(step, sL, s, _input): + y = 's1' + x = s['s1'] + _input['param1'] + return (y, x) +def s2m1(step, sL, s, _input): + y = 's2' + x = s['s2'] + _input['param1'] + return (y, x) + +def s1m2(step, sL, s, _input): + y = 's1' + x = s['s1'] + _input['param1'] + return (y, x) +def s2m2(step, sL, s, _input): + y = 's2' + x = s['s2'] + _input['param1'] + return (y, x) + +def s1m3(step, sL, s, _input): + y = 's1' + x = s['s1'] + _input['param1'] + return (y, x) +def s2m3(step, sL, s, _input): + y = 's2' + x = s['s2'] + _input['param1'] + return (y, x) + +# Exogenous States +proc_one_coef_A = 0.7 +proc_one_coef_B = 1.3 + +def es3p1(step, sL, s, _input): + y = 's3' + x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) + return (y, x) + +def es4p2(step, sL, s, _input): + y = 's4' + x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) + return (y, x) + +ts_format = '%Y-%m-%d %H:%M:%S' +t_delta = timedelta(days=0, minutes=0, seconds=1) +def es5p2(step, sL, s, _input): + y = 'timestamp' + x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) + return (y, x) + + +# Environment States +def env_a(x): + return 10 +def env_b(x): + return 10 +# def what_ever(x): +# return x + 1 + +# Genesis States +genesis_states = { + 's1': Decimal(0.0), + 's2': Decimal(0.0), + 's3': Decimal(1.0), + 's4': Decimal(1.0), + 'timestamp': '2018-10-01 15:16:24' +} + +# remove `exo_update_per_ts` to update every ts +exogenous_states = exo_update_per_ts( + { + "s3": es3p1, + "s4": es4p2, + "timestamp": es5p2 + } +) + +# make env proc trigger field agnostic + +# ToDo: Bug - Can't use environments without proc_trigger. TypeError: 'int' object is not callable +# "/Users/jjodesty/Projects/DiffyQ-SimCAD/SimCAD/engine/simulation.py" +env_processes = { + # "s3": env_a, + # "s4": env_b + "s3": proc_trigger('2018-10-01 15:16:25', env_a), + "s4": proc_trigger('2018-10-01 15:16:25', env_b) +} + +# need at least 1 behaviour and 1 state function for the 1st mech with behaviors +# mechanisms = {} +mechanisms = { + "m1": { + "behaviors": { + "b1": b1m1, # lambda step, sL, s: s['s1'] + 1, + "b2": b2m1 + }, + "states": { # exclude only. TypeError: reduce() of empty sequence with no initial value + "s1": s1m1, + "s2": s2m1 + } + }, + "m2": { + "behaviors": { + "b1": b1m2, + "b2": b2m2 + }, + "states": { + "s1": s1m2, + "s2": s2m2 + } + }, + "m3": { + "behaviors": { + "b1": b1m3, + "b2": b2m3 + }, + "states": { + "s1": s1m3, + "s2": s2m3 + } + } +} + +sim_config = { + "N": 2, + "T": range(5) +} + +configs.append( + Configuration( + sim_config=sim_config, + state_dict=genesis_states, + seed=seed, + exogenous_states=exogenous_states, + env_processes=env_processes, + mechanisms=mechanisms + ) +) \ No newline at end of file diff --git a/simulations/validation/base_config2.py b/simulations/validation/base_config2.py new file mode 100644 index 0000000..6b9469e --- /dev/null +++ b/simulations/validation/base_config2.py @@ -0,0 +1,180 @@ +from decimal import Decimal +import numpy as np +from datetime import timedelta + +from SimCAD import configs +from SimCAD.configuration import Configuration +from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ + ep_time_step + + +seed = { + 'z': np.random.RandomState(1), + 'a': np.random.RandomState(2), + 'b': np.random.RandomState(3), + 'c': np.random.RandomState(3) +} + +# Behaviors per Mechanism +# Different return types per mechanism ?? *** No *** +def b1m1(step, sL, s): + return {'param1': 1} +def b2m1(step, sL, s): + return {'param2': 4} + +def b1m2(step, sL, s): + return {'param1': 'a', 'param2': 2} +def b2m2(step, sL, s): + return {'param1': 'b', 'param2': 4} + + +def b1m3(step, sL, s): + return {'param1': ['c'], 'param2': np.array([10, 100])} +def b2m3(step, sL, s): + return {'param1': ['d'], 'param2': np.array([20, 200])} + + +# Internal States per Mechanism +def s1m1(step, sL, s, _input): + y = 's1' + x = _input['param1'] + return (y, x) +def s2m1(step, sL, s, _input): + y = 's2' + x = _input['param2'] + return (y, x) + +def s1m2(step, sL, s, _input): + y = 's1' + x = _input['param1'] + return (y, x) +def s2m2(step, sL, s, _input): + y = 's2' + x = _input['param2'] + return (y, x) + +def s1m3(step, sL, s, _input): + y = 's1' + x = _input['param1'] + return (y, x) +def s2m3(step, sL, s, _input): + y = 's2' + x = _input['param2'] + return (y, x) + +# Exogenous States +proc_one_coef_A = 0.7 +proc_one_coef_B = 1.3 + +def es3p1(step, sL, s, _input): + y = 's3' + x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) + return (y, x) + +def es4p2(step, sL, s, _input): + y = 's4' + x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) + return (y, x) + +ts_format = '%Y-%m-%d %H:%M:%S' +t_delta = timedelta(days=0, minutes=0, seconds=1) +def es5p2(step, sL, s, _input): + y = 'timestamp' + x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) + return (y, x) + + +# Environment States +def env_a(x): + return 10 +def env_b(x): + return 10 +# def what_ever(x): +# return x + 1 + +# Genesis States +genesis_states = { + 's1': Decimal(0.0), + 's2': Decimal(0.0), + 's3': Decimal(1.0), + 's4': Decimal(1.0), + 'timestamp': '2018-10-01 15:16:24' +} + +# remove `exo_update_per_ts` to update every ts +# why `exo_update_per_ts` here instead of `env_processes` +exogenous_states = exo_update_per_ts( + { + "s3": es3p1, + "s4": es4p2, + "timestamp": es5p2 + } +) + +# make env proc trigger field agnostic +env_processes = { + "s3": proc_trigger('2018-10-01 15:16:25', env_a), + "s4": proc_trigger('2018-10-01 15:16:25', env_b) +} + +# lambdas +# genesis Sites should always be there +# [1, 2] +# behavior_ops = [ foldr(_ + _), lambda x: x + 0 ] + + +# [1, 2] = {'b1': ['a'], 'b2', [1]} = +# behavior_ops = [behavior_to_dict, print_fwd, sum_dict_values] +# behavior_ops = [foldr(dict_elemwise_sum())] +# behavior_ops = [] + +# need at least 1 behaviour and 1 state function for the 1st mech with behaviors +# mechanisms = {} +mechanisms = { + "m1": { + "behaviors": { + "b1": b1m1, # lambda step, sL, s: s['s1'] + 1, + # "b2": b2m1 + }, + "states": { # exclude only. TypeError: reduce() of empty sequence with no initial value + "s1": s1m1, + # "s2": s2m1 + } + }, + "m2": { + "behaviors": { + "b1": b1m2, + # "b2": b2m2 + }, + "states": { + "s1": s1m2, + # "s2": s2m2 + } + }, + "m3": { + "behaviors": { + "b1": b1m3, + "b2": b2m3 + }, + "states": { + "s1": s1m3, + "s2": s2m3 + } + } +} + +sim_config = { + "N": 2, + "T": range(5) +} + +configs.append( + Configuration( + sim_config=sim_config, + state_dict=genesis_states, + seed=seed, + exogenous_states=exogenous_states, + env_processes=env_processes, + mechanisms=mechanisms + ) +) \ No newline at end of file diff --git a/simulations/validation/config_1.py b/simulations/validation/config_1.py new file mode 100644 index 0000000..7bdd5ac --- /dev/null +++ b/simulations/validation/config_1.py @@ -0,0 +1,178 @@ +from decimal import Decimal +import numpy as np +from datetime import timedelta + +from SimCAD import configs +from SimCAD.configuration import Configuration +from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ + ep_time_step + +seed = { + 'z': np.random.RandomState(1), + 'a': np.random.RandomState(2), + 'b': np.random.RandomState(3), + 'c': np.random.RandomState(3) +} + +# Behaviors per Mechanism +# Different return types per mechanism ?? *** No *** +def b1m1(step, sL, s): + return {'param1': 1} +def b2m1(step, sL, s): + return {'param2': 4} + +def b1m2(step, sL, s): + return {'param1': 'a', 'param2': 2} +def b2m2(step, sL, s): + return {'param1': 'b', 'param2': 4} + +def b1m3(step, sL, s): + return {'param1': ['c'], 'param2': np.array([10, 100])} +def b2m3(step, sL, s): + return {'param1': ['d'], 'param2': np.array([20, 200])} + +# deff not more than 2 +# Internal States per Mechanism +def s1m1(step, sL, s, _input): + y = 's1' + x = _input['param1'] #+ [Coef1 x 5] + return (y, x) +def s2m1(step, sL, s, _input): + y = 's2' + x = _input['param2'] #+ [Coef2 x 5] + return (y, x) + +def s1m2(step, sL, s, _input): + y = 's1' + x = _input['param1'] + return (y, x) +def s2m2(step, sL, s, _input): + y = 's2' + x = _input['param2'] + return (y, x) + +def s1m3(step, sL, s, _input): + y = 's1' + x = _input['param1'] + return (y, x) +def s2m3(step, sL, s, _input): + y = 's2' + x = _input['param2'] + return (y, x) + +# Exogenous States +proc_one_coef_A = 0.7 +proc_one_coef_B = 1.3 + +def es3p1(step, sL, s, _input): + y = 's3' + x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) + return (y, x) + +def es4p2(step, sL, s, _input): + y = 's4' + x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) + return (y, x) + +ts_format = '%Y-%m-%d %H:%M:%S' +t_delta = timedelta(days=0, minutes=0, seconds=1) +def es5p2(step, sL, s, _input): + y = 'timestamp' + x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) + return (y, x) + + +# Environment States +def env_a(x): + return 5 +def env_b(x): + return 10 +# def what_ever(x): +# return x + 1 + +# Genesis States +genesis_states = { + 's1': Decimal(0.0), + 's2': Decimal(0.0), + 's3': Decimal(1.0), + 's4': Decimal(1.0), + 'timestamp': '2018-10-01 15:16:24' +} + +# remove `exo_update_per_ts` to update every ts +exogenous_states = exo_update_per_ts( + { + "s3": es3p1, + "s4": es4p2, + "timestamp": es5p2 + } +) + +# ToDo: make env proc trigger field agnostic +# ToDo: input json into function renaming __name__ +env_processes = { + "s3": env_a, + "s4": proc_trigger('2018-10-01 15:16:25', env_b) +} + +# lambdas +# genesis Sites should always be there +# [1, 2] +# behavior_ops = [ foldr(_ + _), lambda x: x + 0 ] + +# [1, 2] = {'b1': ['a'], 'b2', [1]} = +# behavior_ops = [ behavior_to_dict, print_fwd, sum_dict_values ] +# behavior_ops = [foldr(dict_elemwise_sum())] +# behavior_ops = [foldr(lambda a, b: a + b)] + +# need at least 1 behaviour and 1 state function for the 1st mech with behaviors +# mechanisms = {} + +mechanisms = { + "m1": { + "behaviors": { + "b1": b1m1, # lambda step, sL, s: s['s1'] + 1, + "b2": b2m1 + }, + "states": { # exclude only. TypeError: reduce() of empty sequence with no initial value + "s1": s1m1, + "s2": s2m1 + } + }, + "m2": { + "behaviors": { + "b1": b1m2, + "b2": b2m2 + }, + "states": { + "s1": s1m2, + "s2": s2m2 + } + }, + "m3": { + "behaviors": { + "b1": b1m3, + "b2": b2m3 + }, + "states": { + "s1": s1m3, + "s2": s2m3 + } + } +} + +sim_config = { + "N": 2, + "T": range(5) +} + +configs.append( + Configuration( + sim_config=sim_config, + state_dict=genesis_states, + seed=seed, + exogenous_states=exogenous_states, + env_processes=env_processes, + mechanisms=mechanisms + ) +) \ No newline at end of file diff --git a/simulations/validation/config_2.py b/simulations/validation/config_2.py new file mode 100644 index 0000000..6b9469e --- /dev/null +++ b/simulations/validation/config_2.py @@ -0,0 +1,180 @@ +from decimal import Decimal +import numpy as np +from datetime import timedelta + +from SimCAD import configs +from SimCAD.configuration import Configuration +from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ + ep_time_step + + +seed = { + 'z': np.random.RandomState(1), + 'a': np.random.RandomState(2), + 'b': np.random.RandomState(3), + 'c': np.random.RandomState(3) +} + +# Behaviors per Mechanism +# Different return types per mechanism ?? *** No *** +def b1m1(step, sL, s): + return {'param1': 1} +def b2m1(step, sL, s): + return {'param2': 4} + +def b1m2(step, sL, s): + return {'param1': 'a', 'param2': 2} +def b2m2(step, sL, s): + return {'param1': 'b', 'param2': 4} + + +def b1m3(step, sL, s): + return {'param1': ['c'], 'param2': np.array([10, 100])} +def b2m3(step, sL, s): + return {'param1': ['d'], 'param2': np.array([20, 200])} + + +# Internal States per Mechanism +def s1m1(step, sL, s, _input): + y = 's1' + x = _input['param1'] + return (y, x) +def s2m1(step, sL, s, _input): + y = 's2' + x = _input['param2'] + return (y, x) + +def s1m2(step, sL, s, _input): + y = 's1' + x = _input['param1'] + return (y, x) +def s2m2(step, sL, s, _input): + y = 's2' + x = _input['param2'] + return (y, x) + +def s1m3(step, sL, s, _input): + y = 's1' + x = _input['param1'] + return (y, x) +def s2m3(step, sL, s, _input): + y = 's2' + x = _input['param2'] + return (y, x) + +# Exogenous States +proc_one_coef_A = 0.7 +proc_one_coef_B = 1.3 + +def es3p1(step, sL, s, _input): + y = 's3' + x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) + return (y, x) + +def es4p2(step, sL, s, _input): + y = 's4' + x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) + return (y, x) + +ts_format = '%Y-%m-%d %H:%M:%S' +t_delta = timedelta(days=0, minutes=0, seconds=1) +def es5p2(step, sL, s, _input): + y = 'timestamp' + x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) + return (y, x) + + +# Environment States +def env_a(x): + return 10 +def env_b(x): + return 10 +# def what_ever(x): +# return x + 1 + +# Genesis States +genesis_states = { + 's1': Decimal(0.0), + 's2': Decimal(0.0), + 's3': Decimal(1.0), + 's4': Decimal(1.0), + 'timestamp': '2018-10-01 15:16:24' +} + +# remove `exo_update_per_ts` to update every ts +# why `exo_update_per_ts` here instead of `env_processes` +exogenous_states = exo_update_per_ts( + { + "s3": es3p1, + "s4": es4p2, + "timestamp": es5p2 + } +) + +# make env proc trigger field agnostic +env_processes = { + "s3": proc_trigger('2018-10-01 15:16:25', env_a), + "s4": proc_trigger('2018-10-01 15:16:25', env_b) +} + +# lambdas +# genesis Sites should always be there +# [1, 2] +# behavior_ops = [ foldr(_ + _), lambda x: x + 0 ] + + +# [1, 2] = {'b1': ['a'], 'b2', [1]} = +# behavior_ops = [behavior_to_dict, print_fwd, sum_dict_values] +# behavior_ops = [foldr(dict_elemwise_sum())] +# behavior_ops = [] + +# need at least 1 behaviour and 1 state function for the 1st mech with behaviors +# mechanisms = {} +mechanisms = { + "m1": { + "behaviors": { + "b1": b1m1, # lambda step, sL, s: s['s1'] + 1, + # "b2": b2m1 + }, + "states": { # exclude only. TypeError: reduce() of empty sequence with no initial value + "s1": s1m1, + # "s2": s2m1 + } + }, + "m2": { + "behaviors": { + "b1": b1m2, + # "b2": b2m2 + }, + "states": { + "s1": s1m2, + # "s2": s2m2 + } + }, + "m3": { + "behaviors": { + "b1": b1m3, + "b2": b2m3 + }, + "states": { + "s1": s1m3, + "s2": s2m3 + } + } +} + +sim_config = { + "N": 2, + "T": range(5) +} + +configs.append( + Configuration( + sim_config=sim_config, + state_dict=genesis_states, + seed=seed, + exogenous_states=exogenous_states, + env_processes=env_processes, + mechanisms=mechanisms + ) +) \ No newline at end of file From 061e60e98c921ee9984489ea82ab0de53dbc2711 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Mon, 7 Jan 2019 20:35:23 -0500 Subject: [PATCH 3/5] LICENSE.txt --- LICENSE.txt | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..b5d9242 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,150 @@ +SOFTWARE LICENSE AGREEMENT + +This Software License Agreement (the “Agreement”) is entered into as of December __ 2018, (the “Effective Date”) between +Dapper Labs, Inc., a Canadian corporation having its principal place of business at 980-350 Howe Street, +Vancouver, BC V6Z 1N9 (“DLI”) and BlockScience, Inc., a California corporation with an address at 471 McAuley Street, +Oakland, CA 94609 (“BlockScience”). This Agreement includes the attached Exhibit A. + +WHEREAS, DLI and BlockScience are parties to that certain Professional Services Agreement dated March 23, 2018 (the +“PSA”), pursuant to which BlockScience performed and is currently performing professional services and other development +work for DLI; + +WHEREAS, as part of BlockScience’s performance under the PSA, BlockScience developed certain “behaviour archetypes” and +“configuration of the Null Model”, which the parties agree are “Work Product” under the PSA; + +WHEREAS, the parties agree that BlockScience’s proprietary SimCAD software tool is considered “Contractor Technology” +under the PSA; and + +WHEREAS, the parties wish to enter into this Agreement to clarify DLI’s rights to use the SimCAD software tool on a +going-forward basis. + +NOW, THEREFORE, for good and valuable consideration, the receipt and sufficiency of which is hereby acknowledged, DLI +and BlockScience agree as follows: + +1. DEFINITIONS + +(a) “Affiliate” means any entity that, directly or indirectly through one or more intermediaries, controls, is +controlled by, or is under common control with, DLI. + +(b) “Documentation” means any manuals, documentation and other supporting materials related to the Software. +Documentation is considered part of the related Software. + +(c) “Intellectual Property Rights” means patent rights (including patent applications and disclosures), copyrights, +trade marks, trade secrets, know-how and any other intellectual property rights recognized in any country or +jurisdiction in the world. + +(d) “Software” means the object and source code versions of BlockScience’s proprietary SimCAD software product more +fully described in Exhibit A. Software includes the applicable Documentation, as well as any Updates. + +(e) “Update” means any bug fix, error correction, patch, modification, enhancement, update, upgrade, replacement, +successor product, new version, new release, or derivative work of or to the Software. + +(f) “Zeus” means the decentralized synchronous computational network developed by DLI, as such name or reference may be +changed from time to time at DLI’s sole discretion. + +2. SOFTWARE LICENSE + +(a) License Grant. BlockScience hereby grants to DLI and its Affiliates a worldwide, non-exclusive, royalty-free, +irrevocable, perpetual license to (i) download, install, use, execute, access, copy, perform, and modify, the Software +in connection with the Zeus project; (ii) distribute and display the Software internally amongst DLI and its Affiliates, +its and their employees, contractors, and agents, subject to the use of reasonable efforts to maintain the confidential +status of the non-public aspects of the Software display; and (iii) create derivative works of the Software in +connection with the Zeus project, provided that any such derivative works may only be used in connection with the Zeus +project. For the sake of clarity, nothing in this Agreement (including, without limitation, this Section 2) will create +any liability to DLI for or restrict DLI’s ability to externally distribute python scripts containing the “input” +configuration files specific to the Zeus project, as well as the notebooks with the resulting “output” data from the +Software, all of which may be distributed, displayed, and shared publicly at DLI’s discretion. + +(b) Ownership; Limited Rights. As between the parties, BlockScience owns and retains all right, title and interest in +and to the Software, and all Intellectual Property Rights therein. DLI’s rights in the Software are limited to those +expressly granted in Section 2(a) and in the PSA. BlockScience reserves all rights and licenses in the Software not +expressly granted to DLI herein and in the PSA. + +(c) Delivery. BlockScience will deliver a copy of the Software and Documentation to DLI on the Effective Date. The +delivery may be made in electronic form, or via hardcopy medium (e.g., a CD). + +(d) Updates. BlockScience will deliver Updates to DLI as and when such Updates become available. The obligation to +deliver Updates will continue for as long as the PSA remains in force; upon termination or expiration of the PSA, +BlockScience’s obligation to provide Updates will automatically terminate. + +(e) Support. BlockScience will provide reasonable technical support for the Software, to help DLI manage any support +issues that arise. The obligation to provide support will continue for as long as the PSA remains in force; upon +termination or expiration of the PSA, BlockScience’s obligation to provide support will automatically terminate. + +3. NO FEES. + +There are no fees owed by DLI for the license granted or the Updates or support provided by BlockScience +pursuant to this Agreement. Each party will bear its own costs and expenses arising out of or relating to its +obligations, efforts and performance under this Agreement. + +4. LIMITED WARRANTY; DISCLAIMER + +(a) Limited Warranty. BlockScience represents and warrants as follows: (i) that it has the right to enter into this +Agreement, and to perform its obligations hereunder, without violating the terms of any other agreement; (ii) that the +Software, and any Updates, do not and will not infringe, violate, or misappropriate the Intellectual Property Rights of +any third party; (iii) that the Software and any Updates do not and will not contain any virus, malware, spyware, trojan +horse, or other malicious code; and (iv) that the Software and each Update will substantially conform to its +Documentation. + +(b) Disclaimer. EXCEPT AS OTHERWISE SET FORTH IN THIS AGREEMENT, BLOCKSCIENCE DISCLAIMS ALL OTHER WARRANTIES, EXPRESS OR +IMPLIED, RELATED TO THE SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR +PURPOSE. + +5. TERM & TERMINATION + +(a) Term. This Agreement begins on the Effective Date, and will continue in effect until one of us terminates it in +accordance with Section 5(b). + +(b) Termination for Breach. Either party may terminate this Agreement if the other party breaches any material term or +condition of this Agreement, and the breaching party fails to cure the breach within thirty (30) days of receiving +written notice of it. + +(c) Survival. Sections 2 through 7 will survive termination or expiration of this Agreement. + +6. INDEMNIFICATION. + +BlockScience will defend, indemnify, and hold DLI harmless from and against any claim, damage, loss, +liability, expense and cost (including, without limitation, reasonable attorneys’ fees) incurred by or brought against +DLI arising out of or related to: (i) any claim that the Software infringes or misappropriates the Intellectual Property +Rights of that third party; or (ii) BlockScience’s breach of its limited warranties in Section 4(a). + +7. GENERAL TERMS + +(a) Entire Agreement; Waiver. This Agreement is the entire understanding of the parties, and supersedes any and all +prior agreements or understandings between the parties as to its subject matter. It may be amended or modified, or +provisions waived, only in a writing signed by both parties. The waiver of a breach of any provision of this Agreement +will not operate or be interpreted as a waiver of any other or subsequent breach. + +(b) Acknowledgement. BlockScience acknowledges and agrees that the “behaviour archetypes” and “configuration of the Null +Model” referenced in the PSA are considered “Work Product” under the PSA. + +(c) Governing Law. This Agreement will be construed, interpreted and applies in accordance with the internal laws of +British Columbia, Canada (excluding its body of law controlling conflicts of law). Any legal action or proceeding +arising under or related to this Agreement will be brought exclusively in the federal or provincial courts located in +Vancouver, British Columbia, and the parties irrevocably consent to personal jurisdiction and venue there. + +(d) Severability. If any provision of this Agreement is held to be invalid or unenforceable for any reason, that +provision will be enforced to the maximum extent permitted by law, and the remaining provisions will continue in full +force and effect. + +(e) Miscellaneous. This Agreement may be executed in one or more counterparts, with the same effect as if the parties +had signed the same document. Each counterpart so executed will be deemed to be an original, and all such counterparts +will be construed together and will constitute one Agreement. The prevailing party in any action or legal proceeding +arising out of this Agreement will be entitled to recover from the other party all reasonable costs and expenses +incurred in connection with such action or proceeding, including reasonable attorneys’ fees and court costs. In the +event of a direct conflict between the terms of this Agreement and the PSA with respect to the DLI’s rights in and to +the Software, the terms of this Agreement will control. + +EXHIBIT A + +SOFTWARE + +Software Name: SimCAD tool + +Software Description: SimCAD is a Monte-Carlo based simulation software package for research, validation, and +Computer Aided Design of economic systems. An economic system is treated as a state based model and defined +through a set of endogenous and exogenous state variables which are updated through mechanisms and +environmental processes, respectively. Behavioral models, which may be deterministic or stochastic, provide the +evolution of the system within the action space of the mechanisms. Simulations can be run with a range of initial +conditions and parameters for states, behaviors, mechanisms, and environmental processes to understand and +visualize network behavior under various conditions. \ No newline at end of file From 54a06a671b7f19cbf5f30ebf20be12de0975a8f1 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Mon, 7 Jan 2019 20:39:42 -0500 Subject: [PATCH 4/5] put back notebooks/test.ipynb --- notebooks/test.ipynb | 78 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 notebooks/test.ipynb diff --git a/notebooks/test.ipynb b/notebooks/test.ipynb new file mode 100644 index 0000000..4814a4a --- /dev/null +++ b/notebooks/test.ipynb @@ -0,0 +1,78 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Simulation Run 2: Pairwise Execution\")\n", + "print()\n", + "multi_proc_ctx = ExecutionContext(exec_mode.multi_proc)\n", + "run2 = Executor(multi_proc_ctx, configs)\n", + "run2_raw_results = run2.main()\n", + "for raw_result in run2_raw_results:\n", + " result = pd.DataFrame(raw_result)\n", + " print(tabulate(result, headers='keys', tablefmt='psql'))\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Simulation Run 1\")\n", + "print()\n", + "single_config = [configs[0]]\n", + "single_proc_ctx = ExecutionContext(exec_mode.single_proc)\n", + "run1 = Executor(single_proc_ctx, single_config)\n", + "run1_raw_result = run1.main()\n", + "result = pd.DataFrame(run1_raw_result)\n", + "result" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "from tabulate import tabulate\n", + "\n", + "from SimCAD.engine import ExecutionMode, ExecutionContext, Executor\n", + "from sandboxUX import config1, config2\n", + "from SimCAD import configs\n", + "\n", + "# ToDo: pass ExecutionContext with execution method as ExecutionContext input\n", + "\n", + "exec_mode = ExecutionMode()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} From 0eeed616e0784073d517fd818d1206f101c96792 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Mon, 7 Jan 2019 20:42:42 -0500 Subject: [PATCH 5/5] put back notebooks/test.ipynb --- notebooks/test.ipynb | 78 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 notebooks/test.ipynb diff --git a/notebooks/test.ipynb b/notebooks/test.ipynb new file mode 100644 index 0000000..4814a4a --- /dev/null +++ b/notebooks/test.ipynb @@ -0,0 +1,78 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Simulation Run 2: Pairwise Execution\")\n", + "print()\n", + "multi_proc_ctx = ExecutionContext(exec_mode.multi_proc)\n", + "run2 = Executor(multi_proc_ctx, configs)\n", + "run2_raw_results = run2.main()\n", + "for raw_result in run2_raw_results:\n", + " result = pd.DataFrame(raw_result)\n", + " print(tabulate(result, headers='keys', tablefmt='psql'))\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Simulation Run 1\")\n", + "print()\n", + "single_config = [configs[0]]\n", + "single_proc_ctx = ExecutionContext(exec_mode.single_proc)\n", + "run1 = Executor(single_proc_ctx, single_config)\n", + "run1_raw_result = run1.main()\n", + "result = pd.DataFrame(run1_raw_result)\n", + "result" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "from tabulate import tabulate\n", + "\n", + "from SimCAD.engine import ExecutionMode, ExecutionContext, Executor\n", + "from sandboxUX import config1, config2\n", + "from SimCAD import configs\n", + "\n", + "# ToDo: pass ExecutionContext with execution method as ExecutionContext input\n", + "\n", + "exec_mode = ExecutionMode()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +}