From d46e9ad2555e65f63278859c7a7bd07601719d57 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Mon, 26 Nov 2018 15:04:15 -0500 Subject: [PATCH] behavior id bug --- .gitignore | 3 +- README.md | 19 ++- SimCAD/__init__.py | 2 +- SimCAD/utils/configProcessor.py | 5 +- SimCAD/utils/configuration.py | 9 +- sandboxUX/config1.py | 3 +- sandboxUX/config2.py | 1 + sandboxUX/config3.py | 218 ++++++++++++++++++++++++++++++++ sandboxUX/sim_test.py | 3 +- 9 files changed, 248 insertions(+), 15 deletions(-) create mode 100644 sandboxUX/config3.py diff --git a/.gitignore b/.gitignore index aae3663..3c4e94a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ ui/__pycache__ SimCAD.egg-info __pycache__ Pipfile -Pipfile.lock \ No newline at end of file +Pipfile.lock +scrapbox/ \ No newline at end of file diff --git a/README.md b/README.md index e32b654..80d7c7d 100644 --- a/README.md +++ b/README.md @@ -34,13 +34,20 @@ Step 2. Import Package & Run: import pandas as pd from tabulate import tabulate -from SimCAD.engine import ExecutionContext, Executor -from sandboxUX import config1, config2 +from SimCAD.engine import ExecutionMode, ExecutionContext, Executor +# from sandboxUX import config1, config2 +from SimCAD import configs + +# ToDo: pass ExecutionContext with execution method as ExecutionContext input + +exec_mode = ExecutionMode() + print("Simulation Run 1") print() -single_config = [config1] -run1 = Executor(ExecutionContext, single_config) +single_config = [configs[0]] +single_proc_ctx = ExecutionContext(exec_mode.single_proc) +run1 = Executor(single_proc_ctx, single_config) run1_raw_result = run1.main() result = pd.DataFrame(run1_raw_result) print(tabulate(result, headers='keys', tablefmt='psql')) @@ -48,8 +55,8 @@ print() print("Simulation Run 2: Pairwise Execution") print() -configs = [config1, config2] -run2 = Executor(ExecutionContext, configs) +multi_proc_ctx = ExecutionContext(exec_mode.multi_proc) +run2 = Executor(multi_proc_ctx, configs) run2_raw_results = run2.main() for raw_result in run2_raw_results: result = pd.DataFrame(raw_result) diff --git a/SimCAD/__init__.py b/SimCAD/__init__.py index 8ba50b2..afb7760 100644 --- a/SimCAD/__init__.py +++ b/SimCAD/__init__.py @@ -4,7 +4,7 @@ from SimCAD.utils.configuration import dict_elemwise_sum configs = [] - +#Configuration(sim_config, state_dict, seed, exogenous_states, env_processes, mechanisms) class Configuration: def __init__(self, sim_config, state_dict, seed, exogenous_states, env_processes, mechanisms, behavior_ops=[foldr(dict_elemwise_sum())]): self.sim_config = sim_config diff --git a/SimCAD/utils/configProcessor.py b/SimCAD/utils/configProcessor.py index d32a43a..254c532 100644 --- a/SimCAD/utils/configProcessor.py +++ b/SimCAD/utils/configProcessor.py @@ -10,8 +10,9 @@ def state_identity(k): return lambda step, sL, s, _input: (k, s[k]) +# fix def b_identity(step, sL, s): - return 0 + return {'identity': 0} def behavior_identity(k): @@ -19,7 +20,7 @@ def behavior_identity(k): def key_filter(mechanisms, keyname): - return [ v[keyname] for k, v in mechanisms.items() ] + return [v[keyname] for k, v in mechanisms.items()] def fillna_with_id_func(identity, df, col): diff --git a/SimCAD/utils/configuration.py b/SimCAD/utils/configuration.py index a134fd4..e01f4bd 100644 --- a/SimCAD/utils/configuration.py +++ b/SimCAD/utils/configuration.py @@ -75,10 +75,15 @@ def foldr_dict_vals(f, d): def sum_dict_values(): return foldr_dict_vals(add) - +# AttributeError: 'int' object has no attribute 'keys' +# config7c @curried def dict_op(f, d1, d2): - + print('d1') + print(d1) + print('d2') + print(d2) + print() def set_base_value(target_dict, source_dict, key): if key not in target_dict: return get_base_value(type(source_dict[key])) diff --git a/sandboxUX/config1.py b/sandboxUX/config1.py index a0ba9df..1f2af9e 100644 --- a/sandboxUX/config1.py +++ b/sandboxUX/config1.py @@ -1,6 +1,5 @@ from decimal import Decimal import numpy as np -from fn.op import foldr from SimCAD import Configuration, configs from SimCAD.utils.configuration import exo_update_per_ts, proc_trigger, bound_norm_random, \ @@ -119,7 +118,7 @@ env_processes = { # [1, 2] = {'b1': ['a'], 'b2', [1]} = # behavior_ops = [ behavior_to_dict, print_fwd, sum_dict_values ] # behavior_ops = [foldr(dict_elemwise_sum())] -# behavior_ops = [] +# behavior_ops = [foldr(lambda a, b: a + b)] # need at least 1 behaviour and 1 state function for the 1st mech with behaviors # mechanisms = {} diff --git a/sandboxUX/config2.py b/sandboxUX/config2.py index 06c66b8..785331e 100644 --- a/sandboxUX/config2.py +++ b/sandboxUX/config2.py @@ -98,6 +98,7 @@ state_dict = { } # 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, diff --git a/sandboxUX/config3.py b/sandboxUX/config3.py new file mode 100644 index 0000000..3b3f2b0 --- /dev/null +++ b/sandboxUX/config3.py @@ -0,0 +1,218 @@ +from decimal import Decimal +import numpy as np + +from SimCAD import Configuration, configs +from SimCAD.utils.configuration import exo_update_per_ts, proc_trigger, bound_norm_random, \ + ep_time_step + +seed = { + 'z': np.random.RandomState(1) +} + +# Signals +# Pr_signal +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') + 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} + + +# 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) + +# Exogenous States +proc_one_coef_A = -125 +proc_one_coef_B = 125 + +# 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 +# NONE + +# 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), + 'timestamp': '2018-10-01 15:16:24' +} + +def env_proc_id(x): + return x + +env_processes = { + "P_Ext_Markets": env_proc_id, + "timestamp": env_proc_id +} + +exogenous_states = exo_update_per_ts( + { + "P_Ext_Markets": es4p2, + "timestamp": es5p2 + } +) + +sim_config = { + "N": 1, + "T": range(1000) +} + +# test return vs. non-return functions as lambdas +# test fully defined functions +mechanisms = { + "m1": { + "behaviors": { + "b1": b1m1 + }, + "states": { + "Z": s1m1, + "Buy_Log": s3m1 + } + }, + # "m2": { + # "behaviors": { + # "b1": b1m2, + # # "b4": b4m2 + # }, + # "states": { + # "Sell_Log": s4m2 + # } + # }, + # "m3": { + # "behaviors": { + # }, + # "states": { + # "Price": s2m3 + # } + # } +} + +configs.append(Configuration(sim_config, state_dict, seed, exogenous_states, env_processes, mechanisms)) \ No newline at end of file diff --git a/sandboxUX/sim_test.py b/sandboxUX/sim_test.py index 714a308..80507f5 100644 --- a/sandboxUX/sim_test.py +++ b/sandboxUX/sim_test.py @@ -2,13 +2,14 @@ import pandas as pd from tabulate import tabulate from SimCAD.engine import ExecutionMode, ExecutionContext, Executor -from sandboxUX import config1, config2 +# from sandboxUX import config1, config2 from SimCAD import configs # ToDo: pass ExecutionContext with execution method as ExecutionContext input exec_mode = ExecutionMode() + print("Simulation Run 1") print() single_config = [configs[0]]