-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsim.py
202 lines (156 loc) · 6.26 KB
/
sim.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
from simulation_util import *
import multiprocessing as mp
import pickle
import os
import argparse
ASSETS = None
RISK = None
def run_on_thread(sample_size, belief_factor, assets, risk_params, cdp_rate, tx_fee, run_index, eth_price_per_day, days_per_config,
logdir, logger):
dai_price_history = []
market_dai_history = []
assert (len(eth_price_per_day) >= days_per_config)
asset_history = [assets[:]]
cur_assets = assets
cur_dai_price = 1
for day in range(0, days_per_config):
s = Simulator(belief_factor=belief_factor, rho=2.5, cdpRate=cdp_rate, txf=tx_fee, run_index=run_index, eth_price=eth_price_per_day[day],
sample_size=sample_size,
initial_distribution=cur_assets, risk_params=risk_params, logdir=logdir, logger=logger)
s.dai_price = cur_dai_price
dai_price, market_dai = s.run_simulation()
# get asset state
cur_assets = s.final_distribution
cur_dai_price = dai_price
# store asset_history and dump into a separate pickle file
asset_history.append(cur_assets[:])
dai_price_history.append(dai_price)
market_dai_history.append(market_dai)
return dai_price_history, asset_history
def generate_assets_and_risk(sample_size, test_type, runs):
# if ASSETS was populated from config, return. Else generate a random ASSETS
if ASSETS is not None:
return ASSETS, RISK
assets_runs = [get_assets(sample_size, test_type) for k in range(runs)]
risk_params = get_risk_params(sample_size)
return assets_runs, risk_params
def run_tests(sample_size, belief_factor, cdp_rates, tx_fees, runs, eth_price_per_day, days_per_config, test_type, logdir, logger,
sumfile):
# Get number of CPUs
cpus = mp.cpu_count()
pool_count = cpus * 2
# Process pool to handle k simulations/process!
pool = mp.Pool(processes=pool_count)
args = []
# Define initial allocation and risk distribution
# If multiple runs, then each run has a different asset allocation, but same risk distribution.
assets_runs, risk_params = generate_assets_and_risk(sample_size, test_type, runs)
for tx_fee in tx_fees:
for cdp_rate in cdp_rates:
for run in range(runs):
args.append(
(sample_size, belief_factor, assets_runs[run], risk_params, cdp_rate, tx_fee, run, eth_price_per_day,
days_per_config, logdir, logger))
results = pool.starmap(run_on_thread, args)
# Get all required parameters and dump to pickle
cdp_axis = [args[i][3] for i in range(len(args))]
txf_axis = [args[i][4] for i in range(len(args))]
run_axis = [args[i][5] for i in range(len(args))]
dai_axis = [res[0] for res in results]
asset_history = [res[1] for res in results]
dump = [cdp_axis, txf_axis, run_axis, dai_axis, asset_history, risk_params]
pickle.dump(dump, sumfile)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='MAKER Simulation CLI')
parser.add_argument(
"--investors",
type=int,
default=10,
help="Number of participating investors in the simulation"
)
parser.add_argument(
"--runs",
type=int,
default=1,
help="Number of runs for each config pair"
)
parser.add_argument(
"--type",
type=str,
default="normal",
help="Can be either normal/uniform/random"
)
parser.add_argument(
"--days_per_config",
type=int,
default=1,
help="Number of days to run the simulation for each CDPRate TXF Pair"
)
parser.add_argument(
"--log",
type=bool,
default=True,
help="Logs simulation results in specified directory"
)
parser.add_argument(
"--logdir",
type=str,
default="sim-logs",
help="Log Directory. Creates if not found."
)
parser.add_argument(
"--config",
type=str,
default="",
help="Config File for test",
required=True
)
args = parser.parse_args()
# Clear log directory if found
if os.path.exists(args.logdir):
os.system("rm -rvf " + args.logdir + "/*")
else:
os.mkdir(args.logdir)
summary_filename = "sim-summary.pickle"
sumfile = open(os.path.join(args.logdir, summary_filename), "wb")
# read CDPRates, TXFs from config
config = open(args.config, "r")
config_lines = config.readlines()
assert (len(config_lines) >= 3)
cdp_config = config_lines[0].split(' ')
txf_config = config_lines[1].split(' ')
eth_price_per_day = list(map(int, config_lines[2].split(' ')))
# If this happens, then assets/risk have been provided in the config
assets = []
risk_params = []
if len(config_lines) > 3:
# Config overrides parameters set in CLI, currently this only supports 1 run.
print("Config might override parameters set by CLI")
args.investors = int(config_lines[3])
args.runs = 1
for i in range(4, 4 + args.investors):
line_split = list(map(float, config_lines[i].split(' ')))
assert (len(line_split) == 5)
assets.append(line_split[:-1])
risk_params.append(line_split[-1])
# Fix global values of ASSETS, RISK
ASSETS = [assets]
RISK = risk_params
if len(eth_price_per_day) < args.days_per_config:
args.days_per_config = len(eth_price_per_day)
print("days_per_config supplied was greater than length of price list")
cdp_rates = [float(cdp_config[2]) * i for i in range(int(cdp_config[0]), int(cdp_config[1]))]
tx_fees = [float(txf_config[2]) * i for i in range(int(txf_config[0]), int(txf_config[1]))]
belief_factor = float(config_lines[-1])
print("Input Parameters for Test")
print("--investors", args.investors)
print("--days_per_config", args.days_per_config)
print("--type", args.type)
print("--runs", args.runs)
print("--log", args.log)
print("--logidr", args.logdir)
print("--config", args.config)
run_tests(args.investors, belief_factor, cdp_rates, tx_fees, args.runs, eth_price_per_day, args.days_per_config, args.type,
args.logdir,
args.log, sumfile)
sumfile.close()