From b4601b7688273d2ee3eb224f00c6171822348e2f Mon Sep 17 00:00:00 2001 From: Rishith Seelam Date: Wed, 26 Jun 2024 15:01:29 -0400 Subject: [PATCH 01/34] partial random seeding --- marketsim/agent/extented_zi_agent.py | 9 ++++++++- marketsim/simulator/sampled_arrival_simulator.py | 12 ++++++++++-- marketsim/simulator/simulator.py | 12 ++++++++++-- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/marketsim/agent/extented_zi_agent.py b/marketsim/agent/extented_zi_agent.py index 1c7327f5..201a400b 100644 --- a/marketsim/agent/extented_zi_agent.py +++ b/marketsim/agent/extented_zi_agent.py @@ -8,7 +8,14 @@ class ZIAgent(Agent): - def __init__(self, agent_id: int, market: Market, q_max: int, offset: float, eta: float, shade: List): + def __init__(self, agent_id: int, market: Market, q_max: int, offset: float, eta: float, shade: List, random_seed: int = 0): + + if random_seed != 0: + # torch.manual_seed(random_seed) + random.seed(random_seed) + # np.random.seed(random_seed) + + self.agent_id = agent_id self.market = market self.pv = PrivateValues(q_max) diff --git a/marketsim/simulator/sampled_arrival_simulator.py b/marketsim/simulator/sampled_arrival_simulator.py index b992b736..557d37a1 100644 --- a/marketsim/simulator/sampled_arrival_simulator.py +++ b/marketsim/simulator/sampled_arrival_simulator.py @@ -6,6 +6,7 @@ from agent.hbl_agent import HBLAgent import torch.distributions as dist import torch +import numpy as np from collections import defaultdict @@ -23,9 +24,16 @@ def __init__(self, shade=None, eta: float = 0.2, hbl_agent: bool = False, - lam_r: float = None + lam_r: float = None, + random_seed: int = 0 ): + + if random_seed != 0: + torch.manual_seed(random_seed) + random.seed(random_seed) + np.random.seed(random_seed) + if shade is None: shade = [10, 30] if lam_r is None: @@ -65,7 +73,7 @@ def __init__(self, pv_var=pv_var, eta=eta )) - expanded_zi + # expanded_zi # else: # for agent_id in range(24): # self.arrivals[self.arrival_times[self.arrival_index].item()].append(agent_id) diff --git a/marketsim/simulator/simulator.py b/marketsim/simulator/simulator.py index 70348329..b2404212 100644 --- a/marketsim/simulator/simulator.py +++ b/marketsim/simulator/simulator.py @@ -6,7 +6,6 @@ from marketsim.agent.zero_intelligence_agent import ZIAgent - class Simulator: def __init__(self, num_background_agents: int, @@ -17,7 +16,16 @@ def __init__(self, r: float = .6, shock_var=10, q_max: int = 10, - zi_shade: List = [10, 30]): + zi_shade: List = [10, 30], + random_seed: int = 0 + ): + + if random_seed != 0: + # torch.manual_seed(random_seed) + random.seed(random_seed) + # np.random.seed(random_seed) + + self.num_agents = num_background_agents self.num_assets = num_assets self.sim_time = sim_time From a44edc3c3e0906d895470b2802da7c016d02e177 Mon Sep 17 00:00:00 2001 From: Rishith Seelam Date: Wed, 26 Jun 2024 15:43:52 -0400 Subject: [PATCH 02/34] full random seeding - must add test for consistency --- marketsim/agent/hbl_agent.py | 8 +++++++- marketsim/agent/market_maker.py | 8 +++++++- marketsim/agent/market_maker_beta.py | 8 +++++++- marketsim/agent/spoofer.py | 9 ++++++++- marketsim/agent/zero_intelligence_agent.py | 8 +++++++- marketsim/event/event_queue.py | 11 +++++++++-- marketsim/fundamental/constant.py | 8 +++++++- marketsim/fundamental/lazy_mean_reverting.py | 8 +++++++- marketsim/fundamental/mean_reverting.py | 8 +++++++- marketsim/private_values/private_values.py | 7 ++++++- marketsim/simulator/sampled_arrival_simulator.py | 5 +++-- marketsim/simulator/simulator.py | 5 +++-- 12 files changed, 78 insertions(+), 15 deletions(-) diff --git a/marketsim/agent/hbl_agent.py b/marketsim/agent/hbl_agent.py index 6e56efb3..657b0152 100644 --- a/marketsim/agent/hbl_agent.py +++ b/marketsim/agent/hbl_agent.py @@ -15,7 +15,13 @@ class HBLAgent(Agent): def __init__(self, agent_id: int, market: Market, q_max: int, shade: List, L: int, pv_var: float, - arrival_rate: float): + arrival_rate: float, random_seed: int = 0): + + if random_seed != 0: + # torch.manual_seed(random_seed) + random.seed(random_seed) + np.random.seed(random_seed) + self.agent_id = agent_id self.market = market self.pv = PrivateValues(q_max, pv_var) diff --git a/marketsim/agent/market_maker.py b/marketsim/agent/market_maker.py index 0d04705e..14bf8b0b 100644 --- a/marketsim/agent/market_maker.py +++ b/marketsim/agent/market_maker.py @@ -8,7 +8,13 @@ class MMAgent(Agent): - def __init__(self, agent_id: int, market: Market, xi: float, K: int, omega: float): + def __init__(self, agent_id: int, market: Market, xi: float, K: int, omega: float, random_seed: int = 0): + + if random_seed != 0: + # torch.manual_seed(random_seed) + random.seed(random_seed) + # np.random.seed(random_seed) + self.agent_id = agent_id self.market = market diff --git a/marketsim/agent/market_maker_beta.py b/marketsim/agent/market_maker_beta.py index 78b24267..ffc8d304 100644 --- a/marketsim/agent/market_maker_beta.py +++ b/marketsim/agent/market_maker_beta.py @@ -38,7 +38,13 @@ def __init__(self, xi: float, omega: float, beta_params: dict=None, - policy: Any=None): + policy: Any=None, + random_seed: int = 0): + + if random_seed != 0: + # torch.manual_seed(random_seed) + random.seed(random_seed) + np.random.seed(random_seed) self.agent_id = agent_id self.market = market diff --git a/marketsim/agent/spoofer.py b/marketsim/agent/spoofer.py index e677a4b4..79ccec1a 100644 --- a/marketsim/agent/spoofer.py +++ b/marketsim/agent/spoofer.py @@ -7,7 +7,14 @@ class SpoofingAgent(Agent): - def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: float, order_size:int, spoofing_size: int, normalizers: dict): + def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: float, order_size:int, spoofing_size: int, normalizers: dict, random_seed: int = 0): + + if random_seed != 0: + # torch.manual_seed(random_seed) + random.seed(random_seed) + # np.random.seed(random_seed) + + self.agent_id = agent_id self.market = market self.pv = PrivateValues(q_max, pv_var) diff --git a/marketsim/agent/zero_intelligence_agent.py b/marketsim/agent/zero_intelligence_agent.py index 50ef82db..f0d8a59a 100644 --- a/marketsim/agent/zero_intelligence_agent.py +++ b/marketsim/agent/zero_intelligence_agent.py @@ -9,7 +9,13 @@ class ZIAgent(Agent): - def __init__(self, agent_id: int, market: Market, q_max: int, shade: List, pv_var: float, eta: float = 1.0): + def __init__(self, agent_id: int, market: Market, q_max: int, shade: List, pv_var: float, eta: float = 1.0, random_seed: int = 0): + + if random_seed != 0: + # torch.manual_seed(random_seed) + random.seed(random_seed) + np.random.seed(random_seed) + self.agent_id = agent_id self.market = market self.pv = PrivateValues(q_max, pv_var) diff --git a/marketsim/event/event_queue.py b/marketsim/event/event_queue.py index 310d86ae..077c65ba 100644 --- a/marketsim/event/event_queue.py +++ b/marketsim/event/event_queue.py @@ -6,8 +6,15 @@ class EventQueue: - def __init__(self, rand_seed: int = None): - self.rand = random.Random(rand_seed) + def __init__(self, random_seed: int = 0): + + if random_seed != 0: + # torch.manual_seed(random_seed) + random.seed(random_seed) + # np.random.seed(random_seed) + + # self.rand = random.Random(rand_seed) + self.scheduled_activities = defaultdict(list) self.current_time = 0 diff --git a/marketsim/fundamental/constant.py b/marketsim/fundamental/constant.py index 24d1c569..3cc58bc7 100644 --- a/marketsim/fundamental/constant.py +++ b/marketsim/fundamental/constant.py @@ -4,7 +4,13 @@ class Constant(Fundamental): - def __init__(self, final_time: int, value: float): + def __init__(self, final_time: int, value: float, random_seed: int = 0): + + if random_seed != 0: + torch.manual_seed(random_seed) + # random.seed(random_seed) + # np.random.seed(random_seed) + self.fundamental_values = torch.ones(final_time, dtype=torch.float32)*value def get_value_at(self, time: int) -> float: diff --git a/marketsim/fundamental/lazy_mean_reverting.py b/marketsim/fundamental/lazy_mean_reverting.py index 82ac32bb..55eb6432 100644 --- a/marketsim/fundamental/lazy_mean_reverting.py +++ b/marketsim/fundamental/lazy_mean_reverting.py @@ -13,7 +13,13 @@ class LazyGaussianMeanReverting(Fundamental): shock_var (float): The variance of the Gaussian shocks. shock_mean (float, optional): The mean of the Gaussian shocks. Default is 0. """ - def __init__(self, final_time: int, mean: float, r: float, shock_var: float, shock_mean: float = 0): + def __init__(self, final_time: int, mean: float, r: float, shock_var: float, shock_mean: float = 0, random_seed: int = 0): + + if random_seed != 0: + torch.manual_seed(random_seed) + # random.seed(random_seed) + # np.random.seed(random_seed) + self.final_time = final_time self.mean = torch.tensor(mean, dtype=torch.float32) self.r = torch.tensor(r, dtype=torch.float32) diff --git a/marketsim/fundamental/mean_reverting.py b/marketsim/fundamental/mean_reverting.py index 37cfb6c5..25cb8eab 100644 --- a/marketsim/fundamental/mean_reverting.py +++ b/marketsim/fundamental/mean_reverting.py @@ -3,7 +3,13 @@ class GaussianMeanReverting(Fundamental): - def __init__(self, final_time: int, mean: float, r: float, shock_var: float, shock_mean: float = 0): + def __init__(self, final_time: int, mean: float, r: float, shock_var: float, shock_mean: float = 0, random_seed: int = 0): + + if random_seed != 0: + torch.manual_seed(random_seed) + # random.seed(random_seed) + # np.random.seed(random_seed) + self.final_time = final_time self.mean = torch.tensor(mean, dtype=torch.float32) self.r = torch.tensor(r, dtype=torch.float32) diff --git a/marketsim/private_values/private_values.py b/marketsim/private_values/private_values.py index c8179bae..49bba33c 100644 --- a/marketsim/private_values/private_values.py +++ b/marketsim/private_values/private_values.py @@ -12,13 +12,18 @@ class PrivateValues: as well as calculate the cumulative value up to a given position. """ - def __init__(self, q_max: int, val_var=5e6): + def __init__(self, q_max: int, val_var=5e6, random_seed: int = 0): """ Initialize the PrivateValues object. :param q_max: The maximum quantity. :param val_var: The variance of the values (default: 1). """ + if random_seed != 0: + torch.manual_seed(random_seed) + # random.seed(random_seed) + # np.random.seed(random_seed) + self.values = torch.randn(2 * q_max) * torch.sqrt(torch.tensor(val_var)) self.values, _ = self.values.sort(descending=True) diff --git a/marketsim/simulator/sampled_arrival_simulator.py b/marketsim/simulator/sampled_arrival_simulator.py index 557d37a1..299069d5 100644 --- a/marketsim/simulator/sampled_arrival_simulator.py +++ b/marketsim/simulator/sampled_arrival_simulator.py @@ -55,7 +55,7 @@ def __init__(self, self.markets = [] for _ in range(num_assets): - fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var) + fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random_seed) self.markets.append(Market(fundamental=fundamental, time_steps=sim_time)) self.agents = {} @@ -71,7 +71,8 @@ def __init__(self, q_max=q_max, shade=shade, pv_var=pv_var, - eta=eta + eta=eta, + random_seed=random_seed )) # expanded_zi # else: diff --git a/marketsim/simulator/simulator.py b/marketsim/simulator/simulator.py index b2404212..8883c38b 100644 --- a/marketsim/simulator/simulator.py +++ b/marketsim/simulator/simulator.py @@ -34,7 +34,7 @@ def __init__(self, self.markets = [] for _ in range(num_assets): - fundamental = GaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var) + fundamental = GaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random_seed) # fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var) self.markets.append(Market(fundamental=fundamental, time_steps=sim_time)) @@ -45,7 +45,8 @@ def __init__(self, agent_id=agent_id, market=self.markets[0], q_max=q_max, - shade=[10, 30] + shade=[10, 30], + random_seed=random_seed )) def step(self): From 9719dc2e3f4596b974b81cb783c2d2b594f5a3f7 Mon Sep 17 00:00:00 2001 From: Rishith Seelam Date: Mon, 1 Jul 2024 10:20:28 -0400 Subject: [PATCH 03/34] completed random seeding --- marketsim/MM/simMM.py | 20 +- marketsim/agent/extented_zi_agent.py | 4 +- marketsim/agent/hbl_agent.py | 2 +- marketsim/agent/spoofer.py | 2 +- marketsim/agent/zero_intelligence_agent.py | 2 +- marketsim/intro_notebook.ipynb | 305 +++++++++++---------- marketsim/market/market.py | 14 +- marketsim/test_event_queue.ipynb | 260 ++++++++++-------- test_sim.ipynb | 218 ++++++++------- 9 files changed, 448 insertions(+), 379 deletions(-) diff --git a/marketsim/MM/simMM.py b/marketsim/MM/simMM.py index 54e92ea5..d7ffe820 100644 --- a/marketsim/MM/simMM.py +++ b/marketsim/MM/simMM.py @@ -30,8 +30,14 @@ def __init__(self, K:int = 4, # n_level - 1 beta_params: dict = None, policy=None, - beta_MM=False + beta_MM=False, + random_seed: int = 0 ): + + if random_seed != 0: + torch.manual_seed(random_seed) + random.seed(random_seed) + # np.random.seed(random_seed) if shade is None: shade = [10, 30] @@ -56,7 +62,7 @@ def __init__(self, self.markets = [] for _ in range(num_assets): - fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var) + fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random_seed) self.markets.append(Market(fundamental=fundamental, time_steps=sim_time)) self.agents = {} @@ -70,7 +76,8 @@ def __init__(self, market=self.markets[0], q_max=q_max, shade=shade, - pv_var=pv_var + pv_var=pv_var, + random_seed=random_seed )) self.arrivals_MM[self.arrival_times_MM[self.arrival_index_MM].item()].append(self.num_agents) @@ -85,7 +92,8 @@ def __init__(self, xi=xi, omega=omega, beta_params=beta_params, - policy=policy + policy=policy, + random_seed=random_seed ) else: @@ -94,8 +102,10 @@ def __init__(self, market=self.markets[0], K=K, xi=xi, - omega=omega + omega=omega, + random_seed=random_seed ) + self.agents[self.num_agents] = self.MM diff --git a/marketsim/agent/extented_zi_agent.py b/marketsim/agent/extented_zi_agent.py index 201a400b..8d7d7814 100644 --- a/marketsim/agent/extented_zi_agent.py +++ b/marketsim/agent/extented_zi_agent.py @@ -8,7 +8,7 @@ class ZIAgent(Agent): - def __init__(self, agent_id: int, market: Market, q_max: int, offset: float, eta: float, shade: List, random_seed: int = 0): + def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: int, offset: float, eta: float, shade: List, random_seed: int = 0): if random_seed != 0: # torch.manual_seed(random_seed) @@ -18,7 +18,7 @@ def __init__(self, agent_id: int, market: Market, q_max: int, offset: float, eta self.agent_id = agent_id self.market = market - self.pv = PrivateValues(q_max) + self.pv = PrivateValues(q_max, pv_var, random_seed=random_seed) self.position = 0 self.offset = offset self.eta = eta diff --git a/marketsim/agent/hbl_agent.py b/marketsim/agent/hbl_agent.py index 657b0152..090d86bd 100644 --- a/marketsim/agent/hbl_agent.py +++ b/marketsim/agent/hbl_agent.py @@ -24,7 +24,7 @@ def __init__(self, agent_id: int, market: Market, q_max: int, shade: List, L: in self.agent_id = agent_id self.market = market - self.pv = PrivateValues(q_max, pv_var) + self.pv = PrivateValues(q_max, pv_var, random_seed=random_seed) self.position = 0 self.shade = shade self.cash = 0 diff --git a/marketsim/agent/spoofer.py b/marketsim/agent/spoofer.py index 79ccec1a..089c846a 100644 --- a/marketsim/agent/spoofer.py +++ b/marketsim/agent/spoofer.py @@ -17,7 +17,7 @@ def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: float, ord self.agent_id = agent_id self.market = market - self.pv = PrivateValues(q_max, pv_var) + self.pv = PrivateValues(q_max, pv_var, random_seed=random_seed) self.position = 0 self.spoofing_size = spoofing_size self.order_size = order_size diff --git a/marketsim/agent/zero_intelligence_agent.py b/marketsim/agent/zero_intelligence_agent.py index f0d8a59a..8db6a297 100644 --- a/marketsim/agent/zero_intelligence_agent.py +++ b/marketsim/agent/zero_intelligence_agent.py @@ -18,7 +18,7 @@ def __init__(self, agent_id: int, market: Market, q_max: int, shade: List, pv_va self.agent_id = agent_id self.market = market - self.pv = PrivateValues(q_max, pv_var) + self.pv = PrivateValues(q_max, pv_var, random_seed=random_seed) self.position = 0 self.shade = shade self.cash = 0 diff --git a/marketsim/intro_notebook.ipynb b/marketsim/intro_notebook.ipynb index ba79e69c..b2d6b5cb 100644 --- a/marketsim/intro_notebook.ipynb +++ b/marketsim/intro_notebook.ipynb @@ -5,11 +5,11 @@ "execution_count": 1, "id": "initial_id", "metadata": { - "collapsed": true, "ExecuteTime": { "end_time": "2024-02-15T04:09:48.703057400Z", "start_time": "2024-02-15T04:09:48.664059300Z" - } + }, + "collapsed": true }, "outputs": [], "source": [ @@ -20,6 +20,15 @@ }, { "cell_type": "code", + "execution_count": 2, + "id": "94fd9db23a88d5c5", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:09:49.138070Z", + "start_time": "2024-02-15T04:09:49.136069300Z" + }, + "collapsed": false + }, "outputs": [], "source": [ "# Let's start with order\n", @@ -28,41 +37,43 @@ "order2 = Order(price=32, order_type=SELL, quantity=22, time=1, agent_id=1, order_id=2)\n", "order3 = Order(price=7, order_type=SELL, quantity=7, time=1, agent_id=1, order_id=3)\n", "order4 = Order(price=9, order_type=SELL, quantity=8, time=1, agent_id=1, order_id=4)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:09:49.138070Z", - "start_time": "2024-02-15T04:09:49.136069300Z" - } - }, - "id": "94fd9db23a88d5c5", - "execution_count": 2 + ] }, { "cell_type": "code", - "outputs": [], - "source": [ - "# Now let's see initialize the fourheap\n", - "\n", - "fh = FourHeap() " - ], + "execution_count": 3, + "id": "cc7b3ae1ebf76ee1", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2024-02-15T04:09:49.335085500Z", "start_time": "2024-02-15T04:09:49.333084400Z" - } + }, + "collapsed": false }, - "id": "cc7b3ae1ebf76ee1", - "execution_count": 3 + "outputs": [], + "source": [ + "# Now let's see initialize the fourheap\n", + "\n", + "fh = FourHeap() " + ] }, { "cell_type": "code", + "execution_count": 4, + "id": "361113b24009b04e", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:09:49.582092300Z", + "start_time": "2024-02-15T04:09:49.577092900Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "{1: Order(price=12, order_type=1, quantity=12, agent_id=1, time=1, order_id=1, asset_id=1)}" + "text/plain": [ + "{1: Order(price=12, order_type=1, quantity=12, agent_id=1, time=1, order_id=1, asset_id=1)}" + ] }, "execution_count": 4, "metadata": {}, @@ -74,23 +85,25 @@ "\n", "fh.insert(order1)\n", "fh.buy_unmatched.order_dict" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:09:49.582092300Z", - "start_time": "2024-02-15T04:09:49.577092900Z" - } - }, - "id": "361113b24009b04e", - "execution_count": 4 + ] }, { "cell_type": "code", + "execution_count": 5, + "id": "ebe4a5b482eb8d70", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:09:49.844940900Z", + "start_time": "2024-02-15T04:09:49.791936400Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "{2: Order(price=32, order_type=-1, quantity=22, agent_id=1, time=1, order_id=2, asset_id=1)}" + "text/plain": [ + "{2: Order(price=32, order_type=-1, quantity=22, agent_id=1, time=1, order_id=2, asset_id=1)}" + ] }, "execution_count": 5, "metadata": {}, @@ -105,19 +118,19 @@ "# Because it's price is higher than the buy price this won't cause a match\n", "\n", "fh.sell_unmatched.order_dict" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:09:49.844940900Z", - "start_time": "2024-02-15T04:09:49.791936400Z" - } - }, - "id": "ebe4a5b482eb8d70", - "execution_count": 5 + ] }, { "cell_type": "code", + "execution_count": 6, + "id": "5b93a62e48ad867e", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:09:50.031942Z", + "start_time": "2024-02-15T04:09:49.985942100Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -141,19 +154,19 @@ "# Since order 1 is larger some will be matched and some will be unmatched\n", "print(fh.buy_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:09:50.031942Z", - "start_time": "2024-02-15T04:09:49.985942100Z" - } - }, - "id": "5b93a62e48ad867e", - "execution_count": 6 + ] }, { "cell_type": "code", + "execution_count": 7, + "id": "ae2bfd9555f5e434", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:09:50.303405Z", + "start_time": "2024-02-15T04:09:50.253396300Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -175,19 +188,19 @@ "print(fh.sell_matched.order_dict)\n", "print(fh.buy_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:09:50.303405Z", - "start_time": "2024-02-15T04:09:50.253396300Z" - } - }, - "id": "ae2bfd9555f5e434", - "execution_count": 7 + ] }, { "cell_type": "code", + "execution_count": 8, + "id": "3ea852481fc4c008", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:09:50.524404700Z", + "start_time": "2024-02-15T04:09:50.482405500Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -208,19 +221,19 @@ "print(fh.sell_matched.order_dict)\n", "print(fh.sell_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:09:50.524404700Z", - "start_time": "2024-02-15T04:09:50.482405500Z" - } - }, - "id": "3ea852481fc4c008", - "execution_count": 8 + ] }, { "cell_type": "code", + "execution_count": 9, + "id": "a13c3435bf208848", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:09:50.906926200Z", + "start_time": "2024-02-15T04:09:50.864927100Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -242,19 +255,19 @@ "print(fh.sell_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n", "print(fh.buy_unmatched.order_dict)\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:09:50.906926200Z", - "start_time": "2024-02-15T04:09:50.864927100Z" - } - }, - "id": "a13c3435bf208848", - "execution_count": 9 + ] }, { "cell_type": "code", + "execution_count": 11, + "id": "bcd1634ff00877e8", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:11:22.295305500Z", + "start_time": "2024-02-15T04:11:22.248306800Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -285,19 +298,19 @@ "print(fh.sell_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n", "print(fh.buy_unmatched.order_dict)\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:11:22.295305500Z", - "start_time": "2024-02-15T04:11:22.248306800Z" - } - }, - "id": "bcd1634ff00877e8", - "execution_count": 11 + ] }, { "cell_type": "code", + "execution_count": 12, + "id": "fe3c9bd1cdefe8d8", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:11:56.266000300Z", + "start_time": "2024-02-15T04:11:56.220995Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -317,19 +330,19 @@ "print(fh.sell_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n", "print(fh.buy_unmatched.order_dict)\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:11:56.266000300Z", - "start_time": "2024-02-15T04:11:56.220995Z" - } - }, - "id": "fe3c9bd1cdefe8d8", - "execution_count": 12 + ] }, { "cell_type": "code", + "execution_count": 7, + "id": "d49d7335bdfc4f4d", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:35:44.877998600Z", + "start_time": "2024-02-15T04:35:44.870998500Z" + }, + "collapsed": false + }, "outputs": [], "source": [ "from fundamental.lazy_mean_reverting import LazyGaussianMeanReverting\n", @@ -337,23 +350,25 @@ "# Let's look at the fundamental next\n", "\n", "f = LazyGaussianMeanReverting(final_time=100, mean=12, r=.2, shock_var=.01)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:35:44.877998600Z", - "start_time": "2024-02-15T04:35:44.870998500Z" - } - }, - "id": "d49d7335bdfc4f4d", - "execution_count": 7 + ] }, { "cell_type": "code", + "execution_count": 8, + "id": "cc2bd7a5d3a7ad3f", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:35:46.433997800Z", + "start_time": "2024-02-15T04:35:46.430998500Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "{0: 12}" + "text/plain": [ + "{0: 12}" + ] }, "execution_count": 8, "metadata": {}, @@ -364,19 +379,19 @@ "# The fundamental starts at the mean\n", "\n", "f.fundamental_values" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:35:46.433997800Z", - "start_time": "2024-02-15T04:35:46.430998500Z" - } - }, - "id": "cc2bd7a5d3a7ad3f", - "execution_count": 8 + ] }, { "cell_type": "code", + "execution_count": 9, + "id": "b902e6769c663d52", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:35:46.900183400Z", + "start_time": "2024-02-15T04:35:46.897184600Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -392,19 +407,19 @@ "f.get_value_at(12)\n", "\n", "print(f.fundamental_values)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:35:46.900183400Z", - "start_time": "2024-02-15T04:35:46.897184600Z" - } - }, - "id": "b902e6769c663d52", - "execution_count": 9 + ] }, { "cell_type": "code", + "execution_count": 10, + "id": "6bdef9c2a15fd033", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:35:47.745318600Z", + "start_time": "2024-02-15T04:35:47.742319600Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -420,25 +435,17 @@ "f.get_final_fundamental()\n", "\n", "print(f.fundamental_values)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:35:47.745318600Z", - "start_time": "2024-02-15T04:35:47.742319600Z" - } - }, - "id": "6bdef9c2a15fd033", - "execution_count": 10 + ] }, { "cell_type": "code", - "outputs": [], - "source": [], + "execution_count": null, + "id": "ba5a64455c821680", "metadata": { "collapsed": false }, - "id": "ba5a64455c821680" + "outputs": [], + "source": [] } ], "metadata": { @@ -457,7 +464,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.6" + "version": "3.9.12" } }, "nbformat": 4, diff --git a/marketsim/market/market.py b/marketsim/market/market.py index f3f91683..d5da5fbf 100644 --- a/marketsim/market/market.py +++ b/marketsim/market/market.py @@ -4,11 +4,19 @@ class Market: - def __init__(self, fundamental: Fundamental, time_steps): + def __init__(self, fundamental: Fundamental, time_steps, random_seed: int = 0): + + # if random_seed != 0: + # torch.manual_seed(random_seed) + # random.seed(random_seed) + # np.random.seed(random_seed) + + self.random_seed = random_seed + self.order_book = FourHeap() self.matched_orders = [] self.fundamental = fundamental - self.event_queue = EventQueue() + self.event_queue = EventQueue(random_seed=random_seed) self.end_time = time_steps def get_fundamental_value(self): @@ -48,4 +56,4 @@ def step(self): def reset(self): self.order_book = FourHeap() self.matched_orders = [] - self.event_queue = EventQueue() + self.event_queue = EventQueue(random_seed=self.random_seed) diff --git a/marketsim/test_event_queue.ipynb b/marketsim/test_event_queue.ipynb index 4e514273..e18e461d 100644 --- a/marketsim/test_event_queue.ipynb +++ b/marketsim/test_event_queue.ipynb @@ -5,11 +5,11 @@ "execution_count": 1, "id": "initial_id", "metadata": { - "collapsed": true, "ExecuteTime": { "end_time": "2023-11-02T02:00:54.071626Z", "start_time": "2023-11-02T02:00:52.890317Z" - } + }, + "collapsed": true }, "outputs": [], "source": [ @@ -23,62 +23,72 @@ { "cell_type": "code", "execution_count": 2, - "outputs": [], - "source": [ - "e = EventQueue()" - ], + "id": "adf6ffdda3d8a689", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:00:55.364165Z", "start_time": "2023-11-02T02:00:55.357739Z" - } + }, + "collapsed": false }, - "id": "adf6ffdda3d8a689" + "outputs": [], + "source": [ + "e = EventQueue()" + ] }, { "cell_type": "code", "execution_count": 3, - "outputs": [], - "source": [ - "order1 = Order(price=1, quantity=1, time=1, agent_id=1, order_id=1, order_type=BUY)\n", - "order2 = Order(price=1, quantity=1, time=1, agent_id=1, order_id=2, order_type=BUY)\n", - "order3 = Order(price=1, quantity=1, time=3, agent_id=1, order_id=3, order_type=SELL)\n" - ], + "id": "acd56cd67811e74d", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:00:55.631574Z", "start_time": "2023-11-02T02:00:55.627375Z" - } + }, + "collapsed": false }, - "id": "acd56cd67811e74d" + "outputs": [], + "source": [ + "order1 = Order(price=1, quantity=1, time=1, agent_id=1, order_id=1, order_type=BUY)\n", + "order2 = Order(price=1, quantity=1, time=1, agent_id=1, order_id=2, order_type=BUY)\n", + "order3 = Order(price=1, quantity=1, time=3, agent_id=1, order_id=3, order_type=SELL)\n" + ] }, { "cell_type": "code", "execution_count": 4, - "outputs": [], - "source": [ - "e.schedule_activity(order1)\n", - "e.schedule_activity(order2)\n", - "e.schedule_activity(order3)\n" - ], + "id": "e81b92116b7c7b9d", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:00:55.846956Z", "start_time": "2023-11-02T02:00:55.845125Z" - } + }, + "collapsed": false }, - "id": "e81b92116b7c7b9d" + "outputs": [], + "source": [ + "e.schedule_activity(order1)\n", + "e.schedule_activity(order2)\n", + "e.schedule_activity(order3)\n" + ] }, { "cell_type": "code", "execution_count": 5, + "id": "2b15b5866d781227", + "metadata": { + "ExecuteTime": { + "end_time": "2023-11-02T02:00:56.086065Z", + "start_time": "2023-11-02T02:00:56.051275Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "[]" + "text/plain": [ + "[]" + ] }, "execution_count": 5, "metadata": {}, @@ -87,23 +97,26 @@ ], "source": [ "e.step()" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2023-11-02T02:00:56.086065Z", - "start_time": "2023-11-02T02:00:56.051275Z" - } - }, - "id": "2b15b5866d781227" + ] }, { "cell_type": "code", "execution_count": 6, + "id": "eba7945d5a7f5263", + "metadata": { + "ExecuteTime": { + "end_time": "2023-11-02T02:00:56.227455Z", + "start_time": "2023-11-02T02:00:56.224831Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "[Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=1, asset_id=1),\n Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=2, asset_id=1)]" + "text/plain": [ + "[Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=1, asset_id=1),\n", + " Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=2, asset_id=1)]" + ] }, "execution_count": 6, "metadata": {}, @@ -112,23 +125,25 @@ ], "source": [ "e.step()" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2023-11-02T02:00:56.227455Z", - "start_time": "2023-11-02T02:00:56.224831Z" - } - }, - "id": "eba7945d5a7f5263" + ] }, { "cell_type": "code", "execution_count": 7, + "id": "8ac0f93a500647fb", + "metadata": { + "ExecuteTime": { + "end_time": "2023-11-02T02:00:56.439237Z", + "start_time": "2023-11-02T02:00:56.434962Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "[]" + "text/plain": [ + "[]" + ] }, "execution_count": 7, "metadata": {}, @@ -137,55 +152,57 @@ ], "source": [ "e.step()" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2023-11-02T02:00:56.439237Z", - "start_time": "2023-11-02T02:00:56.434962Z" - } - }, - "id": "8ac0f93a500647fb" + ] }, { "cell_type": "code", "execution_count": 8, - "outputs": [], - "source": [ - "f = GaussianMeanReverting(mean=100, r=0.2, final_time=100, shock_var=10)" - ], + "id": "88cbe58aba097195", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:00:56.645679Z", "start_time": "2023-11-02T02:00:56.640489Z" - } + }, + "collapsed": false }, - "id": "88cbe58aba097195" + "outputs": [], + "source": [ + "f = GaussianMeanReverting(mean=100, r=0.2, final_time=100, shock_var=10)" + ] }, { "cell_type": "code", "execution_count": 9, - "outputs": [], - "source": [ - "m = Market(f)" - ], + "id": "b19ca32418bbd288", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:00:57.178505Z", "start_time": "2023-11-02T02:00:57.176993Z" - } + }, + "collapsed": false }, - "id": "b19ca32418bbd288" + "outputs": [], + "source": [ + "m = Market(f)" + ] }, { "cell_type": "code", "execution_count": 10, + "id": "910dcd209c37965", + "metadata": { + "ExecuteTime": { + "end_time": "2023-11-02T02:00:57.896940Z", + "start_time": "2023-11-02T02:00:57.883064Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "100.0" + "text/plain": [ + "100.0" + ] }, "execution_count": 10, "metadata": {}, @@ -194,57 +211,64 @@ ], "source": [ "m.get_fundamental_value()" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2023-11-02T02:00:57.896940Z", - "start_time": "2023-11-02T02:00:57.883064Z" - } - }, - "id": "910dcd209c37965" + ] }, { "cell_type": "code", "execution_count": 13, - "outputs": [], - "source": [ - "m.add_order(order1)\n", - "m.add_order(order2)\n", - "m.add_order(order3)\n" - ], + "id": "fecf8d0b5d2b0d76", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:01:34.513870Z", "start_time": "2023-11-02T02:01:34.507170Z" - } + }, + "collapsed": false }, - "id": "fecf8d0b5d2b0d76" + "outputs": [], + "source": [ + "m.add_order(order1)\n", + "m.add_order(order2)\n", + "m.add_order(order3)\n" + ] }, { "cell_type": "code", "execution_count": 24, - "outputs": [], - "source": [ - "m.step()" - ], + "id": "5592a8bef91a39dd", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:02:15.127481Z", "start_time": "2023-11-02T02:02:15.119847Z" - } + }, + "collapsed": false }, - "id": "5592a8bef91a39dd" + "outputs": [], + "source": [ + "m.step()" + ] }, { "cell_type": "code", "execution_count": 25, + "id": "3ec35fc46b4dfdaf", + "metadata": { + "ExecuteTime": { + "end_time": "2023-11-02T02:02:15.439666Z", + "start_time": "2023-11-02T02:02:15.435653Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "defaultdict(list,\n {1: [Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=1, asset_id=1),\n Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=2, asset_id=1)],\n 3: [Order(price=1, order_type=-1, quantity=1, agent_id=1, time=3, order_id=3, asset_id=1)],\n 0: [],\n 2: []})" + "text/plain": [ + "defaultdict(list,\n", + " {1: [Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=1, asset_id=1),\n", + " Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=2, asset_id=1)],\n", + " 3: [Order(price=1, order_type=-1, quantity=1, agent_id=1, time=3, order_id=3, asset_id=1)],\n", + " 0: [],\n", + " 2: []})" + ] }, "execution_count": 25, "metadata": {}, @@ -253,23 +277,25 @@ ], "source": [ "m.event_queue.scheduled_activities" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2023-11-02T02:02:15.439666Z", - "start_time": "2023-11-02T02:02:15.435653Z" - } - }, - "id": "3ec35fc46b4dfdaf" + ] }, { "cell_type": "code", "execution_count": 26, + "id": "f226ab58891b1b9f", + "metadata": { + "ExecuteTime": { + "end_time": "2023-11-02T02:02:16.395887Z", + "start_time": "2023-11-02T02:02:16.353163Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "4" + "text/plain": [ + "4" + ] }, "execution_count": 26, "metadata": {}, @@ -278,25 +304,17 @@ ], "source": [ "m.get_time()" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2023-11-02T02:02:16.395887Z", - "start_time": "2023-11-02T02:02:16.353163Z" - } - }, - "id": "f226ab58891b1b9f" + ] }, { "cell_type": "code", "execution_count": null, - "outputs": [], - "source": [], + "id": "2747f8bda9e21ed1", "metadata": { "collapsed": false }, - "id": "2747f8bda9e21ed1" + "outputs": [], + "source": [] } ], "metadata": { @@ -315,7 +333,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.6" + "version": "3.9.12" } }, "nbformat": 4, diff --git a/test_sim.ipynb b/test_sim.ipynb index 7aa739d6..2c073b3c 100644 --- a/test_sim.ipynb +++ b/test_sim.ipynb @@ -2,16 +2,29 @@ "cells": [ { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "initial_id", "metadata": { - "collapsed": true, "ExecuteTime": { "end_time": "2024-03-27T23:39:39.806325Z", "start_time": "2024-03-27T23:39:37.947319Z" - } + }, + "collapsed": true }, - "outputs": [], + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'fourheap'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mmarketsim\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01msimulator\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01msampled_arrival_simulator\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m SimulatorSampledArrival\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mtqdm\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mnotebook\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m tqdm\n", + "File \u001b[0;32m~/Code/SURE-SRG/market-sim-py/marketsim/simulator/sampled_arrival_simulator.py:2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mrandom\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfourheap\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mconstants\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m BUY, SELL\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mmarket\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mmarket\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Market\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfundamental\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mlazy_mean_reverting\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m LazyGaussianMeanReverting\n", + "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'fourheap'" + ] + } + ], "source": [ "from marketsim.simulator.sampled_arrival_simulator import SimulatorSampledArrival\n", "from tqdm.notebook import tqdm" @@ -20,34 +33,44 @@ { "cell_type": "code", "execution_count": 3, + "id": "72ae6676eeab193e", + "metadata": { + "ExecuteTime": { + "end_time": "2024-03-25T08:07:38.106565700Z", + "start_time": "2024-03-25T08:07:38.103557300Z" + }, + "collapsed": false + }, "outputs": [], "source": [ "# %%timeit\n", "# \n", "# sim = Simulator(num_agents=66, sim_time=60000, lam=1e-4, mean=1e7, r=.05, shock_var=1e6)\n", "# sim.run()" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-25T08:07:38.106565700Z", - "start_time": "2024-03-25T08:07:38.103557300Z" - } - }, - "id": "72ae6676eeab193e" + ] }, { "cell_type": "code", "execution_count": 21, + "id": "a68010fcb5fc866b", + "metadata": { + "ExecuteTime": { + "end_time": "2024-03-25T08:38:17.892762800Z", + "start_time": "2024-03-25T08:35:52.049473800Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": " 0%| | 0/10000 [00:00", - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlAAAAHHCAYAAABwaWYjAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABj1klEQVR4nO3deVxU1f8/8NewzSDCAMqaiLikIqahSeCeBCialPu+kKZhiVtqpqgf01zL3G1RM00zl9zCELdSwn1BhVxwZ8BEBlxAhPP7w9/cryMDchUYwNfz8ZhHzbnve+ecWZwXdzmjEEIIEBEREVGhmRi7A0RERERlDQMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFJU7/fv3R7Vq1QpVO3nyZCgUiuLtUDlRrVo19O/f39jdKFJHjhyBn58frKysoFAocPLkyRJ9fDnv1VfBvn37oFAosG/fPmN3hei5GKBKocWLF0OhUMDHx8fYXTFo8eLFWLlyZaHrFQqFdDMxMYGrqysCAgJK7B/JBw8eYPLkya/MP8rz5s2DQqHA7t2786357rvvoFAosHXr1hLsWfG6desWJk+eXOgQlJ2djS5duiA1NRVff/01Vq9eDXd39+LtZDk3ffp0bNmypdgf5969e4iIiEBQUBDs7e2hUCgK/Dfp/PnzCAoKQsWKFWFvb48+ffrg9u3bejW3bt1C7969Ubt2bVhbW8PW1hZNmjTBqlWr8OwvniUkJGDEiBHw8/ODSqWCQqHAlStXDD52ZmYmZsyYAU9PT1SoUAGvvfYaunTpgrNnz+rVRUdHY+DAgXj99ddRoUIFVK9eHR9++CGSkpIK9Zxs3rwZgYGBcHV1hVKpRJUqVdC5c2fExcXlqR0xYgS8vb1hb2+PChUqoG7dupg8eTLu3bunV6cLtIZu//zzj15tdnY2pkyZgurVq0OpVKJ69eqYNm0aHj9+rFd39uxZdOnSBdWrV0eFChVQuXJltGjRAtu2bcvTz/weW6FQ4N1335Xqrly5km/dunXrCvX8vQizYtsyvbA1a9agWrVqOHz4MC5evIiaNWsau0t6Fi9ejMqVK8vaG/Huu++ib9++EEIgMTERixcvxjvvvIMdO3agbdu2Rdq/7777Drm5udL9Bw8eYMqUKQCAVq1a6dV+8cUXGDduXJE+vrF1794dY8aMwdq1a+Hv72+wZu3atahUqVKRP/fGdOvWLUyZMgXVqlVDw4YNn1t/6dIlXL16Fd999x0+/PDD4u/gK2D69Ono3LkzQkJCivVx/vvvP0ydOhVVq1ZFgwYNCvzj6MaNG2jRogXUajWmT5+Oe/fuYc6cOThz5gwOHz4MCwsLaZs3btxA586dUbVqVWRnZyMqKgr9+/dHQkICpk+fLm0zJiYG3377LTw9PVG3bt0CQ3uvXr2wdetWDBo0CN7e3rh16xYWLVoEX19fnDlzRgrtY8eORWpqKrp06YJatWrh8uXLWLhwIbZv346TJ0/C2dm5wOfkzJkzsLOzw/Dhw1G5cmVoNBr8+OOPaNKkCWJiYtCgQQOp9siRI2jevDkGDBgAlUqFEydO4KuvvsLu3btx4MABmJjo71v59NNP8dZbb+m1Pfu91Lt3b2zYsAEDBw5E48aN8c8//2DixIm4du0ali9fLtVdvXoVGRkZ6NevH1xdXfHgwQNs3LgR7733HpYtW4bBgwdLtatXr84zzqNHj2L+/PkICAjIs6xHjx5o166dXpuvr2+Bz9tLEVSqXL58WQAQmzZtEg4ODmLy5MnG7lIe9erVEy1btix0PQARFham13b69GkBQAQEBBRx7/K6ffu2ACAiIiKK/bFKizZt2gi1Wi0yMzPzLLtx44YwMTERQ4YMkbVNd3d30a9fvyLqYdE7cuSIACBWrFhRqPr9+/cLAGLDhg3F27EC9OvXT7i7uxvt8YualZXVS71H9u7dKwCIvXv3FliXmZkpkpKShBDPf92HDh0qLC0txdWrV6W2qKgoAUAsW7bsuX1q3769sLKyEo8fP5ba7ty5I9LT04UQQsyePVsAEImJiXnWvXHjhgAgRo8erde+Z88eAUDMmzdPatu/f7/IycnRq9O9RydMmPDcfhqi0WiEmZmZ+Oijj55bO2fOHAFAxMTESG261+N5n5HDhw8LAGLixIl67aNGjRIKhUKcOnWqwPUfP34sGjRoIGrXrv3cfoaGhgqFQiGuX78utSUmJgoAYvbs2c9dvyjxEF4ps2bNGtjZ2SE4OBidO3fGmjVrDNbduXMHffr0gY2NDWxtbdGvXz+cOnXK4K7s+Ph4dO7cGfb29lCpVGjcuHGeQzcrV66EQqHAwYMHMXLkSDg4OMDKygrvv/++3q7uatWq4ezZs9i/f7+0i/TZvTqFUb9+fVSuXBmJiYlS2549e9C8eXNYWVnB1tYWHTt2xPnz5/XWy8jIQHh4OKpVqwalUglHR0e8++67OH78uFTz9HklV65cgYODAwBgypQpUp8nT54MwPA5UI8fP8b//vc/1KhRA0qlEtWqVcPnn3+OrKwsvbpq1aqhffv2+Pvvv9GkSROoVCpUr14dP/30U4Fjz87Ohr29PQYMGJBnWXp6OlQqFUaPHi21LViwAPXq1UOFChVgZ2eHxo0bY+3atQU+Ru/evaHVarFjx448y9atW4fc3Fz06tULADBnzhz4+fmhUqVKsLS0RKNGjfDbb78VuH0g//PHdO+lZw9p/PHHH9Lra21tjeDg4DyHMQxJTU3F6NGjUb9+fVSsWBE2NjZo27YtTp06JdXs27dP+gt5wIAB0uuc32Gd/v37o2XLlgCALl266L2PW7VqZfA9/ez5SrrDBnPmzMHy5cul98tbb72FI0eO5Fl/y5Yt8PLygkqlgpeXFzZv3mywb4V9PRQKBYYNG4YNGzbA09MTlpaW0l4NAFi2bBlq1qwJlUqFVq1aGTzEFBsbi6CgIKjValSoUAEtW7bEwYMH9Wp0r/PFixfRv39/2NraQq1WY8CAAXjw4IFef+7fv49Vq1ZJz79uL/XVq1fx8ccfo3bt2rC0tESlSpXQpUuXfA97PY9SqXzuHhmdjRs3on379qhatarU5u/vj9dffx2//vrrc9evVq0aHjx4gEePHklt9vb2sLa2fu66GRkZAAAnJye9dhcXFwCApaWl1NaiRYs8e35atGgBe3v7PP8OFpajoyMqVKiAtLS059bq3tv51WZkZOQ5HKfz119/AXiy9/tp3bt3hxAC69evL/CxTU1N4ebm9tx+ZmVlYePGjWjZsiWqVKlisOb+/ft6r1WxKtG4Rs9Vp04dERoaKoQQ4sCBAwKAOHz4sF5NTk6O8PX1FaampmLYsGFi4cKF4t133xUNGjTI85dYXFycUKvVwtPTU8ycOVMsXLhQtGjRQigUCrFp0yapbsWKFQKAePPNN8U777wjFixYIEaNGiVMTU1F165dpbrNmzeLKlWqiDp16ojVq1eL1atXiz///LPAMcHAHqjU1FRhamoq3n77bSHEk78IzczMxOuvvy5mzZolpkyZIipXrizs7Oz0/rLr2bOnsLCwECNHjhTff/+9mDlzpujQoYP4+eefpZqn/6q/d++eWLJkiQAg3n//fanPur+IIiIixLMfg379+gkAonPnzmLRokWib9++AoAICQnRq3N3dxe1a9cWTk5O4vPPPxcLFy4U3t7eQqFQiLi4uAKfk4EDBwpbW1uRlZWl175q1SoBQBw5ckQIIcTy5culvixbtkzMnz9fhIaGik8//bTA7Wu1WqFSqUSnTp3yLPP29hbu7u4iNzdXCCFElSpVxMcffywWLlwo5s2bJ5o0aSIAiO3bt+cZ79N7Fww9d0L833vp6dftp59+EgqFQgQFBYkFCxaImTNnimrVqglbW1uDf7k/7ciRI6JGjRpi3LhxYtmyZWLq1KnitddeE2q1Wty8eVMI8eQv7alTpwoAYvDgwdLrfOnSJYPbPHTokPj8888FAPHpp5/qvY9btmxpcA/rs3uLdH/1vvnmm6JmzZpi5syZYtasWaJy5cqiSpUq4tGjR1Ltrl27hImJifDy8hLz5s0TEyZMEGq1WtSrVy/PHqjCvh4AxBtvvCHc3NzEV199Jb766iuhVqtF1apVxcKFC4Wnp6eYO3eu+OKLL4SFhYVo3bq13vrR0dHCwsJC+Pr6irlz54qvv/5avPHGG8LCwkLExsZKdbrX+c033xQffPCBWLx4sfjwww8FAPHZZ59JdatXrxZKpVI0b95cev4PHTokhBBiw4YNokGDBmLSpEli+fLl4vPPPxd2dnbC3d1d3L9/X9pGYfdAPa2gPVC6PUAzZ87Ms6x3797C3t4+T/uDBw/E7du3RWJioli5cqWwsrISfn5++T5+QXugHj16JKpUqSKcnZ3F1q1bxfXr10VsbKxo2bKl8PDwEHfv3i1wbBkZGcLCwkIMHjy4wLqn3b17V6SkpIjTp0+LgQMHCgBi+fLleeqys7PF7du3xc2bN8WuXbtEnTp1hLW1tbhz545Uo3s9KlasKAAIU1NT0apVK+nfJ53p06cLAOLy5ct67WfPnhUARGBgYJ7Hv3fvnrh9+7a4ePGimDdvnjA1NRU9e/YscGybNm0SAMR3332n1677LOr6qVAoROPGjcWuXbue+3y9DAaoUuTo0aMCgIiKihJCCJGbmyuqVKkihg8frle3ceNGAUB88803UltOTo5455138vxD0qZNG1G/fn29Qzm5ubnCz89P1KpVS2rTfen5+/tLX6xCCDFixAhhamoq0tLSpLYXOYQXGhoqbt++LVJSUkRsbKxo06aNACDmzp0rhBCiYcOGwtHRUe/De+rUKWFiYiL69u0rtanV6jxh7FnPftEVdAjv2RBw8uRJAUB8+OGHenWjR48WAMSePXukNnd3dwFAHDhwQGpLSUkRSqVSjBo1qsA+7tq1SwAQ27Zt02tv166dqF69unS/Y8eOol69egVuKz9dunQRKpVKaLVaqS0+Pl4AEOPHj5faHjx4oLfeo0ePhJeXl3jnnXf02l80QGVkZAhbW1sxaNAgvTqNRiPUanWe9mdlZmbmObSRmJgolEqlmDp1qtQm9xBefocn5AaoSpUqidTUVKn9999/z/PaNmzYULi4uOh9jv78808BIE+AKuzrAUAolUq9L+5ly5YJAMLZ2Vk6xCSEEOPHj9d7TXJzc0WtWrVEYGCg3uf9wYMHwsPDQ7z77rtSm+51HjhwoN7jv//++6JSpUp6bfkdwnt2TEIIERMTIwCIn376SWor6gClW/b0Y+iMGTNGAMhzmHvGjBkCgHRr06aNuHbtWr6PX1CAEkKI2NhYUaNGDb1tNmrUSDoEWZD//e9/AoCIjo5+bq1O7dq1pcepWLGi+OKLL/J8foT4v+dfd6tdu3ae5/3gwYOiU6dO4ocffhC///67mDFjhqhUqZJQqVTi+PHjUp3uO2n16tV66y9dulQAEF5eXnke/6OPPpIe28TERHTu3Fnvc2RIp06dhFKpzBM8r169KgICAsSSJUvE1q1bxTfffCOqVq0qTExM8vzhUZR4CK8UWbNmDZycnNC6dWsAT3aJd+vWDevWrUNOTo5UFxkZCXNzcwwaNEhqMzExQVhYmN72UlNTsWfPHnTt2hUZGRn477//8N9//+HOnTsIDAzEhQsXcPPmTb11Bg8erHdYpnnz5sjJycHVq1dfamw//PADHBwc4OjoCB8fH+lQYXh4OJKSknDy5En0798f9vb20jpvvPEG3n33XezcuVNqs7W1RWxsLG7duvVS/cmP7rFGjhyp1z5q1CgAyHNIzNPTE82bN5fuOzg4oHbt2rh8+XKBj/POO++gcuXKeru27969i6ioKHTr1k1qs7W1xY0bNwweEnqe3r17IzMzE5s2bZLadIf+dIfvAP3DCHfv3oVWq0Xz5s31Dou+jKioKKSlpaFHjx7Se/C///6DqakpfHx8sHfv3gLXVyqV0qGNnJwc3LlzBxUrVkTt2rWLrI8vo1u3brCzs5Pu694PuveA7v3dr18/qNVqqe7dd9+Fp6dnnu3JeT3atGmjd1hRd+Vup06d9A4x6dp1fTp58iQuXLiAnj174s6dO9Jrcv/+fbRp0wYHDhzQuxADAIYMGaJ3v3nz5rhz5w7S09MLeHbyjik7Oxt37txBzZo1YWtrW6yv4cOHDwE8eQ89S6VS6dXo9OjRA1FRUVi7di169uxpsEYOOzs7NGzYEOPGjcOWLVswZ84cXLlyBV26dEFmZma+6x04cABTpkxB165d8c477xT68VasWIHIyEgsXrwYdevWxcOHD/W+P3Q8PT0RFRWFLVu24LPPPoOVlVWeq/D8/Pzw22+/YeDAgXjvvfcwbtw4/PPPP1AoFBg/frxU165dO7i7u2P06NHYtGkTrl69il9//RUTJkyAmZmZwecvPDwcUVFRWLVqFdq2bYucnJwCD72lp6djx44daNeuHWxtbfWWVa1aFbt27cKQIUPQoUMHDB8+HCdOnICDg4P0b3dx4FV4pUROTg7WrVuH1q1b650X5OPjg7lz5yI6Olq66uDq1atwcXFBhQoV9Lbx7FURFy9ehBACEydOxMSJEw0+bkpKCl577TXp/tPnCQCQvhju3r374oMD0LFjRwwbNgwKhQLW1taoV68erKyspPEAQO3atfOsV7duXezatQv379+HlZUVZs2ahX79+sHNzQ2NGjVCu3bt0LdvX1SvXv2l+qdz9epVmJiY5HkunZ2dYWtrmydIPvt8AU+es+c9X2ZmZujUqRPWrl2LrKwsKJVKbNq0CdnZ2XoBauzYsdi9ezeaNGmCmjVrIiAgAD179kTTpk2fO5a2bdvC3t4ea9eulc5F+eWXX9CgQQPUq1dPqtu+fTumTZuGkydP6p3nVVTzY124cAEA8v0SsLGxKXD93NxczJ8/H4sXL0ZiYqLel0GlSpWKpI8v43mfGd17platWnnWNRQC5bwezz62LqC5ubkZbNf1Sfea9OvXL99xabVavWBY0Dif9xo+fPgQM2bMwIoVK3Dz5k29aQG0Wm2B674MXXB79vxFAFJ4eTrcAYC7u7t0ZVyPHj0wePBg+Pv7IyEhIU/t8+jC75gxY/S+yBs3boxWrVphxYoVGDp0aJ714uPj8f7778PLywvff/+9rMd8+qqz7t27o27dugCenFv3NBsbG+kq3Y4dO2Lt2rXo2LEjjh8/rnfF3rNq1qyJjh07YtOmTcjJyYGpqSlUKhV27NiBrl27olOnTgCehNZZs2bhyy+/RMWKFfNsp06dOqhTpw4AoG/fvggICECHDh0QGxtr8L2+ceNGZGZm6v3xVxDdeaZfffUVbty4ke85Uy+DAaqU2LNnD5KSkrBu3TqD81asWbPG4GWbBdH9BTl69GgEBgYarHk2KJiamhqse/ofvBdRpUqVfC+pl6Nr165o3rw5Nm/ejD///BOzZ8/GzJkzsWnTpiK9JL+w4eFlnq/u3btj2bJl+OOPPxASEoJff/0VderU0fvHq27dukhISMD27dsRGRmJjRs3YvHixZg0aZI0NUN+zM3N0bVrV3z33XdITk7GtWvXcOHCBcyaNUuq+euvv/Dee++hRYsWWLx4MVxcXGBubo4VK1Y890T1/J6jZ//a1b0PV69ebfDEXzOzgv8Zmj59OiZOnIiBAwfif//7H+zt7WFiYoLw8PA8e0mKgkKhMPj6GforHijaz4zc1yO/x35en3TP2+zZs/Od8uHZL72XGecnn3yCFStWIDw8HL6+vlCr1VAoFOjevXuxvIY6upO1Dc2llJSUBHt7e4N7p57WuXNnfPfddzhw4EC+/47mZ+PGjUhOTsZ7772n196yZUvY2Njg4MGDeQLU9evXERAQALVajZ07dxbqZPX82NnZ4Z133sGaNWvyBKhnffDBB+jTpw/WrVtXYIACngT0R48e4f79+1J4rlevHuLi4nDu3DncvXtXurBhxIgR0gUbBencuTM++ugj/Pvvvwb/mF6zZg3UajXat2//3G093U/gydEYBqhybM2aNXB0dMSiRYvyLNu0aRM2b96MpUuXwtLSEu7u7ti7dy8ePHigtxfq4sWLeuvp9sqYm5sXSXjRKeqZu3V/7SUkJORZFh8fj8qVK0t7q4An/yh+/PHH+Pjjj5GSkgJvb298+eWX+QYoOf11d3dHbm4uLly4IP3lBgDJyclIS0sr0okWW7RoARcXF6xfvx7NmjXDnj17MGHChDx1VlZW6NatG7p164ZHjx7hgw8+wJdffonx48dLhyHy06tXLyxduhTr169HYmIiFAoFevToIS3fuHEjVCoVdu3apfdFsmLFiuf2X7cHIi0tTW+X+rN76WrUqAHgyRVBL/I+/O2339C6dWv88MMPeu1paWmoXLmydL+o3pd2dnYGD8G+6GFs3XtGt9fnac++51/m9ZBD95o8vReiKOT3Gvz222/o168f5s6dK7VlZmYW6uqwl/Haa6/BwcEBR48ezbPs8OHDhZovTHf46UX2lCUnJwPIG76FEMjJyclzVdudO3cQEBCArKwsREdHSwHwZTx8+LBQfc/KykJubm6hai9fvgyVSpUnZCsUCr292zt37kRubm6h3mMFPc9JSUnYu3cv+vfv/9zA+2w/AUhXYhc1ngNVCjx8+BCbNm1C+/bt0blz5zy3YcOGISMjQ5p6IDAwENnZ2fjuu++kbeTm5uYJX46OjmjVqhWWLVtm8C+wZ2fiLSwrK6si/YfPxcUFDRs2xKpVq/S2GxcXhz///FOaGC0nJyfPh8vR0RGurq4Gd9Hr6EJmYfqse6xvvvlGr33evHkAgODg4Oduo7BMTEzQuXNnbNu2DatXr8bjx4/1Dt8BT/5BfZqFhQU8PT0hhEB2dvZzH6Np06aoVq0afv75Z6xfvz7P5b+mpqZQKBR6/8BfuXKlULNJ676EDxw4ILXpLmN/WmBgIGxsbDB9+nSDfX7e+9DU1DTPXo4NGzbkOX9PF7Jf9r1Zo0YNxMfH6/Xr1KlTeS7vL6yn399Pv3+joqJw7tw5vdqXeT3kaNSoEWrUqIE5c+bkOe8FKPp/Gwy9hgsWLMh3r15R6tSpE7Zv347r169LbdHR0fj333/RpUsXqS2/Mf/www9QKBTw9vaW/divv/46AOQ5qrB161bcv38fb775ptR2//59tGvXDjdv3sTOnTsNHvLVuXbtGuLj4/XaUlJS8tRduXIF0dHRaNy4sdSWlpZm8HOoO1T4dK2h5+TUqVPYunUrAgIC8ky78LSHDx9i4sSJcHFx0fujzVA/s7Oz8dNPP8HS0tLgeYHPTr3yLEP9vHnzJn788Ue88cYbRRJEDeEeqFJg69atyMjIyLObV+ftt9+Gg4MD1qxZg27duiEkJARNmjTBqFGjcPHiRdSpUwdbt25FamoqAP2/AhctWoRmzZqhfv36GDRoEKpXr47k5GTExMTgxo0benPpFFajRo2wZMkSTJs2DTVr1oSjo6OskxwNmT17Ntq2bQtfX1+Ehobi4cOHWLBgAdRqtTRnU0ZGhvTzBA0aNEDFihWxe/duHDlyRO8v22fpPpTr16/H66+/Dnt7e3h5ecHLyytPbYMGDdCvXz8sX74caWlpaNmyJQ4fPoxVq1YhJCREOsG/qHTr1g0LFixAREQE6tevr7fXCwACAgLg7OyMpk2bwsnJCefPn8fChQsRHBxcqF37CoUCPXv2lGZRnjp1qt7y4OBgzJs3D0FBQejZsydSUlKwaNEi1KxZE6dPny5w2wEBAahatSpCQ0MxZswYmJqa4scff4SDgwOuXbsm1dnY2GDJkiXo06cPvL290b17d6lmx44daNq0KRYuXJjv47Rv3x5Tp07FgAED4OfnhzNnzmDNmjV5znurUaMGbG1tsXTpUlhbW8PKygo+Pj7w8PB47vP0tIEDB2LevHkIDAxEaGgoUlJSsHTpUtSrV69QJ0wbMmPGDAQHB6NZs2YYOHAgUlNTpfm9ng4wL/N6yGFiYoLvv/8ebdu2Rb169TBgwAC89tpruHnzJvbu3QsbGxuDP63xPI0aNcLu3bsxb948uLq6wsPDAz4+Pmjfvj1Wr14NtVoNT09PxMTEYPfu3S91DtvChQuRlpYmXVCybds23LhxA8CTQ4a6874+//xzbNiwAa1bt8bw4cNx7949zJ49G/Xr19ebi+3LL7/EwYMHERQUhKpVqyI1NRUbN27EkSNH8Mknn+id7qDVarFgwQIAkIL1woULYWtrC1tbWwwbNgwA0KFDB9SrVw9Tp07F1atX8fbbb+PixYtYuHAhXFxcEBoaKm2zV69eOHz4MAYOHIjz58/rzf1UsWJFvdnd+/bti/379+uF0vr166NNmzZo2LAh7OzscOHCBfzwww/Izs7GV199JdXt27cPn376KTp37oxatWrh0aNH+Ouvv7Bp0yY0btwYvXv3lmq7desGS0tL+Pn5wdHREefOncPy5ctRoUIFvW0CT06vcHV1haenJ9LT0/Hjjz/i8uXL2LFjh96/VR999BHS09PRokULvPbaa9BoNFizZg3i4+Mxd+5cg+dLrVmzBq6urvnOOfjZZ5/h0qVLaNOmDVxdXXHlyhUsW7YM9+/fx/z58w2uUySK7fo+KrQOHToIlUqlNx/Ks/r37y/Mzc3Ff//9J4R4cml+z549hbW1tVCr1aJ///7i4MGDAoBYt26d3rqXLl0Sffv2Fc7OzsLc3Fy89tpron379uK3336TanSXnj87v4ehy4o1Go0IDg4W1tbWAsBzpzSAgXmgDNm9e7do2rSpsLS0FDY2NqJDhw7i3Llz0vKsrCwxZswY0aBBA2FtbS2srKxEgwYNxOLFi/W2Y2h250OHDolGjRoJCwsLvSkNDF2Kn52dLaZMmSI8PDyEubm5cHNzE+PHj89zubO7u7sIDg7OM478LoM3JDc3V7i5uQkAYtq0aXmWL1u2TLRo0UJUqlRJKJVKUaNGDTFmzBi9qQmeRzcXi6HLf4UQ4ocffhC1atUSSqVS1KlTR6xYscLg82JoJvJjx44JHx8fYWFhIapWrSrmzZtncB4oIZ68lwIDA4VarRYqlUrUqFFD9O/fXxw9erTA/mdmZopRo0YJFxcXYWlpKZo2bSpiYmIMPs+///678PT0FGZmZs+d0qCgWZZ//vlnUb16dWFhYSEaNmwodu3ale80BoZmP376PaazceNGUbduXaFUKoWnp6fYtGmTwfdqYV8PQ5+r/PqU31hPnDghPvjgA+n95e7uLrp27ap32bzusW/fvq23rqHXOT4+XrRo0UJYWloKANL75e7du2LAgAGicuXKomLFiiIwMFDEx8fneU/JmcZAN42Ioduz7724uDgREBAgKlSoIGxtbUWvXr2ERqPRq/nzzz9F+/bthaurqzA3NxfW1taiadOmYsWKFXpTPTz9PBu6Pft6pqamihEjRojXX39dKJVKUblyZdG9e/c8cyYVNJ5nt9myZcs874eIiAjRuHFjYWdnJ8zMzISrq6vo3r27OH36tF7dxYsXRd++fUX16tWFpaWlUKlUol69eiIiIkLcu3dPr3b+/PmiSZMmwt7eXpiZmQkXFxfRu3dvceHChTyvx8yZM0WdOnWESqUSdnZ24r333hMnTpzIU/fLL78If39/4eTkJMzMzISdnZ3w9/cXv//+e55aIf5v6pWRI0caXC6EEGvXrhUtWrQQDg4OwszMTFSuXFm8//774tixY/muUxQUQrzk2cFUamzZsgXvv/8+/v7770JdpUVEREQvhgGqjHr48KHeJbU5OTkICAjA0aNHodFoZF9uS0RERIXHc6DKqE8++QQPHz6Er68vsrKysGnTJhw6dAjTp09neCIiIipm3ANVRq1duxZz587FxYsXkZmZiZo1a2Lo0KHSyYtERERUfBigiIiIiGTiPFBEREREMjFAEREREcnEk8iLQW5uLm7dugVra+si/9kTIiIiKh5CCGRkZMDV1bXAmdYBBqhicevWrTy/hk5ERERlw/Xr15/7A8QMUMVAN2399evXpV+qJiIiotItPT0dbm5uhfqpLAaoYqA7bGdjY8MARUREVMYU5vQbnkROREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCQTZyInIiKiMiEnV+BwYipSMjLhaK1CEw97mJo8f9bw4sAARURERKVeZFwSpmw7hyRtptTmolYhooMngrxcSrw/PIRHREREpVpkXBKG/nxcLzwBgEabiaE/H0dkXFKJ94kBioiIiEqtnFyBKdvOQRhYpmubsu0ccnINVRQfBigiIiIqtQ4npubZ8/Q0ASBJm4nDiakl1ymUoQCVk5ODiRMnwsPDA5aWlqhRowb+97//QYj/S5xCCEyaNAkuLi6wtLSEv78/Lly4oLed1NRU9OrVCzY2NrC1tUVoaCju3bunV3P69Gk0b94cKpUKbm5umDVrVomMkYiIiPSlZOQfnl6krqiUmQA1c+ZMLFmyBAsXLsT58+cxc+ZMzJo1CwsWLJBqZs2ahW+//RZLly5FbGwsrKysEBgYiMzM/3tSe/XqhbNnzyIqKgrbt2/HgQMHMHjwYGl5eno6AgIC4O7ujmPHjmH27NmYPHkyli9fXqLjJSIiIsDRWlWkdUVFIZ7ehVOKtW/fHk5OTvjhhx+ktk6dOsHS0hI///wzhBBwdXXFqFGjMHr0aACAVquFk5MTVq5cie7du+P8+fPw9PTEkSNH0LhxYwBAZGQk2rVrhxs3bsDV1RVLlizBhAkToNFoYGFhAQAYN24ctmzZgvj4+EL1NT09HWq1GlqtFjY2NkX8TBAREb06cnIFms3cU+BhPBe1Cn+PfeelpzSQ8/1dZvZA+fn5ITo6Gv/++y8A4NSpU/j777/Rtm1bAEBiYiI0Gg38/f2lddRqNXx8fBATEwMAiImJga2trRSeAMDf3x8mJiaIjY2Valq0aCGFJwAIDAxEQkIC7t69a7BvWVlZSE9P17sRERHRyzM1UeC9BgVPU/BeA5cSnw+qzASocePGoXv37qhTpw7Mzc3x5ptvIjw8HL169QIAaDQaAICTk5Peek5OTtIyjUYDR0dHveVmZmawt7fXqzG0jacf41kzZsyAWq2Wbm5ubi85WiIiIgKe7IHaeqrgaQq2nkriVXj5+fXXX7FmzRqsXbsWx48fx6pVqzBnzhysWrXK2F3D+PHjodVqpdv169eN3SUiIqJy4XlX4QHGuQqvzMxEPmbMGGkvFADUr18fV69exYwZM9CvXz84OzsDAJKTk+Hi8n+7+pKTk9GwYUMAgLOzM1JSUvS2+/jxY6SmpkrrOzs7Izk5Wa9Gd19X8yylUgmlUvnygyQiIiI9vArvJT148AAmJvrdNTU1RW5uLgDAw8MDzs7OiI6Olpanp6cjNjYWvr6+AABfX1+kpaXh2LFjUs2ePXuQm5sLHx8fqebAgQPIzs6WaqKiolC7dm3Y2dkV2/iIiIgor9J6FV6ZCVAdOnTAl19+iR07duDKlSvYvHkz5s2bh/fffx8AoFAoEB4ejmnTpmHr1q04c+YM+vbtC1dXV4SEhAAA6tati6CgIAwaNAiHDx/GwYMHMWzYMHTv3h2urq4AgJ49e8LCwgKhoaE4e/Ys1q9fj/nz52PkyJHGGjoREdErq4mHPVzUKuR3irgCT67Ca+JhX5LdKjvTGGRkZGDixInYvHkzUlJS4Orqih49emDSpEnSFXNCCERERGD58uVIS0tDs2bNsHjxYrz++uvSdlJTUzFs2DBs27YNJiYm6NSpE7799ltUrFhRqjl9+jTCwsJw5MgRVK5cGZ988gnGjh1b6L5yGgMiIqKio/stPAB6P+miC1VLensXyQ8Ky/n+LjMBqixhgCIiIipakXFJmLLtnN4J5S5qFSI6eBZJeALkfX+XmZPIiYiI6NUV5OWCdz2dcTgxFSkZmXC0fnLYrqTnf9JhgCIiIqIywdREAd8alYzdDQBl6CRyIiIiotKCAYqIiIhIJgYoIiIiIpkYoIiIiIhkYoAiIiIikokBioiIiEgmBigiIiIimRigiIiIiGRigCIiIiKSiQGKiIiISCYGKCIiIiKZGKCIiIiIZGKAIiIiIpKJAYqIiIhIJgYoIiIiIpkYoIiIiIhkYoAiIiIikokBioiIiEgmBigiIiIimRigiIiIiGRigCIiIiKSyczYHSAiIiIqjJxcgcOJqUjJyISjtQpNPOxhaqIwSl8YoIiIiKjUi4xLwpRt55CkzZTaXNQqRHTwRJCXS4n3h4fwiIiIqFSLjEvC0J+P64UnANBoMzH05+OIjEsq8T4xQBEREVGplZMrMGXbOQgDy3RtU7adQ06uoYriwwBFREREpdbhxNQ8e56eJgAkaTNxODG15DoFBigiIiIqxVIy8g9PL1JXVBigiIiIqNRytFYVaV1RYYAiIiKiUquJhz1c1CrkN1mBAk+uxmviYV+S3WKAIiIiotLL1ESBiA6eAJAnROnuR3TwLPH5oBigiIiIqFQL8nLBkt7ecFbrH6ZzVquwpLe3UeaB4kSaREREVOoFebngXU9nzkROREREJIepiQK+NSoZuxsAeAiPiIiISDYGKCIiIiKZGKCIiIiIZCpTAermzZvo3bs3KlWqBEtLS9SvXx9Hjx6VlgshMGnSJLi4uMDS0hL+/v64cOGC3jZSU1PRq1cv2NjYwNbWFqGhobh3755ezenTp9G8eXOoVCq4ublh1qxZJTI+IiIiKhvKTIC6e/cumjZtCnNzc/zxxx84d+4c5s6dCzs7O6lm1qxZ+Pbbb7F06VLExsbCysoKgYGByMz8v+nde/XqhbNnzyIqKgrbt2/HgQMHMHjwYGl5eno6AgIC4O7ujmPHjmH27NmYPHkyli9fXqLjJSIiotJLIYQo2Z8vfkHjxo3DwYMH8ddffxlcLoSAq6srRo0ahdGjRwMAtFotnJycsHLlSnTv3h3nz5+Hp6cnjhw5gsaNGwMAIiMj0a5dO9y4cQOurq5YsmQJJkyYAI1GAwsLC+mxt2zZgvj4+EL1NT09HWq1GlqtFjY2NkUweiIiIipucr6/y8weqK1bt6Jx48bo0qULHB0d8eabb+K7776TlicmJkKj0cDf319qU6vV8PHxQUxMDAAgJiYGtra2UngCAH9/f5iYmCA2NlaqadGihRSeACAwMBAJCQm4e/euwb5lZWUhPT1d70ZERETlV5kJUJcvX8aSJUtQq1Yt7Nq1C0OHDsWnn36KVatWAQA0Gg0AwMnJSW89JycnaZlGo4Gjo6PecjMzM9jb2+vVGNrG04/xrBkzZkCtVks3Nze3lxwtERERlWZlJkDl5ubC29sb06dPx5tvvonBgwdj0KBBWLp0qbG7hvHjx0Or1Uq369evG7tLREREVIzKTIBycXGBp6enXlvdunVx7do1AICzszMAIDk5Wa8mOTlZWubs7IyUlBS95Y8fP0ZqaqpejaFtPP0Yz1IqlbCxsdG7ERERUflVZgJU06ZNkZCQoNf277//wt3dHQDg4eEBZ2dnREdHS8vT09MRGxsLX19fAICvry/S0tJw7NgxqWbPnj3Izc2Fj4+PVHPgwAFkZ2dLNVFRUahdu7beFX9ERET06iozAWrEiBH4559/MH36dFy8eBFr167F8uXLERYWBgBQKBQIDw/HtGnTsHXrVpw5cwZ9+/aFq6srQkJCADzZYxUUFIRBgwbh8OHDOHjwIIYNG4bu3bvD1dUVANCzZ09YWFggNDQUZ8+exfr16zF//nyMHDnSWEMnIiKi0kaUIdu2bRNeXl5CqVSKOnXqiOXLl+stz83NFRMnThROTk5CqVSKNm3aiISEBL2aO3fuiB49eoiKFSsKGxsbMWDAAJGRkaFXc+rUKdGsWTOhVCrFa6+9Jr766itZ/dRqtQKA0Gq1LzZQIiIiKnFyvr/LzDxQZQnngSIiIip7yuU8UERERESlBQMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERyWRm7A4QERGVlJxcgcOJqUjJyISjtQpNPOxhaqIwdreoDGKAIiKiV0JkXBKmbDuHJG2m1OaiViGigyeCvFyM2DMqi3gIj4iIyr3IuCQM/fm4XngCAI02E0N/Po7IuCQj9YzKKgYoIiIq13JyBaZsOwdhYJmubcq2c8jJNVRBZBgDFBERlWuHE1Pz7Hl6mgCQpM3E4cTUkusUlXkMUEREVK6lZOQfnl6kjghggCIionLO0VpVpHVEAAMUERGVc0087OGiViG/yQoUeHI1XhMP+5LsFpVxDFBERFSumZooENHBEwDyhCjd/YgOnpwPimRhgCIionIvyMsFS3p7w1mtf5jOWa3Ckt7enAeKZCuzAeqrr76CQqFAeHi41JaZmYmwsDBUqlQJFStWRKdOnZCcnKy33rVr1xAcHIwKFSrA0dERY8aMwePHj/Vq9u3bB29vbyiVStSsWRMrV64sgREREVFxCvJywd9j38Evg97G/O4N8cugt/H32HcYnuiFlMkAdeTIESxbtgxv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e8LCwgKhoaE4e/Ys1q9fj/nz52PkyJFSzfDhwxEZGYm5c+ciPj4ekydPxtGjRzFs2DAAgEKhQHh4OKZNm4atW7fizJkz6Nu3L1xdXRESElLSwyYiIqJSyqh7oAorKioKFy9exMWLF1GlShW9ZbpZGNRqNf7880+EhYWhUaNGqFy5MiZNmoTBgwdLtX5+fli7di2++OILfP7556hVqxa2bNkCLy8vqeazzz7D/fv3MXjwYKSlpaFZs2aIjIyESqUqmcESERFRqVdm54EqzTgPFBERUdnzSswDRURERGQsDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQylYl5oIjKg5xcgcOJqUjJyISjtQpNPOxhaqIwdreIiOgFMEARlYDIuCRM3noWmvQsqc3ZRonJ79VDkJdLAWsSEVFpxEN4RMUsMi4JQ34+rheeAECTnoUhPx9HZFySkXpGREQvigGKqBjl5AqM23SmwJpxm84gJ5c/CEBEVJYwQBEVo38u3UHag+wCa9IeZOOfS3dKqEdERFQUGKCIitHBS7eLtI6IiEoHBiiiYnQ99WGR1hERUenAAEVUjBL/u1ekdUREVDowQBEVq8LO88T5oIiIyhIGKKJi1MBNXaR1RERUOjBAERWj8W09i7SOiIhKBwYoomJ05qa2SOuIiKh0YIAiKkYpGZlFWkdERKUDAxRRMXK0VhVpHRERlQ4MUETFqImHPVzUqnyvsVMAcFGr0MTDviS7RUREL4kBiqgYmZooENHhyQniz4Yo3f2IDp4wNeE0BkREZQkDFFExC/JywZLe3nBW6x+mc1arsKS3N4K8XIzUMyIielFmxu4A0asgyMsF73o643BiKlIyMuFo/eSwHfc8ERGVTQxQRCXE1EQB3xqVjN0NIiIqAjyER0RERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCRTmQtQWVlZaNiwIRQKBU6ePKm37PTp02jevDlUKhXc3Nwwa9asPOtv2LABderUgUqlQv369bFz50695UIITJo0CS4uLrC0tIS/vz8uXLhQnEMiIiKiMqbMBajPPvsMrq6uedrT09MREBAAd3d3HDt2DLNnz8bkyZOxfPlyqebQoUPo0aMHQkNDceLECYSEhCAkJARxcXFSzaxZs/Dtt99i6dKliI2NhZWVFQIDA5GZmVki4yMiIqLSTyGEEMbuRGH98ccfGDlyJDZu3Ih69erhxIkTaNiwIQBgyZIlmDBhAjQaDSwsLAAA48aNw5YtWxAfHw8A6NatG+7fv4/t27dL23z77bfRsGFDLF26FEIIuLq6YtSoURg9ejQAQKvVwsnJCStXrkT37t0L1c/09HSo1WpotVrY2NgU4TNARERExUXO93eZ2QOVnJyMQYMGYfXq1ahQoUKe5TExMWjRooUUngAgMDAQCQkJuHv3rlTj7++vt15gYCBiYmIAAImJidBoNHo1arUaPj4+Uo0hWVlZSE9P17sRERFR+VUmApQQAv3798eQIUPQuHFjgzUajQZOTk56bbr7Go2mwJqnlz+9nqEaQ2bMmAG1Wi3d3NzcZIyOiIiIyhqjBqhx48ZBoVAUeIuPj8eCBQuQkZGB8ePHG7O7+Ro/fjy0Wq10u379urG7RERERMXIzJgPPmrUKPTv37/AmurVq2PPnj2IiYmBUqnUW9a4cWP06tULq1atgrOzM5KTk/WW6+47OztL/zVU8/RyXZuLi4teje5cK0OUSmWevhEREVH5ZdQA5eDgAAcHh+fWffvtt5g2bZp0/9atWwgMDMT69evh4+MDAPD19cWECROQnZ0Nc3NzAEBUVBRq164NOzs7qSY6Ohrh4eHStqKiouDr6wsA8PDwgLOzM6Kjo6XAlJ6ejtjYWAwdOrQohkxERETlgFEDVGFVrVpV737FihUBADVq1ECVKlUAAD179sSUKVMQGhqKsWPHIi4uDvPnz8fXX38trTd8+HC0bNkSc+fORXBwMNatW4ejR49KUx0oFAqEh4dj2rRpqFWrFjw8PDBx4kS4uroiJCSkZAZLREREpV6ZCFCFoVar8eeffyIsLAyNGjVC5cqVMWnSJAwePFiq8fPzw9q1a/HFF1/g888/R61atbBlyxZ4eXlJNZ999hnu37+PwYMHIy0tDc2aNUNkZCRUKpUxhkVERESlUJmaB6qsKK55oHJyBQ4npiIlIxOO1io08bCHqYmiyLZPRET0KpPz/V1u9kCVd5FxSZiy7RyStP83I7qLWoWIDp4I8nIpYE0iIiIqamViHqhXXWRcEob+fFwvPAGARpuJoT8fR2RckpF6RkRE9GpigCrlcnIFpmw7B0PHWXVtU7adQ04uj8QSERGVFAaoUu5wYmqePU9PEwCStJk4nJhacp0iIiJ6xTFAlXIpGfmHpxepIyIiopfHAFXKOVoXbvqEwtYRERHRy2OAKuWaeNjDRa1CfpMVKPDkarwmHvYl2S0iIqJXGgNUKWdqokBEB08AyBOidPcjOnhyPigiIqISxABVBgR5uWBJb284q/UP0zmrVVjS25vzQBEREZUwTqRZRgR5ueBdT2fORE5ERFQKMECVIaYmCvjWqGTsbhAREb3yeAiPiIiISCYGKCIiIiKZGKCIiIiIZGKAIiIiIpKJAYqIiIhIJgYoIiIiIpkYoIiIiIhkYoAiIiIikokBioiIiEgmBigiIiIimRigiIiIiGRigCIiIiKSiQGKiIiISCYGKCIiIiKZGKCIiIiIZGKAIiIiIpLJzNgdoMLLyRU4nJiKlIxMOFqr0MTDHqYmCmN3i4iI6JXDAFVGRMYlYcq2c0jSZkptLmoVIjp4IsjLxYg9IyIievXwEF4ZEBmXhKE/H9cLTwCg0WZi6M/HERmXZKSeERERvZoYoEq5nFyBKdvOQRhYpmubsu0ccnINVRAREVFxYIAq5Q4npubZ8/Q0ASBJm4nDiakl1ykiIqJXHANUKZeSkX94epE6IiIienkMUKWco7WqSOuIiIjo5TFAlXJNPOzholYhv8kKFHhyNV4TD/uS7BYREdErjQGqlDM1USCigycA5AlRuvsRHTw5HxQREVEJYoAqA4K8XLCktzec1fqH6ZzVKizp7c15oIiIiEoYJ9IsI4K8XPCupzNnIiciIioFytQeqB07dsDHxweWlpaws7NDSEiI3vJr164hODgYFSpUgKOjI8aMGYPHjx/r1ezbtw/e3t5QKpWoWbMmVq5cmedxFi1ahGrVqkGlUsHHxweHDx8uxlEVnqmJAr41KqFjw9fgW6MSwxMREZGRlJkAtXHjRvTp0wcDBgzAqVOncPDgQfTs2VNanpOTg+DgYDx69AiHDh3CqlWrsHLlSkyaNEmqSUxMRHBwMFq3bo2TJ08iPDwcH374IXbt2iXVrF+/HiNHjkRERASOHz+OBg0aIDAwECkpKSU6XiIiIiq9FEKIUj+F9ePHj1GtWjVMmTIFoaGhBmv++OMPtG/fHrdu3YKTkxMAYOnSpRg7dixu374NCwsLjB07Fjt27EBcXJy0Xvfu3ZGWlobIyEgAgI+PD9566y0sXLgQAJCbmws3Nzd88sknGDduXKH6m56eDrVaDa1WCxsbm5cZOhEREZUQOd/fZWIP1PHjx3Hz5k2YmJjgzTffhIuLC9q2basXhGJiYlC/fn0pPAFAYGAg0tPTcfbsWanG399fb9uBgYGIiYkBADx69AjHjh3TqzExMYG/v79UY0hWVhbS09P1bkRERFR+lYkAdfnyZQDA5MmT8cUXX2D79u2ws7NDq1atkJr65CdMNBqNXngCIN3XaDQF1qSnp+Phw4f477//kJOTY7BGtw1DZsyYAbVaLd3c3NxebsBERERUqhk1QI0bNw4KhaLAW3x8PHJzcwEAEyZMQKdOndCoUSOsWLECCoUCGzZsMOYQAADjx4+HVquVbtevXzd2l4iIiKgYGXUag1GjRqF///4F1lSvXh1JSUkAAE9PT6ldqVSievXquHbtGgDA2dk5z9VyycnJ0jLdf3VtT9fY2NjA0tISpqamMDU1NVij24YhSqUSSqWywHEQERFR+WHUAOXg4AAHB4fn1jVq1AhKpRIJCQlo1qwZACA7OxtXrlyBu7s7AMDX1xdffvklUlJS4OjoCACIioqCjY2NFLx8fX2xc+dOvW1HRUXB19cXAGBhYYFGjRohOjpamiIhNzcX0dHRGDZsWJGMmYiIiMq+MnEOlI2NDYYMGYKIiAj8+eefSEhIwNChQwEAXbp0AQAEBATA09MTffr0walTp7Br1y588cUXCAsLk/YODRkyBJcvX8Znn32G+Ph4LF68GL/++itGjBghPdbIkSPx3XffYdWqVTh//jyGDh2K+/fvY8CAASU/cCIiIiqVysxM5LNnz4aZmRn69OmDhw8fwsfHB3v27IGdnR0AwNTUFNu3b8fQoUPh6+sLKysr9OvXD1OnTpW24eHhgR07dmDEiBGYP38+qlSpgu+//x6BgYFSTbdu3XD79m1MmjQJGo0GDRs2RGRkZJ4Ty4mIiOjVVSbmgSprtFotbG1tcf36dc4DRUREVEakp6fDzc0NaWlpUKvVBdaWmT1QZUlGRgYAcDoDIiKiMigjI+O5AYp7oIpBbm4ubt26BWtraygURft7dbp0XF73bnF8ZV95HyPHV/aV9zFyfC9OCIGMjAy4urrCxKTg08S5B6oYmJiYoEqVKsX6GDY2NuXyg6HD8ZV95X2MHF/ZV97HyPG9mOftedIpE1fhEREREZUmDFBEREREMjFAlTFKpRIRERHlduZzjq/sK+9j5PjKvvI+Ro6vZPAkciIiIiKZuAeKiIiISCYGKCIiIiKZGKCIiIiIZGKAIiIiIpKJAaoUu3LlCkJDQ+Hh4QFLS0vUqFEDERERePToUYHrZWZmIiwsDJUqVULFihXRqVMnJCcnl1Cv5fvyyy/h5+eHChUqwNbWtlDr9O/fHwqFQu8WFBRUvB19QS8yPiEEJk2aBBcXF1haWsLf3x8XLlwo3o6+oNTUVPTq1Qs2NjawtbVFaGgo7t27V+A6rVq1yvP6DRkypIR6/HyLFi1CtWrVoFKp4OPjg8OHDxdYv2HDBtSpUwcqlQr169fHzp07S6inL0bO+FauXJnntVKpVCXYW3kOHDiADh06wNXVFQqFAlu2bHnuOvv27YO3tzeUSiVq1qyJlStXFns/X4bcMe7bty/Pa6hQKKDRaEqmwzLNmDEDb731FqytreHo6IiQkBAkJCQ8d72S/hwyQJVi8fHxyM3NxbJly3D27Fl8/fXXWLp0KT7//PMC1xsxYgS2bduGDRs2YP/+/bh16xY++OCDEuq1fI8ePUKXLl0wdOhQWesFBQUhKSlJuv3yyy/F1MOX8yLjmzVrFr799lssXboUsbGxsLKyQmBgIDIzM4uxpy+mV69eOHv2LKKiorB9+3YcOHAAgwcPfu56gwYN0nv9Zs2aVQK9fb7169dj5MiRiIiIwPHjx9GgQQMEBgYiJSXFYP2hQ4fQo0cPhIaG4sSJEwgJCUFISAji4uJKuOeFI3d8wJMZn59+ra5evVqCPZbn/v37aNCgARYtWlSo+sTERAQHB6N169Y4efIkwsPD8eGHH2LXrl3F3NMXJ3eMOgkJCXqvo6OjYzH18OXs378fYWFh+OeffxAVFYXs7GwEBATg/v37+a5jlM+hoDJl1qxZwsPDI9/laWlpwtzcXGzYsEFqO3/+vAAgYmJiSqKLL2zFihVCrVYXqrZfv36iY8eOxdqfolbY8eXm5gpnZ2cxe/ZsqS0tLU0olUrxyy+/FGMP5Tt37pwAII4cOSK1/fHHH0KhUIibN2/mu17Lli3F8OHDS6CH8jVp0kSEhYVJ93NycoSrq6uYMWOGwfquXbuK4OBgvTYfHx/x0UcfFWs/X5Tc8cn5XJY2AMTmzZsLrPnss89EvXr19Nq6desmAgMDi7FnRacwY9y7d68AIO7evVsifSpqKSkpAoDYv39/vjXG+BxyD1QZo9VqYW9vn+/yY8eOITs7G/7+/lJbnTp1ULVqVcTExJREF0vMvn374OjoiNq1a2Po0KG4c+eOsbtUJBITE6HRaPReQ7VaDR8fn1L3GsbExMDW1haNGzeW2vz9/WFiYoLY2NgC112zZg0qV64MLy8vjB8/Hg8ePCju7j7Xo0ePcOzYMb3n3sTEBP7+/vk+9zExMXr1ABAYGFjqXivgxcYHAPfu3YO7uzvc3NzQsWNHnD17tiS6WyLK0uv3sho2bAgXFxe8++67OHjwoLG7U2harRYACvzuM8bryB8TLkMuXryIBQsWYM6cOfnWaDQaWFhY5DnXxsnJqdQe734RQUFB+OCDD+Dh4YFLly7h888/R9u2bRETEwNTU1Njd++l6F4nJycnvfbS+BpqNJo8hwHMzMxgb29fYF979uwJd3d3uLq64vTp0xg7diwSEhKwadOm4u5ygf777z/k5OQYfO7j4+MNrqPRaMrEawW82Phq166NH3/8EW+88Qa0Wi3mzJkDPz8/nD17tth/NL0k5Pf6paen4+HDh7C0tDRSz4qOi4sLli5disaNGyMrKwvff/89WrVqhdjYWHh7exu7ewXKzc1FeHg4mjZtCi8vr3zrjPE55B4oIxg3bpzBE/qevj37j9nNmzcRFBSELl26YNCgQUbqeeG9yBjl6N69O9577z3Ur18fISEh2L59O44cOYJ9+/YV3SAKUNzjM7biHt/gwYMRGBiI+vXro1evXvjpp5+wefNmXLp0qQhHQUXB19cXffv2RcOGDdGyZUts2rQJDg4OWLZsmbG7RoVUu3ZtfPTRR2jUqBH8/Pzw448/ws/PD19//bWxu/ZcYWFhiIuLw7p164zdlTy4B8oIRo0ahf79+xdYU716den/b926hdatW8PPzw/Lly8vcD1nZ2c8evQIaWlpenuhkpOT4ezs/DLdlkXuGF9W9erVUblyZVy8eBFt2rQpsu3mpzjHp3udkpOT4eLiIrUnJyejYcOGL7RNuQo7Pmdn5zwnHz9+/Bipqamy3m8+Pj4AnuxlrVGjhuz+FpXKlSvD1NQ0z1WrBX1+nJ2dZdUb04uM71nm5uZ48803cfHixeLoYonL7/WzsbEpF3uf8tOkSRP8/fffxu5GgYYNGyZdmPK8vZ3G+BwyQBmBg4MDHBwcClV78+ZNtG7dGo0aNcKKFStgYlLwTsNGjRrB3Nwc0dHR6NSpE4AnV15cu3YNvr6+L933wpIzxqJw48YN3LlzRy9wFKfiHJ+HhwecnZ0RHR0tBab09HTExsbKvlLxRRV2fL6+vkhLS8OxY8fQqFEjAMCePXuQm5srhaLCOHnyJACU2OuXHwsLCzRq1AjR0dEICQkB8OQQQnR0NIYNG2ZwHV9fX0RHRyM8PFxqi4qKKtHPW2G9yPielZOTgzNnzqBdu3bF2NOS4+vrm+dy99L6+hWlkydPGv3zlh8hBD755BNs3rwZ+/btg4eHx3PXMcrnsNhOT6eXduPGDVGzZk3Rpk0bcePGDZGUlCTdnq6pXbu2iI2NldqGDBkiqlatKvbs2SOOHj0qfH19ha+vrzGGUChXr14VJ06cEFOmTBEVK1YUJ06cECdOnBAZGRlSTe3atcWmTZuEEEJkZGSI0aNHi5iYGJGYmCh2794tvL29Ra1atURmZqaxhpEvueMTQoivvvpK2Nrait9//12cPn1adOzYUXh4eIiHDx8aYwgFCgoKEm+++aaIjY0Vf//9t6hVq5bo0aOHtPzZ9+jFixfF1KlTxdGjR0ViYqL4/fffRfXq1UWLFi2MNQQ969atE0qlUqxcuVKcO3dODB48WNja2gqNRiOEEKJPnz5i3LhxUv3BgweFmZmZmDNnjjh//ryIiIgQ5ubm4syZM8YaQoHkjm/KlCli165d4tKlS+LYsWOie/fuQqVSibNnzxprCAXKyMiQPmMAxLx588SJEyfE1atXhRBCjBs3TvTp00eqv3z5sqhQoYIYM2aMOH/+vFi0aJEwNTUVkZGRxhrCc8kd49dffy22bNkiLly4IM6cOSOGDx8uTExMxO7du401hAINHTpUqNVqsW/fPr3vvQcPHkg1peFzyABViq1YsUIAMHjTSUxMFADE3r17pbaHDx+Kjz/+WNjZ2YkKFSqI999/Xy90lTb9+vUzOManxwRArFixQgghxIMHD0RAQIBwcHAQ5ubmwt3dXQwaNEj6Aiht5I5PiCdTGUycOFE4OTkJpVIp2rRpIxISEkq+84Vw584d0aNHD1GxYkVhY2MjBgwYoBcOn32PXrt2TbRo0ULY29sLpVIpatasKcaMGSO0Wq2RRpDXggULRNWqVYWFhYVo0qSJ+Oeff6RlLVu2FP369dOr//XXX8Xrr78uLCwsRL169cSOHTtKuMfyyBlfeHi4VOvk5CTatWsnjh8/boReF47ukv1nb7ox9evXT7Rs2TLPOg0bNhQWFhaievXqep/F0kjuGGfOnClq1KghVCqVsLe3F61atRJ79uwxTucLIb/vvadfl9LwOVT8/84SERERUSHxKjwiIiIimRigiIiIiGRigCIiIiKSiQGKiIiISCYGKCIiIiKZGKCIiIiIZGKAIiIiIpKJAYqI6Dn27dsHhUKBtLS0AuuqVauGb775pkT6RETGxQBFROVG//79oVAooFAoYGFhgZo1a2Lq1Kl4/PjxS23Xz88PSUlJUKvVAICVK1fq/Vi3zpEjRzB48OCXeiwiKhv4Y8JEVK4EBQVhxYoVyMrKws6dOxEWFgZzc3OMHz/+hbdpYWFRqF91L8kf0CYi4+IeKCIqV5RKJZydneHu7o6hQ4fC398fW7duxd27d9G3b1/Y2dmhQoUKaNu2LS5cuCCtd/XqVXTo0AF2dnawsrJCvXr1sHPnTgD6h/D27duHAQMGQKvVSnu7Jk+eDCDvIbxr166hY8eOqFixImxsbNC1a1ckJydLyydPnoyGDRti9erVqFatGtRqNbp3746MjIwSea6I6MUxQBFRuWZpaYlHjx6hf//+OHr0KLZu3YqYmBgIIdCuXTtkZ2cDAMLCwpCVlYUDBw7gzJkzmDlzJipWrJhne35+fvjmm29gY2ODpKQkJCUlYfTo0XnqcnNz0bFjR6SmpmL//v2IiorC5cuX0a1bN726S5cuYcuWLdi+fTu2b9+O/fv346uvviqeJ4OIigwP4RFRuSSEQHR0NHbt2oW2bdtiy5YtOHjwIPz8/AAAa9asgZubG7Zs2YIuXbrg2rVr6NSpE+rXrw8AqF69usHtWlhYQK1WQ6FQFHhYLzo6GmfOnEFiYiLc3NwAAD/99BPq1auHI0eO4K233gLwJGitXLkS1tbWAIA+ffogOjoaX375ZZE9F0RU9LgHiojKle3bt6NixYpQqVRo27YtunXrhv79+8PMzAw+Pj5SXaVKlVC7dm2cP38eAPDpp59i2rRpaNq0KSIiInD69OmX6sf58+fh5uYmhScA8PT0hK2trfSYwJPDfrrwBAAuLi5ISUl5qccmouLHAEVE5Urr1q1x8uRJXLhwAQ8fPsSqVaugUCieu96HH36Iy5cvo0+fPjhz5gwaN26MBQsWFHt/zc3N9e4rFArk5uYW++MS0cthgCKicsXKygo1a9ZE1apVYWb25CyFunXr4vHjx4iNjZXq7ty5g4SEBHh6ekptbm5uGDJkCDZt2oRRo0bhu+++M/gYFhYWyMnJKbAfdevWxfXr13H9+nWp7dy5c0hLS9N7TCIqmxigiKjcq1WrFjp27IhBgwbh77//xqlTp9C7d2+89tpr6NixIwAgPDwcu3btQmJiIo4fP469e/eibt26BrdXrVo13Lt3D9HR0fjvv//w4MGDPDX+/v6oX78+evXqhePHj+Pw4cPo27cvWrZsicaNGxfreImo+DFAEdErYcWKFWjUqBHat28PX19fCCGwc+dO6RBaTk4OwsLCULduXQQFBeH111/H4sWLDW7Lz88PQ4YMQbdu3eDg4IBZs2blqVEoFPj9999hZ2eHFi1awN/fH9WrV8f69euLdZxEVDIUQghh7E4QERERlSXcA0VEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcn0/wARYlezvwXQIQAAAABJRU5ErkJggg==" + "image/png": "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GxsLX19fAICvry/S0tJw7NgxqWbPnj3Izc2Fj4+PVHPgwAFkZ2dLNVFRUahdu7beFX9ERET06iozAWrEiBH4559/MH36dFy8eBFr167F8uXLERYWBgBQKBQIDw/HtGnTsHXrVpw5cwZ9+/aFq6srQkJCADzZYxUUFIRBgwbh8OHDOHjwIIYNG4bu3bvD1dUVANCzZ09YWFggNDQUZ8+exfr16zF//nyMHDnSWEMnIiKi0kaUIdu2bRNeXl5CqVSKOnXqiOXLl+stz83NFRMnThROTk5CqVSKNm3aiISEBL2aO3fuiB49eoiKFSsKGxsbMWDAAJGRkaFXc+rUKdGsWTOhVCrFa6+9Jr766itZ/dRqtQKA0Gq1LzZQIiIiKnFyvr/LzDxQZQnngSIiIip7yuU8UERERESlBQMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERyWRm7A4QERGVlJxcgcOJqUjJyISjtQpNPOxhaqIwdreoDGKAIiKiV0JkXBKmbDuHJG2m1OaiViGigyeCvFyM2DMqi3gIj4iIyr3IuCQM/fm4XngCAI02E0N/Po7IuCQj9YzKKgYoIiIq13JyBaZsOwdhYJmubcq2c8jJNVRBZBgDFBERlWuHE1Pz7Hl6mgCQpM3E4cTUkusUlXkMUEREVK6lZOQfnl6kjghggCIionLO0VpVpHVEAAMUERGVc0087OGiViG/yQoUeHI1XhMP+5LsFpVxDFBERFSumZooENHBEwDyhCjd/YgOnpwPimRhgCIionIvyMsFS3p7w1mtf5jOWa3Ckt7enAeKZCuzAeqrr76CQqFAeHi41JaZmYmwsDBUqlQJFStWRKdOnZCcnKy33rVr1xAcHIwKFSrA0dERY8aMwePHj/Vq9u3bB29vbyiVStSsWRMrV64sgREREVFxCvJywd9j38Evg97G/O4N8cugt/H32HcYnuiFlMkAdeTIESxbtgxv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e8LCwgKhoaE4e/Ys1q9fj/nz52PkyJFSzfDhwxEZGYm5c+ciPj4ekydPxtGjRzFs2DAAgEKhQHh4OKZNm4atW7fizJkz6Nu3L1xdXRESElLSwyYiIqJSyqh7oAorKioKFy9exMWLF1GlShW9ZbpZGNRqNf7880+EhYWhUaNGqFy5MiZNmoTBgwdLtX5+fli7di2++OILfP7556hVqxa2bNkCLy8vqeazzz7D/fv3MXjwYKSlpaFZs2aIjIyESqUqmcESERFRqVdm54EqzTgPFBERUdnzSswDRURERGQsDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQylYl5oIjKg5xcgcOJqUjJyISjtQpNPOxhaqIwdreIiOgFMEARlYDIuCRM3noWmvQsqc3ZRonJ79VDkJdLAWsSEVFpxEN4RMUsMi4JQ34+rheeAECTnoUhPx9HZFySkXpGREQvigGKqBjl5AqM23SmwJpxm84gJ5c/CEBEVJYwQBEVo38u3UHag+wCa9IeZOOfS3dKqEdERFQUGKCIitHBS7eLtI6IiEoHBiiiYnQ99WGR1hERUenAAEVUjBL/u1ekdUREVDowQBEVq8LO88T5oIiIyhIGKKJi1MBNXaR1RERUOjBAERWj8W09i7SOiIhKBwYoomJ05qa2SOuIiKh0YIAiKkYpGZlFWkdERKUDAxRRMXK0VhVpHRERlQ4MUETFqImHPVzUqnyvsVMAcFGr0MTDviS7RUREL4kBiqgYmZooENHhyQniz4Yo3f2IDp4wNeE0BkREZQkDFFExC/JywZLe3nBW6x+mc1arsKS3N4K8XIzUMyIielFmxu4A0asgyMsF73o643BiKlIyMuFo/eSwHfc8ERGVTQxQRCXE1EQB3xqVjN0NIiIqAjyER0RERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCRTmQtQWVlZaNiwIRQKBU6ePKm37PTp02jevDlUKhXc3Nwwa9asPOtv2LABderUgUqlQv369bFz50695UIITJo0CS4uLrC0tIS/vz8uXLhQnEMiIiKiMqbMBajPPvsMrq6uedrT09MREBAAd3d3HDt2DLNnz8bkyZOx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8uRJXLhwAQ8fPsSqVaugUCieu96HH36Iy5cvo0+fPjhz5gwaN26MBQsWFHt/zc3N9e4rFArk5uYW++MS0cthgCKicsXKygo1a9ZE1apVYWb25CyFunXr4vHjx4iNjZXq7ty5g4SEBHh6ekptbm5uGDJkCDZt2oRRo0bhu+++M/gYFhYWyMnJKbAfdevWxfXr13H9+nWp7dy5c0hLS9N7TCIqmxigiKjcq1WrFjp27IhBgwbh77//xqlTp9C7d2+89tpr6NixIwAgPDwcu3btQmJiIo4fP469e/eibt26BrdXrVo13Lt3D9HR0fjvv//w4MGDPDX+/v6oX78+evXqhePHj+Pw4cPo27cvWrZsicaNGxfreImo+DFAEdErYcWKFWjUqBHat28PX19fCCGwc+dO6RBaTk4OwsLCULduXQQFBeH111/H4sWLDW7Lz88PQ4YMQbdu3eDg4IBZs2blqVEoFPj9999hZ2eHFi1awN/fH9WrV8f69euLdZxEVDIUQghh7E4QERERlSXcA0VEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcn0/wARYlezvwXQIQAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] }, "metadata": {}, "output_type": "display_data" @@ -275,19 +305,19 @@ "plt.ylabel('Value')\n", "plt.title(f'Agent Position vs Value at fundamental {fundamental_val}')\n", "plt.show()\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-26T20:44:46.314860800Z", - "start_time": "2024-03-26T20:44:46.196664700Z" - } - }, - "id": "da028cd7fb618978", - "execution_count": 32 + ] }, { "cell_type": "code", + "execution_count": 38, + "id": "44a74cbe8acf673", + "metadata": { + "ExecuteTime": { + "end_time": "2024-03-26T20:44:58.709570600Z", + "start_time": "2024-03-26T20:44:58.596987100Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -298,8 +328,10 @@ }, { "data": { - "text/plain": "
", - "image/png": "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ssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyZ9ZANHv2bLRs2RKOjo5wdXVFr169cPnyZYM+nTp1gkKhMHiMGTPGoE9CQgKCg4NRqVIluLq6YvLkyXj8+LFBn0OHDqF58+ZQKpWoXbs2Vq1aVdqzR0REROWEWQPR4cOHER4ejt9++w1RUVHIyclBQEAAHjx4YNBv9OjRSExMlB5z586VhuXm5iI4OBjZ2dk4duwYVq9ejVWrVuHjjz+W+sTHxyM4OBidO3fG6dOnMX78eLzxxhvYt2+fyeaViIiIyi6FEEKYuwi927dvw9XVFYcPH0aHDh0APNlC1KxZMyxcuDDP1/z000/o3r07bt26BTc3NwBAZGQkpkyZgtu3b8PGxgZTpkzB7t27ERcXJ71uwIABSEtLw969e19Yl1arhVqtRnp6OlQqVfFnlIiIiEpdYb6/y9QxROnp6QAAZ2dng/Z169ahatWqaNSoEaZOnYqHDx9Kw2JiYtC4cWMpDAFAYGAgtFotzp8/L/Xx9/c3GGdgYCBiYmLyrCMrKwtardbgQURERBWXlbkL0NPpdBg/fjzatm2LRo0aSe2DBg1C9erV4eHhgbNnz2LKlCm4fPkytmzZAgBISkoyCEMApOdJSUnP7aPVavHo0SPY2dkZDJs9ezamT59e4vNIREREZVOZCUTh4eGIi4vDr7/+atD+5ptvSv9v3Lgx3N3d8corr+DatWuoVatWqdQydepUTJw4UXqu1Wrh6elZ4tPJ1QnExqciJSMTro62aOXtDEsLRYlPh4iIiJ6vTASisWPHYteuXThy5AiqVav23L6+vr4AgKtXr6JWrVrQaDSIjY016JOcnAwA0Gg00r/6tqf7qFQqo61DAKBUKqFUKos8PwWxNy4R03deQGJ6ptTmrrZFRA8fBDVyL9VpExERkSGzHkMkhMDYsWOxdetWHDhwAN7e3i98zenTpwEA7u5PQoOfnx/OnTuHlJQUqU9UVBRUKhV8fHykPtHR0QbjiYqKgp+fXwnNSeHsjUtE2NpTBmEIAJLSMxG29hT2xiWapS4iIiK5MmsgCg8Px9q1a7F+/Xo4OjoiKSkJSUlJePToEQDg2rVr+OSTT3Dy5Elcv34dO3bswLBhw9ChQwc0adIEABAQEAAfHx8MHToUZ86cwb59+/Dhhx8iPDxc2sozZswY/PXXX3jvvfdw6dIlLFmyBJs2bcKECRNMPs+5OoHpOy8gr1P79G3Td15Arq7MnPxHRERU4Zk1EC1duhTp6eno1KkT3N3dpcfGjRsBADY2Nti/fz8CAgJQv359TJo0CSEhIdi5c6c0DktLS+zatQuWlpbw8/PDkCFDMGzYMMyYMUPq4+3tjd27dyMqKgpNmzbF/Pnz8c033yAwMNDk8xwbn2q0ZehpAkBieiZi41NNVxQREZHMmfUYohddAsnT0xOHDx9+4XiqV6+OPXv2PLdPp06d8McffxSqvtKQkpF/GCpKPyIiIiq+MnUdIjlwdbQt0X5ERERUfAxEJtbK2xnualvkd3K9Ak/ONmvl7ZxPDyIiIippDEQmZmmhQESPJ2e/PRuK9M8jevjwekREREQmxEBkBkGN3LF0SHNo1Ia7xTRqWywd0pzXISIiIjKxMnFhRjkKauSOrj4aXqmaiIioDGAgMiNLCwX8alUxdxlERESyx11mREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQke1bmLoCIiIjkK1cnEBufipSMTLg62qKVtzMsLRQmr4OBiIiIiMxib1wipu+8gMT0TKnNXW2LiB4+CGrkbtJauMuMiIiITG5vXCLC1p4yCEMAkJSeibC1p7A3LtGk9TAQERERkUnl6gSm77wAkccwfdv0nReQq8urR+lgICIiIiKTio1PNdoy9DQBIDE9E7HxqSariYGIiIiITColI/8wVJR+JYGBiIiIiEzK1dG2RPuVBAYiIiIiMqlW3s5wV9siv5Pr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9erVQ79+/VClShX89ttvcHFxAQB88cUX6N69O0JCQtChQwdoNBps2bJFer2lpSV27doFS0tL+Pn5YciQIRg2bBhmzJhhrlkiIio03qzYdF50ALsAD2CvqBRCCL6rL6DVaqFWq5Gens7jiYjIbHgdotIXc+0uBq747YX9vh/dmgewlwOF+f4u02eZERHR//BmxaUvSVuwA9ML2o/KDwYiIqJyhDcrLl2p97NKtB+VH2X6GCIiIiJTcrYv2C2dCtqPyg8GIiIiov/SqAt20d+C9qPyg4GIiIjov/SXOHgeXuKgYmIgIiIi+i9LCwVea/r8M/Zea+rOA9krIAYiIiKi/8rVCew48/wLL+44k8jrEFVAPMuMiEpE9mMd1sRcx9+pD1HduRKG+tWAjRV/c1H58qIb6QK8kW5FxUBERMU2e88FrPglHk//aJ655yJGt/fG1Fd530AqP3gjXfliICKiYpm95wKWHYk3atcJSO0MRVRe8Ea68sXt2URUZNmPdVj+i3EYetryX+KR/VhnooqIioc30pUvBiIiKrLVx67jRXdDFOJJP6LygDfSlS8GIiIqshPX75ZoP6KyIKiRO5YOaQ7NM9cj0qhtsXRIc95It4LiMUREVGSVbAr2EVLQfkRlBW+kKz/8lCKiIgtpXg3bTt8qUD+i8oY30pUX7jIjoiJrU7sqKtlYPrePvY0l2tSuaqKKiIiKhoGIiIrM0kKBBf2aPrfP/H5NuZuBiMo8BiIiKpagRu6IHNIcbo5Kg3aNSolIHoBKROUEjyEiomLjAahEVN4xEBFRieABqERUnnGXGREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREcmelbkLICKigrutzcLrS35F6oMcONtbY+tb7eCiUpq7LKJyT1ZbiBYvXowaNWrA1tYWvr6+iI2NNXdJREQF1mTaPrSctR830zLxMCcXN9My0XLWfjSZts/cpRGVe7IJRBs3bsTEiRMRERGBU6dOoWnTpggMDERKSoq5SyMieqEm0/ZBm/k4z2HazMcMRUTFJJtAtGDBAowePRojRoyAj48PIiMjUalSJXz33XfmLo2I6Llua7PyDUN62szHuK3NMlFFRBWPLAJRdnY2Tp48CX9/f6nNwsIC/v7+iImJMeqflZUFrVZr8CAiMpfXl/xaov2IyJgsAtGdO3eQm5sLNzc3g3Y3NzckJSUZ9Z89ezbUarX08PT0NFWpRERGUh/klGg/IjImi0BUWFOnTkV6err0uHHjhrlLIiIZc7a3LtF+RGRMFoGoatWqsLS0RHJyskF7cnIyNBqNUX+lUgmVSmXwICIyl61vtSvRfkRkTBaByMbGBi1atEB0dLTUptPpEB0dDT8/PzNWRkT0Yi4qJVS2z79snMrWitcjIioGWQQiAJg4cSJWrFiB1atX4+LFiwgLC8ODBw8wYsQIc5dGRPRCZ6cF5huKVLZWODst0MQVEVUssrlSdf/+/XH79m18/PHHSEpKQrNmzbB3716jA62JiMqqs9MCeaVqolKiEEIIcxdR1mm1WqjVaqSnp/N4IiIionKiMN/fstllRkRERJQfBiIiIiKSPQYiIiIikj0GIiIiIpI9BiIiIiKSPQYiIiIikj0GIiIiIpI9BiIiIiKSPQYiIiIikj0GIiIiIpI9BiIiIiKSPdnc3JWISleuTiA2PhUpGZlwdbRFK29nWFoozF0WUZFxnZYXBiIiKra9cYmYvvMCEtMzpTZ3tS0ievggqJG7GSsjKhqu0/LDXWZEVCx74xIRtvaUwRcHACSlZyJs7SnsjUs0U2VERcN1Wp4YiIioyHJ1AtN3XoDIY5i+bfrOC8jV5dWDqOzhOi1fDEREVGSx8alGv6KfJgAkpmciNj7VdEURFQPXafliICKiIkvJyP+Loyj9iMyN67R8MRARUZG5OtqWaD8ic+M6LV8MRERUZK28neGutkV+JyIr8OTMnFbezqYsi6jIuE7LFwMRERWZpYUCET18AMDoC0T/PKKHD6/dQuUG12n5YiAiomIJauSOpUOaQ6M23IWgUdti6ZDmvGYLlTtcp+VJIYTguYMvoNVqoVarkZ6eDpVKZe5yiMokXtWXKhqu0+VfYb6/eaVqIioRlhYK+NWqYu4yiEoM12l54S4zIiIikj0GIiIiIpI9BiIiIiKSPQYiIiIikj0GIiIiIpI9BiIiIiKSPQYiIiIikj0GIiIiIpI9BiIiIiKSPV6pugD0dzfRarVmroSIiIgKSv+9XZC7lDEQFUBGRgYAwNPT08yVEBERUWFlZGRArVY/tw9v7loAOp0Ot27dgqOjIxSKkr2xn1arhaenJ27cuMEbx5YiLmfT4HI2DS5n0+GyNo3SWs5CCGRkZMDDwwMWFs8/SohbiArAwsIC1apVK9VpqFQq/rGZAJezaXA5mwaXs+lwWZtGaSznF20Z0uNB1URERCR7DEREREQkewxEZqZUKhEREQGlUmnuUio0LmfT4HI2DS5n0+GyNo2ysJx5UDURERHJHrcQERERkewxEBEREZHsMRARERGR7DEQERERkewxEJUhr732Gry8vGBrawt3d3cMHToUt27dMndZFcr169cxatQoeHt7w87ODrVq1UJERASys7PNXVqFNHPmTLRp0waVKlWCk5OTucupMBYvXowaNWrA1tYWvr6+iI2NNXdJFc6RI0fQo0cPeHh4QKFQYNu2beYuqcKZPXs2WrZsCUdHR7i6uqJXr164fPmy2ephICpDOnfujE2bNuHy5cv48ccfce3aNfTp08fcZVUoly5dgk6nw7Jly3D+/Hl88cUXiIyMxAcffGDu0iqk7Oxs9O3bF2FhYeYupcLYuHEjJk6ciIiICJw6dQpNmzZFYGAgUlJSzF1ahfLgwQM0bdoUixcvNncpFdbhw4cRHh6O3377DVFRUcjJyUFAQAAePHhglnp42n0ZtmPHDvTq1QtZWVmwtrY2dzkV1rx587B06VL89ddf5i6lwlq1ahXGjx+PtLQ0c5dS7vn6+qJly5b4+uuvATy516KnpyfGjRuH999/38zVVUwKhQJbt25Fr169zF1KhXb79m24urri8OHD6NChg8mnzy1EZVRqairWrVuHNm3aMAyVsvT0dDg7O5u7DKIXys7OxsmTJ+Hv7y+1WVhYwN/fHzExMWasjKj40tPTAcBsn8cMRGXMlClTYG9vjypVqiAhIQHbt283d0kV2tWrV7Fo0SL861//MncpRC90584d5Obmws3NzaDdzc0NSUlJZqqKqPh0Oh3Gjx+Ptm3bolGjRmapgYGolL3//vtQKBTPfVy6dEnqP3nyZPzxxx/4+eefYWlpiWHDhoF7NV+ssMsZAP755x8EBQWhb9++GD16tJkqL3+KsqyJiJ4nPDwccXFx2LBhg9lqsDLblGVi0qRJGD58+HP71KxZU/p/1apVUbVqVdStWxcNGjSAp6cnfvvtN/j5+ZVypeVbYZfzrVu30LlzZ7Rp0wbLly8v5eoqlsIuayo5VatWhaWlJZKTkw3ak5OTodFozFQVUfGMHTsWu3btwpEjR1CtWjWz1cFAVMpcXFzg4uJSpNfqdDoAQFZWVkmWVCEVZjn/888/6Ny5M1q0aIGVK1fCwoIbSgujOOs0FY+NjQ1atGiB6Oho6QBfnU6H6OhojB071rzFERWSEALjxo3D1q1bcejQIXh7e5u1HgaiMuL48eM4ceIE2rVrh8qVK+PatWv46KOPUKtWLW4dKkH//PMPOnXqhOrVq+Pzzz/H7du3pWH8hV3yEhISkJqaioSEBOTm5uL06dMAgNq1a8PBwcG8xZVTEydORGhoKF5++WW0atUKCxcuxIMHDzBixAhzl1ah3L9/H1evXpWex8fH4/Tp03B2doaXl5cZK6s4wsPDsX79emzfvh2Ojo7ScXBqtRp2dnamL0hQmXD27FnRuXNn4ezsLJRKpahRo4YYM2aMuHnzprlLq1BWrlwpAOT5oJIXGhqa57I+ePCguUsr1xYtWiS8vLyEjY2NaNWqlfjtt9/MXVKFc/DgwTzX3dDQUHOXVmHk91m8cuVKs9TD6xARERGR7PHgCSIiIpI9BiIiIiKSPQYiIiIikj0GIiIiIpI9BiIiIiKSPQYiIiIikj0GIiIiIpI9BiIikqVDhw5BoVAgLS3tuf1q1KiBhQsXmqQmIjIfBiIiKtOGDx8OhUIBhUIBGxsb1K5dGzNmzMDjx4+LNd42bdogMTERarUaALBq1So4OTkZ9Ttx4gTefPPNYk2LiMo+3suMiMq8oKAgrFy5EllZWdizZw/Cw8NhbW2NqVOnFnmcNjY2Bbp/HW9kSyQP3EJERGWeUqmERqNB9erVERYWBn9/f+zYsQP37t3DsGHDULlyZVSqVAndunXDlStXpNf9/fff6NGjBypXrgx7e3s0bNgQe/bsAWC4y+zQoUMYMWIE0tPTpa1R06ZNA2C8yywhIQE9e/aEg4MDVCoV+vXrh+TkZGn4tGnT0KxZM6xZswY1atSAWq3GgAEDkJGRYZJlRURFw0BEROWOnZ0dsrOzMXz4cPz+++/YsWMHYmJiIITAq6++ipycHABP7qadlZWFI0eO4Ny5c5gzZw4cHByMxtemTRssXLgQKpUKiYmJSExMxLvvvmvUT6fToWfPnkhNTcXhw4cRFRWFv/76C/379zfod+3aNWzbtg27du3Crl27cPjwYXz22WelszCIqERwlxkRlRtCCERHR2Pfvn3o1q0btm3bhqNHj6JNmzYAgHXr1sHT0xPbtm1D3759kZCQgJCQEDRu3BgAULNmzTzHa2NjA7VaDYVC8dzdaNHR0Th37hzi4+Ph6ekJAPjPf/6Dhg0b4sSJE2jZsiWAJ8Fp1apVcHR0BAAMHToU0dHRmDlzZoktCyIqWdxCRERl3q5du+Dg4ABbW1t069YN/fv3x/Dhw2FlZQVfX1+pX5UqVVCvXj1cvHgRAPD222/j008/Rdu2bREREYGzZ88Wq46LFy/C09NTCkMA4OPjAycnJ2mawJPdbPowBADu7u5ISUkp1rSJqHQxEBFRmde5c2ecPn0aV65cwaNHj7B69WooFIoXvu6NN97AX3/9haFDh+LcuXN4+eWXsWjRolKv19ra2uC5QqGATqcr9ekSUdExEBFRmWdvb4/atWvDy8sLVlZP9vQ3aNAAjx8/xvHjx6V+d+/exeXLl+Hj4yO1eXp6YsyYMdiyZQsmTZqEFStW5DkNGxsb5ObmPreOBg0a4MaNG7hx44bUduHCBaSlpRlMk4jKHwYiIiqX6tSpg549e2L06NH49ddfcebMGQwZMgQvvfQSevbsCQAYP3489u3bh/j4eJw6dQoHDx5EgwYN8hxfjRo1cP/+fURHR+POnTt4+PChUR9/f380btwYgwcPxqlTpxAbG4thw4ahY8eOePnll0t1fomodDEQEVG5tXLlSrRo0QLdu3eHn58fhBDYs2ePtMsqNzcX4eHhaNCgAYKCglC3bl0sWbIkz3G1adMGY8aMQf/+/eHi4oK5c+ca9VEoFNi+fTsqV66MDh06wN/fHzVr1sTGjRtLdT6JqPQphBDC3EUQERERmRO3EBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkez9P4R3cRW82FoGAAAAAElFTkSuQmCC" + "image/png": "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ssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyZ9ZANHv2bLRs2RKOjo5wdXVFr169cPnyZYM+nTp1gkKhMHiMGTPGoE9CQgKCg4NRqVIluLq6YvLkyXj8+LFBn0OHDqF58+ZQKpWoXbs2Vq1aVdqzR0REROWEWQPR4cOHER4ejt9++w1RUVHIyclBQEAAHjx4YNBv9OjRSExMlB5z586VhuXm5iI4OBjZ2dk4duwYVq9ejVWrVuHjjz+W+sTHxyM4OBidO3fG6dOnMX78eLzxxhvYt2+fyeaViIiIyi6FEEKYuwi927dvw9XVFYcPH0aHDh0APNlC1KxZMyxcuDDP1/z000/o3r07bt26BTc3NwBAZGQkpkyZgtu3b8PGxgZTpkzB7t27ERcXJ71uwIABSEtLw969e19Yl1arhVqtRnp6OlQqVfFnlIiIiEpdYb6/y9QxROnp6QAAZ2dng/Z169ahatWqaNSoEaZOnYqHDx9Kw2JiYtC4cWMpDAFAYGAgtFotzp8/L/Xx9/c3GGdgYCBiYmLyrCMrKwtardbgQURERBWXlbkL0NPpdBg/fjzatm2LRo0aSe2DBg1C9erV4eHhgbNnz2LKlCm4fPkytmzZAgBISkoyCEMApOdJSUnP7aPVavHo0SPY2dkZDJs9ezamT59e4vNIREREZVOZCUTh4eGIi4vDr7/+atD+5ptvSv9v3Lgx3N3d8corr+DatWuoVatWqdQydepUTJw4UXqu1Wrh6elZ4tPJ1QnExqciJSMTro62aOXtDEsLRYlPh4iIiJ6vTASisWPHYteuXThy5AiqVav23L6+vr4AgKtXr6JWrVrQaDSIjY016JOcnAwA0Gg00r/6tqf7qFQqo61DAKBUKqFUKos8PwWxNy4R03deQGJ6ptTmrrZFRA8fBDVyL9VpExERkSGzHkMkhMDYsWOxdetWHDhwAN7e3i98zenTpwEA7u5PQoOfnx/OnTuHlJQUqU9UVBRUKhV8fHykPtHR0QbjiYqKgp+fXwnNSeHsjUtE2NpTBmEIAJLSMxG29hT2xiWapS4iIiK5MmsgCg8Px9q1a7F+/Xo4OjoiKSkJSUlJePToEQDg2rVr+OSTT3Dy5Elcv34dO3bswLBhw9ChQwc0adIEABAQEAAfHx8MHToUZ86cwb59+/Dhhx8iPDxc2sozZswY/PXXX3jvvfdw6dIlLFmyBJs2bcKECRNMPs+5OoHpOy8gr1P79G3Td15Arq7MnPxHRERU4Zk1EC1duhTp6eno1KkT3N3dpcfGjRsBADY2Nti/fz8CAgJQv359TJo0CSEhIdi5c6c0DktLS+zatQuWlpbw8/PDkCFDMGzYMMyYMUPq4+3tjd27dyMqKgpNmzbF/Pnz8c033yAwMNDk8xwbn2q0ZehpAkBieiZi41NNVxQREZHMmfUYohddAsnT0xOHDx9+4XiqV6+OPXv2PLdPp06d8McffxSqvtKQkpF/GCpKPyIiIiq+MnUdIjlwdbQt0X5ERERUfAxEJtbK2xnualvkd3K9Ak/ONmvl7ZxPDyIiIippDEQmZmmhQESPJ2e/PRuK9M8jevjwekREREQmxEBkBkGN3LF0SHNo1Ia7xTRqWywd0pzXISIiIjKxMnFhRjkKauSOrj4aXqmaiIioDGAgMiNLCwX8alUxdxlERESyx11mREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQke1bmLoCIiIjkK1cnEBufipSMTLg62qKVtzMsLRQmr4OBiIiIiMxib1wipu+8gMT0TKnNXW2LiB4+CGrkbtJauMuMiIiITG5vXCLC1p4yCEMAkJSeibC1p7A3LtGk9TAQERERkUnl6gSm77wAkccwfdv0nReQq8urR+lgICIiIiKTio1PNdoy9DQBIDE9E7HxqSariYGIiIiITColI/8wVJR+JYGBiIiIiEzK1dG2RPuVBAYiIiIiMqlW3s5wV9siv5Pr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9erVQ79+/VClShX89ttvcHFxAQB88cUX6N69O0JCQtChQwdoNBps2bJFer2lpSV27doFS0tL+Pn5YciQIRg2bBhmzJhhrlkiIio03qzYdF50ALsAD2CvqBRCCL6rL6DVaqFWq5Gens7jiYjIbHgdotIXc+0uBq747YX9vh/dmgewlwOF+f4u02eZERHR//BmxaUvSVuwA9ML2o/KDwYiIqJyhDcrLl2p97NKtB+VH2X6GCIiIiJTcrYv2C2dCtqPyg8GIiIiov/SqAt20d+C9qPyg4GIiIjov/SXOHgeXuKgYmIgIiIi+i9LCwVea/r8M/Zea+rOA9krIAYiIiKi/8rVCew48/wLL+44k8jrEFVAPMuMiEpE9mMd1sRcx9+pD1HduRKG+tWAjRV/c1H58qIb6QK8kW5FxUBERMU2e88FrPglHk//aJ655yJGt/fG1Fd530AqP3gjXfliICKiYpm95wKWHYk3atcJSO0MRVRe8Ea68sXt2URUZNmPdVj+i3EYetryX+KR/VhnooqIioc30pUvBiIiKrLVx67jRXdDFOJJP6LygDfSlS8GIiIqshPX75ZoP6KyIKiRO5YOaQ7NM9cj0qhtsXRIc95It4LiMUREVGSVbAr2EVLQfkRlBW+kKz/8lCKiIgtpXg3bTt8qUD+i8oY30pUX7jIjoiJrU7sqKtlYPrePvY0l2tSuaqKKiIiKhoGIiIrM0kKBBf2aPrfP/H5NuZuBiMo8BiIiKpagRu6IHNIcbo5Kg3aNSolIHoBKROUEjyEiomLjAahEVN4xEBFRieABqERUnnGXGREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREcmelbkLICKigrutzcLrS35F6oMcONtbY+tb7eCiUpq7LKJyT1ZbiBYvXowaNWrA1tYWvr6+iI2NNXdJREQF1mTaPrSctR830zLxMCcXN9My0XLWfjSZts/cpRGVe7IJRBs3bsTEiRMRERGBU6dOoWnTpggMDERKSoq5SyMieqEm0/ZBm/k4z2HazMcMRUTFJJtAtGDBAowePRojRoyAj48P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", + "text/plain": [ + "
" + ] }, "metadata": {}, "output_type": "display_data" @@ -345,19 +377,19 @@ "plt.ylabel('Value')\n", "plt.title(f'Agent Position vs Value at fundamental {fundamental_val}')\n", "plt.show()\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-26T20:44:58.709570600Z", - "start_time": "2024-03-26T20:44:58.596987100Z" - } - }, - "id": "44a74cbe8acf673", - "execution_count": 38 + ] }, { "cell_type": "code", + "execution_count": 5, + "id": "31f002d1c196705a", + "metadata": { + "ExecuteTime": { + "end_time": "2024-03-27T23:40:00.547410Z", + "start_time": "2024-03-27T23:40:00.470896Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -368,8 +400,10 @@ }, { "data": { - "text/plain": "
", - "image/png": "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rl69irNnzyIyMhJxcXEYNWoUrly5gvfeew+nTp3C1atXsWvXLowdOxbdunVDy5YtAQBBQUFQq9UYM2YM/vjjD+zbtw9z5sxBREQEbG1tAQCTJk3Cn3/+ibfeegsXLlzAypUr8f3332P69OlmO+8QP0+sGt0GHir9bjEPlR1WjW6DED9PM2VGREQkT2addj9+/HgcOHAA6enpUKlUaNmyJWbPno3evXvj+vXrGD16NJKSknD37l14e3tj4MCBmDNnjl4X1rVr1zB58mTExcXB0dERYWFh+Oijj1Cjxv8Nj4qLi8P06dORnJyMevXqYe7cuQgPDzc4T2NOu38YV6omIiKqOpX5/ba4dYgsUVUVRERERFR1quU6RERERETmwoKIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPbMWRKtWrULLli2hVCqhVCoREBCAn376Sdqfn5+PiIgI1K5dG05OThg8eDAyMzP1niM1NRWhoaFwcHCAm5sbZs2ahQcPHujFxMXFoU2bNrC1tUXjxo0RHR1titMjIiKiasKsBVG9evXw0Ucf4dSpUzh58iR69eqF/v3749y5cwCA6dOnIyYmBj/88AMOHz6MtLQ0DBo0SHp8cXExQkNDUVhYiCNHjmDdunWIjo7GvHnzpJiUlBSEhoaiZ8+eSExMxLRp0zBhwgTs27fP5OdLRERElkkhhBDmTuJhrq6uWLJkCYYMGYK6deti06ZNGDJkCADgwoULaN68ORISEtCxY0f89NNP6Nu3L9LS0uDu7g4AWL16NWbPno2bN2/CxsYGs2fPxp49e5CUlCQdY8SIEcjJycHevXsNykmj0UClUiE3NxdKpdL4J01ERERGV5nfb4sZQ1RcXIzNmzfj7t27CAgIwKlTp1BUVITAwEAp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" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkQAAAHHCAYAAABeLEexAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABdlklEQVR4nO3deXxM9/4/8NckZM9MBNmuiFiKkeCiiJ1GEg21L7Ulil4aWpRqehG6KVrVqqV1W1FLaV1baGkskbZib0oEPzSEZlORTCxZZD6/P3LnfI0sJkxmJs7r+XjM42HOec+c95kZM+98tqMQQggQERERyZiVuRMgIiIiMjcWRERERCR7LIiIiIhI9lgQERERkeyxICIiIiLZY0FEREREsseCiIiIiGSPBRERERHJHgsiIiIikj0WRPRMCQ8PR4MGDQyKnT9/PhQKRdUm9Ixo0KABwsPDzZ2GUZ04cQKdOnWCo6MjFAoFEhMTTXr8ynxW5SAuLg4KhQJxcXHmToVkigWRhVm5ciUUCgU6dOhg7lTKtHLlSkRHRxscr1AopJuVlRW8vLwQFBRksi+9e/fuYf78+bL5kl26dCkUCgX2799fbsyaNWugUCiwa9cuE2ZWtdLS0jB//nyDi5qioiIMHToU2dnZ+PTTT7F+/Xr4+PhUbZLPuA8//BA7duwwybFOnTqFkJAQKJVKODs7IygoqMz3vqioCAsWLEDDhg1ha2uLhg0b4v3338eDBw/04sLDw/W+qx69/fXXXwBKvk9WrFiBoKAgeHp6wtnZGf/85z+xatUqFBcXlzr+Bx98gJdeegnu7u5QKBSYP3/+E5/zBx98AIVCAT8/P73tVZnT/v370bNnT9SpUwcuLi5o37491q9frxcTHR1d4Wu3ceNGKVb3R+ijNzs7uyd+XYxKkEXp1KmTaNCggQAgLl26ZO50SmnRooXo3r27wfEARO/evcX69evFt99+KxYsWCDc3d2FQqEQP/74o9HzKywsFPn5+dL9mzdvCgAiKiqqVGxRUZG4f/++0XMwp7/++ktYWVmJcePGlRvTo0cPUbt2bVFYWGjw8/r4+IiwsDAjZFg1Tpw4IQCItWvXGhR//vx5AUCsWbOmahOrQFhYmPDx8THb8Y3N0dHxqT4jhw4dEgDEoUOHKow7deqUsLOzE02aNBEff/yxWLx4sWjQoIFQKpXiwoULerHDhg0TCoVCjB8/XqxatUqEhYUJAGLixIl6cUeOHBHr16/Xu3377bfCwcFBqNVqKe7s2bNCoVCIwMBAsXjxYrF69WoxcOBAAUCMHTu2VK4AhIeHhwgODi73e8gQ169fFw4ODsLR0VG0aNFCb19V5bRz506hUChEp06dxPLly8UXX3whunXrJgCIpUuXSnFXrlwp9dqtX79etGnTRlhbW4v09HQpNioqSgAQq1at0ovdtGnTE70uxsaCyIL8+eefAoDYtm2bqFu3rpg/f765UyrlSQqiiIgIvW1nzpwRAERQUJCRsyutooLoWfXCCy8IlUqlVxjq3LhxQ1hZWYlJkyZV6jmftYLo8OHDAoD44YcfqjaxCrAg0mdoQfTiiy+KWrVqib///lvalpaWJpycnMSgQYOkbcePHxcAxNy5c/Ue/+abbwqFQiH++OOPCo/zyy+/CADigw8+kLbdvHlTJCUllYodN25cmX/EpqSkSI97mu+h4cOHi169eonu3buXKoiqKqfevXsLLy8vve+RoqIi0ahRI9GyZcsK8713755wdnYWvXv31tuuK4hu3rxZ4ePNhV1mFmTjxo2oVasWQkNDMWTIEL2mxofdunULY8aMgVKphIuLC8LCwvDHH39AoVCU6s66cOEChgwZAldXV9jZ2aFdu3alukp0TZ6//fYbZsyYgbp168LR0REDBw7EzZs3pbgGDRrg3LlzOHz4sNTU2aNHj0qfp7+/P+rUqYOUlBRp28GDB9G1a1c4OjrCxcUF/fv3x/nz5/Uel5eXh2nTpqFBgwawtbWFm5sbevfujdOnT0sxD4/LuHr1KurWrQsAWLBggZSzrom4rDFEDx48wHvvvYdGjRrB1tYWDRo0wDvvvIOCggK9uAYNGqBv37749ddf0b59e9jZ2aFhw4b49ttvKzz3oqIiuLq6Yty4caX2aTQa2NnZYebMmdK25cuXo0WLFnBwcECtWrXQrl07bNq0qcJjjB49Grm5udizZ0+pfZs3b4ZWq8WoUaMAAB9//DE6deqE2rVrw97eHm3btsXWrVsrfH6g/PFXus/S1atX9bb/9NNP0vvr7OyM0NBQnDt37rHHyc7OxsyZM+Hv7w8nJycolUr06dMHf/zxhxQTFxeH559/HgAwbtw46X0ur2s3PDwc3bt3BwAMHTpU73Pco0ePMj/Tj473uXr1KhQKBT7++GN89dVX0ufl+eefx4kTJ0o9fseOHfDz84OdnR38/Pywffv2MnMz9P1QKBSYMmUKfvjhB6jVatjb2yMgIABnz54FAHz55Zdo3Lgx7Ozs0KNHj1LvBwAcO3YMISEhUKlUcHBwQPfu3fHbb7/pxeje58uXLyM8PBwuLi5QqVQYN24c7t27p5fP3bt3sW7dOun11405u3btGl577TU0bdoU9vb2qF27NoYOHVpmTob45ZdfEBgYiNq1a0vbPD090b17d+zevRt37tyR4gBgxIgReo8fMWIEhBDYsmVLhcfZtGkTFAoFRo4cKW2rU6cOWrRoUSp24MCBAFDqO8sYY8Ti4+OxdetWLFu2rMz9VZWTRqNBrVq1YGtrK22rUaMG6tSpA3t7+wofGxMTg7y8POl75lFCCGg0GgghDMrFVFgQWZCNGzdi0KBBsLGxwcsvv4xLly6V+nLVarXo168fvvvuO4SFheGDDz5Aeno6wsLCSj3fuXPn0LFjR5w/fx5vv/02PvnkEzg6OmLAgAFlfiFPnToVf/zxB6KiojB58mTExMRgypQp0v5ly5ahXr16aNasGdavX4/169fj3//+d6XP8/bt27h9+7b0hbZ//34EBwcjKysL8+fPx4wZM3DkyBF07txZ70tz0qRJWLVqFQYPHoyVK1di5syZsLe3L/UfXqdu3bpYtWoVgJIvB13OgwYNKje3CRMmYN68eWjTpg0+/fRTdO/eHQsXLiz1pQoAly9fxpAhQ9C7d2988sknqFWrFsLDwyv8oa9ZsyYGDhyIHTt2oLCwUG/fjh07UFBQIB1rzZo1eP3116FWq7Fs2TIsWLAArVu3xrFjx8p9fgAYNGgQ7OzsyiycNm3aBB8fH3Tu3BkA8Nlnn+Gf//wn3n33XXz44YeoUaMGhg4dWmYx9aTWr1+P0NBQODk5YdGiRZg7dy6Sk5PRpUuXx/4o/vnnn9ixYwf69u2LpUuXYtasWTh79iy6d++OtLQ0AEDz5s3x7rvvAgBeffVV6X3u1q1bmc/5r3/9C++88w4A4PXXX3/izzFQ8nouWbIE//rXv/D+++/j6tWrGDRoEIqKiqSYn3/+GYMHD4ZCocDChQsxYMAAjBs3DidPniz1fJV5P3755Re8+eabCAsLw/z583H+/Hn07dsXK1aswOeff47XXnsNs2bNQkJCAl555RW9xx48eBDdunWDRqNBVFQUPvzwQ+Tk5KBXr144fvx4qWMNGzYMeXl5WLhwIYYNG4bo6GgsWLBA2r9+/XrY2tqia9eu0uv/r3/9C0DJ4PUjR45gxIgR+PzzzzFp0iQcOHAAPXr00CuqDFVQUFDmD7KDgwMKCwuRlJQkxQEoFevg4ACgZBxSeYqKivD999+jU6dOBhUQGRkZAEqKE2MqLi7G1KlTMWHCBPj7+1fqsU+bU48ePXDu3DnMnTsXly9fxpUrV/Dee+/h5MmTeOuttyp87MaNG2Fvb1/ud23Dhg2hUqng7OyM0aNHIzMz84lyNDozt1DR/5w8eVIAELGxsUIIIbRarahXr55444039OL++9//CgBi2bJl0rbi4mLRq1evUl0GL7zwgvD399dr8tRqtaJTp06iSZMm0ra1a9cKACIwMFBotVpp+/Tp04W1tbXIycmRtj1Jl9n48ePFzZs3RVZWljh27Jh44YUXBADxySefCCGEaN26tXBzcxO3bt2SHvfHH38IKysrvT5wlUpVqvvtUY92Q1TULKxrvtVJTEwUAMSECRP04mbOnCkAiIMHD0rbfHx8BAARHx8vbcvKyhK2trbizTffrDDHffv2CQAiJiZGb/uLL74oGjZsKN3v379/qeZxQw0dOlTY2dmJ3NxcaduFCxcEABEZGSltu3fvnt7jCgsLhZ+fn+jVq5fe9ke7zB597XR0nyVds3xeXp5wcXEpNWYjIyNDqFSqUtsflZ+fL4qLi/W2paSkCFtbW/Huu+9K2yrbZabrnnm0y6x79+5lfr4f/VylpKQIAKJ27doiOztb2r5z585S723r1q2Fp6en3v+jn3/+WQAo1WVm6PsBQNja2kqvsxBCfPnll9L4EI1GI22PjIzUe0+0Wq1o0qSJCA4O1vv/fu/ePeHr66vXzaF7n1955RW94w8cOFDUrl1bb1t5XWaPnpMQQiQkJAgA4ttvv5W2Gdpl5u/vL5577jnx4MEDaVtBQYGoX7++ACC2bt0qhPi/78r169frPX716tUCgPDz8yv3GDExMQKAWLlyZYW56I6tVquFr6+vKCoqKjPmSbvMvvjiC6FSqURWVpYQQpTZZVZVOd25c0cagwVAABAODg5ix44dFR771q1bwsbGRgwbNqzUvmXLlokpU6aIjRs3iq1bt4o33nhD1KhRQzRp0kTvu8pc2EJkITZu3Ah3d3f07NkTQEkT9PDhw7F582a9mQJ79+5FzZo1MXHiRGmblZUVIiIi9J4vOzsbBw8elP6y+/vvv/H333/j1q1bCA4OxqVLl6SZEzqvvvqqXjdI165dUVxcjGvXrj3VuX399deoW7cu3Nzc0KFDB6lrbtq0aUhPT0diYiLCw8Ph6uoqPaZly5bo3bs3fvzxR2mbi4sLjh07JrUMGJvuWDNmzNDb/uabbwJAqb/S1Wo1unbtKt2vW7cumjZtij///LPC4/Tq1Qt16tTRa7K/ffs2YmNjMXz4cGmbi4sLbty4UWYXzOOMHj0a+fn52LZtm7RN12L0cDP2w3893759G7m5uejatateN+TTiI2NRU5ODl5++WXpM/j333/D2toaHTp0wKFDhyp8vK2tLaysSr6miouLcevWLTg5OaFp06ZGy/FpDB8+HLVq1ZLu6z4Pus+A7vMdFhYGlUolxfXu3RtqtbrU81Xm/XjhhRf0Wi90M1MHDx4MZ2fnUtt1OSUmJuLSpUsYOXIkbt26Jb0nd+/exQsvvID4+HhotVq9Y02aNEnvfteuXXHr1i1oNJoKXp3S51RUVIRbt26hcePGcHFxeaL38LXXXsP/+3//D+PHj0dycjKSkpIwduxYpKenAwDu378PAHjxxRfh4+ODmTNnYtu2bbh27Rq+//57/Pvf/0aNGjWkuLJs2rQJNWvWxLBhwx6bz5QpU5CcnIwvvvgCNWrUqPT5lOfWrVuYN28e5s6dK3X9G8oYOdna2uK5557DkCFD8N1332HDhg1o164dRo8ejaNHj5b7uK1bt6KwsLDM7rI33ngDy5cvx8iRIzF48GAsW7YM69atw6VLl7By5conytOYWBBZgOLiYmzevBk9e/ZESkoKLl++jMuXL6NDhw7IzMzEgQMHpNhr167B09NTavbVady4sd79y5cvQwgh/Wd6+BYVFQUAyMrK0ntM/fr19e7rvuhv3779VOfXv39/xMbGYv/+/Th27Bj+/vtvfPLJJ7CyspKKraZNm5Z6XPPmzaUvagBYvHgxkpKS4O3tjfbt22P+/PmPLT4q49q1a7Cysir1Wnp4eMDFxaVUYfjo6wWUvGaPe71q1KiBwYMHY+fOnVKz/rZt21BUVKRXEM2ePRtOTk5o3749mjRpgoiIiFJjPMrTp08fuLq66nWbfffdd2jVqpXeeIPdu3ejY8eOsLOzg6urq9TNmJuba9BxHufSpUsASorARz+HP//8c6nP4KO0Wi0+/fRTNGnSBLa2tqhTpw7q1q2LM2fOGC3Hp/G4/zO6z0yTJk1KPbasz3xl3o9Hj60ruLy9vcvcrstJ956EhYWVek/+85//oKCgoNTxnua74f79+5g3bx68vb313sOcnJwneg8nTZqEd955B5s2bUKLFi3g7++PK1euSN04Tk5OAAA7Ozvs2bMHtWvXxuDBg9GgQQOMHTsW8+bNg6urqxT3qDt37mDnzp0IDg7WG6dUliVLlmDNmjV477338OKLL1b6XCoyZ84cuLq6YurUqZV6nLFymjJlCmJiYrB582aMGDECo0aNwv79++Hp6Yk33nij3Mdt3LgRrq6u6NOnj0HHGTlyJDw8PCpcKsRUjFfO0hM7ePAg0tPTsXnzZmzevLnU/o0bNyIoKKhSz6n7C2/mzJkIDg4uM+bRH35ra+sy48RTDnyrV68eAgMDn+o5gJJxDF27dsX27dvx888/Y8mSJVi0aBG2bdtm8H8+Qxi6WOPTvF4jRozAl19+iZ9++gkDBgzA999/j2bNmqFVq1ZSTPPmzXHx4kXs3r0be/fuxX//+1+sXLkS8+bN0xu/URbdX7dr1qxBZmYmUlNTcenSJSxevFiK+eWXX/DSSy+hW7duWLlyJTw9PVGzZk2sXbv2sQO3y3uNHl33RPc5XL9+PTw8PErFP+6v1w8//BBz587FK6+8gvfeew+urq6wsrLCtGnTSrViGINCoSjz/StrPRfAuP9nKvt+lHfsx+Wke92WLFmC1q1blxn7aLHwNOc5depUrF27FtOmTUNAQABUKhUUCgVGjBjxxO/hBx98gJkzZ+LcuXNQqVTw9/eXxoU999xzUlyLFi2QlJSE5ORk3L59WxqAPn36dGlg/aN27NiBe/fulTsgWCc6OhqzZ8/GpEmTMGfOnCc6j/JcunQJX331FZYtW6bXIp6fn4+ioiJcvXoVSqVSr1XdmDkVFhbi66+/xltvvSW10AIl3yt9+vTBF198gcLCQtjY2Og9LjU1Fb/88gteffVV1KxZ0+DjeXt7Izs7+4nzNRYWRBZg48aNcHNzw4oVK0rt27ZtG7Zv347Vq1fD3t4ePj4+OHToEO7du6fXSnT58mW9xzVs2BBAyQfYGMWIjrFXdtYthnfx4sVS+y5cuIA6derA0dFR2ubp6YnXXnsNr732GrKystCmTRt88MEH5RZElcnXx8cHWq0Wly5dQvPmzaXtmZmZyMnJMerCfd26dYOnpye2bNmCLl264ODBg2UO7HV0dMTw4cMxfPhwFBYWYtCgQfjggw8QGRn52MXMRo0ahdWrV2PLli1ISUmBQqHAyy+/LO3/73//Czs7O+zbt09vJsnatWsfm7+uhSAnJwcuLi7S9kdb0Ro1agQAcHNze6LP4datW9GzZ098/fXXettzcnL0Bosa63NZq1atMlsdn7TbWPeZ0bXKPOzRz/zTvB+VoXtPlEqlSb4btm7dirCwMHzyySfStvz8fOTk5DzV8WrVqoUuXbpI9/fv3y9N+ng0r4dbRX/88Udotdpyz33jxo1wcnLCSy+9VO6xd+7ciQkTJmDQoEFlfm8/rb/++gtarRavv/46Xn/99VL7fX198cYbb+jNPDNmTrdu3cKDBw/K/EOgqKgIWq22zH3fffcdhBCPLSYfJoTA1atX8c9//vOpcjYGdpmZ2f3797Ft2zb07dsXQ4YMKXWbMmUK8vLypKnywcHBKCoqwpo1a6Tn0Gq1pf4DuLm5oUePHvjyyy+lvvWHPTydvjIcHR2f+ovsYZ6enmjdujXWrVun97xJSUn4+eefpSbf4uLiUs3rbm5u8PLyKjUl/mG6otGQnHXHenR669KlSwEAoaGhj30OQ1lZWWHIkCGIiYnB+vXr8eDBA73uMqDkS+lhNjY2UKvVEELozWIqT+fOndGgQQNs2LABW7ZsQffu3VGvXj1pv7W1NRQKhd4X29WrVw1abVj3oxofHy9t0027flhwcDCUSiU+/PDDMnN+3OfQ2tq6VCvEDz/8UGr8m65oftrPZqNGjXDhwgW9vP744w+Duyof9fDn++HPb2xsLJKTk/Vin+b9qIy2bduiUaNG+Pjjj6Up6g8z9ndDWe/h8uXLy211exJbtmzBiRMnMG3aNL0WjUfdv38fc+fOhaenp94fBzo3b97E/v37MXDgwFLDEnTi4+MxYsQIdOvWDRs3bqzweIb6+++/ceHCBWnWnW5phkdvLVq0QP369bF9+3aMHz++ynJyc3ODi4sLtm/frjcb9s6dO4iJiUGzZs3KnOm3adMm1K9fX69QfVhZn61Vq1bh5s2bCAkJeaqcjYEtRGa2a9cu5OXllfvXSMeOHVG3bl1s3LgRw4cPx4ABA9C+fXu8+eabuHz5Mpo1a4Zdu3ZJzY0P/5W2YsUKdOnSBf7+/pg4cSIaNmyIzMxMJCQk4MaNG3pruRiqbdu2WLVqFd5//300btwYbm5u6NWr15Od/P8sWbIEffr0QUBAAMaPH4/79+9j+fLlUKlU0ppBeXl5qFevHoYMGYJWrVrByckJ+/fvx4kTJ/T+8nyUvb091Go1tmzZgueeew6urq7w8/Mrtfw9ALRq1QphYWH46quvkJOTg+7du+P48eNYt24dBgwYIA14N5bhw4dj+fLliIqKgr+/v16rFAAEBQXBw8MDnTt3hru7O86fP48vvvgCoaGheoNmy6NbQ+XDDz8EAGlquk5oaCiWLl2KkJAQjBw5EllZWVixYgUaN26MM2fOVPjcQUFBqF+/PsaPH49Zs2bB2toa33zzDerWrYvU1FQpTqlUYtWqVRgzZgzatGmDESNGSDF79uxB586d8cUXX5R7nL59++Ldd9/FuHHj0KlTJ5w9exYbN26UWkB1GjVqBBcXF6xevRrOzs5wdHREhw4d4Ovr+9jX6WGvvPIKli5diuDgYIwfPx5ZWVlYvXo1WrRoYdAA4rIsXLgQoaGh6NKlC1555RVkZ2dL60s9XJA8zftRGVZWVvjPf/6DPn36oEWLFhg3bhz+8Y9/4K+//sKhQ4egVCoRExNT6edt27Yt9u/fj6VLl8LLywu+vr7o0KED+vbti/Xr10OlUkGtViMhIQH79+9/7Pic8sTHx+Pdd99FUFAQateujaNHj2Lt2rUICQkpNbZl2LBh8PLyglqthkajwTfffIM///wTe/bsKfP/0JYtW/DgwYNyWziuXbuGl156CQqFAkOGDMEPP/ygt79ly5Zo2bKldH/9+vW4du2aVOjEx8fj/fffBwCMGTNGakH84osvsGDBAhw6dAg9evRAnTp1MGDAgFLH1/2x9vC+qsjJ2toaM2fOxJw5c9CxY0eMHTsWxcXF+Prrr3Hjxg1s2LChVG5JSUk4c+YM3n777XJbC318fDB8+HD4+/vDzs4Ov/76KzZv3ozWrVtLyzSYlXkmt5FOv379hJ2dnbh79265MeHh4aJmzZrSyqw3b94UI0eOFM7OzkKlUonw8HDx22+/CQBi8+bNeo+9cuWKGDt2rPDw8BA1a9YU//jHP0Tfvn2lqalC/N9U6RMnTug9tqxpsBkZGSI0NFQ4OzsLAI+dgo8yVqouy/79+0Xnzp2Fvb29UCqVol+/fiI5OVnaX1BQIGbNmiVatWolnJ2dhaOjo2jVqlWpabFlrf575MgR0bZtW2FjY6M3zbSsqeNFRUViwYIFwtfXV9SsWVN4e3uLyMjIUqs++/j4iNDQ0FLnUd607bJotVrh7e0tAIj333+/1P4vv/xSdOvWTdSuXVvY2tqKRo0aiVmzZlVqeuq5c+ekKdq3b98utf/rr78WTZo0Eba2tqJZs2Zi7dq1Zb4uZa1UferUKdGhQwdhY2Mj6tevL5YuXVpq2r3OoUOHRHBwsFCpVMLOzk40atRIhIeHi5MnT1aYf35+vnjzzTeFp6ensLe3F507dxYJCQllvs47d+4UarVa1KhR47FT8Mubdi+EEBs2bBANGzYUNjY2onXr1mLfvn3lTrtfsmRJqcejjKnM//3vf0Xz5s2Fra2tUKvVYtu2bWV+Vg19P8r6f1VeTuWd6++//y4GDRokfb58fHzEsGHDxIEDB6SY8lYWLut9vnDhgujWrZuwt7cXAKTPy+3bt8W4ceNEnTp1hJOTkwgODhYXLlwo9ZkydNr95cuXRVBQkKhTp470Oi1cuFAUFBSUil20aJFo1qyZsLOzE7Vq1RIvvfSS+P3338t97o4dOwo3Nze9Kf0P0+VY3u3R97179+7lxj58nrrX+XHnXta0+6rKSQghNm7cKNq3by9cXFyEvb296NChg95vx8PefvttAUCcOXOm3PwnTJgg1Gq1cHZ2FjVr1hSNGzcWs2fP1lsmwpwUQljYUpH0RHbs2IGBAwfi119/lRbdIyIiIsOwIKqG7t+/r9d/W1xcjKCgIJw8eRIZGRmPXVadiIiI9HEMUTU0depU3L9/HwEBASgoKMC2bdtw5MgRfPjhhyyGiIiIngBbiKqhTZs24ZNPPsHly5eRn5+Pxo0bY/LkyXrXHSMiIiLDsSAiIiIi2eM6RERERCR7LIiIiIhI9jio2gBarRZpaWlwdnY2+qUriIiIqGoIIZCXlwcvL6/HruDNgsgAaWlppa4gTURERNXD9evX9S5dVBYWRAbQLfF+/fp1KJVKM2dDREREhtBoNPD29jbockcsiAyg6yZTKpUsiIiIiKoZQ4a7cFA1ERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSAiIiIi2WNBRERERLLHgoiIiIhkjwURERERyR5XqjajYq3A8ZRsZOXlw83ZDu19XWFtxYvHEhERmZpZW4hWrVqFli1bSpfECAgIwE8//STt79GjBxQKhd5t0qRJes+RmpqK0NBQODg4wM3NDbNmzcKDBw/0YuLi4tCmTRvY2tqicePGiI6ONsXpVWhvUjq6LDqIl9ccxRubE/HymqPosugg9ialmzs1IiIi2TFrQVSvXj189NFHOHXqFE6ePIlevXqhf//+OHfunBQzceJEpKenS7fFixdL+4qLixEaGorCwkIcOXIE69atQ3R0NObNmyfFpKSkIDQ0FD179kRiYiKmTZuGCRMmYN++fSY914ftTUrH5A2nkZ6br7c9IzcfkzecZlFERERkYgohhDB3Eg9zdXXFkiVLMH78ePTo0QOtW7fGsmXLyoz96aef0LdvX6SlpcHd3R0AsHr1asyePRs3b96EjY0NZs+ejT179iApKUl63IgRI5CTk4O9e/calJNGo4FKpUJubu5TX9y1WCvQZdHBUsWQjgKAh8oOv87uxe4zIiKip1CZ32+LGVRdXFyMzZs34+7duwgICJC2b9y4EXXq1IGfnx8iIyNx7949aV9CQgL8/f2lYggAgoODodFopFamhIQEBAYG6h0rODgYCQkJ5eZSUFAAjUajdzOW4ynZ5RZDACAApOfm43hKttGOSURERBUz+6Dqs2fPIiAgAPn5+XBycsL27duhVqsBACNHjoSPjw+8vLxw5swZzJ49GxcvXsS2bdsAABkZGXrFEADpfkZGRoUxGo0G9+/fh729famcFi5ciAULFhj9XAEgK6/8YuhJ4oiIiOjpmb0gatq0KRITE5Gbm4utW7ciLCwMhw8fhlqtxquvvirF+fv7w9PTEy+88AKuXLmCRo0aVVlOkZGRmDFjhnRfo9HA29vbKM/t5mxn1DgiIiJ6embvMrOxsUHjxo3Rtm1bLFy4EK1atcJnn31WZmyHDh0AAJcvXwYAeHh4IDMzUy9Gd9/Dw6PCGKVSWWbrEADY2tpKM990N2Np7+sKT5UdyhsdpADgqSqZgk9ERESmYfaC6FFarRYFBQVl7ktMTAQAeHp6AgACAgJw9uxZZGVlSTGxsbFQKpVSt1tAQAAOHDig9zyxsbF645RMydpKgah+Jbk9WhTp7kf1U3NANRERkQmZtSCKjIxEfHw8rl69irNnzyIyMhJxcXEYNWoUrly5gvfeew+nTp3C1atXsWvXLowdOxbdunVDy5YtAQBBQUFQq9UYM2YM/vjjD+zbtw9z5sxBREQEbG1tAQCTJk3Cn3/+ibfeegsXLlzAypUr8f3332P69OlmO+8QP0+sGt0GHir9bjEPlR1WjW6DED9PM2VGREQkT2addj9+/HgcOHAA6enpUKlUaNmyJWbPno3evXvj+vXrGD16NJKSknD37l14e3tj4MCBmDNnjl4X1rVr1zB58mTExcXB0dERYWFh+Oijj1Cjxv8Nj4qLi8P06dORnJyMevXqYe7cuQgPDzc4T2NOu38YV6omIiKqOpX5/ba4dYgsUVUVRERERFR1quU6RERERETmwoKIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPbMWRKtWrULLli2hVCqhVCoREBCAn376Sdqfn5+PiIgI1K5dG05OThg8eDAyMzP1niM1NRWhoaFwcHCAm5sbZs2ahQcPHujFxMXFoU2bNrC1tUXjxo0RHR1titMjIiKiasKsBVG9evXw0Ucf4dSpUzh58iR69eqF/v3749y5cwCA6dOnIyYmBj/88AMOHz6MtLQ0DBo0SHp8cXExQkNDUVhYiCNHjmDdunWIjo7GvHnzpJiUlBSEhoaiZ8+eSExMxLRp0zBhwgTs27fP5OdLRERElkkhhBDmTuJhrq6uWLJkCYYMGYK6deti06ZNGDJkCADgwoULaN68ORISEtCxY0f89NNP6Nu3L9LS0uDu7g4AWL16NWbPno2bN2/CxsYGs2fPxp49e5CUlCQdY8SIEcjJycHevXsNykmj0UClUiE3NxdKpdL4J01ERERGV5nfb4sZQ1RcXIzNmzfj7t27CAgIwKlTp1BUVITAwEAp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", + "text/plain": [ + "
" + ] }, "metadata": {}, "output_type": "display_data" @@ -414,25 +448,17 @@ "plt.ylabel('Value')\n", "plt.title(f'Agent Position vs Value at fundamental {fundamental_val}')\n", "plt.show()\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-27T23:40:00.547410Z", - "start_time": "2024-03-27T23:40:00.470896Z" - } - }, - "id": "31f002d1c196705a", - "execution_count": 5 + ] }, { "cell_type": "code", - "outputs": [], - "source": [], + "execution_count": null, + "id": "d8c2f016f622c77c", "metadata": { "collapsed": false }, - "id": "d8c2f016f622c77c" + "outputs": [], + "source": [] } ], "metadata": { @@ -444,14 +470,14 @@ "language_info": { "codemirror_mode": { "name": "ipython", - "version": 2 + "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" + "pygments_lexer": "ipython3", + "version": "3.9.12" } }, "nbformat": 4, From 83777c7116adf6744c7d1d1e60223206831a1714 Mon Sep 17 00:00:00 2001 From: Rishith Seelam Date: Mon, 1 Jul 2024 11:13:38 -0400 Subject: [PATCH 04/34] prints for testing - to be removed later --- marketsim/private_values/private_values.py | 2 + .../simulator/sampled_arrival_simulator.py | 13 +- test_sim.ipynb | 142 +++++++++++++++--- 3 files changed, 131 insertions(+), 26 deletions(-) diff --git a/marketsim/private_values/private_values.py b/marketsim/private_values/private_values.py index 49bba33c..37871046 100644 --- a/marketsim/private_values/private_values.py +++ b/marketsim/private_values/private_values.py @@ -32,6 +32,8 @@ def __init__(self, q_max: int, val_var=5e6, random_seed: int = 0): self.extra_buy = min(self.values[-1].item(), 0) self.extra_sell = max(self.values[0].item(), 0) + print(self.values) + def value_for_exchange(self, position: int, order_type: int) -> float: """ Calculates the value associated with a given trade and order type. diff --git a/marketsim/simulator/sampled_arrival_simulator.py b/marketsim/simulator/sampled_arrival_simulator.py index 299069d5..fd2ffabb 100644 --- a/marketsim/simulator/sampled_arrival_simulator.py +++ b/marketsim/simulator/sampled_arrival_simulator.py @@ -1,9 +1,9 @@ import random -from fourheap.constants import BUY, SELL -from market.market import Market -from fundamental.lazy_mean_reverting import LazyGaussianMeanReverting -from agent.zero_intelligence_agent import ZIAgent -from agent.hbl_agent import HBLAgent +from marketsim.fourheap.constants import BUY, SELL +from marketsim.market.market import Market +from marketsim.fundamental.lazy_mean_reverting import LazyGaussianMeanReverting +from marketsim.agent.zero_intelligence_agent import ZIAgent +from marketsim.agent.hbl_agent import HBLAgent import torch.distributions as dist import torch import numpy as np @@ -120,7 +120,8 @@ def step(self): new_orders = market.step() for matched_order in new_orders: - agent_id = matched_order.order.agent_id + print(f"Matched Order: {matched_order}") + agent_id = matched_order.time.agent_id quantity = matched_order.order.order_type*matched_order.order.quantity cash = -matched_order.price*matched_order.order.quantity*matched_order.order.order_type self.agents[agent_id].update_position(quantity, cash) diff --git a/test_sim.ipynb b/test_sim.ipynb index 2c073b3c..0ce0a741 100644 --- a/test_sim.ipynb +++ b/test_sim.ipynb @@ -11,20 +11,7 @@ }, "collapsed": true }, - "outputs": [ - { - "ename": "ModuleNotFoundError", - "evalue": "No module named 'fourheap'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[1], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mmarketsim\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01msimulator\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01msampled_arrival_simulator\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m SimulatorSampledArrival\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mtqdm\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mnotebook\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m tqdm\n", - "File \u001b[0;32m~/Code/SURE-SRG/market-sim-py/marketsim/simulator/sampled_arrival_simulator.py:2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mrandom\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfourheap\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mconstants\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m BUY, SELL\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mmarket\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mmarket\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Market\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfundamental\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mlazy_mean_reverting\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m LazyGaussianMeanReverting\n", - "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'fourheap'" - ] - } - ], + "outputs": [], "source": [ "from marketsim.simulator.sampled_arrival_simulator import SimulatorSampledArrival\n", "from tqdm.notebook import tqdm" @@ -32,7 +19,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "72ae6676eeab193e", "metadata": { "ExecuteTime": { @@ -51,7 +38,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 3, "id": "a68010fcb5fc866b", "metadata": { "ExecuteTime": { @@ -64,7 +51,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "ae8a45d9090a4cb396885cc8201214fd", + "model_id": "81aed90c5f5b432c8c7c23071b213a79", "version_major": 2, "version_minor": 0 }, @@ -79,9 +66,124 @@ "name": "stdout", "output_type": "stream", "text": [ - "tensor(11361.2773)\n", - "CPU times: user 19min 5s, sys: 3.34 s, total: 19min 8s\n", - "Wall time: 2min 25s\n" + "tensor([ 4.0374e+03, 3.4127e+03, 3.3409e+03, 2.8289e+03, 1.7150e+03,\n", + " 1.4345e+03, 6.0636e+02, -3.1856e+00, -3.7968e+02, -8.3827e+02,\n", + " -8.7294e+02, -1.2727e+03, -1.3913e+03, -1.4063e+03, -1.8911e+03,\n", + " -2.3415e+03, -2.4368e+03, -2.4457e+03, -3.0239e+03, -3.0959e+03])\n", + "tensor([ 3625.5420, 2745.6584, 2472.4077, 1768.1614, 1585.1748, 1197.3917,\n", + " 1158.4869, 1054.0867, 853.3533, 524.0330, -13.7219, -116.6675,\n", + " -330.4727, -764.6992, -1028.4326, -1884.1432, -2585.9727, -2777.1248,\n", + " -4092.4089, -5264.8623])\n", + "tensor([ 4990.8975, 2967.4558, 2689.2898, 2216.5825, 2065.7942, 1927.2887,\n", + " 1818.0120, 662.8779, 118.2072, -551.9218, -783.8600, -905.0600,\n", + " -1083.6479, -1436.3757, -1962.8202, -2136.3525, -2329.3916, -2617.8076,\n", + " -3894.5181, -4760.9673])\n", + "tensor([ 5683.4609, 4764.9692, 2129.9780, 1524.4318, 1388.2170, 1157.8470,\n", + " 1109.2512, 295.3438, -735.6852, -994.5444, -1340.7273, -1470.9222,\n", + " -2021.5015, -2135.5083, -2294.4910, -2682.9114, -2854.7139, -3547.1533,\n", + " -3717.2979, -4904.9795])\n", + "tensor([ 4284.7622, 2444.0032, 2393.7090, 1882.5312, 1206.7983, 666.9818,\n", + " 606.0406, 443.3774, 358.2722, 55.1761, -418.2510, -675.5917,\n", + " -729.6736, -1363.0150, -2087.7976, -2491.2368, -2947.8145, -3100.8079,\n", + " -3161.1748, -3468.5325])\n", + "tensor([ 3585.9038, 2069.4087, 1952.7605, 1783.9916, 1658.7635, 1555.9456,\n", + " 1530.6989, 1437.9890, 1019.3367, 656.0310, 307.8891, 288.9088,\n", + " -177.4032, -857.3273, -931.3777, -1064.4598, -1163.4830, -1446.9646,\n", + " -2231.5044, -4006.2070])\n", + "tensor([ 2793.8044, 2419.9260, 2279.7966, 1224.5878, 912.1981, 698.9473,\n", + " 375.9335, 328.4089, -669.5266, -776.6470, -1070.2747, -1099.9990,\n", + " -1120.8108, -1172.9182, -1533.8988, -2844.0942, -3840.3633, -4123.9937,\n", + " -4935.6201, -5152.1353])\n", + "tensor([ 4484.5674, 2706.9724, 2700.6416, 993.5233, 941.8389, 929.6241,\n", + " 909.2783, 770.7112, 437.4997, 346.5242, 280.7657, -233.2945,\n", + " -364.2226, -562.3726, -665.7585, -824.8853, -1051.3944, -1108.5890,\n", + " -3315.8440, -4304.8682])\n", + "tensor([ 4575.2393, 2399.5066, 2187.9524, 1846.3369, 1741.5294, 1612.1676,\n", + " 1543.9113, 1475.0743, 927.9041, 866.0692, 606.7219, 453.1387,\n", + " 428.7309, -501.0787, -682.8043, -1827.1903, -1831.4119, -2526.3674,\n", + " -5630.8213, -8116.3037])\n", + "tensor([ 5193.3784, 4383.3281, 3115.7229, 2983.9446, 2633.0767, 2468.0049,\n", + " 1800.6614, 1571.8492, 1526.6012, 1162.6270, 368.6417, -165.8175,\n", + " -289.7984, -438.3941, -796.3839, -2154.0081, -2572.7180, -3112.4602,\n", + " -3999.3977, -4134.0947])\n", + "tensor([ 6875.6768, 5522.4326, 3337.3909, 2478.7944, 2152.8877, 2119.1140,\n", + " 2103.2593, 1997.8357, 1681.1166, 1421.3298, 334.1860, -220.6704,\n", + " -273.4951, -548.3541, -549.9816, -1909.7540, -2291.6580, -2817.0142,\n", + " -4613.2373, -5063.3232])\n", + "tensor([ 3932.8904, 3452.1587, 3265.9272, 2205.6169, 2124.8706, 1991.9509,\n", + " 1736.6738, 1685.7101, 1499.2333, 1381.8969, 1126.2511, 987.9667,\n", + " 907.6216, 504.3612, -454.1690, -727.5602, -952.3487, -1363.9465,\n", + " -4190.7246, -4436.2759])\n", + "tensor([ 2881.1279, 2307.0776, 2156.6721, 2125.6868, 953.8865, 897.5680,\n", + " 722.2113, 637.7260, 456.5930, 165.6314, 117.9682, 15.3379,\n", + " -163.1063, -197.0741, -375.5018, -873.9814, -959.6514, -1366.1035,\n", + " -1747.4352, -2132.0527])\n", + "tensor([ 4353.1958, 3575.3994, 2563.9272, 1088.9358, 960.2644, 920.5087,\n", + " 547.6674, 517.9410, 304.7414, 185.7539, 122.8681, -258.8566,\n", + " -644.2125, -1046.4401, -1072.3911, -1094.4957, -1705.2950, -2032.5697,\n", + " -2619.1267, -3627.9038])\n", + "tensor([ 4824.1680, 4194.7793, 3915.2122, 3614.2617, 2661.8323, 1341.1837,\n", + " 767.5400, 724.7560, 337.3801, 8.5954, -165.4243, -729.3141,\n", + " -1232.4115, -1589.4865, -1694.5858, -2468.1514, -2548.9958, -3553.5117,\n", + " -3651.9036, -4097.0254])\n", + "tensor([ 5093.6523, 2941.1230, 2841.5344, 2489.5972, 2276.0210, 1886.6360,\n", + " 1390.9089, 873.5195, 164.1704, -841.1102, -928.5546, -1474.3325,\n", + " -1809.0024, -2305.6265, -2368.1895, -3192.6890, -3251.0852, -4022.0027,\n", + " -4025.5049, -4249.1733])\n", + "tensor([ 2443.9707, 2257.9036, 1839.7994, 1768.3953, 1468.7836, 1324.0048,\n", + " 1182.5876, 1074.4474, 960.5504, 827.1175, 748.8782, 328.8743,\n", + " -259.7625, -908.2554, -1373.8010, -1522.3644, -2356.4619, -2761.4468,\n", + " -3032.4241, -6386.1543])\n", + "tensor([ 5793.5278, 4080.3015, 3113.7073, 3112.5884, 2700.0015, 2366.1628,\n", + " 2224.8215, 1978.1353, 1938.9230, 1314.4423, 1036.8851, 867.1976,\n", + " -669.5039, -763.5967, -862.6838, -1114.8029, -1345.6721, -1529.8199,\n", + " -2314.1106, -3840.8872])\n", + "tensor([ 5602.5161, 3645.3757, 2238.8206, 1948.4036, 1869.8054, 1549.3575,\n", + " 1080.9910, 419.6570, 159.6989, 68.8560, -267.8092, -390.8769,\n", + " -437.8201, -710.0922, -1069.5891, -1127.8506, -1347.3177, -1355.7803,\n", + " -4525.8320, -5847.4229])\n", + "tensor([ 3207.8772, 2944.7891, 625.3532, 605.8411, 351.2046, 321.1595,\n", + " -91.0841, -163.4030, -481.5818, -580.6354, -656.0715, -722.9763,\n", + " -907.6949, -1031.2651, -1269.4045, -1612.2400, -1874.8524, -1912.4821,\n", + " -3044.8745, -3611.9019])\n", + "tensor([ 4777.2041, 3447.0771, 3356.3330, 2494.0591, 2086.7581, 1618.5448,\n", + " 521.6508, 305.2572, 229.3872, -112.8537, -489.3099, -680.9890,\n", + " -765.1865, -1225.0430, -1276.1068, -1524.1208, -1707.3149, -3573.7185,\n", + " -3721.1726, -5367.3911])\n", + "tensor([ 4902.1772, 4401.6084, 3552.4773, 2334.8376, 1798.9541, 980.2576,\n", + " 508.2622, 205.4427, 121.8683, -10.1773, -243.4404, -360.8910,\n", + " -439.9512, -622.4166, -1045.7479, -1317.7949, -1457.5364, -1640.3485,\n", + " -1685.2999, -3216.8528])\n", + "tensor([ 4629.8252, 4436.9946, 4020.8359, 2503.6467, 2485.1079, 1459.0348,\n", + " 1353.0420, -401.1107, -828.5568, -870.7722, -1076.3412, -1083.9114,\n", + " -1234.5099, -1440.8784, -1489.9467, -1581.9640, -1815.9023, -1988.8152,\n", + " -2031.9287, -3671.0518])\n", + "tensor([ 2204.8438, 2154.0059, 1948.7183, 1852.5931, 1419.8195, 1307.2908,\n", + " 1146.1451, 760.6382, 68.7262, -154.6456, -284.5941, -372.8197,\n", + " -590.4111, -1341.6794, -1914.8389, -2498.5679, -2987.8022, -3467.5005,\n", + " -4296.0723, -5235.4248])\n", + "tensor([ 4444.3989, 3782.4800, 3285.2009, 2644.4888, 1735.1460, 1496.2708,\n", + " 1207.7823, 1061.8762, 701.4727, -39.9249, -113.0567, -730.8688,\n", + " -1086.9910, -1410.1927, -1628.8431, -2419.5410, -2429.0740, -3042.7917,\n", + " -3304.1248, -4563.3164])\n", + "tensor([ 4463.9312, 3760.1128, 2991.6453, 2800.2969, 2192.3418, 2073.6025,\n", + " 1315.5718, 921.8690, 873.5453, 300.2646, 8.5206, -328.2612,\n", + " -537.3453, -552.4212, -610.7821, -1057.1881, -1197.1388, -1627.0668,\n", + " -1767.0961, -1950.8951])\n", + "Matched Order: MatchedOrder(price=99819.84797440993, time=Order(price=99819.84797440993, order_type=1, quantity=1, agent_id=13, time=121, order_id=237853, asset_id=1), order=739)\n" + ] + }, + { + "ename": "AttributeError", + "evalue": "'int' object has no attribute 'order_type'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "File \u001b[0;32m:13\u001b[0m\n", + "File \u001b[0;32m~/Code/SURE-SRG/market-sim-py/marketsim/simulator/sampled_arrival_simulator.py:146\u001b[0m, in \u001b[0;36mSimulatorSampledArrival.run\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 144\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39marrivals[t]:\n\u001b[1;32m 145\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 146\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstep\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 147\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m:\n\u001b[1;32m 148\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39marrivals[\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtime])\n", + "File \u001b[0;32m~/Code/SURE-SRG/market-sim-py/marketsim/simulator/sampled_arrival_simulator.py:125\u001b[0m, in \u001b[0;36mSimulatorSampledArrival.step\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 123\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mMatched Order: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mmatched_order\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 124\u001b[0m agent_id \u001b[38;5;241m=\u001b[39m matched_order\u001b[38;5;241m.\u001b[39mtime\u001b[38;5;241m.\u001b[39magent_id\n\u001b[0;32m--> 125\u001b[0m quantity \u001b[38;5;241m=\u001b[39m \u001b[43mmatched_order\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43morder\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43morder_type\u001b[49m\u001b[38;5;241m*\u001b[39mmatched_order\u001b[38;5;241m.\u001b[39morder\u001b[38;5;241m.\u001b[39mquantity\n\u001b[1;32m 126\u001b[0m cash \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m-\u001b[39mmatched_order\u001b[38;5;241m.\u001b[39mprice\u001b[38;5;241m*\u001b[39mmatched_order\u001b[38;5;241m.\u001b[39morder\u001b[38;5;241m.\u001b[39mquantity\u001b[38;5;241m*\u001b[39mmatched_order\u001b[38;5;241m.\u001b[39morder\u001b[38;5;241m.\u001b[39morder_type\n\u001b[1;32m 127\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39magents[agent_id]\u001b[38;5;241m.\u001b[39mupdate_position(quantity, cash)\n", + "\u001b[0;31mAttributeError\u001b[0m: 'int' object has no attribute 'order_type'" ] } ], From c5774b95ea686ad0e1397a5c03ccb0e4065216a1 Mon Sep 17 00:00:00 2001 From: Rishith Seelam Date: Mon, 1 Jul 2024 14:40:25 -0400 Subject: [PATCH 05/34] added random sampling to each agent to prevent identical private values --- marketsim/fourheap/order_queue.py | 2 +- marketsim/private_values/private_values.py | 1 - marketsim/simulator/sampled_arrival_simulator.py | 15 ++++++++++----- marketsim/simulator/simulator.py | 6 +++--- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/marketsim/fourheap/order_queue.py b/marketsim/fourheap/order_queue.py index 4d484d67..33bc8aab 100644 --- a/marketsim/fourheap/order_queue.py +++ b/marketsim/fourheap/order_queue.py @@ -73,7 +73,7 @@ def market_clear(self, p, t): for _, order_id in self.heap: if order_id not in self.deleted_ids: order = self.order_dict[order_id] - matched_orders.append(MatchedOrder(p, order, t)) + matched_orders.append(MatchedOrder(p, t, order)) self.clear() return matched_orders return None diff --git a/marketsim/private_values/private_values.py b/marketsim/private_values/private_values.py index 37871046..f02f347b 100644 --- a/marketsim/private_values/private_values.py +++ b/marketsim/private_values/private_values.py @@ -32,7 +32,6 @@ def __init__(self, q_max: int, val_var=5e6, random_seed: int = 0): self.extra_buy = min(self.values[-1].item(), 0) self.extra_sell = max(self.values[0].item(), 0) - print(self.values) def value_for_exchange(self, position: int, order_type: int) -> float: """ diff --git a/marketsim/simulator/sampled_arrival_simulator.py b/marketsim/simulator/sampled_arrival_simulator.py index fd2ffabb..50808100 100644 --- a/marketsim/simulator/sampled_arrival_simulator.py +++ b/marketsim/simulator/sampled_arrival_simulator.py @@ -55,8 +55,8 @@ def __init__(self, self.markets = [] for _ in range(num_assets): - fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random_seed) - self.markets.append(Market(fundamental=fundamental, time_steps=sim_time)) + fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random.randint(1,2048)) + self.markets.append(Market(fundamental=fundamental, time_steps=sim_time, random_seed=random.randint(1,2048))) self.agents = {} # TEMP FOR HBL TESTING @@ -72,7 +72,7 @@ def __init__(self, shade=shade, pv_var=pv_var, eta=eta, - random_seed=random_seed + random_seed=random.randint(1,2048) )) # expanded_zi # else: @@ -120,8 +120,7 @@ def step(self): new_orders = market.step() for matched_order in new_orders: - print(f"Matched Order: {matched_order}") - agent_id = matched_order.time.agent_id + agent_id = matched_order.order.agent_id quantity = matched_order.order.order_type*matched_order.order.quantity cash = -matched_order.price*matched_order.order.quantity*matched_order.order.order_type self.agents[agent_id].update_position(quantity, cash) @@ -139,9 +138,13 @@ def end_sim(self): return values def run(self): + X = [] + Y = [] counter = 0 for t in range(self.sim_time): if self.arrivals[t]: + X.append(t) + Y.append(self.markets[0].order_book.get_best_ask()) try: self.step() except KeyError: @@ -151,6 +154,8 @@ def run(self): self.time += 1 self.step() + return X, Y + def sample_arrivals(p, num_samples): geometric_dist = dist.Geometric(torch.tensor([p])) diff --git a/marketsim/simulator/simulator.py b/marketsim/simulator/simulator.py index 8883c38b..1e2b875a 100644 --- a/marketsim/simulator/simulator.py +++ b/marketsim/simulator/simulator.py @@ -34,9 +34,9 @@ def __init__(self, self.markets = [] for _ in range(num_assets): - fundamental = GaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random_seed) + fundamental = GaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random.randint(1,2048)) # fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var) - self.markets.append(Market(fundamental=fundamental, time_steps=sim_time)) + self.markets.append(Market(fundamental=fundamental, time_steps=sim_time, random_seed=random.randint(1,2048))) self.agents = {} for agent_id in range(num_background_agents): @@ -46,7 +46,7 @@ def __init__(self, market=self.markets[0], q_max=q_max, shade=[10, 30], - random_seed=random_seed + random_seed=random.randint(1,2048) )) def step(self): From 9a1ec059e15acd2da60d411cda56f7a7b82f0e1c Mon Sep 17 00:00:00 2001 From: Rishith Seelam Date: Mon, 1 Jul 2024 14:47:34 -0400 Subject: [PATCH 06/34] cleanup --- marketsim/intro_notebook.ipynb | 305 ++++++++++++++-------------- marketsim/test_event_queue.ipynb | 260 ++++++++++++------------ test_sim.ipynb | 328 ++++++++++--------------------- 3 files changed, 370 insertions(+), 523 deletions(-) diff --git a/marketsim/intro_notebook.ipynb b/marketsim/intro_notebook.ipynb index b2d6b5cb..ba79e69c 100644 --- a/marketsim/intro_notebook.ipynb +++ b/marketsim/intro_notebook.ipynb @@ -5,11 +5,11 @@ "execution_count": 1, "id": "initial_id", "metadata": { + "collapsed": true, "ExecuteTime": { "end_time": "2024-02-15T04:09:48.703057400Z", "start_time": "2024-02-15T04:09:48.664059300Z" - }, - "collapsed": true + } }, "outputs": [], "source": [ @@ -20,15 +20,6 @@ }, { "cell_type": "code", - "execution_count": 2, - "id": "94fd9db23a88d5c5", - "metadata": { - "ExecuteTime": { - "end_time": "2024-02-15T04:09:49.138070Z", - "start_time": "2024-02-15T04:09:49.136069300Z" - }, - "collapsed": false - }, "outputs": [], "source": [ "# Let's start with order\n", @@ -37,43 +28,41 @@ "order2 = Order(price=32, order_type=SELL, quantity=22, time=1, agent_id=1, order_id=2)\n", "order3 = Order(price=7, order_type=SELL, quantity=7, time=1, agent_id=1, order_id=3)\n", "order4 = Order(price=9, order_type=SELL, quantity=8, time=1, agent_id=1, order_id=4)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "cc7b3ae1ebf76ee1", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-02-15T04:09:49.335085500Z", - "start_time": "2024-02-15T04:09:49.333084400Z" - }, - "collapsed": false + "end_time": "2024-02-15T04:09:49.138070Z", + "start_time": "2024-02-15T04:09:49.136069300Z" + } }, + "id": "94fd9db23a88d5c5", + "execution_count": 2 + }, + { + "cell_type": "code", "outputs": [], "source": [ "# Now let's see initialize the fourheap\n", "\n", "fh = FourHeap() " - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "361113b24009b04e", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-02-15T04:09:49.582092300Z", - "start_time": "2024-02-15T04:09:49.577092900Z" - }, - "collapsed": false + "end_time": "2024-02-15T04:09:49.335085500Z", + "start_time": "2024-02-15T04:09:49.333084400Z" + } }, + "id": "cc7b3ae1ebf76ee1", + "execution_count": 3 + }, + { + "cell_type": "code", "outputs": [ { "data": { - "text/plain": [ - "{1: Order(price=12, order_type=1, quantity=12, agent_id=1, time=1, order_id=1, asset_id=1)}" - ] + "text/plain": "{1: Order(price=12, order_type=1, quantity=12, agent_id=1, time=1, order_id=1, asset_id=1)}" }, "execution_count": 4, "metadata": {}, @@ -85,25 +74,23 @@ "\n", "fh.insert(order1)\n", "fh.buy_unmatched.order_dict" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "ebe4a5b482eb8d70", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-02-15T04:09:49.844940900Z", - "start_time": "2024-02-15T04:09:49.791936400Z" - }, - "collapsed": false + "end_time": "2024-02-15T04:09:49.582092300Z", + "start_time": "2024-02-15T04:09:49.577092900Z" + } }, + "id": "361113b24009b04e", + "execution_count": 4 + }, + { + "cell_type": "code", "outputs": [ { "data": { - "text/plain": [ - "{2: Order(price=32, order_type=-1, quantity=22, agent_id=1, time=1, order_id=2, asset_id=1)}" - ] + "text/plain": "{2: Order(price=32, order_type=-1, quantity=22, agent_id=1, time=1, order_id=2, asset_id=1)}" }, "execution_count": 5, "metadata": {}, @@ -118,19 +105,19 @@ "# Because it's price is higher than the buy price this won't cause a match\n", "\n", "fh.sell_unmatched.order_dict" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "5b93a62e48ad867e", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-02-15T04:09:50.031942Z", - "start_time": "2024-02-15T04:09:49.985942100Z" - }, - "collapsed": false + "end_time": "2024-02-15T04:09:49.844940900Z", + "start_time": "2024-02-15T04:09:49.791936400Z" + } }, + "id": "ebe4a5b482eb8d70", + "execution_count": 5 + }, + { + "cell_type": "code", "outputs": [ { "name": "stdout", @@ -154,19 +141,19 @@ "# Since order 1 is larger some will be matched and some will be unmatched\n", "print(fh.buy_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "ae2bfd9555f5e434", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-02-15T04:09:50.303405Z", - "start_time": "2024-02-15T04:09:50.253396300Z" - }, - "collapsed": false + "end_time": "2024-02-15T04:09:50.031942Z", + "start_time": "2024-02-15T04:09:49.985942100Z" + } }, + "id": "5b93a62e48ad867e", + "execution_count": 6 + }, + { + "cell_type": "code", "outputs": [ { "name": "stdout", @@ -188,19 +175,19 @@ "print(fh.sell_matched.order_dict)\n", "print(fh.buy_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "3ea852481fc4c008", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-02-15T04:09:50.524404700Z", - "start_time": "2024-02-15T04:09:50.482405500Z" - }, - "collapsed": false + "end_time": "2024-02-15T04:09:50.303405Z", + "start_time": "2024-02-15T04:09:50.253396300Z" + } }, + "id": "ae2bfd9555f5e434", + "execution_count": 7 + }, + { + "cell_type": "code", "outputs": [ { "name": "stdout", @@ -221,19 +208,19 @@ "print(fh.sell_matched.order_dict)\n", "print(fh.sell_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "a13c3435bf208848", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-02-15T04:09:50.906926200Z", - "start_time": "2024-02-15T04:09:50.864927100Z" - }, - "collapsed": false + "end_time": "2024-02-15T04:09:50.524404700Z", + "start_time": "2024-02-15T04:09:50.482405500Z" + } }, + "id": "3ea852481fc4c008", + "execution_count": 8 + }, + { + "cell_type": "code", "outputs": [ { "name": "stdout", @@ -255,19 +242,19 @@ "print(fh.sell_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n", "print(fh.buy_unmatched.order_dict)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "bcd1634ff00877e8", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-02-15T04:11:22.295305500Z", - "start_time": "2024-02-15T04:11:22.248306800Z" - }, - "collapsed": false + "end_time": "2024-02-15T04:09:50.906926200Z", + "start_time": "2024-02-15T04:09:50.864927100Z" + } }, + "id": "a13c3435bf208848", + "execution_count": 9 + }, + { + "cell_type": "code", "outputs": [ { "name": "stdout", @@ -298,19 +285,19 @@ "print(fh.sell_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n", "print(fh.buy_unmatched.order_dict)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "fe3c9bd1cdefe8d8", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-02-15T04:11:56.266000300Z", - "start_time": "2024-02-15T04:11:56.220995Z" - }, - "collapsed": false + "end_time": "2024-02-15T04:11:22.295305500Z", + "start_time": "2024-02-15T04:11:22.248306800Z" + } }, + "id": "bcd1634ff00877e8", + "execution_count": 11 + }, + { + "cell_type": "code", "outputs": [ { "name": "stdout", @@ -330,19 +317,19 @@ "print(fh.sell_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n", "print(fh.buy_unmatched.order_dict)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "d49d7335bdfc4f4d", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-02-15T04:35:44.877998600Z", - "start_time": "2024-02-15T04:35:44.870998500Z" - }, - "collapsed": false + "end_time": "2024-02-15T04:11:56.266000300Z", + "start_time": "2024-02-15T04:11:56.220995Z" + } }, + "id": "fe3c9bd1cdefe8d8", + "execution_count": 12 + }, + { + "cell_type": "code", "outputs": [], "source": [ "from fundamental.lazy_mean_reverting import LazyGaussianMeanReverting\n", @@ -350,25 +337,23 @@ "# Let's look at the fundamental next\n", "\n", "f = LazyGaussianMeanReverting(final_time=100, mean=12, r=.2, shock_var=.01)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "cc2bd7a5d3a7ad3f", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-02-15T04:35:46.433997800Z", - "start_time": "2024-02-15T04:35:46.430998500Z" - }, - "collapsed": false + "end_time": "2024-02-15T04:35:44.877998600Z", + "start_time": "2024-02-15T04:35:44.870998500Z" + } }, + "id": "d49d7335bdfc4f4d", + "execution_count": 7 + }, + { + "cell_type": "code", "outputs": [ { "data": { - "text/plain": [ - "{0: 12}" - ] + "text/plain": "{0: 12}" }, "execution_count": 8, "metadata": {}, @@ -379,19 +364,19 @@ "# The fundamental starts at the mean\n", "\n", "f.fundamental_values" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "b902e6769c663d52", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-02-15T04:35:46.900183400Z", - "start_time": "2024-02-15T04:35:46.897184600Z" - }, - "collapsed": false + "end_time": "2024-02-15T04:35:46.433997800Z", + "start_time": "2024-02-15T04:35:46.430998500Z" + } }, + "id": "cc2bd7a5d3a7ad3f", + "execution_count": 8 + }, + { + "cell_type": "code", "outputs": [ { "name": "stdout", @@ -407,19 +392,19 @@ "f.get_value_at(12)\n", "\n", "print(f.fundamental_values)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "6bdef9c2a15fd033", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-02-15T04:35:47.745318600Z", - "start_time": "2024-02-15T04:35:47.742319600Z" - }, - "collapsed": false + "end_time": "2024-02-15T04:35:46.900183400Z", + "start_time": "2024-02-15T04:35:46.897184600Z" + } }, + "id": "b902e6769c663d52", + "execution_count": 9 + }, + { + "cell_type": "code", "outputs": [ { "name": "stdout", @@ -435,17 +420,25 @@ "f.get_final_fundamental()\n", "\n", "print(f.fundamental_values)" - ] + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-02-15T04:35:47.745318600Z", + "start_time": "2024-02-15T04:35:47.742319600Z" + } + }, + "id": "6bdef9c2a15fd033", + "execution_count": 10 }, { "cell_type": "code", - "execution_count": null, - "id": "ba5a64455c821680", + "outputs": [], + "source": [], "metadata": { "collapsed": false }, - "outputs": [], - "source": [] + "id": "ba5a64455c821680" } ], "metadata": { @@ -464,7 +457,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "3.9.12" + "version": "2.7.6" } }, "nbformat": 4, diff --git a/marketsim/test_event_queue.ipynb b/marketsim/test_event_queue.ipynb index e18e461d..4e514273 100644 --- a/marketsim/test_event_queue.ipynb +++ b/marketsim/test_event_queue.ipynb @@ -5,11 +5,11 @@ "execution_count": 1, "id": "initial_id", "metadata": { + "collapsed": true, "ExecuteTime": { "end_time": "2023-11-02T02:00:54.071626Z", "start_time": "2023-11-02T02:00:52.890317Z" - }, - "collapsed": true + } }, "outputs": [], "source": [ @@ -23,72 +23,62 @@ { "cell_type": "code", "execution_count": 2, - "id": "adf6ffdda3d8a689", + "outputs": [], + "source": [ + "e = EventQueue()" + ], "metadata": { + "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:00:55.364165Z", "start_time": "2023-11-02T02:00:55.357739Z" - }, - "collapsed": false + } }, - "outputs": [], - "source": [ - "e = EventQueue()" - ] + "id": "adf6ffdda3d8a689" }, { "cell_type": "code", "execution_count": 3, - "id": "acd56cd67811e74d", - "metadata": { - "ExecuteTime": { - "end_time": "2023-11-02T02:00:55.631574Z", - "start_time": "2023-11-02T02:00:55.627375Z" - }, - "collapsed": false - }, "outputs": [], "source": [ "order1 = Order(price=1, quantity=1, time=1, agent_id=1, order_id=1, order_type=BUY)\n", "order2 = Order(price=1, quantity=1, time=1, agent_id=1, order_id=2, order_type=BUY)\n", "order3 = Order(price=1, quantity=1, time=3, agent_id=1, order_id=3, order_type=SELL)\n" - ] + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2023-11-02T02:00:55.631574Z", + "start_time": "2023-11-02T02:00:55.627375Z" + } + }, + "id": "acd56cd67811e74d" }, { "cell_type": "code", "execution_count": 4, - "id": "e81b92116b7c7b9d", - "metadata": { - "ExecuteTime": { - "end_time": "2023-11-02T02:00:55.846956Z", - "start_time": "2023-11-02T02:00:55.845125Z" - }, - "collapsed": false - }, "outputs": [], "source": [ "e.schedule_activity(order1)\n", "e.schedule_activity(order2)\n", "e.schedule_activity(order3)\n" - ] + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2023-11-02T02:00:55.846956Z", + "start_time": "2023-11-02T02:00:55.845125Z" + } + }, + "id": "e81b92116b7c7b9d" }, { "cell_type": "code", "execution_count": 5, - "id": "2b15b5866d781227", - "metadata": { - "ExecuteTime": { - "end_time": "2023-11-02T02:00:56.086065Z", - "start_time": "2023-11-02T02:00:56.051275Z" - }, - "collapsed": false - }, "outputs": [ { "data": { - "text/plain": [ - "[]" - ] + "text/plain": "[]" }, "execution_count": 5, "metadata": {}, @@ -97,26 +87,23 @@ ], "source": [ "e.step()" - ] + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2023-11-02T02:00:56.086065Z", + "start_time": "2023-11-02T02:00:56.051275Z" + } + }, + "id": "2b15b5866d781227" }, { "cell_type": "code", "execution_count": 6, - "id": "eba7945d5a7f5263", - "metadata": { - "ExecuteTime": { - "end_time": "2023-11-02T02:00:56.227455Z", - "start_time": "2023-11-02T02:00:56.224831Z" - }, - "collapsed": false - }, "outputs": [ { "data": { - "text/plain": [ - "[Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=1, asset_id=1),\n", - " Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=2, asset_id=1)]" - ] + "text/plain": "[Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=1, asset_id=1),\n Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=2, asset_id=1)]" }, "execution_count": 6, "metadata": {}, @@ -125,25 +112,23 @@ ], "source": [ "e.step()" - ] + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2023-11-02T02:00:56.227455Z", + "start_time": "2023-11-02T02:00:56.224831Z" + } + }, + "id": "eba7945d5a7f5263" }, { "cell_type": "code", "execution_count": 7, - "id": "8ac0f93a500647fb", - "metadata": { - "ExecuteTime": { - "end_time": "2023-11-02T02:00:56.439237Z", - "start_time": "2023-11-02T02:00:56.434962Z" - }, - "collapsed": false - }, "outputs": [ { "data": { - "text/plain": [ - "[]" - ] + "text/plain": "[]" }, "execution_count": 7, "metadata": {}, @@ -152,57 +137,55 @@ ], "source": [ "e.step()" - ] + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2023-11-02T02:00:56.439237Z", + "start_time": "2023-11-02T02:00:56.434962Z" + } + }, + "id": "8ac0f93a500647fb" }, { "cell_type": "code", "execution_count": 8, - "id": "88cbe58aba097195", + "outputs": [], + "source": [ + "f = GaussianMeanReverting(mean=100, r=0.2, final_time=100, shock_var=10)" + ], "metadata": { + "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:00:56.645679Z", "start_time": "2023-11-02T02:00:56.640489Z" - }, - "collapsed": false + } }, - "outputs": [], - "source": [ - "f = GaussianMeanReverting(mean=100, r=0.2, final_time=100, shock_var=10)" - ] + "id": "88cbe58aba097195" }, { "cell_type": "code", "execution_count": 9, - "id": "b19ca32418bbd288", + "outputs": [], + "source": [ + "m = Market(f)" + ], "metadata": { + "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:00:57.178505Z", "start_time": "2023-11-02T02:00:57.176993Z" - }, - "collapsed": false + } }, - "outputs": [], - "source": [ - "m = Market(f)" - ] + "id": "b19ca32418bbd288" }, { "cell_type": "code", "execution_count": 10, - "id": "910dcd209c37965", - "metadata": { - "ExecuteTime": { - "end_time": "2023-11-02T02:00:57.896940Z", - "start_time": "2023-11-02T02:00:57.883064Z" - }, - "collapsed": false - }, "outputs": [ { "data": { - "text/plain": [ - "100.0" - ] + "text/plain": "100.0" }, "execution_count": 10, "metadata": {}, @@ -211,64 +194,57 @@ ], "source": [ "m.get_fundamental_value()" - ] + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2023-11-02T02:00:57.896940Z", + "start_time": "2023-11-02T02:00:57.883064Z" + } + }, + "id": "910dcd209c37965" }, { "cell_type": "code", "execution_count": 13, - "id": "fecf8d0b5d2b0d76", - "metadata": { - "ExecuteTime": { - "end_time": "2023-11-02T02:01:34.513870Z", - "start_time": "2023-11-02T02:01:34.507170Z" - }, - "collapsed": false - }, "outputs": [], "source": [ "m.add_order(order1)\n", "m.add_order(order2)\n", "m.add_order(order3)\n" - ] + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2023-11-02T02:01:34.513870Z", + "start_time": "2023-11-02T02:01:34.507170Z" + } + }, + "id": "fecf8d0b5d2b0d76" }, { "cell_type": "code", "execution_count": 24, - "id": "5592a8bef91a39dd", + "outputs": [], + "source": [ + "m.step()" + ], "metadata": { + "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:02:15.127481Z", "start_time": "2023-11-02T02:02:15.119847Z" - }, - "collapsed": false + } }, - "outputs": [], - "source": [ - "m.step()" - ] + "id": "5592a8bef91a39dd" }, { "cell_type": "code", "execution_count": 25, - "id": "3ec35fc46b4dfdaf", - "metadata": { - "ExecuteTime": { - "end_time": "2023-11-02T02:02:15.439666Z", - "start_time": "2023-11-02T02:02:15.435653Z" - }, - "collapsed": false - }, "outputs": [ { "data": { - "text/plain": [ - "defaultdict(list,\n", - " {1: [Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=1, asset_id=1),\n", - " Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=2, asset_id=1)],\n", - " 3: [Order(price=1, order_type=-1, quantity=1, agent_id=1, time=3, order_id=3, asset_id=1)],\n", - " 0: [],\n", - " 2: []})" - ] + "text/plain": "defaultdict(list,\n {1: [Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=1, asset_id=1),\n Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=2, asset_id=1)],\n 3: [Order(price=1, order_type=-1, quantity=1, agent_id=1, time=3, order_id=3, asset_id=1)],\n 0: [],\n 2: []})" }, "execution_count": 25, "metadata": {}, @@ -277,25 +253,23 @@ ], "source": [ "m.event_queue.scheduled_activities" - ] + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2023-11-02T02:02:15.439666Z", + "start_time": "2023-11-02T02:02:15.435653Z" + } + }, + "id": "3ec35fc46b4dfdaf" }, { "cell_type": "code", "execution_count": 26, - "id": "f226ab58891b1b9f", - "metadata": { - "ExecuteTime": { - "end_time": "2023-11-02T02:02:16.395887Z", - "start_time": "2023-11-02T02:02:16.353163Z" - }, - "collapsed": false - }, "outputs": [ { "data": { - "text/plain": [ - "4" - ] + "text/plain": "4" }, "execution_count": 26, "metadata": {}, @@ -304,17 +278,25 @@ ], "source": [ "m.get_time()" - ] + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2023-11-02T02:02:16.395887Z", + "start_time": "2023-11-02T02:02:16.353163Z" + } + }, + "id": "f226ab58891b1b9f" }, { "cell_type": "code", "execution_count": null, - "id": "2747f8bda9e21ed1", + "outputs": [], + "source": [], "metadata": { "collapsed": false }, - "outputs": [], - "source": [] + "id": "2747f8bda9e21ed1" } ], "metadata": { @@ -333,7 +315,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "3.9.12" + "version": "2.7.6" } }, "nbformat": 4, diff --git a/test_sim.ipynb b/test_sim.ipynb index 0ce0a741..7aa739d6 100644 --- a/test_sim.ipynb +++ b/test_sim.ipynb @@ -2,14 +2,14 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "id": "initial_id", "metadata": { + "collapsed": true, "ExecuteTime": { "end_time": "2024-03-27T23:39:39.806325Z", "start_time": "2024-03-27T23:39:37.947319Z" - }, - "collapsed": true + } }, "outputs": [], "source": [ @@ -19,45 +19,35 @@ }, { "cell_type": "code", - "execution_count": 2, - "id": "72ae6676eeab193e", - "metadata": { - "ExecuteTime": { - "end_time": "2024-03-25T08:07:38.106565700Z", - "start_time": "2024-03-25T08:07:38.103557300Z" - }, - "collapsed": false - }, + "execution_count": 3, "outputs": [], "source": [ "# %%timeit\n", "# \n", "# sim = Simulator(num_agents=66, sim_time=60000, lam=1e-4, mean=1e7, r=.05, shock_var=1e6)\n", "# sim.run()" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "a68010fcb5fc866b", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-03-25T08:38:17.892762800Z", - "start_time": "2024-03-25T08:35:52.049473800Z" - }, - "collapsed": false + "end_time": "2024-03-25T08:07:38.106565700Z", + "start_time": "2024-03-25T08:07:38.103557300Z" + } }, + "id": "72ae6676eeab193e" + }, + { + "cell_type": "code", + "execution_count": 21, "outputs": [ { "data": { + "text/plain": " 0%| | 0/10000 [00:00:13\u001b[0m\n", - "File \u001b[0;32m~/Code/SURE-SRG/market-sim-py/marketsim/simulator/sampled_arrival_simulator.py:146\u001b[0m, in \u001b[0;36mSimulatorSampledArrival.run\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 144\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39marrivals[t]:\n\u001b[1;32m 145\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 146\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstep\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 147\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m:\n\u001b[1;32m 148\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39marrivals[\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtime])\n", - "File \u001b[0;32m~/Code/SURE-SRG/market-sim-py/marketsim/simulator/sampled_arrival_simulator.py:125\u001b[0m, in \u001b[0;36mSimulatorSampledArrival.step\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 123\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mMatched Order: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mmatched_order\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 124\u001b[0m agent_id \u001b[38;5;241m=\u001b[39m matched_order\u001b[38;5;241m.\u001b[39mtime\u001b[38;5;241m.\u001b[39magent_id\n\u001b[0;32m--> 125\u001b[0m quantity \u001b[38;5;241m=\u001b[39m \u001b[43mmatched_order\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43morder\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43morder_type\u001b[49m\u001b[38;5;241m*\u001b[39mmatched_order\u001b[38;5;241m.\u001b[39morder\u001b[38;5;241m.\u001b[39mquantity\n\u001b[1;32m 126\u001b[0m cash \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m-\u001b[39mmatched_order\u001b[38;5;241m.\u001b[39mprice\u001b[38;5;241m*\u001b[39mmatched_order\u001b[38;5;241m.\u001b[39morder\u001b[38;5;241m.\u001b[39mquantity\u001b[38;5;241m*\u001b[39mmatched_order\u001b[38;5;241m.\u001b[39morder\u001b[38;5;241m.\u001b[39morder_type\n\u001b[1;32m 127\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39magents[agent_id]\u001b[38;5;241m.\u001b[39mupdate_position(quantity, cash)\n", - "\u001b[0;31mAttributeError\u001b[0m: 'int' object has no attribute 'order_type'" + "tensor(11361.2773)\n", + "CPU times: user 19min 5s, sys: 3.34 s, total: 19min 8s\n", + "Wall time: 2min 25s\n" ] } ], @@ -211,30 +86,27 @@ " values.append(value)\n", " surpluses.append(sum(values)/len(values))\n", "print(sum(surpluses)/len(surpluses)*25)" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "2090899632c545a9", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-03-25T08:47:01.079261600Z", - "start_time": "2024-03-25T08:42:17.296566Z" - }, - "collapsed": false + "end_time": "2024-03-25T08:38:17.892762800Z", + "start_time": "2024-03-25T08:35:52.049473800Z" + } }, + "id": "a68010fcb5fc866b" + }, + { + "cell_type": "code", "outputs": [ { "data": { + "text/plain": " 0%| | 0/10000 [00:00" - ] + "text/plain": "
", + "image/png": "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GxsLX19fAICvry/S0tJw7NgxqWbPnj3Izc2Fj4+PVHPgwAFkZ2dLNVFRUahdu7beFX9ERET06iozAWrEiBH4559/MH36dFy8eBFr167F8uXLERYWBgBQKBQIDw/HtGnTsHXrVpw5cwZ9+/aFq6srQkJCADzZYxUUFIRBgwbh8OHDOHjwIIYNG4bu3bvD1dUVANCzZ09YWFggNDQUZ8+exfr16zF//nyMHDnSWEMnIiKi0kaUIdu2bRNeXl5CqVSKOnXqiOXLl+stz83NFRMnThROTk5CqVSKNm3aiISEBL2aO3fuiB49eoiKFSsKGxsbMWDAAJGRkaFXc+rUKdGsWTOhVCrFa6+9Jr766itZ/dRqtQKA0Gq1LzZQIiIiKnFyvr/LzDxQZQnngSIiIip7yuU8UERERESlBQMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERyWRm7A4QERGVlJxcgcOJqUjJyISjtQpNPOxhaqIwdreoDGKAIiKiV0JkXBKmbDuHJG2m1OaiViGigyeCvFyM2DMqi3gIj4iIyr3IuCQM/fm4XngCAI02E0N/Po7IuCQj9YzKKgYoIiIq13JyBaZsOwdhYJmubcq2c8jJNVRBZBgDFBERlWuHE1Pz7Hl6mgCQpM3E4cTUkusUlXkMUEREVK6lZOQfnl6kjghggCIionLO0VpVpHVEAAMUERGVc0087OGiViG/yQoUeHI1XhMP+5LsFpVxDFBERFSumZooENHBEwDyhCjd/YgOnpwPimRhgCIionIvyMsFS3p7w1mtf5jOWa3Ckt7enAeKZCuzAeqrr76CQqFAeHi41JaZmYmwsDBUqlQJFStWRKdOnZCcnKy33rVr1xAcHIwKFSrA0dERY8aMwePHj/Vq9u3bB29vbyiVStSsWRMrV64sgREREVFxCvJywd9j38Evg97G/O4N8cugt/H32HcYnuiFlMkAdeTIESxbtgxv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e8LCwgKhoaE4e/Ys1q9fj/nz52PkyJFSzfDhwxEZGYm5c+ciPj4ekydPxtGjRzFs2DAAgEKhQHh4OKZNm4atW7fizJkz6Nu3L1xdXRESElLSwyYiIqJSyqh7oAorKioKFy9exMWLF1GlShW9ZbpZGNRqNf7880+EhYWhUaNGqFy5MiZNmoTBgwdLtX5+fli7di2++OILfP7556hVqxa2bNkCLy8vqeazzz7D/fv3MXjwYKSlpaFZs2aIjIyESqUqmcESERFRqVdm54EqzTgPFBERUdnzSswDRURERGQsDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQylYl5oIjKg5xcgcOJqUjJyISjtQpNPOxhaqIwdreIiOgFMEARlYDIuCRM3noWmvQsqc3ZRonJ79VDkJdLAWsSEVFpxEN4RMUsMi4JQ34+rheeAECTnoUhPx9HZFySkXpGREQvigGKqBjl5AqM23SmwJpxm84gJ5c/CEBEVJYwQBEVo38u3UHag+wCa9IeZOOfS3dKqEdERFQUGKCIitHBS7eLtI6IiEoHBiiiYnQ99WGR1hERUenAAEVUjBL/u1ekdUREVDowQBEVq8LO88T5oIiIyhIGKKJi1MBNXaR1RERUOjBAERWj8W09i7SOiIhKBwYoomJ05qa2SOuIiKh0YIAiKkYpGZlFWkdERKUDAxRRMXK0VhVpHRERlQ4MUETFqImHPVzUqnyvsVMAcFGr0MTDviS7RUREL4kBiqgYmZooENHhyQniz4Yo3f2IDp4wNeE0BkREZQkDFFExC/JywZLe3nBW6x+mc1arsKS3N4K8XIzUMyIielFmxu4A0asgyMsF73o643BiKlIyMuFo/eSwHfc8ERGVTQxQRCXE1EQB3xqVjN0NIiIqAjyER0RERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCRTmQtQWVlZaNiwIRQKBU6ePKm37PTp02jevDlUKhXc3Nwwa9asPOtv2LABderUgUqlQv369bFz50695UIITJo0CS4uLrC0tIS/vz8uXLhQnEMiIiKiMqbMBajPPvsMrq6uedrT09MREBAAd3d3HDt2DLNnz8bkyZOx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8uRJXLhwAQ8fPsSqVaugUCieu96HH36Iy5cvo0+fPjhz5gwaN26MBQsWFHt/zc3N9e4rFArk5uYW++MS0cthgCKicsXKygo1a9ZE1apVYWb25CyFunXr4vHjx4iNjZXq7ty5g4SEBHh6ekptbm5uGDJkCDZt2oRRo0bhu+++M/gYFhYWyMnJKbAfdevWxfXr13H9+nWp7dy5c0hLS9N7TCIqmxigiKjcq1WrFjp27IhBgwbh77//xqlTp9C7d2+89tpr6NixIwAgPDwcu3btQmJiIo4fP469e/eibt26BrdXrVo13Lt3D9HR0fjvv//w4MGDPDX+/v6oX78+evXqhePHj+Pw4cPo27cvWrZsicaNGxfreImo+DFAEdErYcWKFWjUqBHat28PX19fCCGwc+dO6RBaTk4OwsLCULduXQQFBeH111/H4sWLDW7Lz88PQ4YMQbdu3eDg4IBZs2blqVEoFPj9999hZ2eHFi1awN/fH9WrV8f69euLdZxEVDIUQghh7E4QERERlSXcA0VEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcn0/wARYlezvwXQIQAAAABJRU5ErkJggg==" }, "metadata": {}, "output_type": "display_data" @@ -407,19 +275,19 @@ "plt.ylabel('Value')\n", "plt.title(f'Agent Position vs Value at fundamental {fundamental_val}')\n", "plt.show()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "44a74cbe8acf673", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-03-26T20:44:58.709570600Z", - "start_time": "2024-03-26T20:44:58.596987100Z" - }, - "collapsed": false + "end_time": "2024-03-26T20:44:46.314860800Z", + "start_time": "2024-03-26T20:44:46.196664700Z" + } }, + "id": "da028cd7fb618978", + "execution_count": 32 + }, + { + "cell_type": "code", "outputs": [ { "name": "stdout", @@ -430,10 +298,8 @@ }, { "data": { - "image/png": "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ssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyZ9ZANHv2bLRs2RKOjo5wdXVFr169cPnyZYM+nTp1gkKhMHiMGTPGoE9CQgKCg4NRqVIluLq6YvLkyXj8+LFBn0OHDqF58+ZQKpWoXbs2Vq1aVdqzR0REROWEWQPR4cOHER4ejt9++w1RUVHIyclBQEAAHjx4YNBv9OjRSExMlB5z586VhuXm5iI4OBjZ2dk4duwYVq9ejVWrVuHjjz+W+sTHxyM4OBidO3fG6dOnMX78eLzxxhvYt2+fyeaViIiIyi6FEEKYuwi927dvw9XVFYcPH0aHDh0APNlC1KxZMyxcuDDP1/z000/o3r07bt26BTc3NwBAZGQkpkyZgtu3b8PGxgZTpkzB7t27ERcXJ71uwIABSEtLw969e19Yl1arhVqtRnp6OlQqVfFnlIiIiEpdYb6/y9QxROnp6QAAZ2dng/Z169ahatWqaNSoEaZOnYqHDx9Kw2JiYtC4cWMpDAFAYGAgtFotzp8/L/Xx9/c3GGdgYCBiYmLyrCMrKwtardbgQURERBWXlbkL0NPpdBg/fjzatm2LRo0aSe2DBg1C9erV4eHhgbNnz2LKlCm4fPkytmzZAgBISkoyCEMApOdJSUnP7aPVavHo0SPY2dkZDJs9ezamT59e4vNIREREZVOZCUTh4eGIi4vDr7/+atD+5ptvSv9v3Lgx3N3d8corr+DatWuoVatWqdQydepUTJw4UXqu1Wrh6elZ4tPJ1QnExqciJSMTro62aOXtDEsLRYlPh4iIiJ6vTASisWPHYteuXThy5AiqVav23L6+vr4AgKtXr6JWrVrQaDSIjY016JOcnAwA0Gg00r/6tqf7qFQqo61DAKBUKqFUKos8PwWxNy4R03deQGJ6ptTmrrZFRA8fBDVyL9VpExERkSGzHkMkhMDYsWOxdetWHDhwAN7e3i98zenTpwEA7u5PQoOfnx/OnTuHlJQUqU9UVBRUKhV8fHykPtHR0QbjiYqKgp+fXwnNSeHsjUtE2NpTBmEIAJLSMxG29hT2xiWapS4iIiK5MmsgCg8Px9q1a7F+/Xo4OjoiKSkJSUlJePToEQDg2rVr+OSTT3Dy5Elcv34dO3bswLBhw9ChQwc0adIEABAQEAAfHx8MHToUZ86cwb59+/Dhhx8iPDxc2sozZswY/PXXX3jvvfdw6dIlLFmyBJs2bcKECRNMPs+5OoHpOy8gr1P79G3Td15Arq7MnPxHRERU4Zk1EC1duhTp6eno1KkT3N3dpcfGjRsBADY2Nti/fz8CAgJQv359TJo0CSEhIdi5c6c0DktLS+zatQuWlpbw8/PDkCFDMGzYMMyYMUPq4+3tjd27dyMqKgpNmzbF/Pnz8c033yAwMNDk8xwbn2q0ZehpAkBieiZi41NNVxQREZHMmfUYohddAsnT0xOHDx9+4XiqV6+OPXv2PLdPp06d8McffxSqvtKQkpF/GCpKPyIiIiq+MnUdIjlwdbQt0X5ERERUfAxEJtbK2xnualvkd3K9Ak/ONmvl7ZxPDyIiIippDEQmZmmhQESPJ2e/PRuK9M8jevjwekREREQmxEBkBkGN3LF0SHNo1Ia7xTRqWywd0pzXISIiIjKxMnFhRjkKauSOrj4aXqmaiIioDGAgMiNLCwX8alUxdxlERESyx11mREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQke1bmLoCIiIjkK1cnEBufipSMTLg62qKVtzMsLRQmr4OBiIiIiMxib1wipu+8gMT0TKnNXW2LiB4+CGrkbtJauMuMiIiITG5vXCLC1p4yCEMAkJSeibC1p7A3LtGk9TAQERERkUnl6gSm77wAkccwfdv0nReQq8urR+lgICIiIiKTio1PNdoy9DQBIDE9E7HxqSariYGIiIiITColI/8wVJR+JYGBiIiIiEzK1dG2RPuVBAYiIiIiMqlW3s5wV9siv5Pr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9erVQ79+/VClShX89ttvcHFxAQB88cUX6N69O0JCQtChQwdoNBps2bJFer2lpSV27doFS0tL+Pn5YciQIRg2bBhmzJhhrlkiIio03qzYdF50ALsAD2CvqBRCCL6rL6DVaqFWq5Gens7jiYjIbHgdotIXc+0uBq747YX9vh/dmgewlwOF+f4u02eZERHR//BmxaUvSVuwA9ML2o/KDwYiIqJyhDcrLl2p97NKtB+VH2X6GCIiIiJTcrYv2C2dCtqPyg8GIiIiov/SqAt20d+C9qPyg4GIiIjov/SXOHgeXuKgYmIgIiIi+i9LCwVea/r8M/Zea+rOA9krIAYiIiKi/8rVCew48/wLL+44k8jrEFVAPMuMiEpE9mMd1sRcx9+pD1HduRKG+tWAjRV/c1H58qIb6QK8kW5FxUBERMU2e88FrPglHk//aJ655yJGt/fG1Fd530AqP3gjXfliICKiYpm95wKWHYk3atcJSO0MRVRe8Ea68sXt2URUZNmPdVj+i3EYetryX+KR/VhnooqIioc30pUvBiIiKrLVx67jRXdDFOJJP6LygDfSlS8GIiIqshPX75ZoP6KyIKiRO5YOaQ7NM9cj0qhtsXRIc95It4LiMUREVGSVbAr2EVLQfkRlBW+kKz/8lCKiIgtpXg3bTt8qUD+i8oY30pUX7jIjoiJrU7sqKtlYPrePvY0l2tSuaqKKiIiKhoGIiIrM0kKBBf2aPrfP/H5NuZuBiMo8BiIiKpagRu6IHNIcbo5Kg3aNSolIHoBKROUEjyEiomLjAahEVN4xEBFRieABqERUnnGXGREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREcmelbkLICKigrutzcLrS35F6oMcONtbY+tb7eCiUpq7LKJyT1ZbiBYvXowaNWrA1tYWvr6+iI2NNXdJREQF1mTaPrSctR830zLxMCcXN9My0XLWfjSZts/cpRGVe7IJRBs3bsTEiRMRERGBU6dOoWnTpggMDERKSoq5SyMieqEm0/ZBm/k4z2HazMcMRUTFJJtAtGDBAowePRojRoyAj48P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", - "text/plain": [ - "
" - ] + "text/plain": "
", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkQAAAHHCAYAAABeLEexAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABW5UlEQVR4nO3deVhUZf8G8HvYBgRmEAUGEhR3cf1pirhrCBiaJu4bLtkroeWSmb0VaqmpaZapqJX6uuRS7pqGuJWSmOaCW2oYmiwqwuDCIvP8/vCd8zoOKOsMcO7Pdc2l85xnzvmeM4eZe86qEEIIEBEREcmYhbkLICIiIjI3BiIiIiKSPQYiIiIikj0GIiIiIpI9BiIiIiKSPQYiIiIikj0GIiIiIpI9BiIiIiKSPQYiIiIikj0GIirzhg8fjho1ahSo77Rp06BQKEq3oAqiRo0aGD58uLnLKFEnTpxAmzZtYG9vD4VCgdOnT5t0+oVZV+Xg0KFDUCgUOHTokLlLIXohBiITWLJkCRQKBXx9fc1dSp6WLFmCVatWFbi/QqGQHhYWFvDw8EBAQIDJPvQePnyIadOmyeZDdsGCBVAoFNi/f3++fVasWAGFQoEdO3aYsLLSdevWLUybNq3AoSYnJwd9+/ZFamoqvvjiC6xZswbVq1cv3SIruFmzZmHbtm2lPp379+8jIiICQUFBcHZ2hkKheO5n0sWLFxEUFAQHBwc4Oztj6NChuH37tlE/nU6HuXPnwtvbG7a2tmjSpAm+//77Io9T/4Mrv8fRo0eNpr906VI0a9YMdnZ2qFKlCrp06YIzZ84UaJmMHz8e1apVg1KpRIMGDbB06VKjfomJiXj//ffRuXNnODo6FjiApqWlwdXVFQqFAj/88IPR8KysLEyZMgUeHh6ws7ODr68voqKi8hxXdnY2Zs2ahfr168PW1hZubm4IDg7GzZs3pT4nTpzA2LFj0bBhQ9jb28PLywv9+vXDn3/+aTS+4cOH57l869ev/8L5KhZBpa5NmzaiRo0aAoC4cuWKucsx0rBhQ9GxY8cC9wcgunbtKtasWSP+85//iOnTpws3NzehUCjEnj17Sry+7OxskZmZKT2/ffu2ACAiIiKM+ubk5IhHjx6VeA3m9M8//wgLCwsxYsSIfPt06tRJVKlSRWRnZxd4vNWrVxehoaElUGHpOHHihAAgVq5cWaD+Fy9eFADEihUrSrew5wgNDRXVq1c32/RLmr29fbHWkYMHDwoA4uDBg8/tFx8fLwAILy8v0alTp+e+7zdu3BBVq1YVtWrVEl9++aWYOXOmqFy5smjatKnIysoy6Pv+++8LAGL06NFi+fLlIjg4WAAQ33//fZHGeebMGbFmzRqjh6enp6hcubLR9ENDQ4WVlZUYOXKkWLFihVi4cKEIDQ0VP//883OXx+PHj0WbNm2EjY2NmDBhgliyZIno2bOnACBmzpyZ5zKuU6eO8PPzK9DyFkKIcePGCXt7ewFAbN682Wj4gAEDhJWVlXj33XfFsmXLhJ+fn7CyshK//PKLQb/s7Gzh7+8vKlWqJN555x3x7bffis8//1z07dtXxMXFSf1CQkKERqMR48aNEytWrBCffPKJcHNzE/b29uLcuXNGy02pVBot5x07drxwvoqDgaiU/fXXXwKA2LJli3BxcRHTpk0zd0lGihKIwsPDDdrOnj0rAIiAgIASrs7Y8wJRRfXKK68ItVptEAz1bt68KSwsLMSYMWMKNc6KFogOHz6c74e7qTAQGSpoIMrMzBSJiYlCiBe/72FhYcLOzk78/fffUltUVJQAIJYtWya13bx5U1hbWxt8Vul0OtG+fXtRrVo18fjx40KPMy8JCQlCoVCI0aNHG7Rv3LhR+uwvrE2bNgkA4ttvvzVoDwkJEba2tiI5OVlq02q14u7du0IIITZv3lyg5X3u3DlhZWUlZsyYkeffzPHjxwUAMW/ePKnt0aNHolatWsLPz8+g75w5c4S1tbU4fvz4c6d59OhRo8D4559/CqVSKQYPHmzQHhoaKuzt7Z87vtLAQFTKPvnkE+mXQ1hYmKhTp06e/e7cuSOGDBkiHB0dhVqtFsOGDROnT5/O84Ph4sWLIiQkRFSuXFkolUrRokULsX37doM+K1euFADEr7/+KiZMmCCqVq0qKlWqJHr16iVSUlKkftWrVxcADB4vCkd5BSIhhKhatarB/EVHR4t27dqJSpUqCbVaLV577TVx4cIFg9dotVrxzjvviOrVqwsbGxvh4uIi/P39xcmTJ6U+T3/J6H9JPvvQh6OIiAjx7IbPnJwcMWPGDFGzZk1hY2MjqlevLqZOnWoULqpXry6Cg4PFL7/8Ilq2bCmUSqXw9vYWq1evfu7yyM7OFpUrVxbDhw83Gpaeni6USqWYNGmS1PbVV18JHx8fYWdnJ5ycnESLFi3EunXrnjsN/fv5448/Gg37/PPPBQDpl9u8efOEn5+fcHZ2Fra2tqJ58+Z5hoRnA1Fey+7pacfHxxu079mzR3p/HRwcxKuvvmrwizA/d+/eFZMmTRKNGjUS9vb2wtHRUQQFBYnTp09LffRfpM8+8vuSDA0NzXc97tixY57r9LPhRb9uzZs3TyxbtkxaX15++WURGxtr9PqtW7eKhg0bCqVSKRo2bCi2bNmSZyAq6Puh/7vatGmTaNCggbC1tRWtW7cWZ8+eFUIIERkZKWrVqiWUSqXo2LGj0fshhBC//fabCAwMFCqVStjZ2YkOHTqIX3/91aCP/n2+cuWKCA0NFWq1WqhUKjF8+HDx4MEDg3qefejXl+vXr4uwsDBRt25dYWtrK5ydnUWfPn2MaipoIHraiwKRq6ur6Nu3r1F73bp1xSuvvCI9X7x4sQAgzp8/b9Bv/fr1Bn8vhRlnXubMmSMAiEOHDhm0+/r6ilatWgkhhMjNzRX3799/7nieNm7cOAHA4P0Q4n+BZ/ny5Xm+rqCBqEuXLqJv377S+/Ps+jh58mRhaWkp0tPTDdpnzZolAIiEhARpvjw8PES/fv2EEE8+a5+t+UWaN28umjdvbtCmD0SPHz82qqE08RiiUrZu3Tr07t0bNjY2GDhwIK5cuYITJ04Y9NHpdOjRowe+//57hIaGYubMmUhMTERoaKjR+M6fP4/WrVvj4sWLeP/99zF//nzY29ujV69e2Lp1q1H/cePG4cyZM4iIiEBYWBh27tyJsWPHSsMXLlyIatWqoX79+lizZg3WrFmDf//734Wez3v37uHevXuoUqUKAGD//v0IDAxESkoKpk2bhokTJ+LYsWNo27Ytrl+/Lr1uzJgxWLp0KUJCQrBkyRK8++67sLOzw8WLF/OcjouLi7Qf/fXXX5dq7t27d761vfHGG/j444/RvHlzfPHFF+jYsSNmz56NAQMGGPW9evUq+vTpg65du2L+/PmoXLkyhg8fjvPnz+c7fmtra7z++uvYtm0bsrOzDYZt27YNWVlZ0rRWrFiBt99+Gz4+Pli4cCGmT5+OZs2a4fjx4/mOHwB69+4NW1tbrF+/3mjY+vXrUb16dbRt2xYA8OWXX+L//u//MGPGDMyaNQtWVlbo27cvdu/e/dxpFMaaNWsQHBwMBwcHzJkzBx999BEuXLiAdu3aGby/efnrr7+wbds2dO/eHQsWLMDkyZNx7tw5dOzYEbdu3QIANGjQADNmzAAAvPnmm9L73KFDhzzH+a9//QsffPABAODtt98u8noMPFme8+bNw7/+9S98+umnuH79Onr37o2cnBypz88//4yQkBAoFArMnj0bvXr1wogRI/D7778bja8w78cvv/yCSZMmITQ0FNOmTcPFixfRvXt3LF68GF999RXeeustTJ48GTExMRg5cqTBaw8cOIAOHTpAq9UiIiICs2bNQlpaGrp06YLY2FijafXr1w8ZGRmYPXs2+vXrh1WrVmH69OnS8DVr1kCpVKJ9+/bS8v/Xv/4F4MnxIMeOHcOAAQPw1VdfYcyYMYiOjkanTp3w8OHDIi33gvjnn3+QkpKCl19+2WhYq1at8Mcff0jP//jjD9jb26NBgwZG/fTDCzvOvKxbtw6enp4G66ZWq0VsbCxatmyJDz74AGq1Gg4ODqhZsyY2bdr0wvnMysqCpaUlbGxsDNorVaoEADh58uQLx5GfzZs349ixY5g7d26+ff744w/UrVsXKpXKoF2/7PTH9V24cAG3bt1CkyZN8Oabb8Le3h729vZo0qQJDh48+MJahBBITk5G1apVjYY9fPgQKpUKarUazs7OCA8Px/379wsxp0VgsuglQ7///rsAIKKiooQQTzbXVqtWTbzzzjsG/X788UcBQCxcuFBqy83NFV26dDH6pfTKK6+Ixo0bG2zd0Ol0ok2bNgZbZ/S/6v39/YVOp5PaJ0yYICwtLUVaWprUVpRdZqNGjRK3b98WKSkp4vjx4+KVV14RAMT8+fOFEEI0a9ZMuLq6SptyhXiy/93CwkIMGzZMalOr1XlubXras7+6n7fL7NmtHPqtbG+88YZBv3fffVcAEAcOHJDa9FvLjhw5IrWlpKQYbeHJy759+wQAsXPnToP2V199VdSsWVN63rNnT9GwYcPnjis/ffv2Fba2tga/mC5duiQAiKlTp0ptDx8+NHhddna2aNSokejSpYtBe1G3EGVkZAgnJyejXQRJSUlCrVYbtT8rMzNT5ObmGrTFx8cLpVIpZsyYIbUVdpdZfr92C7uFqEqVKiI1NVVq3759u9F726xZM+Hu7m7wd/Tzzz8LAEZbiAr6fgAQSqXSYCvLsmXLBACh0WiEVquV2qdOnWrwnuh0OlGnTh0RGBho8Pf+8OFD4e3tLbp27Sq16d/nkSNHGkz/9ddfF1WqVDFoy2+X2bPzJIQQMTExAoD4z3/+I7WV9BYi/bCnp6E3efJkAUD6bAwODjb429N78OCBACDef//9Qo/zWXFxcQKAeO+99wzaT506Ja1Lbm5uYsmSJWLdunWiVatWQqFQiJ9++um5y2D+/PlGW7GE+N8xUd27d8/zdS/aQvTw4UPh5eUlfV7k9zfTsGFDo/VTCCHOnz8vAIjIyEghhBBbtmyR5rNOnTpi5cqVYuXKlaJOnTrCxsZGnDlz5rnzuWbNmjx3Db7//vtiypQpYuPGjeL777+XtgC3bdtW5OTkPHecxcEtRKVo3bp1cHNzQ+fOnQE8OTurf//+2LBhA3Jzc6V+e/fuhbW1NUaPHi21WVhYIDw83GB8qampOHDggPTL7s6dO7hz5w7u3r2LwMBAXLlyBf/884/Ba958802D09Dbt2+P3Nxc/P3338Wat2+//RYuLi5wdXWFr68vjh49iokTJ2L8+PFITEzE6dOnMXz4cDg7O0uvadKkCbp27Yo9e/ZIbU5OTjh+/Li0ZaCk6ac1ceJEg/ZJkyYBgNGvdB8fH7Rv31567uLignr16uGvv/567nS6dOmCqlWrYuPGjVLbvXv3EBUVhf79+0ttTk5OuHnzptFWwoIYMmQIMjMzsWXLFqlNv8Vo8ODBUpudnZ1BDenp6Wjfvj1OnTpV6GnmJSoqCmlpaRg4cKC0Dt65cweWlpbw9fV94S9DpVIJC4snHz25ubm4e/cuHBwcUK9evRKrsTj69++PypUrS8/164N+HdCv36GhoVCr1VK/rl27wsfHx2h8hXk/XnnlFYPT9vVnpoaEhMDR0dGoXV/T6dOnceXKFQwaNAh3796V3pMHDx7glVdewZEjR6DT6QymNWbMGIPn7du3x927d6HVap+zdIznKScnB3fv3kXt2rXh5ORUqu/ho0ePADxZh55la2tr0OfRo0cF7lfQcT5r3bp1AAz//gBIWzLu3r2L7du3IywsDIMGDUJ0dDSqVKmCTz/99HmziUGDBkGtVmPkyJGIiorC9evXsXz5cixZsuS59bzIZ599hpycHGlran4Kuuz085mRkYHo6GgMHz4cw4cPx/79+yGEeO5WqEuXLiE8PBx+fn5Ge0Nmz56Nzz77DP369cOAAQOwatUqzJw5E0ePHs3zjLiSwkBUSnJzc7FhwwZ07twZ8fHxuHr1Kq5evQpfX18kJycjOjpa6vv333/D3d1d2hyqV7t2bYPnV69ehRACH330EVxcXAweERERAICUlBSD13h5eRk813/Q37t3r1jz17NnT0RFRWH//v04fvw47ty5g/nz58PCwkIKW/Xq1TN6XYMGDaQPagCYO3cu4uLi4OnpiVatWmHatGkvDB+F8ffff8PCwsJoWWo0Gjg5ORkFw2eXF/Bkmb1oeVlZWSEkJATbt29HVlYWAGDLli3IyckxCERTpkyBg4MDWrVqhTp16iA8PNzoVN38dOvWDc7Ozga7zb7//ns0bdoUDRs2lNp27dqF1q1bw9bWFs7OztJuxvT09AJN50WuXLkC4EkIfHY9/Pnnn43WwWfpdDp88cUXqFOnDpRKJapWrQoXFxecPXu2xGosjhf9zejXmTp16hi9Nq91vjDvx7PT1gcuT0/PPNv1Nenfk9DQUKP35JtvvkFWVpbR9Irz2fDo0SN8/PHH8PT0NHgP09LSSvU91Acx/d/Y0zIzMw362NnZFbhfQcf5NCEE1q9fj0aNGqFJkyZ51unt7W1wuRUHBwf06NEDsbGxePz4cb7zqdFosGPHDmRlZSEgIADe3t6YPHkyFi1aJI2nsK5fv4558+Zh5syZL3x9YZdd27ZtDdZRLy8vtGvXDseOHctz/ElJSQgODoZarcYPP/wAS0vLF9Y/YcIEWFhYPPfyI8VlVWpjlrkDBw4gMTERGzZswIYNG4yGr1u3DgEBAYUap/4X3rvvvovAwMA8+zz7xZ/fiiaEKNS0n1WtWjX4+/sXaxzAk+MY2rdvj61bt+Lnn3/GvHnzMGfOHGzZsgXdunUr9vj1CnqxxuIsrwEDBmDZsmX46aef0KtXL2zatAn169dH06ZNpT4NGjTA5cuXsWvXLuzduxc//vgjlixZgo8//tjg+I28WFtbo1+/flixYgWSk5ORkJCAK1euGPwK++WXX/Daa6+hQ4cOWLJkCdzd3WFtbY2VK1fmefzR0/JbRk9vzQT+tx6uWbMGGo3GqL+V1fM/VmbNmoWPPvoII0eOxCeffAJnZ2dYWFhg/PjxRlsxSoJCocjz/Xt2vvRK8m+msO9HftN+UU365TZv3jw0a9Ysz77PfgkWZz7HjRuHlStXYvz48fDz84NarYZCocCAAQNK5T3Uc3d3B/BkK92zEhMT4ezsLG3ZcHd3x8GDByGEMFi39a/18PAo9DifdvToUfz999+YPXu20TD9uN3c3IyGubq6IicnBw8ePDDYwvisDh064K+//sK5c+fw4MEDNG3aVNqSXrdu3Xxfl5+PP/4YL730Ejp16iQd55eUlAQAuH37Nq5fvw4vLy9YWFjA3d3daG8DYLzsXjSfeR1/lZ6ejm7duiEtLQ2//PKLNI4X0V/HKTU1tUD9i4KBqJSsW7cOrq6uWLx4sdGwLVu2YOvWrYiMjISdnR2qV6+OgwcP4uHDhwZbia5evWrwupo1awJ48sVYEmFEr6Sv7Ky/GN7ly5eNhl26dAlVq1aFvb291Obu7o633noLb731FlJSUtC8eXPMnDkz30BUmHqrV68OnU6HK1euGBxcmZycjLS0tBK9cF+HDh3g7u6OjRs3ol27djhw4ECeB/ba29ujf//+6N+/P7Kzs9G7d2/MnDkTU6dOlTZJ52fw4MGIjIzExo0bER8fD4VCgYEDB0rDf/zxR9ja2mLfvn0GH+IrV658Yf36LQRpaWlwcnKS2p/dilarVi0ATz7wirIe/vDDD+jcuTO+/fZbg/a0tDSDgytLar2sXLlynlsdi7rbWL/O6LfKPO3Zdb4470dh6N8TlUplks+GH374AaGhoZg/f77UlpmZibS0tBKbdl5eeukluLi45HnwemxsrEEYbNasGb755htcvHjRYFem/gQGfd/CjPNp69atg0KhwKBBg4yGeXh4QKPR5Bkqbt26BVtbW4NdoPmxtLQ0mL5+60hR3uOEhARcvXpV+h552ltvvQXgydZBJycnNGvWDAcPHoRWqzU4sPrZZde4cWNYW1vnO58uLi4GbZmZmejRowf+/PNP7N+/P89dzPnRHyby7DhLEneZlYJHjx5hy5Yt6N69O/r06WP0GDt2LDIyMqSrCgcGBiInJwcrVqyQxqHT6YzClKurKzp16oRly5bl+Wsmryu1FoS9vX2JfpC5u7ujWbNmWL16tcF44+Li8PPPP+PVV18F8OQX+rOb111dXeHh4ZHn5lo9fWgsSM36aS1cuNCgfcGCBQCA4ODgF46joCwsLNCnTx/s3LkTa9aswePHjw12lwFPjil4mo2NDXx8fCCEMDiLKT9t27ZFjRo1sHbtWmzcuBEdO3ZEtWrVpOGWlpZQKBQGWz+uX79eoKsN679Ujxw5IrU9ePAAq1evNugXGBgIlUqFWbNm5Vnzi9ZDS0tLo60QmzdvNvpQ1Yfm4q6btWrVwqVLlwzqOnPmTIF3VT7r6fX76fU3KioKFy5cMOhbnPejMFq0aIFatWrh888/z/NMnJL+bMjrPVy0aFG+W91KUkhICHbt2oUbN25IbdHR0fjzzz/Rt29fqa1nz56wtraWjrsBnmz9ioyMxEsvvYQ2bdoUepx6OTk52Lx5M9q1a5fnbnbgybFoN27cMLi68507d7B9+3Z06dJFOo4uJycHly5dyvMz/Wm3b9/GnDlz0KRJkyIFok8//RRbt241eHzyyScAgPfeew9bt26V/ub69OmD3NxcLF++XHp9VlYWVq5cCV9fX2n3mKOjI1599VUcO3YMly5dkvpevHgRx44dQ9euXaW23Nxc9O/fHzExMdi8eTP8/PzyrDMzMxMZGRlG7Z988gmEEAgKCir0vBcUtxCVgh07diAjIwOvvfZansNbt24NFxcXrFu3Dv3790evXr3QqlUrTJo0CVevXkX9+vWxY8cOadPg07/SFi9ejHbt2qFx48YYPXo0atasieTkZMTExODmzZsFuiT8s1q0aIGlS5fi008/Re3ateHq6oouXboUbeb/a968eejWrRv8/PwwatQoPHr0CIsWLYJarca0adMAPEn81apVQ58+fdC0aVM4ODhg//79OHHihMEvz2fZ2dnBx8cHGzduRN26deHs7IxGjRqhUaNGRn2bNm2K0NBQLF++HGlpaejYsSNiY2OxevVq9OrVSzrgvaT0798fixYtQkREBBo3bmx0ym9AQAA0Gg3atm0LNzc3XLx4EV9//TWCg4ML9ItR/4t01qxZACCdmq4XHByMBQsWICgoCIMGDUJKSgoWL16M2rVr4+zZs88dd0BAALy8vDBq1ChMnjwZlpaW+O677+Di4oKEhASpn0qlwtKlSzF06FA0b94cAwYMkPrs3r0bbdu2xddff53vdLp3744ZM2ZgxIgRaNOmDc6dO4d169YZ/XKtVasWnJycEBkZCUdHR9jb28PX1xfe3t4vXE5PGzlyJBYsWIDAwECMGjUKKSkpiIyMRMOGDQt0AHFeZs+ejeDgYLRr1w4jR45EamoqFi1ahIYNGxoEkuK8H4VhYWGBb775Bt26dUPDhg0xYsQIvPTSS/jnn39w8OBBqFQq7Ny5s9DjbdGiBfbv348FCxbAw8NDOiame/fuWLNmDdRqNXx8fBATE4P9+/dLl90oiq+//hppaWnSbqGdO3dKt34YN26ctHvpgw8+wObNm9G5c2e88847uH//PubNm4fGjRtjxIgR0viqVauG8ePHY968ecjJyUHLli2xbds2/PLLL1i3bp3BLsOCjlNv3759uHv3rtHB1E+bOnUqNm3ahJCQEEycOBFqtRqRkZHIycmR/n6BJ6f9N2jQAKGhoQa3K+nYsSP8/PxQu3ZtJCUlYfny5bh//z527dolhSk9/UHa+suDrFmzBr/++isA4MMPPwQAtGvXzqhG/Zbgli1bolevXlK7r68v+vbti6lTpyIlJQW1a9fG6tWrcf36daMtu7NmzUJ0dDS6dOmCt99+GwDw1VdfwdnZ2eDg7UmTJmHHjh3o0aMHUlNTsXbtWoPxDBkyBMCT3Xj/93//h4EDB0q36ti3bx/27NmDoKAg9OzZM99lXmyldv6ajPXo0UPY2to+9wJVw4cPF9bW1uLOnTtCiCenkg8aNEi6MOPw4cPF0aNHBQCxYcMGg9deu3ZNDBs2TGg0GmFtbS1eeukl0b17d/HDDz9IffSnSp84ccLgtXmdBpuUlCSCg4OFo6NjsS7M+Kz9+/eLtm3bCjs7O6FSqUSPHj0MLsyYlZUlJk+eLJo2bSocHR2Fvb29aNq0qViyZInBePK62N2xY8dEixYthI2NTYEuzDh9+nTh7e0trK2thaen53MvzPis/E7bzotOpxOenp4CgPj000+Nhi9btkx06NBBVKlSRSiVSlGrVi0xefLkQl18TH/qq1KpFPfu3TMa/u2334o6deoIpVIp6tevL1auXJnncsnrStUnT54Uvr6+wsbGRnh5eYkFCxbke2HGgwcPisDAQKFWq4Wtra2oVauWGD58uPj999+fW39mZqaYNGmScHd3F3Z2dqJt27YiJiYmz+W8fft24ePjI6ysrF54Cn5+pxALIcTatWulCy02a9ZM7Nu377kXZnzW0+uY3o8//igaNGgglEql8PHxyffCjAV9P/L6u8qvpvzm9Y8//hC9e/eW1q/q1auLfv36iejoaKmPftq3b982eG1e7/OlS5dEhw4dhJ2dncGFGe/duydGjBghqlatKhwcHERgYKC4dOmS0TpVmNPu87pIrP7x7LoXFxcnAgICRKVKlYSTk5MYPHiwSEpKMhpnbm6umDVrlnTh14YNG4q1a9fmOf2CjlOIJ7e1sLa2NrisSF6uXbsmXn/9delCmV26dDG6yKf+PX72b3HChAmiZs2aQqlUChcXFzFo0CBx7dq1PKeT33J70Vf88/5mHj16JN59912h0WiEUqkULVu2FHv37s1zPCdPnhT+/v7ShVZ79uwp/vzzT4M+HTt2LFCd9+7dE0OGDBG1a9cWlSpVki58OmvWrELdmqgoFEIU8+haKjXbtm3D66+/jl9//VW66B4RERGVPAaiMuLRo0cGp3bm5uYiICAAv//+O5KSkvI87ZOIiIhKBo8hKiPGjRuHR48ewc/PD1lZWdiyZQuOHTuGWbNmMQwRERGVMm4hKiPWr1+P+fPn4+rVq8jMzETt2rURFhZmcN8xIiIiKh0MRERERCR7vA4RERERyR4DEREREckeD6ouAJ1Oh1u3bsHR0bHEb3NBREREpUMIgYyMDHh4eBhd0PJZDEQFcOvWLaO7TRMREVH5cOPGDYPbHOWFgagA9LdUuHHjhsGN7oiIiKjs0mq18PT0LNCtkRiICkC/m0ylUjEQERERlTMFOdyFB1UTERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHs8UrVZpSrE4iNT0VKRiZcHW3RytsZlha8eSwREZGpMRCZyd64REzfeQGJ6ZlSm7vaFhE9fBDUyN2MlREREckPd5mZwd64RIStPWUQhgAgKT0TYWtPYW9copkqIyIikicGIhPL1QlM33kBIo9h+rbpOy8gV5dXDyIiIioNDEQmFhufarRl6GkCQGJ6JmLjU01XFBERkcwxEJlYSkb+Yago/YiIiKj4GIhMzNXRtkT7ERERUfExEJlYK29nuKttkd/J9Qo8OduslbezKcsiIiKSNQYiE7O0UCCihw8AGIUi/fOIHj68HhEREZEJmTUQLV26FE2aNIFKpYJKpYKfnx9++uknaXhmZibCw8NRpUoVODg4ICQkBMnJyQbjSEhIQHBwMCpVqgRXV1dMnjwZjx8/Nuhz6NAhNG/eHEqlErVr18aqVatMMXv5CmrkjqVDmkOjNtwtplHbYumQ5rwOERERkYmZ9cKM1apVw2effYY6depACIHVq1ejZ8+e+OOPP9CwYUNMmDABu3fvxubNm6FWqzF27Fj07t0bR48eBQDk5uYiODgYGo0Gx44dQ2JiIoYNGwZra2vMmjULABAfH4/g4GCMGTMG69atQ3R0NN544w24u7sjMDDQbPMe1MgdXX00vFI1ERFRGaAQQpSpC944Oztj3rx56NOnD1xcXLB+/Xr06dMHAHDp0iU0aNAAMTExaN26NX766Sd0794dt27dgpubGwAgMjISU6ZMwe3bt2FjY4MpU6Zg9+7diIuLk6YxYMAApKWlYe/evQWqSavVQq1WIz09HSqVquRnmoiIiEpcYb6/y8wxRLm5udiwYQMePHgAPz8/nDx5Ejk5OfD395f61K9fH15eXoiJiQEAxMTEoHHjxlIYAoDAwEBotVqcP39e6vP0OPR99OPIS1ZWFrRarcGDiIiIKi6zB6Jz587BwcEBSqUSY8aMwdatW+Hj44OkpCTY2NjAycnJoL+bmxuSkpIAAElJSQZhSD9cP+x5fbRaLR49epRnTbNnz4ZarZYenp6eJTGrREREVEaZPRDVq1cPp0+fxvHjxxEWFobQ0FBcuHDBrDVNnToV6enp0uPGjRtmrYeIiIhKl9nvdm9jY4PatWsDAFq0aIETJ07gyy+/RP/+/ZGdnY20tDSDrUTJycnQaDQAAI1Gg9jYWIPx6c9Ce7rPs2emJScnQ6VSwc7OLs+alEollEplicwfERERlX1m30L0LJ1Oh6ysLLRo0QLW1taIjo6Whl2+fBkJCQnw8/MDAPj5+eHcuXNISUmR+kRFRUGlUsHHx0fq8/Q49H304yAiIiIy6xaiqVOnolu3bvDy8kJGRgbWr1+PQ4cOYd++fVCr1Rg1ahQmTpwIZ2dnqFQqjBs3Dn5+fmjdujUAICAgAD4+Phg6dCjmzp2LpKQkfPjhhwgPD5e28IwZMwZff/013nvvPYwcORIHDhzApk2bsHv3bnPOOhEREZUhZg1EKSkpGDZsGBITE6FWq9GkSRPs27cPXbt2BQB88cUXsLCwQEhICLKyshAYGIglS5ZIr7e0tMSuXbsQFhYGPz8/2NvbIzQ0FDNmzJD6eHt7Y/fu3ZgwYQK+/PJLVKtWDd98841Zr0FEREREZUuZuw5RWcTrEBEREZU/5fI6RERERETmwkBEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyZ9ZANHv2bLRs2RKOjo5wdXVFr169cPnyZYM+nTp1gkKhMHiMGTPGoE9CQgKCg4NRqVIluLq6YvLkyXj8+LFBn0OHDqF58+ZQKpWoXbs2Vq1aVdqzR0REROWEWQPR4cOHER4ejt9++w1RUVHIyclBQEAAHjx4YNBv9OjRSExMlB5z586VhuXm5iI4OBjZ2dk4duwYVq9ejVWrVuHjjz+W+sTHxyM4OBidO3fG6dOnMX78eLzxxhvYt2+fyeaViIiIyi6FEEKYuwi927dvw9XVFYcPH0aHDh0APNlC1KxZMyxcuDDP1/z000/o3r07bt26BTc3NwBAZGQkpkyZgtu3b8PGxgZTpkzB7t27ERcXJ71uwIABSEtLw969e19Yl1arhVqtRnp6OlQqVfFnlIiIiEpdYb6/y9QxROnp6QAAZ2dng/Z169ahatWqaNSoEaZOnYqHDx9Kw2JiYtC4cWMpDAFAYGAgtFotzp8/L/Xx9/c3GGdgYCBiYmLyrCMrKwtardbgQURERBWXlbkL0NPpdBg/fjzatm2LRo0aSe2DBg1C9erV4eHhgbNnz2LKlCm4fPkytmzZAgBISkoyCEMApOdJSUnP7aPVavHo0SPY2dkZDJs9ezamT59e4vNIREREZVOZCUTh4eGIi4vDr7/+atD+5ptvSv9v3Lgx3N3d8corr+DatWuoVatWqdQydepUTJw4UXqu1Wrh6elZ4tPJ1QnExqciJSMTro62aOXtDEsLRYlPh4iIiJ6vTASisWPHYteuXThy5AiqVav23L6+vr4AgKtXr6JWrVrQaDSIjY016JOcnAwA0Gg00r/6tqf7qFQqo61DAKBUKqFUKos8PwWxNy4R03deQGJ6ptTmrrZFRA8fBDVyL9VpExERkSGzHkMkhMDYsWOxdetWHDhwAN7e3i98zenTpwEA7u5PQoOfnx/OnTuHlJQUqU9UVBRUKhV8fHykPtHR0QbjiYqKgp+fXwnNSeHsjUtE2NpTBmEIAJLSMxG29hT2xiWapS4iIiK5MmsgCg8Px9q1a7F+/Xo4OjoiKSkJSUlJePToEQDg2rVr+OSTT3Dy5Elcv34dO3bswLBhw9ChQwc0adIEABAQEAAfHx8MHToUZ86cwb59+/Dhhx8iPDxc2sozZswY/PXXX3jvvfdw6dIlLFmyBJs2bcKECRNMPs+5OoHpOy8gr1P79G3Td15Arq7MnPxHRERU4Zk1EC1duhTp6eno1KkT3N3dpcfGjRsBADY2Nti/fz8CAgJQv359TJo0CSEhIdi5c6c0DktLS+zatQuWlpbw8/PDkCFDMGzYMMyYMUPq4+3tjd27dyMqKgpNmzbF/Pnz8c033yAwMNDk8xwbn2q0ZehpAkBieiZi41NNVxQREZHMmfUYohddAsnT0xOHDx9+4XiqV6+OPXv2PLdPp06d8McffxSqvtKQkpF/GCpKPyIiIiq+MnUdIjlwdbQt0X5ERERUfAxEJtbK2xnualvkd3K9Ak/ONmvl7ZxPDyIiIippDEQmZmmhQESPJ2e/PRuK9M8jevjwekREREQmxEBkBkGN3LF0SHNo1Ia7xTRqWywd0pzXISIiIjKxMnFhRjkKauSOrj4aXqmaiIioDGAgMiNLCwX8alUxdxlERESyx11mREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQke1bmLoCIiIjkK1cnEBufipSMTLg62qKVtzMsLRQmr4OBiIiIiMxib1wipu+8gMT0TKnNXW2LiB4+CGrkbtJauMuMiIiITG5vXCLC1p4yCEMAkJSeibC1p7A3LtGk9TAQERERkUnl6gSm77wAkccwfdv0nReQq8urR+lgICIiIiKTio1PNdoy9DQBIDE9E7HxqSariYGIiIiITColI/8wVJR+JYGBiIiIiEzK1dG2RPuVBAYiIiIiMqlW3s5wV9siv5Pr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9erVQ79+/VClShX89ttvcHFxAQB88cUX6N69O0JCQtChQwdoNBps2bJFer2lpSV27doFS0tL+Pn5YciQIRg2bBhmzJhhrlkiIio03qzYdF50ALsAD2CvqBRCCL6rL6DVaqFWq5Gens7jiYjIbHgdotIXc+0uBq747YX9vh/dmgewlwOF+f4u02eZERHR//BmxaUvSVuwA9ML2o/KDwYiIqJyhDcrLl2p97NKtB+VH2X6GCIiIiJTcrYv2C2dCtqPyg8GIiIiov/SqAt20d+C9qPyg4GIiIjov/SXOHgeXuKgYmIgIiIi+i9LCwVea/r8M/Zea+rOA9krIAYiIiKi/8rVCew48/wLL+44k8jrEFVAPMuMiEpE9mMd1sRcx9+pD1HduRKG+tWAjRV/c1H58qIb6QK8kW5FxUBERMU2e88FrPglHk//aJ655yJGt/fG1Fd530AqP3gjXfliICKiYpm95wKWHYk3atcJSO0MRVRe8Ea68sXt2URUZNmPdVj+i3EYetryX+KR/VhnooqIioc30pUvBiIiKrLVx67jRXdDFOJJP6LygDfSlS8GIiIqshPX75ZoP6KyIKiRO5YOaQ7NM9cj0qhtsXRIc95It4LiMUREVGSVbAr2EVLQfkRlBW+kKz/8lCKiIgtpXg3bTt8qUD+i8oY30pUX7jIjoiJrU7sqKtlYPrePvY0l2tSuaqKKiIiKhoGIiIrM0kKBBf2aPrfP/H5NuZuBiMo8BiIiKpagRu6IHNIcbo5Kg3aNSolIHoBKROUEjyEiomLjAahEVN4xEBFRieABqERUnnGXGREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREcmelbkLICKigrutzcLrS35F6oMcONtbY+tb7eCiUpq7LKJyT1ZbiBYvXowaNWrA1tYWvr6+iI2NNXdJREQF1mTaPrSctR830zLxMCcXN9My0XLWfjSZts/cpRGVe7IJRBs3bsTEiRMRERGBU6dOoWnTpggMDERKSoq5SyMieqEm0/ZBm/k4z2HazMcMRUTFJJtAtGDBAowePRojRoyAj48P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" }, "metadata": {}, "output_type": "display_data" @@ -479,19 +345,19 @@ "plt.ylabel('Value')\n", "plt.title(f'Agent Position vs Value at fundamental {fundamental_val}')\n", "plt.show()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "31f002d1c196705a", + ], "metadata": { + "collapsed": false, "ExecuteTime": { - "end_time": "2024-03-27T23:40:00.547410Z", - "start_time": "2024-03-27T23:40:00.470896Z" - }, - "collapsed": false + "end_time": "2024-03-26T20:44:58.709570600Z", + "start_time": "2024-03-26T20:44:58.596987100Z" + } }, + "id": "44a74cbe8acf673", + "execution_count": 38 + }, + { + "cell_type": "code", "outputs": [ { "name": "stdout", @@ -502,10 +368,8 @@ }, { "data": { - "image/png": "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rl69irNnzyIyMhJxcXEYNWoUrly5gvfeew+nTp3C1atXsWvXLowdOxbdunVDy5YtAQBBQUFQq9UYM2YM/vjjD+zbtw9z5sxBREQEbG1tAQCTJk3Cn3/+ibfeegsXLlzAypUr8f3332P69OlmO+8QP0+sGt0GHir9bjEPlR1WjW6DED9PM2VGREQkT2addj9+/HgcOHAA6enpUKlUaNmyJWbPno3evXvj+vXrGD16NJKSknD37l14e3tj4MCBmDNnjl4X1rVr1zB58mTExcXB0dERYWFh+Oijj1Cjxv8Nj4qLi8P06dORnJyMevXqYe7cuQgPDzc4T2NOu38YV6omIiKqOpX5/ba4dYgsUVUVRERERFR1quU6RERERETmwoKIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPbMWRKtWrULLli2hVCqhVCoREBCAn376Sdqfn5+PiIgI1K5dG05OThg8eDAyMzP1niM1NRWhoaFwcHCAm5sbZs2ahQcPHujFxMXFoU2bNrC1tUXjxo0RHR1titMjIiKiasKsBVG9evXw0Ucf4dSpUzh58iR69eqF/v3749y5cwCA6dOnIyYmBj/88AMOHz6MtLQ0DBo0SHp8cXExQkNDUVhYiCNHjmDdunWIjo7GvHnzpJiUlBSEhoaiZ8+eSExMxLRp0zBhwgTs27fP5OdLRERElkkhhBDmTuJhrq6uWLJkCYYMGYK6deti06ZNGDJkCADgwoULaN68ORISEtCxY0f89NNP6Nu3L9LS0uDu7g4AWL16NWbPno2bN2/CxsYGs2fPxp49e5CUlCQdY8SIEcjJycHevXsNykmj0UClUiE3NxdKpdL4J01ERERGV5nfb4sZQ1RcXIzNmzfj7t27CAgIwKlTp1BUVITAwEAp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", - "text/plain": [ - "
" - ] + "text/plain": "
", + "image/png": "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rl69irNnzyIyMhJxcXEYNWoUrly5gvfeew+nTp3C1atXsWvXLowdOxbdunVDy5YtAQBBQUFQq9UYM2YM/vjjD+zbtw9z5sxBREQEbG1tAQCTJk3Cn3/+ibfeegsXLlzAypUr8f3332P69OlmO+8QP0+sGt0GHir9bjEPlR1WjW6DED9PM2VGREQkT2addj9+/HgcOHAA6enpUKlUaNmyJWbPno3evXvj+vXrGD16NJKSknD37l14e3tj4MCBmDNnjl4X1rVr1zB58mTExcXB0dERYWFh+Oijj1Cjxv8Nj4qLi8P06dORnJyMevXqYe7cuQgPDzc4T2NOu38YV6omIiKqOpX5/ba4dYgsUVUVRERERFR1quU6RERERETmwoKIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPbMWRKtWrULLli2hVCqhVCoREBCAn376Sdqfn5+PiIgI1K5dG05OThg8eDAyMzP1niM1NRWhoaFwcHCAm5sbZs2ahQcPHujFxMXFoU2bNrC1tUXjxo0RHR1titMjIiKiasKsBVG9evXw0Ucf4dSpUzh58iR69eqF/v3749y5cwCA6dOnIyYmBj/88AMOHz6MtLQ0DBo0SHp8cXExQkNDUVhYiCNHjmDdunWIjo7GvHnzpJiUlBSEhoaiZ8+eSExMxLRp0zBhwgTs27fP5OdLRERElkkhhBDmTuJhrq6uWLJkCYYMGYK6deti06ZNGDJkCADgwoULaN68ORISEtCxY0f89NNP6Nu3L9LS0uDu7g4AWL16NWbPno2bN2/CxsYGs2fPxp49e5CUlCQdY8SIEcjJycHevXsNykmj0UClUiE3NxdKpdL4J01ERERGV5nfb4sZQ1RcXIzNmzfj7t27CAgIwKlTp1BUVITAwEApplmzZqhfvz4SEhIAAAkJCfD395eKIQAIDg6GRqORWpkSEhL0nkMXo3uOshQUFECj0ejdiIiI6Nll9oLo7NmzcHJygq2tLSZNmoTt27dDrVYjIyMDNjY2cHFx0Yt3d3dHRkYGACAjI0OvGNLt1+2rKEaj0eD+/ftl5rRw4UKoVCrp5u3tbYxTJSIiIgtl9oKoadOmSExMxLFjxzB58mSEhYUhOTnZrDlFRkYiNzdXul2/ft2s+RAREVHVqmHuBGxsbNC4cWMAQNu2bXHixAl89tlnGD58OAoLC5GTk6PXSpSZmQkPDw8AgIeHB44fP673fLpZaA/HPDozLTMzE0qlEvb29mXmZGtrC1tbW6OcHxEREVk+s7cQPUqr1aKgoABt27ZFzZo1ceDAAWnfxYsXkZqaioCAAABAQEAAzp49i6ysLCkmNjYWSqUSarVainn4OXQxuucgIiIiMmsLUWRkJPr06YP69esjLy8PmzZtQlxcHPbt2weVSoXx48djxowZcHV1hVKpxNSpUxEQEICOHTsCAIKCgqBWqzFmzBgsXrwYGRkZmDNnDiIiIqQWnkmTJuGLL77AW2+9hVdeeQUHDx7E999/jz179pjz1ImIiMiCmLUgysrKwtixY5Geng6VSoWWLVti37596N27NwDg008/hZWVFQYPHoyCggIEBwdj5cqV0uOtra2xe/duTJ48GQEBAXB0dERYWBjeffddKcbX1xd79uzB9OnT8dlnn6FevXr4z3/+g+DgYJOfLxEREVkmi1uHyBJxHSIiIqLqp1quQ0RERERkLiyIiIiISPZYEBEREZHssSAiIiIi2WNBRERERLLHgoiIiIhkjwURERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSAiIiIi2WNBRERERLLHgoiIiIhkjwURERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSAiIiIi2WNBRERERLLHgoiIiIhkjwURERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSAiIiIi2WNBRERERLLHgoiIiIhkjwURERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSAiIiIi2TNrQbRw4UI8//zzcHZ2hpubGwYMGICLFy/qxfTo0QMKhULvNmnSJL2Y1NRUhIaGwsHBAW5ubpg1axYePHigFxMXF4c2bdrA1tYWjRs3RnR0dFWfHhEREVUTZi2IDh8+jIiICBw9ehSxsbEoKipCUFAQ7t69qxc3ceJEpKenS7fFixdL+4qLixEaGorCwkIcOXIE69atQ3R0NObNmyfFpKSkIDQ0FD179kRiYiKmTZuGCRMmYN++fSY7VyIiIrJcCiGEMHcSOjdv3oSbmxsOHz6Mbt26AShpIWrdujWWLVtW5mN++ukn9O3bF2lpaXB3dwcArF69GrNnz8bNmzdhY2OD2bNnY8+ePUhKSpIeN2LECOTk5GDv3r2PzUuj0UClUiE3NxdKpfLpT5SIiIiqXGV+vy1qDFFubi4AwNXVVW/7xo0bUadOHfj5+SEyMhL37t2T9iUkJMDf318qhgAgODgYGo0G586dk2ICAwP1njM4OBgJCQll5lFQUACNRqN3IyIiomdXDXMnoKPVajFt2jR07twZfn5+0vaRI0fCx8cHXl5eOHPmDGbPno2LFy9i27ZtAICMjAy9YgiAdD8jI6PCGI1Gg/v378Pe3l5v38KFC7FgwQKjnyMRERFZJospiCIiIpCUlIRff/1Vb/urr74q/dvf3x+enp544YUXcOXKFTRq1KhKcomMjMSMGTOk+xqNBt7e3lVyLCIiIjI/i+gymzJlCnbv3o1Dhw6hXr16FcZ26NABAHD58mUAgIeHBzIzM/VidPc9PDwqjFEqlaVahwDA1tYWSqVS70ZERETPLrMWREIITJkyBdu3b8fBgwfh6+v72MckJiYCADw9PQEAAQEBOHv2LLKysqSY2NhYKJVKqNVqKebAgQN6zxMbG4uAgAAjnQkRERFVZ2YtiCIiIrBhwwZs2rQJzs7OyMjIQEZGBu7fvw8AuHLlCt577z2cOnUKV69exa5duzB27Fh069YNLVu2BAAEBQVBrVZjzJgx+OOPP7Bv3z7MmTMHERERsLW1BQBMmjQJf/75J9566y1cuHABK1euxPfff4/p06eb7dyJiIjIcph12r1CoShz+9q1axEeHo7r169j9OjRSEpKwt27d+Ht7Y2BAwdizpw5et1Y165dw+TJkxEXFwdHR0eEhYXho48+Qo0a/zdEKi4uDtOnT0dycjLq1auHuXPnIjw83KA8Oe2eiIio+qnM77dFrUNkqVgQERERVT/Vdh0iIiIiInNgQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItmrYe4ESL6KtQLHU7KRlZcPN2c7tPd1hbWVwtxpERGRDLEgIrPYm5SOBTHJSM/Nl7Z5quwQ1U+NED9PM2ZGRERyZNYus4ULF+L555+Hs7Mz3NzcMGDAAFy8eFEvJj8/HxEREahduzacnJwwePBgZGZm6sWkpqYiNDQUDg4OcHNzw6xZs/DgwQO9mLi4OLRp0wa2trZo3LgxoqOjq/r0qBx7k9IxecNpvWIIADJy8zF5w2nsTUo3U2ZERCRXZi2IDh8+jIiICBw9ehSxsbEoKipCUFAQ7t69K8VMnz4dMTEx+OGHH3D48GGkpaVh0KBB0v7i4mKEhoaisLAQR44cwbp16xAdHY158+ZJMSkpKQgNDUXPnj2RmJiIadOmYcKECdi3b59Jz5dKuskWxCRDlLFPt21BTDKKtWVFEBERVQ2FEMJifnlu3rwJNzc3HD58GN26dUNubi7q1q2LTZs2YciQIQCACxcuoHnz5khISEDHjh3x008/oW/fvkhLS4O7uzsAYPXq1Zg9ezZu3rwJGxsbzJ49G3v27EFSUpJ0rBEjRiAnJwd79+59bF4ajQYqlQq5ublQKpVVc/IykXDlFl5ec/Sxcd9N7IiARrVNkBERET2rKvP7bVGzzHJzcwEArq6uAIBTp06hqKgIgYGBUkyzZs1Qv359JCQkAAASEhLg7+8vFUMAEBwcDI1Gg3PnzkkxDz+HLkb3HGQ6WXn5jw+qRBwREZExWMygaq1Wi2nTpqFz587w8/MDAGRkZMDGxgYuLi56se7u7sjIyJBiHi6GdPt1+yqK0Wg0uH//Puzt7fX2FRQUoKCgQLqv0Wie/gQJAODmbGfUOCIiImOwmBaiiIgIJCUlYfPmzeZOBQsXLoRKpZJu3t7e5k7pmdHe1xWeKjuUN7legZLZZu19XU2ZFhERyZxFFERTpkzB7t27cejQIdSrV0/a7uHhgcLCQuTk5OjFZ2ZmwsPDQ4p5dNaZ7v7jYpRKZanWIQCIjIxEbm6udLt+/fpTnyOVsLZSIKqfGgBKFUW6+1H91FyPiIiITMqsBZEQAlOmTMH27dtx8OBB+Pr66u1v27YtatasiQMHDkjbLl68iNTUVAQEBAAAAgICcPbsWWRlZUkxsbGxUCqVUKvVUszDz6GL0T3Ho2xtbaFUKvVuZDwhfp5YNboNPFT63WIeKjusGt2G6xAREZHJmXWW2WuvvYZNmzZh586daNq0qbRdpVJJLTeTJ0/Gjz/+iOjoaCiVSkydOhUAcOTIEQAl0+5bt24NLy8vLF68GBkZGRgzZgwmTJiADz/8EEDJtHs/Pz9ERETglVdewcGDB/H6669jz549CA4OfmyenGVWNbhSNRERVaXK/H6btSBSKMr+8Vu7di3Cw8MBlCzM+Oabb+K7775DQUEBgoODsXLlSqk7DACuXbuGyZMnIy4uDo6OjggLC8NHH32EGjX+b8x4XFwcpk+fjuTkZNSrVw9z586VjvE4LIiIiIiqn2pTEFUXLIiIiIiqn2q7DhERERGRObAgIiIiItmzmIUZSX44qJqIiCwFCyIyi71J6VgQk6x3xXtPlR2i+qk57Z6IiEzuibrMHjx4gP379+PLL79EXl4eACAtLQ137twxanL0bNqblI7JG07rFUMAkJGbj8kbTmNvUrqZMiMiIrmqdAvRtWvXEBISgtTUVBQUFKB3795wdnbGokWLUFBQgNWrV1dFnvSMKNYKLIhJRllTGwVKVqteEJOM3moPdp8REZHJVLqF6I033kC7du1w+/ZtvcteDBw4sNRq0ESPOp6SXapl6GECQHpuPo6nZJsuKSIikr1KtxD98ssvOHLkCGxsbPS2N2jQAH/99ZfREqNnU1Ze+cXQk8QREREZQ6VbiLRaLYqLi0ttv3HjBpydnY2SFD273JztHh9UiTgiIiJjqHRBFBQUhGXLlkn3FQoF7ty5g6ioKLz44ovGzI2eQe19XeGpsit1pXsdBUpmm7X3dTVlWmZTrBVIuHILOxP/QsKVWyjWcuF4IiJzqPSlO27cuIHg4GAIIXDp0iW0a9cOly5dQp06dRAfHw83N7eqytVseOkO49LNMgOgN7haVyTJ5Yr3XHqAiKhqVfm1zB48eIDNmzfjzJkzuHPnDtq0aYNRo0bpDbJ+lrAgMj65FwO6ovDR/3xyKwqJiKoSL+5qZCyIqoZcV6ou1gp0WXSw3Nl2CgAeKjv8OruXLF4PIqKqUpnf70rPMvv2228r3D927NjKPiXJlLWVAgGNaps7DZOrzNIDcnx9iIjModIF0RtvvKF3v6ioCPfu3YONjQ0cHBxYEBE9BpceICKyPJWeZXb79m292507d3Dx4kV06dIF3333XVXkSPRMcbW3eXxQJeKIiOjpPdG1zB7VpEkTfPTRR6Vaj4iotAuZeUaNIyKip2eUgggAatSogbS0NGM9HdEz6/rte0aNIyKip1fpMUS7du3Suy+EQHp6Or744gt07tzZaIkRPat8XB2MGkdERE+v0gXRgAED9O4rFArUrVsXvXr1wieffGKsvIieWWMCGuCDH8+jokWprRQlcUREZBqVLoi0Wm1V5EEkGzY1rDCxqy++jE8pN2ZiV1/Y1DBajzYRET0Gv3GJzCDyRTV6q8u+zE1vtRsiX1SbOCMiInkzqIVoxowZBj/h0qVLnzgZIrnYm5SO/clZZe7bn5yFvUnpvHQHEZEJGVQQ/f777wY9mULBywwQPU6xVmBBTHKp65g9bEFMMnqrPXjpDiIiEzGoIDp06FBV50EkG7x0BxGR5eEYIiIT46U7iIgsT6VnmQHAyZMn8f333yM1NRWFhYV6+7Zt22aUxIieVW7OdkaNIyKip1fpFqLNmzejU6dOOH/+PLZv346ioiKcO3cOBw8ehEqlqoociZ4p7X1d4amyQ3mjgxQAPFV2aO/rasq0iIhkrdIF0YcffohPP/0UMTExsLGxwWeffYYLFy5g2LBhqF+/flXkSPRMsbZSIKpfybT6R4si3f2ofmoOqCYiMqFKF0RXrlxBaGgoAMDGxgZ3796FQqHA9OnT8dVXXxk9QaJnUYifJ1aNbgMPlX63mIfKDqtGt+GUeyIiE6v0GKJatWohL6/kKtz/+Mc/kJSUBH9/f+Tk5ODePV6MkshQIX6e6K32wPGUbGTl5cPNuaSbjC1DRESmZ3BBlJSUBD8/P3Tr1g2xsbHw9/fH0KFD8cYbb+DgwYOIjY3FCy+8UJW5Ej1zrK0UnFpPRGQBDC6IWrZsieeffx4DBgzA0KFDAQD//ve/UbNmTRw5cgSDBw/GnDlzqixRIiIioqqiEEJUtGCu5JdffsHatWuxdetWaLVaDB48GBMmTEDXrl2rOkez02g0UKlUyM3NhVKpNHc6REREZIDK/H4bPKi6a9eu+Oabb5Ceno7ly5fj6tWr6N69O5577jksWrQIGRkZT504ERERkTkY3EJUlsuXL2Pt2rVYv349MjIyEBISgl27dhkzP4vAFiKqKsVawUHVRERVpEpaiMrSuHFjvPPOO5gzZw6cnZ2xZ8+eSj0+Pj4e/fr1g5eXFxQKBXbs2KG3Pzw8HAqFQu8WEhKiF5OdnY1Ro0ZBqVTCxcUF48ePx507d/Rizpw5g65du8LOzg7e3t5YvHjxE50vkTHtTUpHl0UH8fKao3hjcyJeXnMUXRYdxN6kdHOnRkQkO09cEMXHxyM8PBweHh6YNWsWBg0ahN9++61Sz3H37l20atUKK1asKDcmJCQE6enp0u27777T2z9q1CicO3cOsbGx2L17N+Lj4/Hqq69K+zUaDYKCguDj44NTp05hyZIlmD9/PtdMIrPam5SOyRtOl7rIa0ZuPiZvOM2iiIjIxCq1DlFaWhqio6MRHR2Ny5cvo1OnTvj8888xbNgwODo6Vvrgffr0QZ8+fSqMsbW1hYeHR5n7zp8/j7179+LEiRNo164dAGD58uV48cUX8fHHH8PLywsbN25EYWEhvvnmG9jY2KBFixZITEzE0qVL9QonIlMp1gosiElGWX3VAiWrVS+ISUZvtQe7z4iITMTgFqI+ffrAx8cHy5cvx8CBA3H+/Hn8+uuvGDdu3BMVQ4aKi4uDm5sbmjZtismTJ+PWrVvSvoSEBLi4uEjFEAAEBgbCysoKx44dk2K6desGGxsbKSY4OBgXL17E7du3qyxvovIcT8ku1TL0MAEgPTcfx1OyTZcUEZHMGdxCVLNmTWzduhV9+/aFtbV1VeYkCQkJwaBBg+Dr64srV67gnXfeQZ8+fZCQkABra2tkZGTAzc1N7zE1atSAq6urNOstIyMDvr6+ejHu7u7Svlq1apU6bkFBAQoKCqT7Go3G2KdGMpaVV34x9CRxRET09AwuiMwxe2zEiBHSv/39/dGyZUs0atQIcXFxVboq9sKFC7FgwYIqe36SNzdnu8cHVSKOiIie3lPNMjO1hg0bok6dOrh8+TIAwMPDA1lZWXoxDx48QHZ2tjTuyMPDA5mZmXoxuvvljU2KjIxEbm6udLt+/bqxT4VkrL2vKzxVdqWudK+jAOCpKpmCT0REplGtCqIbN27g1q1b8PQsuRJ4QEAAcnJycOrUKSnm4MGD0Gq16NChgxQTHx+PoqIiKSY2NhZNmzYts7sMKBnIrVQq9W5ExmJtpUBUPzUAlCqKdPej+qk5oJqIyITMWhDduXMHiYmJSExMBACkpKQgMTERqampuHPnDmbNmoWjR4/i6tWrOHDgAPr374/GjRsjODgYANC8eXOEhIRg4sSJOH78OH777TdMmTIFI0aMgJeXFwBg5MiRsLGxwfjx43Hu3Dls2bIFn332GWbMmGGu0yZCiJ8nVo1uAw+VfreYh8oOq0a3QYifp5kyIyKSp6daqfppxcXFoWfPnqW2h4WFYdWqVRgwYAB+//135OTkwMvLC0FBQXjvvfekQdFAycKMU6ZMQUxMDKysrDB48GB8/vnncHJykmLOnDmDiIgInDhxAnXq1MHUqVMxe/Zsg/PkStVUVQofaLE+4SquZd+Dj6sDxgQ0gE2NatVwS0RksSrz+23Wgqi6YEFEVWFvUjoWxCTrTcH3VNkhqp+aLUREREZgskt3ENGTKW+l6nSuVE1EZBYsiIhMrKKVqoGShRkXxCSjWMvGWyIiU2FBRGRij1upGuBK1UREpsaCiMjEMnLvGzWOiIieHgsiIhPLvlto1DgiInp6LIiITMzVydaocURE9PRYEBGZmIfSsGuUGRpHRERPjwURkYnprmVWEV7LjIjItFgQEZmYtZUCL7WqeOHFl1p58lpmREQmxIKIyMSKtQK7/qh44cVdf6RzHSIiIhNiQURkYlyHiIjI8rAgIjKxrLyKi6HKxhER0dOrYe4EiOTGzdmw2WOGxhFR9VWsFTieko2svHy4OZdMpuD4QfNgQURkYrpZZhm5+WVez0wBwIOzzIieeXuT0rEgJlmvC91TZYeofmqE+FU88YKMj11mRCZmbaVAVD81gJLi52G6+1H91PwrkegZtjcpHZM3nC41njAjNx+TN5zG3qSKJ16Q8bEgIjKDED9PrBrdBh6PrEfkobLDqtFt+Nch0TOsWCuwICa5zBZi3bYFMcmcaWpi7DIjMpMQP0/0Vntw/ACRzDxupqnA/800DWhU23SJyRwLIiIzsrZS8AuPSGY409QyscuMiIjIhDjT1DKxICIiIjIh3UzT8jrHFeD1DM2BBREREZEJcaapZWJBREREZGKcaWp5OKiaiIjIDDjT1LKwICIiIjITzjS1HOwyIyIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI/XMiMiIiKzKdYKi7jArVlbiOLj49GvXz94eXlBoVBgx44devuFEJg3bx48PT1hb2+PwMBAXLp0SS8mOzsbo0aNglKphIuLC8aPH487d+7oxZw5cwZdu3aFnZ0dvL29sXjx4qo+NSIiInqMvUnp6LLoIF5ecxRvbE7Ey2uOosuig9iblG7yXMxaEN29exetWrXCihUryty/ePFifP7551i9ejWOHTsGR0dHBAcHIz8/X4oZNWoUzp07h9jYWOzevRvx8fF49dVXpf0ajQZBQUHw8fHBqVOnsGTJEsyfPx9fffVVlZ8fERERlW1vUjombziN9Nx8ve0ZufmYvOG0yYsihRBCmPSI5VAoFNi+fTsGDBgAoKR1yMvLC2+++SZmzpwJAMjNzYW7uzuio6MxYsQInD9/Hmq1GidOnEC7du0AAHv37sWLL76IGzduwMvLC6tWrcK///1vZGRkwMbGBgDw9ttvY8eOHbhw4YJBuWk0GqhUKuTm5kKpVBr/5ImISJYspbvI1Iq1Al0WHSxVDOkoAHio7PDr7F5P9XpU5vfbYgdVp6SkICMjA4GBgdI2lUqFDh06ICEhAQCQkJAAFxcXqRgCgMDAQFhZWeHYsWNSTLdu3aRiCACCg4Nx8eJF3L59u8xjFxQUQKPR6N2IiIiMyZK6i0zteEp2ucUQAAgA6bn5OJ6SbbKcLLYgysjIAAC4u7vrbXd3d5f2ZWRkwM3NTW9/jRo14OrqqhdT1nM8fIxHLVy4ECqVSrp5e3s//QkRERH9j6V1F5laVl75xdCTxBmDxRZE5hQZGYnc3Fzpdv36dXOnREREz4hircCCmGSUNV5Ft21BTDKKtRYxoqVKuDnbGTXOGCy2IPLw8AAAZGZm6m3PzMyU9nl4eCArK0tv/4MHD5Cdna0XU9ZzPHyMR9na2kKpVOrdiIiIjMESu4tMrb2vKzxVdihvdJACgKeqZEyVqVhsQeTr6wsPDw8cOHBA2qbRaHDs2DEEBAQAAAICApCTk4NTp05JMQcPHoRWq0WHDh2kmPj4eBQVFUkxsbGxaNq0KWrVqmWisyEiIiphid1FpmZtpUBUPzUAlCqKdPej+qlNOsDcrAXRnTt3kJiYiMTERAAlA6kTExORmpoKhUKBadOm4f3338euXbtw9uxZjB07Fl5eXtJMtObNmyMkJAQTJ07E8ePH8dtvv2HKlCkYMWIEvLy8AAAjR46EjY0Nxo8fj3PnzmHLli347LPPMGPGDDOdNRERyZkldheZQ4ifJ1aNbgMPlf55eqjssGp0G4T4eZo0H7NOu4+Li0PPnj1LbQ8LC0N0dDSEEIiKisJXX32FnJwcdOnSBStXrsRzzz0nxWZnZ2PKlCmIiYmBlZUVBg8ejM8//xxOTk5SzJkzZxAREYETJ06gTp06mDp1KmbPnm1wnpx2T0RExqKbcp6Rm1/mOCJjTTmvLqpy6YHK/H5bzDpElowFERERGZNulhkAvaJIVwaYo4XkWfRMrENERET0rLK07iLixV2JyIzkukovEVBSFPVWe/D/gIVgQUREZrE3KR0LYpL1ph97quwQ1U/Nv45JNqytFAhoVNvcaRDYZUZEZiD3VXqJyPKwICIik+IqvURkiVgQEZFJcZVeIrJELIiIyKS4Si8RWSIWRERkUlyll4gsEQsiIjKptj618LhZxVaKkjgiIlNhQUREJnXq2m08bry0VpTEERGZCgsiIjIpjiEiIkvEgoiITIpjiIjIErEgIiKTau/rCk+VHcobRqRAyYrV7X1dTZkWEckcCyIiMilrKwWi+qkrjInqp+b1nIjIpFgQEZHJhfh5wr+essx9/vWUvJYZEZkcCyIiMrmJ357AmRuaMveduaHBxG9PmDgjIvMo1gokXLmFnYl/IeHKLV6yxox4tXsiMqn7hcWITc6qMCY2OQv3C4thb2NtoqyITG9vUjoWxCTrXcrGU2WHqH5qtpKaAVuIiMikPvwx2ahxRNXR3qR0TN5wutR1/TJy8zF5w2nsTUo3U2byxYKIiEzq6q17Ro0jqm6KtQILYpJRVueYbtuCmGR2n5kYCyIiMinvWvZGjSOqbo6nZJdqGXqYAJCem4/jKdmmS4pYEBGRadVzMazQMTSOqLrhau2WiQUREZlU4o1co8YRVTdcrd0ycZYZEZmUg4EzxwyNo+qtWCtwPCUbWXn5cHMuWaH8WV+UU7dae0ZufpnjiBQAPLhau8mxICIyIzn+GAz+Zz3sSEwzKI6ebXKddq5brX3yhtNQAHpFke5/P1drNz0WRERmItcfgw6Nahs1jqon3bTzR1tIdNPOV41u80z/Pwjx88Sq0W1KfQd4yOA7wFKxICIyAzn/GJwwcObMiZRsdG5Sp4qzIXN43LRzBUqmnfdWezzTrSQhfp7orfaQXSuxpeKgaiITk/saJAl//m3UOKp+OO38/1hbKRDQqDb6t/4HAhrVZjFkRiyIiExM7j8GhhZ6z2pBSJx2TpaJBRGRicn9xyDnXpFR46j64bRzskQsiIhMTO4/Bpcy84waR9WPbtp5eZ1DCpRMMOC0czIlFkREJib3HwNDO8LYYfbs0k07rwinnctHsVYg4cot7Ez8CwlXbpmtu5yzzIhMTO5rkDzn7oRTqTkGxdGzK8TPE69288WaX1Lw8O+flQKY2NX3mZ1lSfosafkRthARmYFuDRIPlX63mIfK7pmecg8AKgcbo8ZR9bQ3KR1fxesXQwAgBPBVfAr2JqWbJzEyGd3yI49OMtEtP2LqzwBbiIjMRK5rkNQw8PwMjaPqh+sQkSV+BthCRGRGclyDpEMDA1eqNjCOqh+5Lz1BlvkZYEFERKZlaM337NeGsiX3pSfIMj8DFl0QzZ8/HwqFQu/WrFkzaX9+fj4iIiJQu3ZtODk5YfDgwcjMzNR7jtTUVISGhsLBwQFubm6YNWsWHjx4YOpTIaL/OZZyy6hxVP3IfekJsszPgEUXRADQokULpKenS7dff/1V2jd9+nTExMTghx9+wOHDh5GWloZBgwZJ+4uLixEaGorCwkIcOXIE69atQ3R0NObNm2eOUyEiAGwiIrkvPUGW+Rmw+IKoRo0a8PDwkG516pRc7DE3Nxdff/01li5dil69eqFt27ZYu3Ytjhw5gqNHjwIAfv75ZyQnJ2PDhg1o3bo1+vTpg/feew8rVqxAYWGhOU+LSLYCDLyKvaFxVP08vA7Roz+Iclh64mGWsgaPqVniZ8DiC6JLly7By8sLDRs2xKhRo5CamgoAOHXqFIqKihAYGCjFNmvWDPXr10dCQgIAICEhAf7+/nB3d5digoODodFocO7cuXKPWVBQAI1Go3cjIuPo2LA2XBxqVhhTy6EmOjZkQfQs0y094a6U39ITOnuT0tFl0UG8vOYo3ticiJfXHEWXRQdls+SApS0/YtHT7jt06IDo6Gg0bdoU6enpWLBgAbp27YqkpCRkZGTAxsYGLi4ueo9xd3dHRkYGACAjI0OvGNLt1+0rz8KFC7FgwQLjngwRASj5y/CjQf6YtOF0uTELB/nLonWAgEfXJBdCHi0kujV4Hj1b3Ro8cikKLWn5EYtuIerTpw+GDh2Kli1bIjg4GD/++CNycnLw/fffV+lxIyMjkZubK92uX79epccjkpsQP0+sHt0GHo+0Dniq7LBaJj8EcqcrCDI0BXrbMzUFZlmUz5QetwYPULIGj5y6zyxh+RGLbiF6lIuLC5577jlcvnwZvXv3RmFhIXJycvRaiTIzM+Hh4QEA8PDwwPHjx/WeQzcLTRdTFltbW9ja2hr/BIhIYkl/GZJpWeKifKZUmTV4OJbOdCy6hehRd+7cwZUrV+Dp6Ym2bduiZs2aOHDggLT/4sWLSE1NRUBAAAAgICAAZ8+eRVZWlhQTGxsLpVIJtbriCwsSUdWzlL8MybQscVE+U7LENXjIwluIZs6ciX79+sHHxwdpaWmIioqCtbU1Xn75ZahUKowfPx4zZsyAq6srlEolpk6dioCAAHTs2BEAEBQUBLVajTFjxmDx4sXIyMjAnDlzEBERwRYgIiIzkXtBUMfJsN8fQ+PIOCy6ILpx4wZefvll3Lp1C3Xr1kWXLl1w9OhR1K1bFwDw6aefwsrKCoMHD0ZBQQGCg4OxcuVK6fHW1tbYvXs3Jk+ejICAADg6OiIsLAzvvvuuuU6JiEj2LHFRPlPSFhs2NsjQODIOhZDLkP6noNFooFKpkJubC6VSae50iIiqtWKtQJdFB5GRm1/mOCIFSqZe/zq71zPZjfrxvgv44tCVx8ZN6dkIM4ObPTaOyleZ3+9qNYaIiIiqP92ifOX9NS7wrC/MyNXaLRELIiIiIhPiau2WiQURERGZlG7afXl00+6f1XV4uFq7ZWJBREREJiX3afe61dorwtXaTY8FERERmZTcp90DXK3dEln0tHsiInr21HE0cB0eA+OqK67WbllYEBERkUlpDVztxdC46ky3WjuZH7vMiIjIpI5cuWXUOCJjYAsRERGZ1Nm/cowaV50VawW7zCwECyIiIjIp+5rWRo2rrvYmpWP+rnPI0BRI2zyUtpj/UgsOqjYDdpkREZFJtfd1NWpcdbQ3KR2TNpzWK4YAIENTgEkbTmNvUrqZMpMvFkRERGRSozs2MGpcdVOsFXh729kKY97edvaZXZjSUrEgIiIik0q8nmPUuOrm6JVbyLlXVGFMzr0iHOWgcpNiQURERCaVnnPfqHHVTcKffxs1joyDBREREZnU79dvGzWuujG0I4wdZqbFgoiIiEyq2MAFFw2Nq26UdhVf2LWycWQcLIiIiMikrBWGrbNjaFx1o7lf8fihysaRcbAgIiIik/qndy2jxlU3CgMLPUPjyDhYEBERkUl5utgbNa66MfTaZbzGmWmxICIiIpNq7+sKF4eKx8fUcqj5zC7M2LFhbYPOv2NDFkSmxIKIiIgszrM5nLqEtZUCHw3yrzBm4SB/XtPMxFgQERGRSR1PyTZoYcLjKdkmysj0Qvw8sXp0G3go7fS2e6rssHp0G17LzAx4cVciIjKprLx8o8ZVVyF+nuit9uDV7i0ECyIiIjIpN2e7xwdVIq46s7ZScPC0hWCXGRERmZQhg6pdnuFB1WSZWBAREZHFYacRmRoLIiIiMilDBlXffsYHVZPlYUFEREQmlWbgVewNjSMyBhZERERkUr+nGni1ewPjiIyBBREREZlUWu49o8YRGQMLIiIiMqksTaFR44iMgQURERGZlIfKsPWFDI0jMgYWREREZFIdfA1biNDQOCJjYEFEREQmFdapwWPXGVL8L47IVFgQERGRSVlbKWBvY11hjL2NNa/pRSbFa5kREZnRhsOXMOen/yfdf7/PcxjdvYkZM6p6x1Oyca+wuMKYe4XFOJ6Szet8kcnIqoVoxYoVaNCgAezs7NChQwccP37c3CkRkYw1eHuPXjEEAHN++n9o8PYeM2VkGrzaPVki2RREW7ZswYwZMxAVFYXTp0+jVatWCA4ORlZWlrlTIyIZelzR8ywXRbzaPVki2RRES5cuxcSJEzFu3Dio1WqsXr0aDg4O+Oabb8ydGhHJzIbDl4waV92093WFp8qu3IHVCgCeKjte7Z5MShYFUWFhIU6dOoXAwEBpm5WVFQIDA5GQkFAqvqCgABqNRu9GRGQsj3aTPW1cdWNtpUBUPzWA0le1192P6qfmoGoyKVkURH///TeKi4vh7u6ut93d3R0ZGRml4hcuXAiVSiXdvL29TZUqEZEshPh5YtXoNqUWX/RQ2WHV6DYI8fM0U2YkV5xlVobIyEjMmDFDuq/RaFgUEREZWYifJ3qrPXA8JRtZeflwcy7pJmPLEJmDLAqiOnXqwNraGpmZmXrbMzMz4eHhUSre1tYWtra2pkqPiGTm/T7PGdQd9n6f50yQjXlZWyk4tZ4sgiy6zGxsbNC2bVscOHBA2qbVanHgwAEEBASYMTMikiND1xl61tcjIrIksiiIAGDGjBlYs2YN1q1bh/Pnz2Py5Mm4e/cuxo0bZ+7UiEiGrn4U+lT7ici4ZNFlBgDDhw/HzZs3MW/ePGRkZKB169bYu3dvqYHWRESmsDcpHQoAoox9iv/t58BiItNRCCHK+v9ID9FoNFCpVMjNzYVSqTR3OkRUzRVrBbosOoj03LJXYlagZLbVr7N7cYAx0VOozO+3bLrMiIgsxfGU7HKLIaCk1Sg9Nx/HU7JNlxSRzLEgIiIyMV7Li8jysCAiIjIxXsuLyPKwICIiMjFey4vI8rAgIiIyMV7Li8jysCAiIjIDXsuLyLLIZh0iIiJLw2t5EVkOFkRERGbEa3kRWQZ2mREREZHssSAiIiIi2WNBRERERLLHgoiIiIhkjwURERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHscaVqAwghAAAajcbMmRAREZGhdL/but/xirAgMkBeXh4AwNvb28yZEBERUWXl5eVBpVJVGKMQhpRNMqfVapGWlgZnZ2coFMa96KJGo4G3tzeuX78OpVJp1OeuDuR+/gBfA7mfP8DXgOcv7/MHqu41EEIgLy8PXl5esLKqeJQQW4gMYGVlhXr16lXpMZRKpWz/IwA8f4CvgdzPH+BrwPOX9/kDVfMaPK5lSIeDqomIiEj2WBARERGR7LEgMjNbW1tERUXB1tbW3KmYhdzPH+BrIPfzB/ga8Pzlff6AZbwGHFRNREREsscWIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSCyQAUFBWjdujUUCgUSExPNnY5JvfTSS6hfvz7s7Ozg6emJMWPGIC0tzdxpmcTVq1cxfvx4+Pr6wt7eHo0aNUJUVBQKCwvNnZrJfPDBB+jUqRMcHBzg4uJi7nRMYsWKFWjQoAHs7OzQoUMHHD9+3NwpmUx8fDz69esHLy8vKBQK7Nixw9wpmdTChQvx/PPPw9nZGW5ubhgwYAAuXrxo7rRMatWqVWjZsqW0IGNAQAB++ukns+TCgsgCvfXWW/Dy8jJ3GmbRs2dPfP/997h48SL++9//4sqVKxgyZIi50zKJCxcuQKvV4ssvv8S5c+fw6aefYvXq1XjnnXfMnZrJFBYWYujQoZg8ebK5UzGJLVu2YMaMGYiKisLp06fRqlUrBAcHIysry9ypmcTdu3fRqlUrrFixwtypmMXhw4cRERGBo0ePIjY2FkVFRQgKCsLdu3fNnZrJ1KtXDx999BFOnTqFkydPolevXujfvz/OnTtn+mQEWZQff/xRNGvWTJw7d04AEL///ru5UzKrnTt3CoVCIQoLC82dilksXrxY+Pr6mjsNk1u7dq1QqVTmTqPKtW/fXkREREj3i4uLhZeXl1i4cKEZszIPAGL79u3mTsOssrKyBABx+PBhc6diVrVq1RL/+c9/TH5cthBZkMzMTEycOBHr16+Hg4ODudMxu+zsbGzcuBGdOnVCzZo1zZ2OWeTm5sLV1dXcaVAVKCwsxKlTpxAYGChts7KyQmBgIBISEsyYGZlLbm4uAMj2/3xxcTE2b96Mu3fvIiAgwOTHZ0FkIYQQCA8Px6RJk9CuXTtzp2NWs2fPhqOjI2rXro3U1FTs3LnT3CmZxeXLl7F8+XL861//MncqVAX+/vtvFBcXw93dXW+7u7s7MjIyzJQVmYtWq8W0adPQuXNn+Pn5mTsdkzp79iycnJxga2uLSZMmYfv27VCr1SbPgwVRFXv77behUCgqvF24cAHLly9HXl4eIiMjzZ2y0Rn6GujMmjULv//+O37++WdYW1tj7NixENV4QfXKnj8A/PXXXwgJCcHQoUMxceJEM2VuHE9y/kRyExERgaSkJGzevNncqZhc06ZNkZiYiGPHjmHy5MkICwtDcnKyyfPgpTuq2M2bN3Hr1q0KYxo2bIhhw4YhJiYGCoVC2l5cXAxra2uMGjUK69atq+pUq4yhr4GNjU2p7Tdu3IC3tzeOHDliliZUY6js+aelpaFHjx7o2LEjoqOjYWVVvf9ueZL3Pzo6GtOmTUNOTk4VZ2c+hYWFcHBwwNatWzFgwABpe1hYGHJycmTXMqpQKLB9+3a910IupkyZgp07dyI+Ph6+vr7mTsfsAgMD0ahRI3z55ZcmPW4Nkx5NhurWrYu6des+Nu7zzz/H+++/L91PS0tDcHAwtmzZgg4dOlRlilXO0NegLFqtFkDJUgTVVWXO/6+//kLPnj3Rtm1brF27ttoXQ8DTvf/PMhsbG7Rt2xYHDhyQigCtVosDBw5gypQp5k2OTEIIgalTp2L79u2Ii4tjMfQ/Wq3WLN/5LIgsRP369fXuOzk5AQAaNWqEevXqmSMlkzt27BhOnDiBLl26oFatWrhy5Qrmzp2LRo0aVdvWocr466+/0KNHD/j4+ODjjz/GzZs3pX0eHh5mzMx0UlNTkZ2djdTUVBQXF0vrcDVu3Fj6P/EsmTFjBsLCwtCuXTu0b98ey5Ytw927dzFu3Dhzp2YSd+7cweXLl6X7KSkpSExMhKura6nvxGdRREQENm3ahJ07d8LZ2VkaO6ZSqWBvb2/m7EwjMjISffr0Qf369ZGXl4dNmzYhLi4O+/btM30yJp/XRgZJSUmR3bT7M2fOiJ49ewpXV1dha2srGjRoICZNmiRu3Lhh7tRMYu3atQJAmTe5CAsLK/P8Dx06ZO7Uqszy5ctF/fr1hY2NjWjfvr04evSouVMymUOHDpX5foeFhZk7NZMo7//72rVrzZ2aybzyyivCx8dH2NjYiLp164oXXnhB/Pzzz2bJhWOIiIiISPaq/wAFIiIioqfEgoiIiIhkjwURERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSAiIlmKi4uDQqF47PXSGjRogGXLlpkkJyIyHxZERGTRwsPDoVAooFAoYGNjg8aNG+Pdd9/FgwcPnup5O3XqhPT0dKhUKgAlF5R1cXEpFXfixAm8+uqrT3UsIrJ8vJYZEVm8kJAQrF27FgUFBfjxxx8RERGBmjVrIjIy8omf08bGxqBrxPHCtETywBYiIrJ4tra28PDwgI+PDyZPnozAwEDs2rULt2/fxtixY1GrVi04ODigT58+uHTpkvS4a9euoV+/fqhVqxYcHR3RokUL/PjjjwD0u8zi4uIwbtw45ObmSq1R8+fPB1C6yyw1NRX9+/eHk5MTlEolhg0bhszMTGn//Pnz0bp1a6xfvx4NGjSASqXCiBEjkJeXZ5LXioieDAsiIqp27O3tUVhYiPDwcJw8eRK7du1CQkIChBB48cUXUVRUBKDkauIFBQWIj4/H2bNnsWjRIjg5OZV6vk6dOmHZsmVQKpVIT09Heno6Zs6cWSpOq9Wif//+yM7OxuHDhxEbG4s///wTw4cP14u7cuUKduzYgd27d2P37t04fPgwPvroo6p5MYjIKNhlRkTVhhACBw4cwL59+9CnTx/s2LEDv/32Gzp16gQA2LhxI7y9vbFjxw4MHToUqampGDx4MPz9/QEADRs2LPN5bWxsoFKpoFAoKuxGO3DgAM6ePYuUlBR4e3sDAL799lu0aNECJ06cwPPPPw+gpHCKjo6Gs7MzAGDMmDE4cOAAPvjgA6O9FkRkXGwhIiKLt3v3bjg5OcHOzg59+vTB8OHDER4ejho1aqBDhw5SXO3atdG0aVOcP38eAPD666/j/fffR+fOnREVFYUzZ848VR7nz5+Ht7e3VAwBgFqthouLi3RMoKSbTVcMAYCnpyeysrKe6thEVLVYEBGRxevZsycSExNx6dIl3L9/H+vWrYNCoXjs4yZMmIA///wTY8aMwdmzZ9GuXTssX768yvOtWbOm3n2FQgGtVlvlxyWiJ8eCiIgsnqOjIxo3boz69eujRo2Snv7mzZvjwYMHOHbsmBR369YtXLx4EWq1Wtrm7e2NSZMmYdu2bXjzzTexZs2aMo9hY2OD4uLiCvNo3rw5rl+/juvXr0vbkpOTkZOTo3dMIqp+WBARUbXUpEkT9O/fHxMnTsSvv/6KP/74A6NHj8Y//vEP9O/fHwAwbdo07Nu3DykpKTh9+jQOHTqE5s2bl/l8DRo0wJ07d3DgwAH8/fffuHfvXqmYwMBA+Pv7Y9SoUTh9+jSOHz+OsWPHonv37mjXrl2Vni8RVS0WRERUba1duxZt27ZF3759ERAQACEEfvzxR6nLqri4GBEREWjevDlCQkLw3HPPYeXKlWU+V6dOnTBp0iQMHz4cdevWxeLFi0vFKBQK7Ny5E7Vq1UK3bt0QGBiIhg0bYsuWLVV6nkRU9RRCCGHuJIiIiIjMiS1EREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItn7/wCYNM8gs66DAAAAAElFTkSuQmCC" }, "metadata": {}, "output_type": "display_data" @@ -550,17 +414,25 @@ "plt.ylabel('Value')\n", "plt.title(f'Agent Position vs Value at fundamental {fundamental_val}')\n", "plt.show()\n" - ] + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-27T23:40:00.547410Z", + "start_time": "2024-03-27T23:40:00.470896Z" + } + }, + "id": "31f002d1c196705a", + "execution_count": 5 }, { "cell_type": "code", - "execution_count": null, - "id": "d8c2f016f622c77c", + "outputs": [], + "source": [], "metadata": { "collapsed": false }, - "outputs": [], - "source": [] + "id": "d8c2f016f622c77c" } ], "metadata": { @@ -572,14 +444,14 @@ "language_info": { "codemirror_mode": { "name": "ipython", - "version": 3 + "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.12" + "pygments_lexer": "ipython2", + "version": "2.7.6" } }, "nbformat": 4, From 249e4e095ac75d1d15f2c4c7dd8e1c646b090a3f Mon Sep 17 00:00:00 2001 From: Rishith Seelam Date: Mon, 1 Jul 2024 15:33:41 -0400 Subject: [PATCH 07/34] cleanup --- marketsim/MM/simMM.py | 10 +++++----- marketsim/agent/extented_zi_agent.py | 2 +- marketsim/agent/hbl_agent.py | 2 +- marketsim/agent/spoofer.py | 3 +-- marketsim/agent/zero_intelligence_agent.py | 2 +- marketsim/event/event_queue.py | 2 -- marketsim/market/market.py | 11 +++++------ marketsim/simulator/sampled_arrival_simulator.py | 10 +++------- marketsim/simulator/simulator.py | 6 +++--- 9 files changed, 20 insertions(+), 28 deletions(-) diff --git a/marketsim/MM/simMM.py b/marketsim/MM/simMM.py index d7ffe820..e3c5c99b 100644 --- a/marketsim/MM/simMM.py +++ b/marketsim/MM/simMM.py @@ -62,8 +62,8 @@ def __init__(self, self.markets = [] for _ in range(num_assets): - fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random_seed) - self.markets.append(Market(fundamental=fundamental, time_steps=sim_time)) + fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random.randint(1,4096)) + self.markets.append(Market(fundamental=fundamental, time_steps=sim_time, random_seed=random.randint(1,4096))) self.agents = {} for agent_id in range(num_background_agents): @@ -77,7 +77,7 @@ def __init__(self, q_max=q_max, shade=shade, pv_var=pv_var, - random_seed=random_seed + random_seed=random.randint(1,4096) )) self.arrivals_MM[self.arrival_times_MM[self.arrival_index_MM].item()].append(self.num_agents) @@ -93,7 +93,7 @@ def __init__(self, omega=omega, beta_params=beta_params, policy=policy, - random_seed=random_seed + random_seed=random.randint(1,4096) ) else: @@ -103,7 +103,7 @@ def __init__(self, K=K, xi=xi, omega=omega, - random_seed=random_seed + random_seed=random.randint(1,4096) ) self.agents[self.num_agents] = self.MM diff --git a/marketsim/agent/extented_zi_agent.py b/marketsim/agent/extented_zi_agent.py index 8d7d7814..c70dc882 100644 --- a/marketsim/agent/extented_zi_agent.py +++ b/marketsim/agent/extented_zi_agent.py @@ -18,7 +18,7 @@ def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: int, offse self.agent_id = agent_id self.market = market - self.pv = PrivateValues(q_max, pv_var, random_seed=random_seed) + self.pv = PrivateValues(q_max, pv_var, random_seed=random.randint(1,4096)) self.position = 0 self.offset = offset self.eta = eta diff --git a/marketsim/agent/hbl_agent.py b/marketsim/agent/hbl_agent.py index 090d86bd..159032b1 100644 --- a/marketsim/agent/hbl_agent.py +++ b/marketsim/agent/hbl_agent.py @@ -24,7 +24,7 @@ def __init__(self, agent_id: int, market: Market, q_max: int, shade: List, L: in self.agent_id = agent_id self.market = market - self.pv = PrivateValues(q_max, pv_var, random_seed=random_seed) + self.pv = PrivateValues(q_max, pv_var, random_seed=random.randint(1,4096)) self.position = 0 self.shade = shade self.cash = 0 diff --git a/marketsim/agent/spoofer.py b/marketsim/agent/spoofer.py index 089c846a..5ee68a36 100644 --- a/marketsim/agent/spoofer.py +++ b/marketsim/agent/spoofer.py @@ -14,10 +14,9 @@ def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: float, ord random.seed(random_seed) # np.random.seed(random_seed) - self.agent_id = agent_id self.market = market - self.pv = PrivateValues(q_max, pv_var, random_seed=random_seed) + self.pv = PrivateValues(q_max, pv_var, random_seed=random.randint(1,4096)) self.position = 0 self.spoofing_size = spoofing_size self.order_size = order_size diff --git a/marketsim/agent/zero_intelligence_agent.py b/marketsim/agent/zero_intelligence_agent.py index 8db6a297..e6ba21e8 100644 --- a/marketsim/agent/zero_intelligence_agent.py +++ b/marketsim/agent/zero_intelligence_agent.py @@ -18,7 +18,7 @@ def __init__(self, agent_id: int, market: Market, q_max: int, shade: List, pv_va self.agent_id = agent_id self.market = market - self.pv = PrivateValues(q_max, pv_var, random_seed=random_seed) + self.pv = PrivateValues(q_max, pv_var, random_seed=random.randint(1,4096)) self.position = 0 self.shade = shade self.cash = 0 diff --git a/marketsim/event/event_queue.py b/marketsim/event/event_queue.py index 077c65ba..ef1a140d 100644 --- a/marketsim/event/event_queue.py +++ b/marketsim/event/event_queue.py @@ -12,8 +12,6 @@ def __init__(self, random_seed: int = 0): # torch.manual_seed(random_seed) random.seed(random_seed) # np.random.seed(random_seed) - - # self.rand = random.Random(rand_seed) self.scheduled_activities = defaultdict(list) self.current_time = 0 diff --git a/marketsim/market/market.py b/marketsim/market/market.py index d5da5fbf..7df1dfb1 100644 --- a/marketsim/market/market.py +++ b/marketsim/market/market.py @@ -1,3 +1,4 @@ +import random from marketsim.event.event_queue import EventQueue from marketsim.fourheap.fourheap import FourHeap from marketsim.fundamental.fundamental_abc import Fundamental @@ -6,17 +7,15 @@ class Market: def __init__(self, fundamental: Fundamental, time_steps, random_seed: int = 0): - # if random_seed != 0: + if random_seed != 0: # torch.manual_seed(random_seed) - # random.seed(random_seed) + random.seed(random_seed) # np.random.seed(random_seed) - self.random_seed = random_seed - self.order_book = FourHeap() self.matched_orders = [] self.fundamental = fundamental - self.event_queue = EventQueue(random_seed=random_seed) + self.event_queue = EventQueue(random_seed=random.randint(1,4096)) self.end_time = time_steps def get_fundamental_value(self): @@ -56,4 +55,4 @@ def step(self): def reset(self): self.order_book = FourHeap() self.matched_orders = [] - self.event_queue = EventQueue(random_seed=self.random_seed) + self.event_queue = EventQueue(random_seed=random.randint(1,4096)) diff --git a/marketsim/simulator/sampled_arrival_simulator.py b/marketsim/simulator/sampled_arrival_simulator.py index 50808100..c18191e0 100644 --- a/marketsim/simulator/sampled_arrival_simulator.py +++ b/marketsim/simulator/sampled_arrival_simulator.py @@ -55,8 +55,8 @@ def __init__(self, self.markets = [] for _ in range(num_assets): - fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random.randint(1,2048)) - self.markets.append(Market(fundamental=fundamental, time_steps=sim_time, random_seed=random.randint(1,2048))) + fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random.randint(1,4096)) + self.markets.append(Market(fundamental=fundamental, time_steps=sim_time, random_seed=random.randint(1,4096))) self.agents = {} # TEMP FOR HBL TESTING @@ -72,7 +72,7 @@ def __init__(self, shade=shade, pv_var=pv_var, eta=eta, - random_seed=random.randint(1,2048) + random_seed=random.randint(1,4096) )) # expanded_zi # else: @@ -138,8 +138,6 @@ def end_sim(self): return values def run(self): - X = [] - Y = [] counter = 0 for t in range(self.sim_time): if self.arrivals[t]: @@ -154,8 +152,6 @@ def run(self): self.time += 1 self.step() - return X, Y - def sample_arrivals(p, num_samples): geometric_dist = dist.Geometric(torch.tensor([p])) diff --git a/marketsim/simulator/simulator.py b/marketsim/simulator/simulator.py index 1e2b875a..67e64d1f 100644 --- a/marketsim/simulator/simulator.py +++ b/marketsim/simulator/simulator.py @@ -34,9 +34,9 @@ def __init__(self, self.markets = [] for _ in range(num_assets): - fundamental = GaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random.randint(1,2048)) + fundamental = GaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random.randint(1,4096)) # fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var) - self.markets.append(Market(fundamental=fundamental, time_steps=sim_time, random_seed=random.randint(1,2048))) + self.markets.append(Market(fundamental=fundamental, time_steps=sim_time, random_seed=random.randint(1,4096))) self.agents = {} for agent_id in range(num_background_agents): @@ -46,7 +46,7 @@ def __init__(self, market=self.markets[0], q_max=q_max, shade=[10, 30], - random_seed=random.randint(1,2048) + random_seed=random.randint(1,4096) )) def step(self): From 526750a0c14155427557c75214e19e99c9122101 Mon Sep 17 00:00:00 2001 From: Rishith Seelam Date: Mon, 1 Jul 2024 16:47:34 -0400 Subject: [PATCH 08/34] cleanup --- marketsim/simulator/sampled_arrival_simulator.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/marketsim/simulator/sampled_arrival_simulator.py b/marketsim/simulator/sampled_arrival_simulator.py index c18191e0..2fb73616 100644 --- a/marketsim/simulator/sampled_arrival_simulator.py +++ b/marketsim/simulator/sampled_arrival_simulator.py @@ -141,8 +141,6 @@ def run(self): counter = 0 for t in range(self.sim_time): if self.arrivals[t]: - X.append(t) - Y.append(self.markets[0].order_book.get_best_ask()) try: self.step() except KeyError: From ecb2ba5ba0e78d2568e956a9c2ebc35ae720b90d Mon Sep 17 00:00:00 2001 From: wangyzh Date: Sun, 26 May 2024 19:37:30 +0100 Subject: [PATCH 09/34] add more features to the observations --- marketsim/MM/RLMM_example.py | 227 +++++++++++++++++++++++ marketsim/MM/parameters/__init__.py | 0 marketsim/MM/parameters/generate_json.py | 38 ++++ marketsim/MM/simMM.py | 49 +++-- marketsim/MM/simMM_example.py | 79 ++++---- marketsim/agent/market_maker_beta.py | 52 ++++-- marketsim/fourheap/fourheap.py | 19 ++ marketsim/market/market.py | 8 + marketsim/wrappers/MM_wrapper.py | 165 +++++++++------- marketsim/wrappers/SP_wrapper.py | 119 ++++++++---- marketsim/wrappers/examples/MMexample.py | 4 +- marketsim/wrappers/metrics.py | 93 ++++++++++ 12 files changed, 689 insertions(+), 164 deletions(-) create mode 100644 marketsim/MM/RLMM_example.py create mode 100644 marketsim/MM/parameters/__init__.py create mode 100644 marketsim/MM/parameters/generate_json.py create mode 100644 marketsim/wrappers/metrics.py diff --git a/marketsim/MM/RLMM_example.py b/marketsim/MM/RLMM_example.py new file mode 100644 index 00000000..573053d5 --- /dev/null +++ b/marketsim/MM/RLMM_example.py @@ -0,0 +1,227 @@ +import argparse +import os +import sys +import pprint +import datetime +from typing import Any + +import gymnasium as gym +import numpy as np +import torch +from gymnasium.core import WrapperActType, WrapperObsType +from torch.utils.tensorboard import SummaryWriter + +from tianshou.data import Collector, VectorReplayBuffer +from tianshou.env import SubprocVectorEnv +from tianshou.policy import SACPolicy +from tianshou.policy.base import BasePolicy +from tianshou.trainer import OffpolicyTrainer +from tianshou.utils import TensorboardLogger +from tianshou.utils.net.common import Net +from tianshou.utils.net.continuous import ActorProb, Critic +from tianshou.utils.space_info import SpaceInfo + +#MM +from marketsim.wrappers.MM_wrapper import MMEnv + + +def get_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--task", type=str, default="RLMM") + parser.add_argument("--seed", type=int, default=0) + parser.add_argument("--buffer-size", type=int, default=1000000) + parser.add_argument("--actor-lr", type=float, default=3e-4) + parser.add_argument("--critic-lr", type=float, default=1e-3) + parser.add_argument("--gamma", type=float, default=0.99) + parser.add_argument("--tau", type=float, default=0.005) + parser.add_argument("--alpha", type=float, default=0.1) + parser.add_argument("--auto-alpha", type=int, default=1) + parser.add_argument("--alpha-lr", type=float, default=3e-4) + parser.add_argument("--epoch", type=int, default=100) + parser.add_argument("--step-per-epoch", type=int, default=100000) + parser.add_argument("--step-per-collect", type=int, default=10) + parser.add_argument("--update-per-step", type=float, default=0.1) + parser.add_argument("--batch-size", type=int, default=128) + parser.add_argument("--hidden-sizes", type=int, nargs="*", default=[128, 128]) + parser.add_argument("--training-num", type=int, default=10) + parser.add_argument("--test-num", type=int, default=10) + parser.add_argument("--logdir", type=str, default="root_results") + parser.add_argument("--render", type=float, default=0.0) + parser.add_argument("--n-step", type=int, default=4) + parser.add_argument( + "--device", + type=str, + default="cuda" if torch.cuda.is_available() else "cpu", + ) + parser.add_argument("--resume-path", type=str, default=None) + return parser.parse_args() + + +def make_env(): + normalizers = {"fundamental": 5e5, "invt": 1e3, "cash": 1e5} + beta_params = {'a_buy': 0.5, 'b_buy': 0.5, 'a_sell': 0.5, 'b_sell': 0.5} + + env = MMEnv(num_background_agents=25, + sim_time=1200, + lam=75e-3, + lamMM= 5e-3, + mean=1e5, + r=0.05, + shock_var=5e6, + q_max=10, + pv_var=5e6, + shade=[250,500], + n_levels= 101, + total_volume= 100, + xi= 100, # rung size + omega= 64, # spread + normalizers=normalizers, + beta_params=beta_params) + + return env + +def run_MM(args: argparse.Namespace = get_args()) -> None: + env = make_env() + space_info = SpaceInfo.from_env(env) + args.state_shape = space_info.observation_info.obs_shape + args.action_shape = space_info.action_info.action_shape + args.max_action = space_info.action_info.max_action + train_envs = SubprocVectorEnv( + [lambda: make_env() for _ in range(args.training_num)], + ) + # test_envs = gym.make(args.task) + test_envs = SubprocVectorEnv( + [ + lambda: make_env() for _ in range(args.test_num) + ], + ) + + # seed + np.random.seed(args.seed) + torch.manual_seed(args.seed) + train_envs.seed(args.seed) + test_envs.seed(args.seed) + + # model + net_a = Net(state_shape=args.state_shape, hidden_sizes=args.hidden_sizes, device=args.device) + actor = ActorProb( + preprocess_net=net_a, + action_shape=args.action_shape, + device=args.device, + unbounded=True, + ).to(args.device) + actor_optim = torch.optim.Adam(actor.parameters(), lr=args.actor_lr) + + net_c1 = Net( + state_shape=args.state_shape, + action_shape=args.action_shape, + hidden_sizes=args.hidden_sizes, + concat=True, + device=args.device, + ) + critic1 = Critic(net_c1, device=args.device).to(args.device) + critic1_optim = torch.optim.Adam(critic1.parameters(), lr=args.critic_lr) + + net_c2 = Net( + state_shape=args.state_shape, + action_shape=args.action_shape, + hidden_sizes=args.hidden_sizes, + concat=True, + device=args.device, + ) + critic2 = Critic(net_c2, device=args.device).to(args.device) + critic2_optim = torch.optim.Adam(critic2.parameters(), lr=args.critic_lr) + + action_dim = space_info.action_info.action_dim + if args.auto_alpha: + target_entropy = -action_dim + log_alpha = torch.zeros(1, requires_grad=True, device=args.device) + alpha_optim = torch.optim.Adam([log_alpha], lr=args.alpha_lr) + args.alpha = (target_entropy, log_alpha, alpha_optim) + + policy: SACPolicy = SACPolicy( + actor=actor, + actor_optim=actor_optim, + critic=critic1, + critic_optim=critic1_optim, + critic2=critic2, + critic2_optim=critic2_optim, + tau=args.tau, + gamma=args.gamma, + alpha=args.alpha, + estimation_step=args.n_step, + action_space=env.action_space, + ) + + # load a previous policy + if args.resume_path: + policy.load_state_dict(torch.load(args.resume_path)) + print("Loaded agent from: ", args.resume_path) + + # collector + train_collector = Collector( + policy, + train_envs, + VectorReplayBuffer(args.buffer_size, len(train_envs)), + exploration_noise=True, + ) + test_collector = Collector(policy, test_envs) + # train_collector.collect(n_step=args.buffer_size) + + # log + + if not os.path.exists(args.logdir): + os.makedirs(args.logdir) + + checkpoint_dir = "" + checkpoint_dir += args.task + "_" + checkpoint_dir += datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + checkpoint_dir = os.path.join(os.getcwd(), args.logdir, checkpoint_dir) + + if not os.path.exists(checkpoint_dir): + os.makedirs(checkpoint_dir) + + sys.stdout = open(checkpoint_dir + '/stdout.txt', 'w+') + writer = SummaryWriter(checkpoint_dir) + logger = TensorboardLogger(writer) + + def save_best_fn(policy: BasePolicy) -> None: + torch.save(policy.state_dict(), os.path.join(checkpoint_dir, "policy.pth")) + + def stop_fn(mean_rewards: float) -> bool: + if env.spec: + if not env.spec.reward_threshold: + return False + else: + return mean_rewards >= env.spec.reward_threshold + return False + + # trainer + result = OffpolicyTrainer( + policy=policy, + train_collector=train_collector, + test_collector=test_collector, + max_epoch=args.epoch, + step_per_epoch=args.step_per_epoch, + step_per_collect=args.step_per_collect, + episode_per_test=args.test_num, + batch_size=args.batch_size, + update_per_step=args.update_per_step, + test_in_train=False, + stop_fn=stop_fn, + save_best_fn=save_best_fn, + logger=logger, + ).run() + + if __name__ == "__main__": + pprint.pprint(result) + # Let's watch its performance! + policy.eval() + test_envs.seed(args.seed) + test_collector.reset() + collector_stats = test_collector.collect(n_episode=args.test_num, render=args.render) + print(collector_stats) + + +if __name__ == "__main__": + run_MM() diff --git a/marketsim/MM/parameters/__init__.py b/marketsim/MM/parameters/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/marketsim/MM/parameters/generate_json.py b/marketsim/MM/parameters/generate_json.py new file mode 100644 index 00000000..b346cbf0 --- /dev/null +++ b/marketsim/MM/parameters/generate_json.py @@ -0,0 +1,38 @@ +import itertools +import json + +def generate_combinations(parameters): + keys = parameters.keys() + values = parameters.values() + combinations = list(itertools.product(*values)) + result = [{k: v for k, v in zip(keys, combination)} for combination in combinations] + return result + +def save_to_json(data, filename): + with open(filename, 'w') as file: + json.dump(data, file, indent=4) + +# Parameters +parameters = { + "num_background_agents" : [100, 200], + "shock_var": [1e6, 5e6], + "lam": [0.001, 0.005], + "lamMM": [0.005], + "K": [50, 100], # number of rungs + "xi": [100], # two-rung space + "omega": [64, 128, 256, 512, 1024, 2048], #spread + "num_simulations": [1000], + "sim_time": [1000, 2000, 4000, 8000, 12000], + "eta": [1, 0.8, 0.6, 0.4], # surplus required + "buy_alpha": [1,2,5], + "buy_beta": [1,2,5], + "sell_alpha": [1,2,5], + "sell_beta": [1,2,5], + "n_level": [101] +} + +# Generate combinations +combinations = generate_combinations(parameters) + +# Save combinations to JSON file +save_to_json(combinations, './combinations.json') diff --git a/marketsim/MM/simMM.py b/marketsim/MM/simMM.py index e3c5c99b..8b3e1aa3 100644 --- a/marketsim/MM/simMM.py +++ b/marketsim/MM/simMM.py @@ -13,25 +13,30 @@ class SimulatorSampledArrival_MM: def __init__(self, num_background_agents: int, - sim_time: int, + sim_time: int = 12000, num_assets: int = 1, - lam: float = 0.1, - lamMM: float = 0.2, - mean: float = 100, - r: float = .05, - shock_var: float = 10, + lam: float = 1e-3, + lamMM: float = 5, + mean: float = 1e5, + r: float = 0.05, + shock_var: float = 5e6, q_max: int = 10, pv_var: float = 5e6, shade=None, - xi: float = 10, # rung size - omega: float = 10, # spread, - n_levels: int = 5, - total_volume: int = 20, - K:int = 4, # n_level - 1 + xi: float = 100, # rung size + omega: float = 64, # spread, + n_levels: int = 101, + total_volume: int = 100, + K: int = 100, # n_level - 1 beta_params: dict = None, policy=None, beta_MM=False, - random_seed: int = 0 + inv_driven=False, + w0=5, + p=2, + k_min=5, + k_max=20, + max_position=100 ): if random_seed != 0: @@ -58,6 +63,7 @@ def __init__(self, self.arrivals_MM = defaultdict(list) self.arrival_times_MM = sample_arrivals(lamMM, self.arrivals_sampled) self.arrival_index_MM = 0 + self.warm_up_time = 0.01 * self.sim_time self.markets = [] @@ -93,10 +99,14 @@ def __init__(self, omega=omega, beta_params=beta_params, policy=policy, - random_seed=random.randint(1,4096) + inv_driven=inv_driven, + w0=w0, + p=p, + k_min=k_min, + k_max=k_max, + max_position=max_position ) else: - self.MM = MMAgent( agent_id=self.num_agents, market=self.markets[0], @@ -118,6 +128,8 @@ def step(self): agent = self.agents[agent_id] market.withdraw_all(agent_id) if agent_id == self.num_agents: # MM + if self.time < self.warm_up_time: # Warm up the simulator + continue orders = agent.take_action() market.add_orders(orders) if self.arrival_index_MM == self.arrivals_sampled: @@ -136,8 +148,10 @@ def step(self): self.arrival_index = 0 self.arrivals[self.arrival_times[self.arrival_index].item() + 1 + self.time].append(agent_id) self.arrival_index += 1 + print("time:", self.time, "orders:", orders) new_orders = market.step() + print("time:", self.time, "orders:", new_orders) for matched_order in new_orders: agent_id = matched_order.order.agent_id quantity = matched_order.order.order_type*matched_order.order.quantity @@ -160,11 +174,15 @@ def end_sim(self): def run(self): counter = 0 + print("Arrival Time:", self.arrivals) + print("Arrival Time MM:", self.arrivals_MM) for t in range(self.sim_time): if self.arrivals[t]: try: - # print(f'It is time {t}') + print(f'------------It is time {t}-------------') self.step() + print("MM position:", self.MM.position) + print("MM cash:", self.MM.cash) # print(self.markets[0].order_book.observe()) print("----Best ask:", self.markets[0].order_book.get_best_ask()) print("----Best bid:", self.markets[0].order_book.get_best_bid()) @@ -181,3 +199,4 @@ def run(self): def sample_arrivals(p, num_samples): geometric_dist = dist.Geometric(torch.tensor([p])) return geometric_dist.sample((num_samples,)).squeeze() # Returns a tensor of 1000 sampled time steps + diff --git a/marketsim/MM/simMM_example.py b/marketsim/MM/simMM_example.py index 0768bc21..b65714e9 100644 --- a/marketsim/MM/simMM_example.py +++ b/marketsim/MM/simMM_example.py @@ -1,35 +1,48 @@ from marketsim.MM.simMM import SimulatorSampledArrival_MM +import numpy as np -surpluses = [] - -for _ in range(10): - sim = SimulatorSampledArrival_MM(num_background_agents=25, - sim_time=1200, - lam=0.1, - lamMM=0.2, - mean=1e5, - r=0.05, - shock_var=5e6, - q_max=10, - pv_var=5e6, - shade=[250,500], - xi= 10, # rung size - omega= 10, # spread, - K = 4 # n_level - 1 - ) - - sim.run() - fundamental_val = sim.markets[0].get_final_fundamental() - values = [] - for agent_id in sim.agents: - agent = sim.agents[agent_id] - if agent_id == len(sim.agents): - value = agent.position * fundamental_val + agent.cash - else: - value = agent.get_pos_value() + agent.position * fundamental_val + agent.cash - # print(agent.cash, agent.position, agent.get_pos_value(), value) - values.append(value) - print(f'At the end of the simulation we get {values}') - surpluses.append(sum(values)/len(values)) - -print(sum(surpluses)/len(surpluses)*25) \ No newline at end of file + +def run(): + values_over_sim = [] + + for _ in range(10): + sim = SimulatorSampledArrival_MM(num_background_agents=25, + sim_time=1200, + lam=1e-3, + lamMM=5e-3, + mean=1e5, + r=0.05, + shock_var=5e6, + q_max=10, + pv_var=5e6, + shade=[250, 500], + xi= 100, # rung size + omega= 64, # spread, + K = 100 # n_level - 1 + ) + + sim.run() + fundamental_val = sim.markets[0].get_final_fundamental() + # print("fundamental:", fundamental_val) + values = [] + for agent_id in sim.agents: + agent = sim.agents[agent_id] + if agent_id == len(sim.agents): + value = agent.position * fundamental_val + agent.cash + else: + value = agent.get_pos_value() + agent.position * fundamental_val + agent.cash + # print(agent.cash, agent.position, agent.get_pos_value(), value) + values.append(value) + values_over_sim.append(values) + + # Simulation Output + + average_values = np.mean(values_over_sim, axis=0) + + print("=============== END of SIM ================") + print("MM Profit:", average_values[-1]) + print("SW:", sum(average_values)) + + +if __name__ == "__main__": + run() \ No newline at end of file diff --git a/marketsim/agent/market_maker_beta.py b/marketsim/agent/market_maker_beta.py index ffc8d304..55151218 100644 --- a/marketsim/agent/market_maker_beta.py +++ b/marketsim/agent/market_maker_beta.py @@ -38,13 +38,13 @@ def __init__(self, xi: float, omega: float, beta_params: dict=None, - policy: Any=None, - random_seed: int = 0): - - if random_seed != 0: - # torch.manual_seed(random_seed) - random.seed(random_seed) - np.random.seed(random_seed) + policy: bool=False, + inv_driven=False, + w0=5, + p=2, + k_min=5, + k_max=20, + max_position=100): self.agent_id = agent_id self.market = market @@ -55,6 +55,7 @@ def __init__(self, self.n_levels = n_levels self.beta_params = beta_params self.policy = policy + self.inv_driven = inv_driven self.total_volume = total_volume self.xi = xi @@ -62,6 +63,13 @@ def __init__(self, self.last_value = 0 + # Inventory-driven policy + self.w0 = w0 + self.p = p + self.k_max = k_max + self.k_min = k_min + self.max_position = max_position + def get_id(self) -> int: return self.agent_id @@ -80,9 +88,11 @@ def take_action(self, action=None): t = self.market.get_time() orders = [] - if self.policy is not None: + if self.policy: # Get MM obs and apply the policy. a_buy, b_buy, a_sell, b_sell = action + elif self.inv_driven: + a_buy, b_buy, a_sell, b_sell = self.inv_driven_policy() else: a_buy = self.beta_params['a_buy'] b_buy = self.beta_params['b_buy'] @@ -133,16 +143,34 @@ def take_action(self, action=None): ) ) - print("orders:", orders) + # print("orders:", orders) return orders + def inv_driven_policy(self): + clamp = min(-1, abs(self.position / self.max_position)) ** self.p + f1 = 1 / self.w0 * (1 + (1 / self.w0 - 1) * clamp) + f2 = 1 / self.w0 * (1 - clamp) + if self.position >= 0: + w_bid = f1 + w_ask = f2 + else: + w_bid = f2 + w_ask = f1 + + k = (self.k_max - self.k_min) * clamp + self.k_min + + a_buy = w_bid * (k - 2) + 1 + b_buy = (1 - w_bid) * (k - 2) + 1 + a_sell = w_ask * (k - 2) + 1 + b_sell =(1 - w_ask) * (k - 2) + 1 + + return a_buy, b_buy, a_sell, b_sell + + def update_position(self, q, p): self.position += q self.cash += p - def update_policy(self, new_policy): - self.policy = new_policy - def update_beta_params(self, new_beta_params): self.beta_params = new_beta_params diff --git a/marketsim/fourheap/fourheap.py b/marketsim/fourheap/fourheap.py index c2cc9310..81b0b40e 100644 --- a/marketsim/fourheap/fourheap.py +++ b/marketsim/fourheap/fourheap.py @@ -3,6 +3,9 @@ from marketsim.fourheap.order import Order from marketsim.fourheap.order_queue import OrderQueue +import math +import numpy as np + class FourHeap: """ @@ -20,6 +23,8 @@ def __init__(self, plus_one=False): self.heaps = [self.buy_matched, self.buy_unmatched, self.sell_matched, self.sell_unmatched] self.agent_id_map = defaultdict(list) + self.midprices = [] + def handle_new_order(self, order): q_order = order.quantity order_matched = self.sell_matched if order.order_type == constants.SELL else self.buy_matched @@ -150,6 +155,20 @@ def get_best_bid(self) -> float: def get_best_ask(self) -> float: return self.sell_unmatched.peek() + def update_midprice(self, lookback=14): + best_ask = self.get_best_ask() + best_bid = self.get_best_bid() + + if math.isinf(best_ask) or math.isinf(best_bid): + if len(self.midprices) < lookback and len(self.midprices) > 0: + self.midprices.append(np.mean(self.midprices)) + elif len(self.midprices) >= lookback: + self.midprices.append(np.mean(self.midprices[-lookback:])) + else: + self.midprices.append((best_ask - best_bid) / 2) + + + def observe(self) -> str: s = '--------------\n' names = ['buy_matched', 'buy_unmatched', 'sell_matched', 'sell_unmatched'] diff --git a/marketsim/market/market.py b/marketsim/market/market.py index 7df1dfb1..61743143 100644 --- a/marketsim/market/market.py +++ b/marketsim/market/market.py @@ -2,6 +2,7 @@ from marketsim.event.event_queue import EventQueue from marketsim.fourheap.fourheap import FourHeap from marketsim.fundamental.fundamental_abc import Fundamental +from marketsim.fourheap import constants class Market: @@ -18,6 +19,7 @@ def __init__(self, fundamental: Fundamental, time_steps, random_seed: int = 0): self.event_queue = EventQueue(random_seed=random.randint(1,4096)) self.end_time = time_steps + def get_fundamental_value(self): t = self.get_time() return self.fundamental.get_value_at(t) @@ -46,12 +48,18 @@ def get_info(self): def step(self): # TODO Need to figure out how to handle ties for price and time orders = self.event_queue.step() + self.buy_init_volume, self.sell_init_volumn = 0, 0 for order in orders: self.order_book.insert(order) new_orders = self.clear_market() + # Compute midprices. + self.order_book.update_midprice() return new_orders + def get_midprices(self): + return self.order_book.midprices + def reset(self): self.order_book = FourHeap() self.matched_orders = [] diff --git a/marketsim/wrappers/MM_wrapper.py b/marketsim/wrappers/MM_wrapper.py index 7a8aa579..6a332016 100644 --- a/marketsim/wrappers/MM_wrapper.py +++ b/marketsim/wrappers/MM_wrapper.py @@ -9,6 +9,7 @@ from marketsim.fundamental.mean_reverting import GaussianMeanReverting from marketsim.agent.zero_intelligence_agent import ZIAgent from marketsim.agent.market_maker_beta import MMAgent +from marketsim.wrappers.metrics import volume_imbalance, queue_imbalance, realized_volatility, relative_strength_index, midprice_move import torch.distributions as dist import torch from collections import defaultdict @@ -22,18 +23,18 @@ def __init__(self, num_background_agents: int, sim_time: int, num_assets: int = 1, - lam: float = 0.1, - lamMM: float = 0.3, + lam: float = 75e-3, + lamMM: float = 5e-3, mean: float = 1e5, r: float = 0.05, shock_var: float = 5e6, q_max: int = 10, pv_var: float = 5e6, shade=None, - n_levels: int=5, - total_volume: int=20, - xi: float = 10, # rung size - omega: float = 10, #spread + n_levels: int=101, + total_volume: int=100, + xi: float = 100, # rung size + omega: float = 64, #spread beta_params: dict = None, policy=None, normalizers=None @@ -103,33 +104,55 @@ def __init__(self, # Gym Setup """ Given a market state s when the self agent arrives at time t, - the agent receives an observation O(s) that includes the number of time steps left T − t, - the current fundamental value rt, - the current best BID and ASK price in the limit order book (if any), - the self agent’s inventory I, - the self agent’s cash, + 1.the agent receives an observation O(s) that includes the number of time steps left T − t, + 2.the current fundamental value rt, + 3.the current best BID price in the limit order book (if any), + 4.the current best ASK price in the limit order book (if any), + 5.the self agent’s inventory I, + 6.the self agent’s cash, + ------ + Extra from Rahul's paper: + 7.Mid-price move, + 8.Volume imbalance + 9.Queue imbalance, + 10.Volatility, + 11.Relative strength index, """ - self.observation_space = spaces.Box(low=np.array([0.0, 0.0, 0.0, 0.0, -1.0, 0.0]), high=np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0]), shape=(6,), dtype=np.float64) # Need rescale the obs. + self.observation_space = spaces.Box(low=np.array([0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0]), + high=np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]), + shape=(11,), + dtype=np.float64) # Need rescale the obs. + self.action_space = spaces.Box(low=0.0, high=1.0, shape=(4,), dtype=np.float64) # a_buy, b_buy, a_sell, b_sell def get_obs(self): return self.observation def update_obs(self): - self.time_left = self.sim_time - self.time - self.fundamental_value = self.markets[0].fundamental.get_value_at(self.time) - self.best_ask = self.markets[0].order_book.get_best_ask() - self.best_bid = self.markets[0].order_book.get_best_bid() - self.MMinvt = self.MM.position - self.MMcash = self.MM.cash + time_left = self.sim_time - self.time + fundamental_value = self.markets[0].fundamental.get_value_at(self.time) + best_ask = self.markets[0].order_book.get_best_ask() + best_bid = self.markets[0].order_book.get_best_bid() + MMinvt = self.MM.position + + midprice_delta = midprice_move(self.MM.market) + vol_imbalance = volume_imbalance(self.MM.market) + que_imbalance = queue_imbalance(self.MM.market) + vr = realized_volatility(self.MM.market) + rsi = relative_strength_index(self.MM.market) self.observation = self.normalization( - time_left=self.time_left, - fundamental_value=self.fundamental_value, - best_ask=self.best_ask, - best_bid=self.best_bid, - MMinvt=self.MMinvt, - MMcash=self.MMcash) + time_left=time_left, + fundamental_value=fundamental_value, + best_ask=best_ask, + best_bid=best_bid, + MMinvt=MMinvt, + MMcash=self.MM.cash, + midprice_delta=midprice_delta, + vol_imbalance=vol_imbalance, + que_imbalance=que_imbalance, + vr=vr, + rsi=rsi) def normalization(self, time_left: int, @@ -137,7 +160,12 @@ def normalization(self, best_ask: float, best_bid: float, MMinvt: float, - MMcash: float): + MMcash: float, + midprice_delta: float, + vol_imbalance: float, + que_imbalance: float, + vr: float, + rsi: float): if self.normalizers is None: print("No normalizer warning!") @@ -158,7 +186,21 @@ def normalization(self, MMinvt /= self.normalizers["invt"] MMcash /= self.normalizers["cash"] - return np.array([time_left, fundamental_value, best_ask, best_bid, MMinvt, MMcash]) + #------- + midprice_delta /= 1e2 # TODO: need to tune + rsi /= 100 + + return np.array([time_left, + fundamental_value, + best_ask, + best_bid, + MMinvt, + MMcash, + midprice_delta, + vol_imbalance * 10, + que_imbalance * 10, + vr, + rsi]) def reset(self, seed=None, options=None): @@ -176,14 +218,16 @@ def reset(self, seed=None, options=None): # Reset MM self.MM.reset() - self.update_obs() # Reset Arrivals self.reset_arrivals() # Run until the MM enters. - _ = self.run_until_next_MM_arrival() self.run_agents_only() + end = self.run_until_next_MM_arrival() + + if end: + raise ValueError("An episode without MM. Length of an episode should be set large.") return self.get_obs(), {} @@ -209,9 +253,13 @@ def reset_arrivals(self): def step(self, action): + print("----midprices:", self.MM.market.get_midprices()) + print("----Best ask:", self.MM.market.order_book.get_best_ask()) + print("----Best bid:", self.MM.market.order_book.get_best_bid()) if self.time < self.sim_time: - reward = self.MM_step(action) + self.MM_step(action) self.agents_step() + reward = self.market_step(agent_only=False) self.time += 1 end = self.run_until_next_MM_arrival() if end: @@ -239,21 +287,7 @@ def agents_step(self): self.arrivals[self.arrival_times[self.arrival_index].item() + 1 + self.time].append(agent_id) self.arrival_index += 1 - new_orders = market.step() - # print("new_orders:", new_orders) - for matched_order in new_orders: - agent_id = matched_order.order.agent_id - quantity = matched_order.order.order_type * matched_order.order.quantity - cash = -matched_order.price * matched_order.order.quantity * matched_order.order.order_type - if agent_id == self.num_agents: - # raise NotImplemented("dfdf") - self.MM.update_position(quantity, cash) - else: - self.agents[agent_id].update_position(quantity, cash) - def MM_step(self, action): - print("----Last Best ask:", self.MM.market.order_book.get_best_ask()) - print("----Last Best bid:", self.MM.market.order_book.get_best_bid()) for market in self.markets: market.event_queue.set_time(self.time) market.withdraw_all(self.num_agents) @@ -266,33 +300,38 @@ def MM_step(self, action): self.arrivals_MM[self.arrival_times_MM[self.arrival_index_MM].item() + 1 + self.time].append(self.num_agents) self.arrival_index_MM += 1 + def market_step(self, agent_only=True, verbose=False): + if verbose: + print("----Last Best ask:", self.MM.market.order_book.get_best_ask()) + print("----Last Best bid:", self.MM.market.order_book.get_best_bid()) + for market in self.markets: new_orders = market.step() for matched_order in new_orders: agent_id = matched_order.order.agent_id quantity = matched_order.order.order_type * matched_order.order.quantity cash = -matched_order.price * matched_order.order.quantity * matched_order.order.order_type if agent_id == self.num_agents: - raise NotImplemented("dfdf") self.MM.update_position(quantity, cash) else: self.agents[agent_id].update_position(quantity, cash) - estimated_fundamental = self.MM.estimate_fundamental() - current_value = self.MM.position * estimated_fundamental + self.MM.cash - reward = current_value - self.MM.last_value - print("----matched orders:", new_orders) - print("----estimated_fundamental:", estimated_fundamental) - print("----current_value:", current_value) - print("----self.MM.last_value:", self.MM.last_value) - print("----Best ask:", self.MM.market.order_book.get_best_ask()) - print("----Best bid:", self.MM.market.order_book.get_best_bid()) - print("----Bids:", self.MM.market.order_book.buy_unmatched) - print("----Asks:", self.MM.market.order_book.sell_unmatched) - self.MM.last_value = reward - - return reward / self.normalizers["fundamental"] #TODO: Check if this normalizer works. - - + if not agent_only: + estimated_fundamental = self.MM.estimate_fundamental() + current_value = self.MM.position * estimated_fundamental + self.MM.cash + reward = current_value - self.MM.last_value + if verbose: + print("----matched orders:", new_orders) + print("----estimated_fundamental:", estimated_fundamental) + print("----current_value:", current_value) + print("----self.MM.last_value:", self.MM.last_value) + print("----Best ask:", self.MM.market.order_book.get_best_ask()) + print("----Best bid:", self.MM.market.order_book.get_best_bid()) + print("----Bids:", self.MM.market.order_book.buy_unmatched) + print("----Asks:", self.MM.market.order_book.sell_unmatched) + self.MM.last_value = reward + + # Assume single market, so reward is a scalar. + return reward / self.normalizers["fundamental"] # TODO: Check if this normalizer works. def end_sim_summarize(self): fundamental_val = self.markets[0].get_final_fundamental() @@ -302,7 +341,7 @@ def end_sim_summarize(self): values[agent_id] = agent.get_pos_value() + agent.position * fundamental_val + agent.cash values[self.num_agents] = self.MM.position * fundamental_val + self.MM.cash - print(f'At the end of the simulation we get {values}') + # print(f'At the end of the simulation we get {values}') def end_sim(self): estimated_fundamental = self.MM.estimate_fundamental() @@ -314,6 +353,7 @@ def end_sim(self): def run_until_next_MM_arrival(self): while len(self.arrivals_MM[self.time]) == 0 and self.time < self.sim_time: self.agents_step() + self.market_step(agent_only=True) # print(self.markets[0].order_book.observe()) self.time += 1 @@ -324,9 +364,10 @@ def run_until_next_MM_arrival(self): return False def run_agents_only(self): - for t in range(int(0.1 * self.sim_time)): + for t in range(int(0.01 * self.sim_time)): if self.arrivals[t]: self.agents_step() + self.market_step(agent_only=True) self.time += 1 diff --git a/marketsim/wrappers/SP_wrapper.py b/marketsim/wrappers/SP_wrapper.py index 885567aa..510de31f 100644 --- a/marketsim/wrappers/SP_wrapper.py +++ b/marketsim/wrappers/SP_wrapper.py @@ -9,6 +9,7 @@ from marketsim.fundamental.mean_reverting import GaussianMeanReverting from marketsim.agent.zero_intelligence_agent import ZIAgent from marketsim.agent.spoofer import SpoofingAgent +from marketsim.wrappers.metrics import volume_imbalance, queue_imbalance, signed_volume, realized_volatility, relative_strength_index, midprice_move import torch.distributions as dist import torch from collections import defaultdict @@ -94,33 +95,54 @@ def __init__(self, # Gym Setup """ Given a market state s when the self agent arrives at time t, - the agent receives an observation O(s) that includes the number of time steps left T − t, - the current fundamental value rt, - the current best BID and ASK price in the limit order book (if any), - the self agent’s inventory I, - the self agent’s cash, + 1.the agent receives an observation O(s) that includes the number of time steps left T − t, + 2.the current fundamental value rt, + 3.the current best BID price in the limit order book (if any), + 4.the current best ASK price in the limit order book (if any), + 5.the self agent’s inventory I, + 6.the self agent’s cash, + ------ + Extra from Rahul's paper: + 7.Mid-price move, + 8.Volume imbalance + 9.Queue imbalance, + 10.Volatility, + 11.Relative strength index, """ - self.observation_space = spaces.Box(low=np.array([0.0, 0.0, 0.0, 0.0, -1.0, 0.0]), high=np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0]), shape=(6,), dtype=np.float32) + self.observation_space = spaces.Box(low=np.array([0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0]), + high=np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]), + shape=(11,), + dtype=np.float64) # Need rescale the obs. self.action_space = spaces.Box(low=0.0, high=1.0, shape=(2,), dtype=np.float32) # price for regular order and price for spoofing def get_obs(self): return self.observation - def update_obs(self): # TODO: Check if this observation works. - self.time_left = self.sim_time - self.time - self.fundamental_value = self.markets[0].fundamental.get_value_at(self.time) - self.best_ask = self.markets[0].order_book.get_best_ask() - self.best_bid = self.markets[0].order_book.get_best_bid() - self.SPinvt = self.spoofer.position - self.SPcash = self.spoofer.cash + def update_obs(self): + time_left = self.sim_time - self.time + fundamental_value = self.markets[0].fundamental.get_value_at(self.time) + best_ask = self.markets[0].order_book.get_best_ask() + best_bid = self.markets[0].order_book.get_best_bid() + SPinvt = self.spoofer.position + + midprice_delta = midprice_move(self.markets[0]) + vol_imbalance = volume_imbalance(self.markets[0]) + que_imbalance = queue_imbalance(self.markets[0]) + vr = realized_volatility(self.markets[0]) + rsi = relative_strength_index(self.markets[0]) self.observation = self.normalization( - time_left=self.time_left, - fundamental_value=self.fundamental_value, - best_ask=self.best_ask, - best_bid=self.best_bid, - SPinvt=self.SPinvt, - SPcash=self.SPcash) + time_left=time_left, + fundamental_value=fundamental_value, + best_ask=best_ask, + best_bid=best_bid, + SPinvt=SPinvt, + SPcash=self.spoofer.cash, + midprice_delta=midprice_delta, + vol_imbalance=vol_imbalance, + que_imbalance=que_imbalance, + vr=vr, + rsi=rsi) def normalization(self, time_left: int, @@ -128,7 +150,12 @@ def normalization(self, best_ask: float, best_bid: float, SPinvt: float, - SPcash: float): + SPcash: float, + midprice_delta: float, + vol_imbalance: float, + que_imbalance: float, + vr: float, + rsi: float): if self.normalizers is None: print("No normalizer warning!") @@ -149,7 +176,21 @@ def normalization(self, SPinvt /= self.normalizers["invt"] SPcash /= self.normalizers["cash"] - return np.array([time_left, fundamental_value, best_ask, best_bid, SPinvt, SPcash]) + # ------- + midprice_delta /= 1e2 # TODO: need to tune + rsi /= 100 + + return np.array([time_left, + fundamental_value, + best_ask, + best_bid, + SPinvt, + SPcash, + midprice_delta, + vol_imbalance * 10, + que_imbalance * 10, + vr, + rsi]) def reset(self, seed=None, options=None): self.time = 0 @@ -166,14 +207,17 @@ def reset(self, seed=None, options=None): # Reset spoofer self.spoofer.reset() - self.update_obs() # Reset Arrivals self.reset_arrivals() # Run until the spoofer enters. - _ = self.run_until_next_SP_arrival() self.run_agents_only() + end = self.run_until_next_SP_arrival() + + if end: + raise ValueError("An episode without spoofer. Length of an episode should be set large.") + return self.get_obs(), {} @@ -198,8 +242,9 @@ def reset_arrivals(self): def step(self, action): if self.time < self.sim_time: - reward = self.SP_step(action) + self.SP_step(action) self.agents_step() + reward = self.market_step(agent_only=False) self.time += 1 end = self.run_until_next_SP_arrival() if end: @@ -227,16 +272,6 @@ def agents_step(self): self.arrivals[self.arrival_times[self.arrival_index].item() + 1 + self.time].append(agent_id) self.arrival_index += 1 - new_orders = market.step() - for matched_order in new_orders: - agent_id = matched_order.order.agent_id - quantity = matched_order.order.order_type * matched_order.order.quantity - cash = -matched_order.price * matched_order.order.quantity * matched_order.order.order_type - if agent_id == self.num_agents: - self.spoofer.update_position(quantity, cash) - else: - self.agents[agent_id].update_position(quantity, cash) - def SP_step(self, action): for market in self.markets: market.event_queue.set_time(self.time) @@ -250,6 +285,8 @@ def SP_step(self, action): self.arrivals_SP[self.arrival_times_SP[self.arrival_index_SP].item() + 1 + self.time].append(self.num_agents) self.arrival_index_SP += 1 + def market_step(self, agent_only=True): + for market in self.markets: new_orders = market.step() for matched_order in new_orders: agent_id = matched_order.order.agent_id @@ -260,13 +297,13 @@ def SP_step(self, action): else: self.agents[agent_id].update_position(quantity, cash) - estimated_fundamental = self.spoofer.estimate_fundamental() - current_value = self.spoofer.position * estimated_fundamental + self.spoofer.cash - reward = current_value - self.spoofer.last_value - self.spoofer.last_value = reward #TODO: Check if we need to normalize the reward - - return reward / self.normalizers["fundamental"] #TODO: Check if this normalizer works. + if not agent_only: + estimated_fundamental = self.spoofer.estimate_fundamental() + current_value = self.spoofer.position * estimated_fundamental + self.spoofer.cash + reward = current_value - self.spoofer.last_value + self.spoofer.last_value = reward # TODO: Check if we need to normalize the reward + return reward / self.normalizers["fundamental"] # TODO: Check if this normalizer works. def end_sim_summarize(self): fundamental_val = self.markets[0].get_final_fundamental() @@ -288,6 +325,7 @@ def end_sim(self): def run_until_next_SP_arrival(self): while len(self.arrivals_SP[self.time]) == 0 and self.time < self.sim_time: self.agents_step() + self.market_step(agent_only=True) # print(self.markets[0].order_book.observe()) self.time += 1 @@ -301,6 +339,7 @@ def run_agents_only(self): for t in range(int(0.1 * self.sim_time)): if self.arrivals[t]: self.agents_step() + self.market_step(agent_only=True) self.time += 1 diff --git a/marketsim/wrappers/examples/MMexample.py b/marketsim/wrappers/examples/MMexample.py index f8d08088..b798364a 100644 --- a/marketsim/wrappers/examples/MMexample.py +++ b/marketsim/wrappers/examples/MMexample.py @@ -2,11 +2,11 @@ def run(): - normalizers = {"fundamental": 5e5, "invt": 1e3, "cash": 1e5} + normalizers = {"fundamental": 1.2e5, "invt": 10, "cash": 5e5} beta_params = {'a_buy': 0.5, 'b_buy': 0.5, 'a_sell': 0.5, 'b_sell': 0.5} env = MMEnv(num_background_agents=25, - sim_time=100, + sim_time=1000, lam=0.1, mean=1e5, r=0.05, diff --git a/marketsim/wrappers/metrics.py b/marketsim/wrappers/metrics.py new file mode 100644 index 00000000..29784e96 --- /dev/null +++ b/marketsim/wrappers/metrics.py @@ -0,0 +1,93 @@ +# This file includes metrics that can be used for learning in markets. + +import numpy as np + +def volume_imbalance(market): + # The ratio of the difference between buy and sell volumes to their sum. + order_book = market.order_book + sell_book_size = order_book.sell_unmatched.count() + buy_book_size = order_book.buy_unmatched.count() + if sell_book_size + buy_book_size == 0: + return 0.0 + imbalance = (sell_book_size - buy_book_size) / (sell_book_size + buy_book_size) + return imbalance + + +def queue_imbalance(market): + # The ratio of the difference between the number of buy and sell orders to their sum. + order_book = market.order_book + sell_book_size = len(order_book.sell_unmatched.order_dict) + buy_book_size = len(order_book.buy_unmatched.order_dict) + if sell_book_size + buy_book_size == 0: + return 0.0 + imbalance = (sell_book_size - buy_book_size) / (sell_book_size + buy_book_size) + return imbalance + + +def signed_volume(market): + """ + Traded volume in a limit order book is either buyer or seller initiated; + for example, if a resting ask is matched by an incoming buy (market or limit order) + then the resulting traded volume is buyer initiated. Signed volume just associated a + with buyer-initiated volume + and a - with seller initiated volume. + """ + return market.get_signed_volume() + + +def realized_volatility(market, lookback=20): + """ + (RV) is an assessment of variation for assets by analyzing its historical returns within a defined period, it can be calculated by: + sqrt(\sum_{i=1}^n (log(pt) - log(pt-1))^2) + """ + midprices = market.get_midprices() + if len(midprices) >= lookback: + prices = np.array(midprices)[-lookback:] + elif len(midprices) <= 1: + return 0.0 + else: + prices = np.array(midprices) + + price_ratio = np.log(prices[1:] / prices[:-1]) ** 2 + rv = np.sqrt(np.sum(price_ratio)) + + return rv + + +def relative_strength_index(market, lookback=20): + """ + (RSI) is a technical indicator used in momentum trading that measures + the speed of a security’s recent price changes to evaluate overvalued or undervalued + conditions in the price of that security. (Rescaled by 100) + """ + midprices = market.get_midprices() + if len(midprices) >= lookback: + prices = np.array(midprices)[-lookback:] + deltas = np.diff(prices) + up = deltas[deltas >= 0].sum() / lookback + down = -deltas[deltas < 0].sum() / lookback + else: + prices = np.array(midprices) + deltas = np.diff(prices) + up = deltas[deltas >= 0].sum() / len(midprices) + down = -deltas[deltas < 0].sum() / len(midprices) + + if down == 0: + return 100 + + rs = up / down + rsi = 100. - 100. / (1. + rs) + + return rsi + + +def midprice_move(market, lookback=20): + midprices = market.get_midprices() + if len(midprices) >= lookback: + return midprices[-1] - np.mean(midprices[-lookback:-1]) + elif len(midprices) >= 2: + return midprices[-1] - np.mean(midprices[:-1]) + else: + return 0.0 + + + From b1bef55c4fbd9deddb84a8a3d9f05040d87148a8 Mon Sep 17 00:00:00 2001 From: wangyzh Date: Fri, 31 May 2024 20:56:46 +0100 Subject: [PATCH 10/34] remove cash, reset PV and fundamental --- marketsim/agent/zero_intelligence_agent.py | 6 +- marketsim/fourheap/fourheap.py | 2 +- marketsim/market/market.py | 5 +- marketsim/private_values/private_values.py | 100 ++++++++++----------- marketsim/wrappers/MM_wrapper.py | 31 +++---- marketsim/wrappers/SP_wrapper.py | 27 +++--- 6 files changed, 86 insertions(+), 85 deletions(-) diff --git a/marketsim/agent/zero_intelligence_agent.py b/marketsim/agent/zero_intelligence_agent.py index e6ba21e8..d8308d0a 100644 --- a/marketsim/agent/zero_intelligence_agent.py +++ b/marketsim/agent/zero_intelligence_agent.py @@ -18,7 +18,9 @@ def __init__(self, agent_id: int, market: Market, q_max: int, shade: List, pv_va self.agent_id = agent_id self.market = market - self.pv = PrivateValues(q_max, pv_var, random_seed=random.randint(1,4096)) + self.q_max = q_max + self.pv_var = pv_var + self.pv = PrivateValues(q_max, pv_var) self.position = 0 self.shade = shade self.cash = 0 @@ -90,3 +92,5 @@ def get_pos_value(self) -> float: def reset(self): self.position = 0 self.cash = 0 + self.pv = PrivateValues(self.q_max, self.pv_var) + diff --git a/marketsim/fourheap/fourheap.py b/marketsim/fourheap/fourheap.py index 81b0b40e..3f849e4d 100644 --- a/marketsim/fourheap/fourheap.py +++ b/marketsim/fourheap/fourheap.py @@ -165,7 +165,7 @@ def update_midprice(self, lookback=14): elif len(self.midprices) >= lookback: self.midprices.append(np.mean(self.midprices[-lookback:])) else: - self.midprices.append((best_ask - best_bid) / 2) + self.midprices.append((best_ask + best_bid) / 2) diff --git a/marketsim/market/market.py b/marketsim/market/market.py index 61743143..dcef788a 100644 --- a/marketsim/market/market.py +++ b/marketsim/market/market.py @@ -60,7 +60,8 @@ def step(self): def get_midprices(self): return self.order_book.midprices - def reset(self): + def reset(self, fundamental): self.order_book = FourHeap() self.matched_orders = [] - self.event_queue = EventQueue(random_seed=random.randint(1,4096)) + self.event_queue = EventQueue() + self.fundamental = fundamental diff --git a/marketsim/private_values/private_values.py b/marketsim/private_values/private_values.py index f02f347b..81b7cea5 100644 --- a/marketsim/private_values/private_values.py +++ b/marketsim/private_values/private_values.py @@ -5,6 +5,8 @@ class PrivateValues: """ A class representing private values for a trading scenario. + """ + A class representing private values for a trading scenario. The PrivateValues class generates and manages a set of private values for buy and sell orders. The private values are generated from a normal distribution with a specified variance. @@ -12,64 +14,58 @@ class PrivateValues: as well as calculate the cumulative value up to a given position. """ - def __init__(self, q_max: int, val_var=5e6, random_seed: int = 0): - """ - Initialize the PrivateValues object. - - :param q_max: The maximum quantity. - :param val_var: The variance of the values (default: 1). - """ - if random_seed != 0: - torch.manual_seed(random_seed) - # random.seed(random_seed) - # np.random.seed(random_seed) - - self.values = torch.randn(2 * q_max) * torch.sqrt(torch.tensor(val_var)) - self.values, _ = self.values.sort(descending=True) +def __init__(self, q_max: int, val_var=5e6): + """ + Initialize the PrivateValues object. - self.offset = q_max + :param q_max: The maximum quantity. + :param val_var: The variance of the values (default: 1). + """ + self.values = torch.randn(2 * q_max) * torch.sqrt(torch.tensor(val_var)) + self.values, _ = self.values.sort(descending=True) - self.extra_buy = min(self.values[-1].item(), 0) - self.extra_sell = max(self.values[0].item(), 0) + self.offset = q_max + self.extra_buy = min(self.values[-1].item(), 0) + self.extra_sell = max(self.values[0].item(), 0) - def value_for_exchange(self, position: int, order_type: int) -> float: - """ - Calculates the value associated with a given trade and order type. +def value_for_exchange(self, position: int, order_type: int) -> float: + """ + Calculates the value associated with a given trade and order type. - Args: - position (int): The position for which to calculate the value. - order_type (int): The type of order (BUY or SELL). + Args: + position (int): The position for which to calculate the value. + order_type (int): The type of order (BUY or SELL). - Returns: - float: The value associated with the position and order type. - """ - index = position + self.offset - (1 if order_type == SELL else 0) - if index >= len(self.values): - return self.extra_buy - elif index < 0: - return self.extra_sell - else: - return self.values[index].item() + Returns: + float: The value associated with the position and order type. + """ + index = position + self.offset - (1 if order_type == SELL else 0) + if index >= len(self.values): + return self.extra_buy + elif index < 0: + return self.extra_sell + else: + return self.values[index].item() - def value_at_position(self, position: int) -> float: - """ - Calculates the total value at a given position. +def value_at_position(self, position: int) -> float: + """ + Calculates the total value at a given position. - Args: - position (int): The position for which to calculate the total value. + Args: + position (int): The position for which to calculate the total value. - Returns: - float: The total value at the given position. - """ - value = 0 - position += self.offset - if position > self.offset: - index = min(position, len(self.values)) - value += torch.sum(self.values[self.offset:index]) - value += max(0, position - 2*self.offset)*self.extra_buy - else: - index = max(0, position) - value -= torch.sum(self.values[index:self.offset]) - value -= -1*min(0, position)*self.extra_sell - return value + Returns: + float: The total value at the given position. + """ + value = 0 + position += self.offset + if position > self.offset: + index = min(position, len(self.values)) + value += torch.sum(self.values[self.offset:index]) + value += max(0, position - 2*self.offset)*self.extra_buy + else: + index = max(0, position) + value -= torch.sum(self.values[index:self.offset]) + value -= -1*min(0, position)*self.extra_sell + return value diff --git a/marketsim/wrappers/MM_wrapper.py b/marketsim/wrappers/MM_wrapper.py index 6a332016..cc2976a5 100644 --- a/marketsim/wrappers/MM_wrapper.py +++ b/marketsim/wrappers/MM_wrapper.py @@ -63,7 +63,9 @@ def __init__(self, self.arrival_index_MM = 0 self.normalizers = normalizers - + self.mean = mean + self.shock_var = shock_var + self.r = r self.markets = [] if num_assets > 1: raise NotImplemented("Only support single market currently") @@ -109,18 +111,17 @@ def __init__(self, 3.the current best BID price in the limit order book (if any), 4.the current best ASK price in the limit order book (if any), 5.the self agent’s inventory I, - 6.the self agent’s cash, ------ Extra from Rahul's paper: - 7.Mid-price move, - 8.Volume imbalance - 9.Queue imbalance, - 10.Volatility, - 11.Relative strength index, + 6.Mid-price move, + 7.Volume imbalance + 8.Queue imbalance, + 9.Volatility, + 10.Relative strength index, """ - self.observation_space = spaces.Box(low=np.array([0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0]), - high=np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]), - shape=(11,), + self.observation_space = spaces.Box(low=np.array([0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0]), + high=np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]), + shape=(10,), dtype=np.float64) # Need rescale the obs. self.action_space = spaces.Box(low=0.0, high=1.0, shape=(4,), dtype=np.float64) # a_buy, b_buy, a_sell, b_sell @@ -147,7 +148,6 @@ def update_obs(self): best_ask=best_ask, best_bid=best_bid, MMinvt=MMinvt, - MMcash=self.MM.cash, midprice_delta=midprice_delta, vol_imbalance=vol_imbalance, que_imbalance=que_imbalance, @@ -160,7 +160,6 @@ def normalization(self, best_ask: float, best_bid: float, MMinvt: float, - MMcash: float, midprice_delta: float, vol_imbalance: float, que_imbalance: float, @@ -184,7 +183,6 @@ def normalization(self, best_bid /= self.normalizers["fundamental"] MMinvt /= self.normalizers["invt"] - MMcash /= self.normalizers["cash"] #------- midprice_delta /= 1e2 # TODO: need to tune @@ -195,7 +193,6 @@ def normalization(self, best_ask, best_bid, MMinvt, - MMcash, midprice_delta, vol_imbalance * 10, que_imbalance * 10, @@ -209,7 +206,11 @@ def reset(self, seed=None, options=None): # Reset the markets for market in self.markets: - market.reset() + fundamental = GaussianMeanReverting(mean=self.mean, + final_time=self.sim_time + 1, + r=self.r, + shock_var=self.shock_var) + market.reset(fundamental=fundamental) # Reset the agents for agent_id in self.agents: diff --git a/marketsim/wrappers/SP_wrapper.py b/marketsim/wrappers/SP_wrapper.py index 510de31f..7a0df9e4 100644 --- a/marketsim/wrappers/SP_wrapper.py +++ b/marketsim/wrappers/SP_wrapper.py @@ -59,6 +59,9 @@ def __init__(self, self.normalizers = normalizers # Set up markets + self.mean = mean + self.shock_var = shock_var + self.r = r self.markets = [] for _ in range(num_assets): fundamental = GaussianMeanReverting(mean=mean, final_time=sim_time+1, r=r, shock_var=shock_var) @@ -100,18 +103,17 @@ def __init__(self, 3.the current best BID price in the limit order book (if any), 4.the current best ASK price in the limit order book (if any), 5.the self agent’s inventory I, - 6.the self agent’s cash, ------ Extra from Rahul's paper: - 7.Mid-price move, - 8.Volume imbalance - 9.Queue imbalance, - 10.Volatility, - 11.Relative strength index, + 6.Mid-price move, + 7.Volume imbalance + 8.Queue imbalance, + 9.Volatility, + 10.Relative strength index, """ - self.observation_space = spaces.Box(low=np.array([0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0]), - high=np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]), - shape=(11,), + self.observation_space = spaces.Box(low=np.array([0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0]), + high=np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]), + shape=(10,), dtype=np.float64) # Need rescale the obs. self.action_space = spaces.Box(low=0.0, high=1.0, shape=(2,), dtype=np.float32) # price for regular order and price for spoofing @@ -137,7 +139,6 @@ def update_obs(self): best_ask=best_ask, best_bid=best_bid, SPinvt=SPinvt, - SPcash=self.spoofer.cash, midprice_delta=midprice_delta, vol_imbalance=vol_imbalance, que_imbalance=que_imbalance, @@ -150,7 +151,6 @@ def normalization(self, best_ask: float, best_bid: float, SPinvt: float, - SPcash: float, midprice_delta: float, vol_imbalance: float, que_imbalance: float, @@ -174,7 +174,6 @@ def normalization(self, best_bid /= self.normalizers["fundamental"] SPinvt /= self.normalizers["invt"] - SPcash /= self.normalizers["cash"] # ------- midprice_delta /= 1e2 # TODO: need to tune @@ -185,7 +184,6 @@ def normalization(self, best_ask, best_bid, SPinvt, - SPcash, midprice_delta, vol_imbalance * 10, que_imbalance * 10, @@ -198,7 +196,8 @@ def reset(self, seed=None, options=None): # Reset the markets for market in self.markets: - market.reset() + fundamental = GaussianMeanReverting(mean=self.mean, final_time=self.sim_time + 1, r=self.r, shock_var=self.shock_var) + market.reset(fundamental=fundamental) # Reset the agents for agent_id in self.agents: From 7b0788302ce10bf0cba4af25f425ffc11f892a6b Mon Sep 17 00:00:00 2001 From: wangyzh Date: Thu, 6 Jun 2024 15:51:02 -0400 Subject: [PATCH 11/34] "fix reward function and include PV in obs for spoofer" --- marketsim/agent/spoofer.py | 4 ++++ marketsim/wrappers/MM_wrapper.py | 13 +++++----- marketsim/wrappers/SP_wrapper.py | 41 ++++++++++++++++++++++---------- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/marketsim/agent/spoofer.py b/marketsim/agent/spoofer.py index 5ee68a36..a1cf0950 100644 --- a/marketsim/agent/spoofer.py +++ b/marketsim/agent/spoofer.py @@ -24,6 +24,9 @@ def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: float, ord self.last_value = 0 # value at last time step (liquidate all inventory) self.normalizers = normalizers # A dictionary {"fundamental": float, "invt": float, "cash": float} + self.q_max = q_max + self.pv_var = pv_var + def get_id(self) -> int: return self.agent_id @@ -78,6 +81,7 @@ def get_pos_value(self) -> float: return self.pv.value_at_position(self.position) def reset(self): + self.pv = PrivateValues(self.q_max, self.pv_var) self.position = 0 self.cash = 0 self.last_value = 0 diff --git a/marketsim/wrappers/MM_wrapper.py b/marketsim/wrappers/MM_wrapper.py index cc2976a5..48e32e49 100644 --- a/marketsim/wrappers/MM_wrapper.py +++ b/marketsim/wrappers/MM_wrapper.py @@ -6,7 +6,7 @@ import random from marketsim.fourheap.constants import BUY, SELL from marketsim.market.market import Market -from marketsim.fundamental.mean_reverting import GaussianMeanReverting +from marketsim.fundamental.lazy_mean_reverting import LazyGaussianMeanReverting from marketsim.agent.zero_intelligence_agent import ZIAgent from marketsim.agent.market_maker_beta import MMAgent from marketsim.wrappers.metrics import volume_imbalance, queue_imbalance, realized_volatility, relative_strength_index, midprice_move @@ -71,7 +71,7 @@ def __init__(self, raise NotImplemented("Only support single market currently") for _ in range(num_assets): - fundamental = GaussianMeanReverting(mean=mean, final_time=sim_time+1, r=r, shock_var=shock_var) + fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time+1, r=r, shock_var=shock_var) self.markets.append(Market(fundamental=fundamental, time_steps=sim_time)) # Set up for regular traders. @@ -206,7 +206,7 @@ def reset(self, seed=None, options=None): # Reset the markets for market in self.markets: - fundamental = GaussianMeanReverting(mean=self.mean, + fundamental = LazyGaussianMeanReverting(mean=self.mean, final_time=self.sim_time + 1, r=self.r, shock_var=self.shock_var) @@ -317,19 +317,18 @@ def market_step(self, agent_only=True, verbose=False): self.agents[agent_id].update_position(quantity, cash) if not agent_only: - estimated_fundamental = self.MM.estimate_fundamental() - current_value = self.MM.position * estimated_fundamental + self.MM.cash + fundamental_val = self.markets[0].get_final_fundamental() + current_value = self.MM.position * fundamental_val + self.MM.cash reward = current_value - self.MM.last_value if verbose: print("----matched orders:", new_orders) - print("----estimated_fundamental:", estimated_fundamental) print("----current_value:", current_value) print("----self.MM.last_value:", self.MM.last_value) print("----Best ask:", self.MM.market.order_book.get_best_ask()) print("----Best bid:", self.MM.market.order_book.get_best_bid()) print("----Bids:", self.MM.market.order_book.buy_unmatched) print("----Asks:", self.MM.market.order_book.sell_unmatched) - self.MM.last_value = reward + self.MM.last_value = current_value # Assume single market, so reward is a scalar. return reward / self.normalizers["fundamental"] # TODO: Check if this normalizer works. diff --git a/marketsim/wrappers/SP_wrapper.py b/marketsim/wrappers/SP_wrapper.py index 7a0df9e4..3d0b2b9c 100644 --- a/marketsim/wrappers/SP_wrapper.py +++ b/marketsim/wrappers/SP_wrapper.py @@ -6,7 +6,7 @@ import random from marketsim.fourheap.constants import BUY, SELL from marketsim.market.market import Market -from marketsim.fundamental.mean_reverting import GaussianMeanReverting +from marketsim.fundamental.lazy_mean_reverting import LazyGaussianMeanReverting from marketsim.agent.zero_intelligence_agent import ZIAgent from marketsim.agent.spoofer import SpoofingAgent from marketsim.wrappers.metrics import volume_imbalance, queue_imbalance, signed_volume, realized_volatility, relative_strength_index, midprice_move @@ -64,7 +64,7 @@ def __init__(self, self.r = r self.markets = [] for _ in range(num_assets): - fundamental = GaussianMeanReverting(mean=mean, final_time=sim_time+1, r=r, shock_var=shock_var) + fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time+1, r=r, shock_var=shock_var) self.markets.append(Market(fundamental=fundamental, time_steps=sim_time)) # Set up for regular traders. @@ -110,10 +110,16 @@ def __init__(self, 8.Queue imbalance, 9.Volatility, 10.Relative strength index, + ------ + 11. Private values 2 * q_max """ - self.observation_space = spaces.Box(low=np.array([0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0]), - high=np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]), - shape=(10,), + lower_bound = np.zeros(10 + 2 * q_max) + for i in [4,5,6,7]: + lower_bound[i] = -1 + uppper_bound = np.ones(10 + 2 * q_max) + self.observation_space = spaces.Box(low=lower_bound, + high=uppper_bound, + shape=(10 + 2*q_max,), dtype=np.float64) # Need rescale the obs. self.action_space = spaces.Box(low=0.0, high=1.0, shape=(2,), dtype=np.float32) # price for regular order and price for spoofing @@ -133,6 +139,8 @@ def update_obs(self): vr = realized_volatility(self.markets[0]) rsi = relative_strength_index(self.markets[0]) + pv = self.spoofer.pv.values.numpy() + self.observation = self.normalization( time_left=time_left, fundamental_value=fundamental_value, @@ -143,7 +151,8 @@ def update_obs(self): vol_imbalance=vol_imbalance, que_imbalance=que_imbalance, vr=vr, - rsi=rsi) + rsi=rsi, + pv=pv) def normalization(self, time_left: int, @@ -155,7 +164,8 @@ def normalization(self, vol_imbalance: float, que_imbalance: float, vr: float, - rsi: float): + rsi: float, + pv:np.ndarray): if self.normalizers is None: print("No normalizer warning!") @@ -178,8 +188,9 @@ def normalization(self, # ------- midprice_delta /= 1e2 # TODO: need to tune rsi /= 100 + pv /= 5e5 - return np.array([time_left, + obs1 = np.array([time_left, fundamental_value, best_ask, best_bid, @@ -190,13 +201,17 @@ def normalization(self, vr, rsi]) + obs = np.concatenate((obs1, pv)) + + return obs + def reset(self, seed=None, options=None): self.time = 0 self.observation = None # Reset the markets for market in self.markets: - fundamental = GaussianMeanReverting(mean=self.mean, final_time=self.sim_time + 1, r=self.r, shock_var=self.shock_var) + fundamental = LazyGaussianMeanReverting(mean=self.mean, final_time=self.sim_time + 1, r=self.r, shock_var=self.shock_var) market.reset(fundamental=fundamental) # Reset the agents @@ -297,12 +312,12 @@ def market_step(self, agent_only=True): self.agents[agent_id].update_position(quantity, cash) if not agent_only: - estimated_fundamental = self.spoofer.estimate_fundamental() - current_value = self.spoofer.position * estimated_fundamental + self.spoofer.cash + fundamental_val = self.markets[0].get_final_fundamental() + current_value = self.spoofer.position * fundamental_val + self.spoofer.cash + self.spoofer.get_pos_value() reward = current_value - self.spoofer.last_value - self.spoofer.last_value = reward # TODO: Check if we need to normalize the reward + self.spoofer.last_value = current_value # TODO: Check if we need to normalize the reward - return reward / self.normalizers["fundamental"] # TODO: Check if this normalizer works. + return reward / self.normalizers["fundamental"] # TODO: Check if this normalizer works. Anri: 1e2 def end_sim_summarize(self): fundamental_val = self.markets[0].get_final_fundamental() From aa99468e460baf06f61ec4135f144c61526fc964 Mon Sep 17 00:00:00 2001 From: wangyzh Date: Wed, 19 Jun 2024 22:45:54 -0400 Subject: [PATCH 12/34] "update static MM" --- marketsim/MM/RLMM_example.py | 2 +- marketsim/MM/simMM.py | 204 ++++++++++++++++----- marketsim/MM/simMM_example.py | 196 ++++++++++++++++---- marketsim/MM/utils.py | 10 + marketsim/agent/market_maker.py | 13 +- marketsim/agent/market_maker_beta.py | 6 +- marketsim/private_values/private_values.py | 92 +++++----- 7 files changed, 388 insertions(+), 135 deletions(-) create mode 100644 marketsim/MM/utils.py diff --git a/marketsim/MM/RLMM_example.py b/marketsim/MM/RLMM_example.py index 573053d5..793d58d0 100644 --- a/marketsim/MM/RLMM_example.py +++ b/marketsim/MM/RLMM_example.py @@ -58,7 +58,7 @@ def get_args() -> argparse.Namespace: def make_env(): - normalizers = {"fundamental": 5e5, "invt": 1e3, "cash": 1e5} + normalizers = {"fundamental": 1e5, "reward":1e4, "min_order_val": 1e5, "invt": 10, "cash": 1e7} beta_params = {'a_buy': 0.5, 'b_buy': 0.5, 'a_sell': 0.5, 'b_sell': 0.5} env = MMEnv(num_background_agents=25, diff --git a/marketsim/MM/simMM.py b/marketsim/MM/simMM.py index 8b3e1aa3..eb54df43 100644 --- a/marketsim/MM/simMM.py +++ b/marketsim/MM/simMM.py @@ -31,7 +31,7 @@ def __init__(self, beta_params: dict = None, policy=None, beta_MM=False, - inv_driven=False, + inv_driven=False, # enable inventory driven policy w0=5, p=2, k_min=5, @@ -45,7 +45,8 @@ def __init__(self, # np.random.seed(random_seed) if shade is None: - shade = [10, 30] + shade = [250, 500] + self.num_background_agents = num_background_agents self.num_agents = num_background_agents + 1 self.num_assets = num_assets self.sim_time = sim_time @@ -65,11 +66,18 @@ def __init__(self, self.arrival_index_MM = 0 self.warm_up_time = 0.01 * self.sim_time + self.mean = mean + self.shock_var = shock_var + self.r = r + self.markets = [] + if num_assets > 1: + raise NotImplemented("Only support single market currently") + self.markets = [] for _ in range(num_assets): - fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random.randint(1,4096)) - self.markets.append(Market(fundamental=fundamental, time_steps=sim_time, random_seed=random.randint(1,4096))) + fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time+1, r=r, shock_var=shock_var) + self.markets.append(Market(fundamental=fundamental, time_steps=sim_time)) self.agents = {} for agent_id in range(num_background_agents): @@ -86,12 +94,12 @@ def __init__(self, random_seed=random.randint(1,4096) )) - self.arrivals_MM[self.arrival_times_MM[self.arrival_index_MM].item()].append(self.num_agents) + self.arrivals_MM[self.arrival_times_MM[self.arrival_index_MM].item()].append(self.num_background_agents) self.arrival_index_MM += 1 - if beta_MM: + if beta_MM: # beta policy self.MM = MMbetaAgent( - agent_id=self.num_agents, + agent_id=self.num_background_agents, market=self.markets[0], n_levels=n_levels, total_volume=total_volume, @@ -106,38 +114,46 @@ def __init__(self, k_max=k_max, max_position=max_position ) - else: + else: # ladder policy self.MM = MMAgent( - agent_id=self.num_agents, + agent_id=self.num_background_agents, market=self.markets[0], K=K, xi=xi, omega=omega, random_seed=random.randint(1,4096) ) - - self.agents[self.num_agents] = self.MM + self.agents[self.num_background_agents] = self.MM + # Metrics + self.spreads = [] + self.midprices = [] + self.inventory = [] + self.value_MM = 0 + self.total_quantity = 0 + self.MM_quantity = 0 + + def step(self, agent_only=False): + agents = self.arrivals[self.time] + if not agent_only: + agents += self.arrivals_MM[self.time] - def step(self): - agents = self.arrivals[self.time] + self.arrivals_MM[self.time] if self.time < self.sim_time: for market in self.markets: market.event_queue.set_time(self.time) for agent_id in agents: agent = self.agents[agent_id] market.withdraw_all(agent_id) - if agent_id == self.num_agents: # MM - if self.time < self.warm_up_time: # Warm up the simulator - continue + if agent_id == self.num_background_agents: # MM orders = agent.take_action() + # print("MM Orders:", orders) market.add_orders(orders) if self.arrival_index_MM == self.arrivals_sampled: self.arrival_times_MM = sample_arrivals(self.lamMM, self.arrivals_sampled) self.arrival_index_MM = 0 - self.arrivals_MM[self.arrival_times_MM[self.arrival_index_MM].item() + 1 + self.time].append( - self.num_agents) + self.arrivals_MM[self.arrival_times_MM[self.arrival_index_MM].item() + 1 + self.time].append(agent_id) self.arrival_index_MM += 1 + print(self.arrival_times_MM[self.arrival_index_MM].item() + 1 + self.time) else: # Regular agents. side = random.choice([BUY, SELL]) orders = agent.take_action(side) @@ -148,52 +164,150 @@ def step(self): self.arrival_index = 0 self.arrivals[self.arrival_times[self.arrival_index].item() + 1 + self.time].append(agent_id) self.arrival_index += 1 - print("time:", self.time, "orders:", orders) + # print("time:", self.time, "orders:", orders) new_orders = market.step() - print("time:", self.time, "orders:", new_orders) + # print("time:", self.time, "orders:", new_orders) for matched_order in new_orders: agent_id = matched_order.order.agent_id quantity = matched_order.order.order_type*matched_order.order.quantity cash = -matched_order.price*matched_order.order.quantity*matched_order.order.order_type self.agents[agent_id].update_position(quantity, cash) + # Record + self.total_quantity += abs(quantity) + if agent_id == self.num_background_agents: + self.MM_quantity += abs(quantity) - else: - self.end_sim() + # Record stats + best_ask = market.order_book.get_best_ask() + best_bid = market.order_book.get_best_bid() + self.spreads.append(best_ask - best_bid) + self.midprices.append((best_ask + best_bid)/2) + self.inventory.append(self.MM.position) + + # else: + # self.end_sim() def end_sim(self): fundamental_val = self.markets[0].get_final_fundamental() - values = {} - for agent_id in self.agents: - agent = self.agents[agent_id] - if agent_id == self.num_agents: - values[agent_id] = agent.position * fundamental_val + agent.cash - else: - values[agent_id] = agent.get_pos_value() + agent.position*fundamental_val + agent.cash - # print(f'At the end of the simulation we get {values}') + agent = self.agents[self.num_background_agents] + self.value_MM = agent.position * fundamental_val + agent.cash + # for agent_id in self.agents: + # agent = self.agents[agent_id] + # if agent_id == self.num_background_agents: # MM: does not have private values. + # self.values.append(agent.position * fundamental_val + agent.cash) + # else: + # self.values.append(agent.get_pos_value() + agent.position * fundamental_val + agent.cash) + + def run(self): counter = 0 print("Arrival Time:", self.arrivals) print("Arrival Time MM:", self.arrivals_MM) for t in range(self.sim_time): - if self.arrivals[t]: - try: - print(f'------------It is time {t}-------------') - self.step() - print("MM position:", self.MM.position) - print("MM cash:", self.MM.cash) - # print(self.markets[0].order_book.observe()) - print("----Best ask:", self.markets[0].order_book.get_best_ask()) - print("----Best bid:", self.markets[0].order_book.get_best_bid()) - print("----Bids:", self.markets[0].order_book.buy_unmatched) - print("----Asks:", self.markets[0].order_book.sell_unmatched) - except KeyError: - print(self.arrivals[self.time]) - return self.markets + if self.arrivals[t] + self.arrivals_MM[t]: + print(f'------------It is time {t}-------------') + self.step() + print("MM position:", self.MM.position) + print("MM cash:", self.MM.cash) + # print(self.markets[0].order_book.observe()) + # print("----Best ask:", self.markets[0].order_book.get_best_ask()) + # print("----Best bid:", self.markets[0].order_book.get_best_bid()) + # print("----Bids:", self.markets[0].order_book.buy_unmatched) + # print("----Asks:", self.markets[0].order_book.sell_unmatched) counter += 1 + else: + # Record stats + best_ask = self.markets[0].order_book.get_best_ask() + best_bid = self.markets[0].order_book.get_best_bid() + self.spreads.append(best_ask - best_bid) + self.midprices.append((best_ask + best_bid) / 2) + self.inventory.append(self.MM.position) + self.time += 1 + self.end_sim() + #TODO: We can track the value of MM by using the true fundamental. + stats = self.get_stats() + return stats + + + def reset(self, seed=None, options=None): + self.time = 0 + + # Reset the markets + for market in self.markets: + fundamental = LazyGaussianMeanReverting(mean=self.mean, + final_time=self.sim_time + 1, + r=self.r, + shock_var=self.shock_var) + market.reset(fundamental=fundamental) + + # Reset the agents + for agent_id in self.agents: + agent = self.agents[agent_id] + agent.reset() + + # Reset Metrics + self.spreads = [] + self.midprices = [] + self.inventory = [] + self.value_MM = 0 + self.total_quantity = 0 + self.MM_quantity = 0 + + # Reset Arrivals + self.reset_arrivals() + + # Run until the MM enters. + # self.run_agents_only() + + + + def reset_arrivals(self): + # Regular Trader + self.arrivals = defaultdict(list) + self.arrival_times = sample_arrivals(self.lam, self.arrivals_sampled) + self.arrival_index = 0 + + self.arrivals_MM = defaultdict(list) + self.arrival_times_MM = sample_arrivals(self.lamMM, self.arrivals_sampled) + self.arrival_index_MM = 0 + + for agent_id in range(self.num_background_agents): + self.arrivals[self.arrival_times[self.arrival_index].item()].append(agent_id) + self.arrival_index += 1 + + # self.arrivals_MM[self.arrival_times_MM[self.arrival_index_MM].item()].append(self.num_background_agents) + # self.arrival_index_MM += 1 + self.arrivals_MM[0].append(self.num_background_agents) + + + def run_agents_only(self, all_time_steps=False): + if all_time_steps: + sim_time = self.sim_time + else: + sim_time = self.warm_up_time + for t in range(int(sim_time)): + if self.arrivals[t]: + self.step(agent_only=True) self.time += 1 - self.step() + + if all_time_steps: + return self.get_stats() + + + def get_stats(self): + stats = {} + stats["spreads"] = self.spreads.copy() + stats["midprices"] = self.midprices.copy() + stats["inventory"] = self.inventory.copy() + stats["total_quantity"] = self.total_quantity + stats["MM_quantity"] = self.MM_quantity + stats["MM_value"] = self.value_MM + + return stats + + def sample_arrivals(p, num_samples): diff --git a/marketsim/MM/simMM_example.py b/marketsim/MM/simMM_example.py index b65714e9..6c9d094f 100644 --- a/marketsim/MM/simMM_example.py +++ b/marketsim/MM/simMM_example.py @@ -1,48 +1,172 @@ from marketsim.MM.simMM import SimulatorSampledArrival_MM import numpy as np +from absl import app +from absl import flags +import datetime +from marketsim.MM.utils import write_to_csv +import os +import sys + +FLAGS = flags.FLAGS +flags.DEFINE_string("game_name", "LadderMM", "Game name.") +flags.DEFINE_string("root_result_folder", './root_result_static', "root directory of saved results") +flags.DEFINE_integer("num_iteration", 1, "num_iteration") + +flags.DEFINE_integer("num_background_agents", 100, "Number of background agents.") +flags.DEFINE_integer("sim_time", int(1e4), "Simulation time.") +flags.DEFINE_float("lam", 5e-3, "Lambda.") +flags.DEFINE_float("lamMM", 5e-2, "Lambda MM.") +flags.DEFINE_float("mean", 1e5, "Mean.") +flags.DEFINE_float("r", 0.05, "Interest rate.") +flags.DEFINE_float("shock_var", 5e6, "Shock variance.") +flags.DEFINE_integer("q_max", 10, "Maximum quantity.") +flags.DEFINE_float("pv_var", 5e6, "PV variance.") +flags.DEFINE_list("shade", [250, 500], "Shade.") +flags.DEFINE_integer("xi", 100, "Rung size.") +flags.DEFINE_integer("omega", 10, "Spread.") +flags.DEFINE_integer("K", 10, "Number of levels - 1.") +flags.DEFINE_integer("n_levels", 101, "n_levels.") +flags.DEFINE_integer("total_volume", 100, "total_volume.") +flags.DEFINE_float("a_sell", 0.5, "a_sell.") +flags.DEFINE_float("b_sell", 0.5, "b_sell.") +flags.DEFINE_float("a_buy", 0.5, "a_buy.") +flags.DEFINE_float("b_buy", 0.5, "b_buy.") +flags.DEFINE_string("policy", None, "Policy.") +flags.DEFINE_boolean("beta_MM", False, "Beta MM.") +flags.DEFINE_boolean("inv_driven", False, "Inventory driven.") +flags.DEFINE_integer("w0", 5, "Initial wealth.") +flags.DEFINE_integer("p", 2, "Parameter p.") +flags.DEFINE_integer("k_min", 5, "Minimum k.") +flags.DEFINE_integer("k_max", 20, "Maximum k.") +flags.DEFINE_integer("max_position", 100, "Maximum position.") +flags.DEFINE_boolean("agents_only", False, "agents_only.") + + +def run(argv): + print("========== Parameters ==========") + print(f"game_name: {FLAGS.game_name}") + print(f"root_result_folder: {FLAGS.root_result_folder}") + print(f"num_iteration: {FLAGS.num_iteration}") + print(f"num_background_agents: {FLAGS.num_background_agents}") + print(f"sim_time: {FLAGS.sim_time}") + print(f"lam: {FLAGS.lam}") + print(f"lamMM: {FLAGS.lamMM}") + print(f"mean: {FLAGS.mean}") + print(f"r: {FLAGS.r}") + print(f"shock_var: {FLAGS.shock_var}") + print(f"q_max: {FLAGS.q_max}") + print(f"pv_var: {FLAGS.pv_var}") + print(f"shade: {FLAGS.shade}") + print(f"xi: {FLAGS.xi}") + print(f"omega: {FLAGS.omega}") + print(f"n_levels: {FLAGS.n_levels}") + print(f"K: {FLAGS.K}") + print(f"total_volume: {FLAGS.total_volume}") + print(f"a_sell: {FLAGS.a_sell}") + print(f"b_sell: {FLAGS.b_sell}") + print(f"a_buy: {FLAGS.a_buy}") + print(f"b_buy: {FLAGS.b_buy}") + print(f"policy: {FLAGS.policy}") + print(f"beta_MM: {FLAGS.beta_MM}") + print(f"inv_driven: {FLAGS.inv_driven}") + print(f"w0: {FLAGS.w0}") + print(f"p: {FLAGS.p}") + print(f"k_min: {FLAGS.k_min}") + print(f"k_max: {FLAGS.k_max}") + print(f"max_position: {FLAGS.max_position}") + + all_spreads, all_midprices, all_inventory, all_tq, all_MM_q , MM_values = [], [], [], [], [], [] + beta_params = {} + beta_params["a_sell"] = FLAGS.a_sell + beta_params["b_sell"] = FLAGS.b_sell + beta_params["a_buy"] = FLAGS.a_buy + beta_params["b_buy"] = FLAGS.b_buy + + + sim = SimulatorSampledArrival_MM(num_background_agents = FLAGS.num_background_agents, + sim_time = FLAGS.sim_time, + lam = FLAGS.lam, + lamMM = FLAGS.lamMM, + mean = FLAGS.mean, + r = FLAGS.r, + shock_var = FLAGS.shock_var, + q_max = FLAGS.q_max, + pv_var = FLAGS.pv_var, + shade = FLAGS.shade, + xi = FLAGS.xi, + omega = FLAGS.omega, + K = FLAGS.K, + n_levels=FLAGS.n_levels, + total_volume=FLAGS.total_volume, + beta_params = beta_params, + policy = FLAGS.policy, + beta_MM = FLAGS.beta_MM, + inv_driven = FLAGS.inv_driven, + w0 = FLAGS.w0, + p = FLAGS.p, + k_min = FLAGS.k_min, + k_max = FLAGS.k_max, + max_position = FLAGS.max_position + ) + + sim.reset() + print("=============== START of SIM ================") + for iteration in range(FLAGS.num_iteration): + print("Running Simulation Iteration {}".format(iteration)) + if FLAGS.agents_only: + stats = sim.run_agents_only(all_time_steps=True) + else: + stats = sim.run() + sim.reset() + all_spreads.append(stats["spreads"]) + all_midprices.append(stats["midprices"]) + all_inventory.append(stats["inventory"]) + all_tq.append(stats["total_quantity"]) + all_MM_q.append(stats["MM_quantity"]) + MM_values.append(stats["MM_value"]) -def run(): - values_over_sim = [] - - for _ in range(10): - sim = SimulatorSampledArrival_MM(num_background_agents=25, - sim_time=1200, - lam=1e-3, - lamMM=5e-3, - mean=1e5, - r=0.05, - shock_var=5e6, - q_max=10, - pv_var=5e6, - shade=[250, 500], - xi= 100, # rung size - omega= 64, # spread, - K = 100 # n_level - 1 - ) - - sim.run() - fundamental_val = sim.markets[0].get_final_fundamental() - # print("fundamental:", fundamental_val) - values = [] - for agent_id in sim.agents: - agent = sim.agents[agent_id] - if agent_id == len(sim.agents): - value = agent.position * fundamental_val + agent.cash - else: - value = agent.get_pos_value() + agent.position * fundamental_val + agent.cash - # print(agent.cash, agent.position, agent.get_pos_value(), value) - values.append(value) - values_over_sim.append(values) # Simulation Output + average_spreads = np.mean(all_spreads, axis=0) + average_midprices = np.mean(all_midprices, axis=0) + average_inventory = np.mean(all_inventory, axis=0) + average_tq = np.mean(all_tq) + average_MM_q = np.mean(all_MM_q) + average_values = np.mean(MM_values) - average_values = np.mean(values_over_sim, axis=0) + print("Average Spreads:", average_spreads) + print("Average Midprices:", average_midprices) + print("Average Inventory:", average_inventory) + print("Average Total Quantity:", average_tq) + print("Average MM Quantity:", average_MM_q) + print("Average Values:", average_values) print("=============== END of SIM ================") - print("MM Profit:", average_values[-1]) - print("SW:", sum(average_values)) + + # Set up working directory. + if not os.path.exists(FLAGS.root_result_folder): + os.makedirs(FLAGS.root_result_folder) + + seed = np.random.randint(0, 10000) + + checkpoint_dir = FLAGS.game_name + checkpoint_dir = checkpoint_dir + "se_" + str(seed) + '_' + datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + checkpoint_dir = os.path.join(os.getcwd(), FLAGS.root_result_folder, checkpoint_dir) + + if not os.path.exists(checkpoint_dir): + os.makedirs(checkpoint_dir) + + # Save everything + write_to_csv(checkpoint_dir + "/average_spreads.csv", average_spreads) + write_to_csv(checkpoint_dir + "/average_spreads.csv", average_midprices) + write_to_csv(checkpoint_dir + "/average_spreads.csv", average_inventory) + # write_to_csv(average_trade_market_share + "/average_spreads.csv", average_spreads) + # write_to_csv(average_values + "/average_spreads.csv", average_spreads) + + # Save the original standard output + sys.stdout = open(checkpoint_dir+'/stdout.txt','w+') if __name__ == "__main__": - run() \ No newline at end of file + app.run(run) \ No newline at end of file diff --git a/marketsim/MM/utils.py b/marketsim/MM/utils.py new file mode 100644 index 00000000..f809a628 --- /dev/null +++ b/marketsim/MM/utils.py @@ -0,0 +1,10 @@ +import csv + +def write_to_csv(filename, content): + # Write to a CSV file + with open(filename, mode='w', newline='') as file: + writer = csv.writer(file) + # Writing the numbers as a single row + writer.writerow(content) + + diff --git a/marketsim/agent/market_maker.py b/marketsim/agent/market_maker.py index 14bf8b0b..72760918 100644 --- a/marketsim/agent/market_maker.py +++ b/marketsim/agent/market_maker.py @@ -40,15 +40,20 @@ def estimate_fundamental(self): def take_action(self): t = self.market.get_time() - estimate = self.estimate_fundamental() orders = [] - st = estimate + 1/2*self.omega - bt = estimate - 1 / 2 * self.omega + # Get the best bid and best ask + best_ask = self.market.order_book.get_best_ask() + best_bid = self.market.order_book.get_best_bid() + + estimate = self.estimate_fundamental() + st = max(estimate + 1 / 2 * self.omega, best_bid) + bt = min(estimate - 1 / 2 * self.omega, best_ask) + for k in range(self.K): orders.append( Order( - price= bt - (k + 1)*self.xi, + price= bt - (k + 1) * self.xi, quantity=1, agent_id=self.get_id(), time=t, diff --git a/marketsim/agent/market_maker_beta.py b/marketsim/agent/market_maker_beta.py index 55151218..9d02b44f 100644 --- a/marketsim/agent/market_maker_beta.py +++ b/marketsim/agent/market_maker_beta.py @@ -89,11 +89,13 @@ def take_action(self, action=None): orders = [] if self.policy: - # Get MM obs and apply the policy. + # RL policy a_buy, b_buy, a_sell, b_sell = action elif self.inv_driven: + # Inventory driven policy a_buy, b_buy, a_sell, b_sell = self.inv_driven_policy() else: + # Static beta policy a_buy = self.beta_params['a_buy'] b_buy = self.beta_params['b_buy'] a_sell = self.beta_params['a_sell'] @@ -113,8 +115,6 @@ def take_action(self, action=None): best_ask = self.market.order_book.get_best_ask() best_bid = self.market.order_book.get_best_bid() - #TODO: best_ask/best_bid are not inf? - estimate = self.estimate_fundamental() st = max(estimate + 1 / 2 * self.omega, best_bid) bt = min(estimate - 1 / 2 * self.omega, best_ask) diff --git a/marketsim/private_values/private_values.py b/marketsim/private_values/private_values.py index 81b7cea5..b287caaa 100644 --- a/marketsim/private_values/private_values.py +++ b/marketsim/private_values/private_values.py @@ -14,58 +14,58 @@ class PrivateValues: as well as calculate the cumulative value up to a given position. """ -def __init__(self, q_max: int, val_var=5e6): - """ - Initialize the PrivateValues object. + def __init__(self, q_max: int, val_var=5e6): + """ + Initialize the PrivateValues object. - :param q_max: The maximum quantity. - :param val_var: The variance of the values (default: 1). - """ - self.values = torch.randn(2 * q_max) * torch.sqrt(torch.tensor(val_var)) - self.values, _ = self.values.sort(descending=True) + :param q_max: The maximum quantity. + :param val_var: The variance of the values (default: 1). + """ + self.values = torch.randn(2 * q_max) * torch.sqrt(torch.tensor(val_var)) + self.values, _ = self.values.sort(descending=True) - self.offset = q_max + self.offset = q_max - self.extra_buy = min(self.values[-1].item(), 0) - self.extra_sell = max(self.values[0].item(), 0) + self.extra_buy = min(self.values[-1].item(), 0) + self.extra_sell = max(self.values[0].item(), 0) -def value_for_exchange(self, position: int, order_type: int) -> float: - """ - Calculates the value associated with a given trade and order type. + def value_for_exchange(self, position: int, order_type: int) -> float: + """ + Calculates the value associated with a given trade and order type. - Args: - position (int): The position for which to calculate the value. - order_type (int): The type of order (BUY or SELL). + Args: + position (int): The position for which to calculate the value. + order_type (int): The type of order (BUY or SELL). - Returns: - float: The value associated with the position and order type. - """ - index = position + self.offset - (1 if order_type == SELL else 0) - if index >= len(self.values): - return self.extra_buy - elif index < 0: - return self.extra_sell - else: - return self.values[index].item() + Returns: + float: The value associated with the position and order type. + """ + index = position + self.offset - (1 if order_type == SELL else 0) + if index >= len(self.values): + return self.extra_buy + elif index < 0: + return self.extra_sell + else: + return self.values[index].item() -def value_at_position(self, position: int) -> float: - """ - Calculates the total value at a given position. + def value_at_position(self, position: int) -> float: + """ + Calculates the total value at a given position. - Args: - position (int): The position for which to calculate the total value. + Args: + position (int): The position for which to calculate the total value. - Returns: - float: The total value at the given position. - """ - value = 0 - position += self.offset - if position > self.offset: - index = min(position, len(self.values)) - value += torch.sum(self.values[self.offset:index]) - value += max(0, position - 2*self.offset)*self.extra_buy - else: - index = max(0, position) - value -= torch.sum(self.values[index:self.offset]) - value -= -1*min(0, position)*self.extra_sell - return value + Returns: + float: The total value at the given position. + """ + value = 0 + position += self.offset + if position > self.offset: + index = min(position, len(self.values)) + value += torch.sum(self.values[self.offset:index]) + value += max(0, position - 2*self.offset)*self.extra_buy + else: + index = max(0, position) + value -= torch.sum(self.values[index:self.offset]) + value -= -1*min(0, position)*self.extra_sell + return value From 23850fc9ee2a0929626c411854de71dd4ccc5753 Mon Sep 17 00:00:00 2001 From: wangyzh Date: Thu, 20 Jun 2024 20:40:59 -0400 Subject: [PATCH 13/34] "upload before running noMM and static MM" --- marketsim/MM/parameters/generate_json.py | 38 -------- marketsim/MM/{parameters => plot}/__init__.py | 0 marketsim/MM/scripts/__init__.py | 0 marketsim/MM/scripts/generate_scripts.py | 88 +++++++++++++++++++ marketsim/MM/scripts/generate_scripts_noMM.py | 78 ++++++++++++++++ marketsim/MM/scripts/run_agents_only.sh | 5 ++ marketsim/MM/scripts/run_static_beta.sh | 29 ++++++ marketsim/MM/simMM.py | 12 +-- marketsim/MM/simMM_example.py | 64 ++++++++------ marketsim/MM/utils.py | 13 +++ marketsim/agent/market_maker_beta.py | 6 +- marketsim/market/market.py | 2 + 12 files changed, 261 insertions(+), 74 deletions(-) delete mode 100644 marketsim/MM/parameters/generate_json.py rename marketsim/MM/{parameters => plot}/__init__.py (100%) create mode 100644 marketsim/MM/scripts/__init__.py create mode 100644 marketsim/MM/scripts/generate_scripts.py create mode 100644 marketsim/MM/scripts/generate_scripts_noMM.py create mode 100644 marketsim/MM/scripts/run_agents_only.sh create mode 100644 marketsim/MM/scripts/run_static_beta.sh diff --git a/marketsim/MM/parameters/generate_json.py b/marketsim/MM/parameters/generate_json.py deleted file mode 100644 index b346cbf0..00000000 --- a/marketsim/MM/parameters/generate_json.py +++ /dev/null @@ -1,38 +0,0 @@ -import itertools -import json - -def generate_combinations(parameters): - keys = parameters.keys() - values = parameters.values() - combinations = list(itertools.product(*values)) - result = [{k: v for k, v in zip(keys, combination)} for combination in combinations] - return result - -def save_to_json(data, filename): - with open(filename, 'w') as file: - json.dump(data, file, indent=4) - -# Parameters -parameters = { - "num_background_agents" : [100, 200], - "shock_var": [1e6, 5e6], - "lam": [0.001, 0.005], - "lamMM": [0.005], - "K": [50, 100], # number of rungs - "xi": [100], # two-rung space - "omega": [64, 128, 256, 512, 1024, 2048], #spread - "num_simulations": [1000], - "sim_time": [1000, 2000, 4000, 8000, 12000], - "eta": [1, 0.8, 0.6, 0.4], # surplus required - "buy_alpha": [1,2,5], - "buy_beta": [1,2,5], - "sell_alpha": [1,2,5], - "sell_beta": [1,2,5], - "n_level": [101] -} - -# Generate combinations -combinations = generate_combinations(parameters) - -# Save combinations to JSON file -save_to_json(combinations, './combinations.json') diff --git a/marketsim/MM/parameters/__init__.py b/marketsim/MM/plot/__init__.py similarity index 100% rename from marketsim/MM/parameters/__init__.py rename to marketsim/MM/plot/__init__.py diff --git a/marketsim/MM/scripts/__init__.py b/marketsim/MM/scripts/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/marketsim/MM/scripts/generate_scripts.py b/marketsim/MM/scripts/generate_scripts.py new file mode 100644 index 00000000..8f8b8593 --- /dev/null +++ b/marketsim/MM/scripts/generate_scripts.py @@ -0,0 +1,88 @@ +# Define the list of variables +game_name_list = ["LadderMM"] +root_result_folder_list = ["./root_result_static_beta"] +num_iteration_list = [10000] +num_background_agents_list = [100] +sim_time_list = [1e5] +lam_list = [5e-3] +lamMM_list = [5e-2] +omega_list = [10, 30, 60] +K_list = [10] +n_levels_list = [11] +total_volume_list = [50] +beta_MM_list = ["True"] +inv_driven_list = ["False"] +beta_params = [ + "--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1", + "--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2", + "--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5", + "--a_sell=2 --b_sell=1, --a_buy=2, b_buy=1", + "--a_sell=2 --b_sell=2, --a_buy=2, b_buy=2", + "--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5", + "--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1", + "--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2", + "--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5" +] +w0_list = [5] +p_list = [2] +k_min_list = [5] +k_max_list = [20] +max_position_list = [20] +agents_only_list = ["False"] + +file_name = "run_static_beta.sh" + +# Generate the bash script content +bash_script_content = "#!/bin/bash\n\n" + +for game_name in game_name_list: + for root_result_folder in root_result_folder_list: + for num_iteration in num_iteration_list: + for num_background_agents in num_background_agents_list: + for sim_time in sim_time_list: + for lam in lam_list: + for lamMM in lamMM_list: + for omega in omega_list: + for K in K_list: + for n_levels in n_levels_list: + for total_volume in total_volume_list: + for beta_MM in beta_MM_list: + for inv_driven in inv_driven_list: + for w0 in w0_list: + for p in p_list: + for k_min in k_min_list: + for k_max in k_max_list: + for max_position in max_position_list: + for agents_only in agents_only_list: + for param in beta_params: + bash_script_content += ( + f"python simMM_example.py --game_name={game_name} " + f"--root_result_folder={root_result_folder} " + f"--num_iteration={num_iteration} " + f"--num_background_agents={num_background_agents} " + f"--sim_time={sim_time} " + f"--lam={lam} " + f"--lamMM={lamMM} " + f"--omega={omega} " + f"--K={K} " + f"--n_levels={n_levels} " + f"--total_volume={total_volume} " + f"--beta_MM={beta_MM} " + f"--inv_driven={inv_driven} " + f"--w0={w0} " + f"--p={p} " + f"--k_min={k_min} " + f"--k_max={k_max} " + f"--max_position={max_position} " + f"--agents_only={agents_only}" + ) + bash_script_content += param + "&& \\\n" + +# # Remove the last "&& \\\n" +# bash_script_content = bash_script_content.rstrip(" && \\\n") + +# Write the bash script to a file +with open(file_name, 'w') as file: + file.write(bash_script_content) + +print(f"Bash script generated and saved as '{file_name}'") diff --git a/marketsim/MM/scripts/generate_scripts_noMM.py b/marketsim/MM/scripts/generate_scripts_noMM.py new file mode 100644 index 00000000..a5463c50 --- /dev/null +++ b/marketsim/MM/scripts/generate_scripts_noMM.py @@ -0,0 +1,78 @@ +# Define the list of variables +game_name_list = ["LadderMM"] +root_result_folder_list = ["./root_result_noMM"] +num_iteration_list = [10000] +num_background_agents_list = [100] +sim_time_list = [1e5] +lam_list = [5e-3] +lamMM_list = [5e-2] +omega_list = [10, 30, 60] +K_list = [10] +n_levels_list = [11] +total_volume_list = [50] +beta_MM_list = ["False"] +inv_driven_list = ["False"] +beta_params = [""] +w0_list = [5] +p_list = [2] +k_min_list = [5] +k_max_list = [20] +max_position_list = [20] +agents_only_list = ["True"] + +file_name = "run_agents_only.sh" + +# Generate the bash script content +bash_script_content = "#!/bin/bash\n\n" + +for game_name in game_name_list: + for root_result_folder in root_result_folder_list: + for num_iteration in num_iteration_list: + for num_background_agents in num_background_agents_list: + for sim_time in sim_time_list: + for lam in lam_list: + for lamMM in lamMM_list: + for omega in omega_list: + for K in K_list: + for n_levels in n_levels_list: + for total_volume in total_volume_list: + for beta_MM in beta_MM_list: + for inv_driven in inv_driven_list: + for w0 in w0_list: + for p in p_list: + for k_min in k_min_list: + for k_max in k_max_list: + for max_position in max_position_list: + for agents_only in agents_only_list: + for param in beta_params: + bash_script_content += ( + f"python simMM_example.py --game_name={game_name} " + f"--root_result_folder={root_result_folder} " + f"--num_iteration={num_iteration} " + f"--num_background_agents={num_background_agents} " + f"--sim_time={sim_time} " + f"--lam={lam} " + f"--lamMM={lamMM} " + f"--omega={omega} " + f"--K={K} " + f"--n_levels={n_levels} " + f"--total_volume={total_volume} " + f"--beta_MM={beta_MM} " + f"--inv_driven={inv_driven} " + f"--w0={w0} " + f"--p={p} " + f"--k_min={k_min} " + f"--k_max={k_max} " + f"--max_position={max_position} " + f"--agents_only={agents_only}" + ) + bash_script_content += param + "&& \\\n" + +# # Remove the last "&& \\\n" +# bash_script_content = bash_script_content.rstrip(" && \\\n") + +# Write the bash script to a file +with open(file_name, 'w') as file: + file.write(bash_script_content) + +print(f"Bash script generated and saved as '{file_name}'") diff --git a/marketsim/MM/scripts/run_agents_only.sh b/marketsim/MM/scripts/run_agents_only.sh new file mode 100644 index 00000000..31a157c6 --- /dev/null +++ b/marketsim/MM/scripts/run_agents_only.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_noMM --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=False --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=True&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_noMM --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=False --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=True&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_noMM --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=False --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=True&& \ diff --git a/marketsim/MM/scripts/run_static_beta.sh b/marketsim/MM/scripts/run_static_beta.sh new file mode 100644 index 00000000..dae45465 --- /dev/null +++ b/marketsim/MM/scripts/run_static_beta.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5&& \ diff --git a/marketsim/MM/simMM.py b/marketsim/MM/simMM.py index eb54df43..04f98bcd 100644 --- a/marketsim/MM/simMM.py +++ b/marketsim/MM/simMM.py @@ -153,7 +153,7 @@ def step(self, agent_only=False): self.arrival_index_MM = 0 self.arrivals_MM[self.arrival_times_MM[self.arrival_index_MM].item() + 1 + self.time].append(agent_id) self.arrival_index_MM += 1 - print(self.arrival_times_MM[self.arrival_index_MM].item() + 1 + self.time) + # print(self.arrival_times_MM[self.arrival_index_MM].item() + 1 + self.time) else: # Regular agents. side = random.choice([BUY, SELL]) orders = agent.take_action(side) @@ -203,14 +203,14 @@ def end_sim(self): def run(self): counter = 0 - print("Arrival Time:", self.arrivals) - print("Arrival Time MM:", self.arrivals_MM) + # print("Arrival Time:", self.arrivals) + # print("Arrival Time MM:", self.arrivals_MM) for t in range(self.sim_time): if self.arrivals[t] + self.arrivals_MM[t]: - print(f'------------It is time {t}-------------') + # print(f'------------It is time {t}-------------') self.step() - print("MM position:", self.MM.position) - print("MM cash:", self.MM.cash) + # print("MM position:", self.MM.position) + # print("MM cash:", self.MM.cash) # print(self.markets[0].order_book.observe()) # print("----Best ask:", self.markets[0].order_book.get_best_ask()) # print("----Best bid:", self.markets[0].order_book.get_best_bid()) diff --git a/marketsim/MM/simMM_example.py b/marketsim/MM/simMM_example.py index 6c9d094f..fc387578 100644 --- a/marketsim/MM/simMM_example.py +++ b/marketsim/MM/simMM_example.py @@ -4,6 +4,7 @@ from absl import flags import datetime from marketsim.MM.utils import write_to_csv +from utils import replace_inf_with_nearest_2d import os import sys @@ -25,24 +26,42 @@ flags.DEFINE_integer("xi", 100, "Rung size.") flags.DEFINE_integer("omega", 10, "Spread.") flags.DEFINE_integer("K", 10, "Number of levels - 1.") -flags.DEFINE_integer("n_levels", 101, "n_levels.") -flags.DEFINE_integer("total_volume", 100, "total_volume.") -flags.DEFINE_float("a_sell", 0.5, "a_sell.") -flags.DEFINE_float("b_sell", 0.5, "b_sell.") -flags.DEFINE_float("a_buy", 0.5, "a_buy.") -flags.DEFINE_float("b_buy", 0.5, "b_buy.") +flags.DEFINE_integer("n_levels", 11, "n_levels.") +flags.DEFINE_integer("total_volume", 50, "total_volume.") flags.DEFINE_string("policy", None, "Policy.") -flags.DEFINE_boolean("beta_MM", False, "Beta MM.") +flags.DEFINE_boolean("beta_MM", True, "Beta MM.") flags.DEFINE_boolean("inv_driven", False, "Inventory driven.") flags.DEFINE_integer("w0", 5, "Initial wealth.") flags.DEFINE_integer("p", 2, "Parameter p.") flags.DEFINE_integer("k_min", 5, "Minimum k.") flags.DEFINE_integer("k_max", 20, "Maximum k.") -flags.DEFINE_integer("max_position", 100, "Maximum position.") +flags.DEFINE_integer("max_position", 20, "Maximum position.") flags.DEFINE_boolean("agents_only", False, "agents_only.") +# Beta Policy +flags.DEFINE_float("a_sell", 1, "a_sell.") +flags.DEFINE_float("b_sell", 2, "b_sell.") +flags.DEFINE_float("a_buy", 1, "a_buy.") +flags.DEFINE_float("b_buy", 2, "b_buy.") def run(argv): + # Set up working directory. + if not os.path.exists(FLAGS.root_result_folder): + os.makedirs(FLAGS.root_result_folder) + + seed = np.random.randint(0, 10000) + + checkpoint_dir = FLAGS.game_name + checkpoint_dir = checkpoint_dir + "agonly_" + str(FLAGS.agents_only) + "se_" + str( + seed) + '_' + datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + checkpoint_dir = os.path.join(os.getcwd(), FLAGS.root_result_folder, checkpoint_dir) + + if not os.path.exists(checkpoint_dir): + os.makedirs(checkpoint_dir) + + # Save the original standard output + # sys.stdout = open(checkpoint_dir + '/stdout.txt', 'w+') + print("========== Parameters ==========") print(f"game_name: {FLAGS.game_name}") print(f"root_result_folder: {FLAGS.root_result_folder}") @@ -117,6 +136,7 @@ def run(argv): stats = sim.run_agents_only(all_time_steps=True) else: stats = sim.run() + sim.reset() all_spreads.append(stats["spreads"]) all_midprices.append(stats["midprices"]) @@ -126,6 +146,9 @@ def run(argv): MM_values.append(stats["MM_value"]) + # Remove inf + all_spreads = replace_inf_with_nearest_2d(all_spreads) + all_midprices = replace_inf_with_nearest_2d(all_midprices) # Simulation Output average_spreads = np.mean(all_spreads, axis=0) @@ -135,37 +158,24 @@ def run(argv): average_MM_q = np.mean(all_MM_q) average_values = np.mean(MM_values) - print("Average Spreads:", average_spreads) - print("Average Midprices:", average_midprices) - print("Average Inventory:", average_inventory) + print("Average Spreads:", np.mean(average_spreads)) + print("Average Midprices:", np.mean(average_midprices)) + print("Average Inventory:", np.mean(average_inventory)) + print("Average Total Quantity:", average_tq) print("Average MM Quantity:", average_MM_q) print("Average Values:", average_values) print("=============== END of SIM ================") - # Set up working directory. - if not os.path.exists(FLAGS.root_result_folder): - os.makedirs(FLAGS.root_result_folder) - - seed = np.random.randint(0, 10000) - - checkpoint_dir = FLAGS.game_name - checkpoint_dir = checkpoint_dir + "se_" + str(seed) + '_' + datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S') - checkpoint_dir = os.path.join(os.getcwd(), FLAGS.root_result_folder, checkpoint_dir) - - if not os.path.exists(checkpoint_dir): - os.makedirs(checkpoint_dir) # Save everything write_to_csv(checkpoint_dir + "/average_spreads.csv", average_spreads) - write_to_csv(checkpoint_dir + "/average_spreads.csv", average_midprices) - write_to_csv(checkpoint_dir + "/average_spreads.csv", average_inventory) + write_to_csv(checkpoint_dir + "/average_midprices.csv", average_midprices) + write_to_csv(checkpoint_dir + "/average_inventory.csv", average_inventory) # write_to_csv(average_trade_market_share + "/average_spreads.csv", average_spreads) # write_to_csv(average_values + "/average_spreads.csv", average_spreads) - # Save the original standard output - sys.stdout = open(checkpoint_dir+'/stdout.txt','w+') if __name__ == "__main__": diff --git a/marketsim/MM/utils.py b/marketsim/MM/utils.py index f809a628..609c6586 100644 --- a/marketsim/MM/utils.py +++ b/marketsim/MM/utils.py @@ -1,4 +1,5 @@ import csv +import numpy as np def write_to_csv(filename, content): # Write to a CSV file @@ -8,3 +9,15 @@ def write_to_csv(filename, content): writer.writerow(content) +def replace_inf_with_nearest_2d(arr): + arr = np.array(arr) + for row in arr: + if np.isinf(row).any(): + finite_indices = np.where(np.isfinite(row))[0] + finite_values = row[finite_indices] + + for i in np.where(np.isinf(row))[0]: + nearest_idx = np.argmin(np.abs(finite_indices - i)) + row[i] = finite_values[nearest_idx] + + return arr \ No newline at end of file diff --git a/marketsim/agent/market_maker_beta.py b/marketsim/agent/market_maker_beta.py index 9d02b44f..1d5dd691 100644 --- a/marketsim/agent/market_maker_beta.py +++ b/marketsim/agent/market_maker_beta.py @@ -44,7 +44,7 @@ def __init__(self, p=2, k_min=5, k_max=20, - max_position=100): + max_position=15): self.agent_id = agent_id self.market = market @@ -124,7 +124,7 @@ def take_action(self, action=None): orders.append( Order( price= bt - (k + 1) * self.xi, - quantity=buy_orders[k], + quantity=int(buy_orders[k]), agent_id=self.get_id(), time=t, order_type=BUY, @@ -135,7 +135,7 @@ def take_action(self, action=None): orders.append( Order( price=st + (k + 1) * self.xi, - quantity=sell_orders[k], + quantity=int(sell_orders[k]), agent_id=self.get_id(), time=t, order_type=SELL, diff --git a/marketsim/market/market.py b/marketsim/market/market.py index dcef788a..8b9685eb 100644 --- a/marketsim/market/market.py +++ b/marketsim/market/market.py @@ -50,6 +50,8 @@ def step(self): orders = self.event_queue.step() self.buy_init_volume, self.sell_init_volumn = 0, 0 for order in orders: + if order.quantity <= 0: + continue self.order_book.insert(order) new_orders = self.clear_market() From ee8cf6556bf97b2f8e5569f47ac7121e464e6728 Mon Sep 17 00:00:00 2001 From: wangyzh Date: Thu, 20 Jun 2024 21:13:45 -0400 Subject: [PATCH 14/34] "upload before running noMM and static MM" --- marketsim/MM/{scripts => }/run_agents_only.sh | 0 marketsim/MM/{scripts => }/run_static_beta.sh | 0 marketsim/MM/scripts/generate_scripts.py | 2 +- marketsim/MM/scripts/generate_scripts_noMM.py | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) rename marketsim/MM/{scripts => }/run_agents_only.sh (100%) rename marketsim/MM/{scripts => }/run_static_beta.sh (100%) diff --git a/marketsim/MM/scripts/run_agents_only.sh b/marketsim/MM/run_agents_only.sh similarity index 100% rename from marketsim/MM/scripts/run_agents_only.sh rename to marketsim/MM/run_agents_only.sh diff --git a/marketsim/MM/scripts/run_static_beta.sh b/marketsim/MM/run_static_beta.sh similarity index 100% rename from marketsim/MM/scripts/run_static_beta.sh rename to marketsim/MM/run_static_beta.sh diff --git a/marketsim/MM/scripts/generate_scripts.py b/marketsim/MM/scripts/generate_scripts.py index 8f8b8593..763685af 100644 --- a/marketsim/MM/scripts/generate_scripts.py +++ b/marketsim/MM/scripts/generate_scripts.py @@ -30,7 +30,7 @@ max_position_list = [20] agents_only_list = ["False"] -file_name = "run_static_beta.sh" +file_name = "../run_static_beta.sh" # Generate the bash script content bash_script_content = "#!/bin/bash\n\n" diff --git a/marketsim/MM/scripts/generate_scripts_noMM.py b/marketsim/MM/scripts/generate_scripts_noMM.py index a5463c50..b45b76f5 100644 --- a/marketsim/MM/scripts/generate_scripts_noMM.py +++ b/marketsim/MM/scripts/generate_scripts_noMM.py @@ -20,7 +20,7 @@ max_position_list = [20] agents_only_list = ["True"] -file_name = "run_agents_only.sh" +file_name = "../run_agents_only.sh" # Generate the bash script content bash_script_content = "#!/bin/bash\n\n" From 87bc526598b27fd39bea26a2878bd79c72b2f871 Mon Sep 17 00:00:00 2001 From: wangyzh Date: Thu, 20 Jun 2024 21:19:24 -0400 Subject: [PATCH 15/34] "upload before running noMM and static MM" --- marketsim/MM/run_agents_only.sh | 2 -- marketsim/MM/run_static_beta.sh | 2 -- marketsim/MM/scripts/generate_scripts.py | 2 +- marketsim/MM/scripts/generate_scripts_noMM.py | 2 +- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/marketsim/MM/run_agents_only.sh b/marketsim/MM/run_agents_only.sh index 31a157c6..7fda9faf 100644 --- a/marketsim/MM/run_agents_only.sh +++ b/marketsim/MM/run_agents_only.sh @@ -1,5 +1,3 @@ -#!/bin/bash - python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_noMM --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=False --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=True&& \ python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_noMM --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=False --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=True&& \ python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_noMM --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=False --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=True&& \ diff --git a/marketsim/MM/run_static_beta.sh b/marketsim/MM/run_static_beta.sh index dae45465..869cc523 100644 --- a/marketsim/MM/run_static_beta.sh +++ b/marketsim/MM/run_static_beta.sh @@ -1,5 +1,3 @@ -#!/bin/bash - python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ diff --git a/marketsim/MM/scripts/generate_scripts.py b/marketsim/MM/scripts/generate_scripts.py index 763685af..5188fe2c 100644 --- a/marketsim/MM/scripts/generate_scripts.py +++ b/marketsim/MM/scripts/generate_scripts.py @@ -33,7 +33,7 @@ file_name = "../run_static_beta.sh" # Generate the bash script content -bash_script_content = "#!/bin/bash\n\n" +bash_script_content = "" for game_name in game_name_list: for root_result_folder in root_result_folder_list: diff --git a/marketsim/MM/scripts/generate_scripts_noMM.py b/marketsim/MM/scripts/generate_scripts_noMM.py index b45b76f5..0a747816 100644 --- a/marketsim/MM/scripts/generate_scripts_noMM.py +++ b/marketsim/MM/scripts/generate_scripts_noMM.py @@ -23,7 +23,7 @@ file_name = "../run_agents_only.sh" # Generate the bash script content -bash_script_content = "#!/bin/bash\n\n" +bash_script_content = "" for game_name in game_name_list: for root_result_folder in root_result_folder_list: From e10b549bb747099de3f44511f019f0638ae94abc Mon Sep 17 00:00:00 2001 From: wangyzh Date: Thu, 20 Jun 2024 21:21:39 -0400 Subject: [PATCH 16/34] "upload before running noMM and static MM" --- marketsim/MM/run_agents_only.sh | 2 +- marketsim/MM/run_static_beta.sh | 2 +- marketsim/MM/scripts/generate_scripts.py | 4 ++-- marketsim/MM/scripts/generate_scripts_noMM.py | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/marketsim/MM/run_agents_only.sh b/marketsim/MM/run_agents_only.sh index 7fda9faf..34fdda8c 100644 --- a/marketsim/MM/run_agents_only.sh +++ b/marketsim/MM/run_agents_only.sh @@ -1,3 +1,3 @@ python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_noMM --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=False --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=True&& \ python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_noMM --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=False --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=True&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_noMM --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=False --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=True&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_noMM --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=False --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=True \ No newline at end of file diff --git a/marketsim/MM/run_static_beta.sh b/marketsim/MM/run_static_beta.sh index 869cc523..6585adba 100644 --- a/marketsim/MM/run_static_beta.sh +++ b/marketsim/MM/run_static_beta.sh @@ -24,4 +24,4 @@ python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_ python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5 \ No newline at end of file diff --git a/marketsim/MM/scripts/generate_scripts.py b/marketsim/MM/scripts/generate_scripts.py index 5188fe2c..16cd5291 100644 --- a/marketsim/MM/scripts/generate_scripts.py +++ b/marketsim/MM/scripts/generate_scripts.py @@ -78,8 +78,8 @@ ) bash_script_content += param + "&& \\\n" -# # Remove the last "&& \\\n" -# bash_script_content = bash_script_content.rstrip(" && \\\n") +# Remove the last "&& \\\n" +bash_script_content = bash_script_content.rstrip(" && \\\n") # Write the bash script to a file with open(file_name, 'w') as file: diff --git a/marketsim/MM/scripts/generate_scripts_noMM.py b/marketsim/MM/scripts/generate_scripts_noMM.py index 0a747816..340b5081 100644 --- a/marketsim/MM/scripts/generate_scripts_noMM.py +++ b/marketsim/MM/scripts/generate_scripts_noMM.py @@ -68,8 +68,8 @@ ) bash_script_content += param + "&& \\\n" -# # Remove the last "&& \\\n" -# bash_script_content = bash_script_content.rstrip(" && \\\n") +# Remove the last "&& \\\n" +bash_script_content = bash_script_content.rstrip(" && \\\n") # Write the bash script to a file with open(file_name, 'w') as file: From 3dc821b8e5e6327214883f0a9d1e91d03b3cdb6a Mon Sep 17 00:00:00 2001 From: wangyzh Date: Thu, 20 Jun 2024 21:40:16 -0400 Subject: [PATCH 17/34] "remove from marketsim" --- marketsim/MM/RLMM_example.py | 2 +- marketsim/MM/simMM.py | 12 ++++++------ marketsim/MM/simMM_example.py | 4 ++-- marketsim/agent/market_maker_beta.py | 8 ++++---- marketsim/wrappers/MM_wrapper.py | 12 ++++++------ marketsim/wrappers/SP_wrapper.py | 12 ++++++------ 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/marketsim/MM/RLMM_example.py b/marketsim/MM/RLMM_example.py index 793d58d0..5b93e1ac 100644 --- a/marketsim/MM/RLMM_example.py +++ b/marketsim/MM/RLMM_example.py @@ -22,7 +22,7 @@ from tianshou.utils.space_info import SpaceInfo #MM -from marketsim.wrappers.MM_wrapper import MMEnv +from wrappers.MM_wrapper import MMEnv def get_args() -> argparse.Namespace: diff --git a/marketsim/MM/simMM.py b/marketsim/MM/simMM.py index 04f98bcd..4d74dc16 100644 --- a/marketsim/MM/simMM.py +++ b/marketsim/MM/simMM.py @@ -1,10 +1,10 @@ import random -from marketsim.fourheap.constants import BUY, SELL -from marketsim.market.market import Market -from marketsim.fundamental.lazy_mean_reverting import LazyGaussianMeanReverting -from marketsim.agent.zero_intelligence_agent import ZIAgent -from marketsim.agent.market_maker import MMAgent -from marketsim.agent.market_maker_beta import MMAgent as MMbetaAgent +from fourheap.constants import BUY, SELL +from market.market import Market +from fundamental.lazy_mean_reverting import LazyGaussianMeanReverting +from agent.zero_intelligence_agent import ZIAgent +from agent.market_maker import MMAgent +from agent.market_maker_beta import MMAgent as MMbetaAgent import torch.distributions as dist import torch from collections import defaultdict diff --git a/marketsim/MM/simMM_example.py b/marketsim/MM/simMM_example.py index fc387578..6fb4a151 100644 --- a/marketsim/MM/simMM_example.py +++ b/marketsim/MM/simMM_example.py @@ -1,9 +1,9 @@ -from marketsim.MM.simMM import SimulatorSampledArrival_MM +from MM.simMM import SimulatorSampledArrival_MM import numpy as np from absl import app from absl import flags import datetime -from marketsim.MM.utils import write_to_csv +from MM.utils import write_to_csv from utils import replace_inf_with_nearest_2d import os import sys diff --git a/marketsim/agent/market_maker_beta.py b/marketsim/agent/market_maker_beta.py index 1d5dd691..43fe6917 100644 --- a/marketsim/agent/market_maker_beta.py +++ b/marketsim/agent/market_maker_beta.py @@ -1,10 +1,10 @@ import random import numpy as np import scipy -from marketsim.agent.agent import Agent -from marketsim.market.market import Market -from marketsim.fourheap.order import Order -from marketsim.fourheap.constants import BUY, SELL +from agent.agent import Agent +from market import Market +from fourheap.order import Order +from fourheap.constants import BUY, SELL from typing import List, Optional, Any """ diff --git a/marketsim/wrappers/MM_wrapper.py b/marketsim/wrappers/MM_wrapper.py index 48e32e49..9cb309fd 100644 --- a/marketsim/wrappers/MM_wrapper.py +++ b/marketsim/wrappers/MM_wrapper.py @@ -4,12 +4,12 @@ import math import random -from marketsim.fourheap.constants import BUY, SELL -from marketsim.market.market import Market -from marketsim.fundamental.lazy_mean_reverting import LazyGaussianMeanReverting -from marketsim.agent.zero_intelligence_agent import ZIAgent -from marketsim.agent.market_maker_beta import MMAgent -from marketsim.wrappers.metrics import volume_imbalance, queue_imbalance, realized_volatility, relative_strength_index, midprice_move +from fourheap.constants import BUY, SELL +from market.market import Market +from fundamental.lazy_mean_reverting import LazyGaussianMeanReverting +from agent.zero_intelligence_agent import ZIAgent +from agent.market_maker_beta import MMAgent +from wrappers.metrics import volume_imbalance, queue_imbalance, realized_volatility, relative_strength_index, midprice_move import torch.distributions as dist import torch from collections import defaultdict diff --git a/marketsim/wrappers/SP_wrapper.py b/marketsim/wrappers/SP_wrapper.py index 3d0b2b9c..f0001d37 100644 --- a/marketsim/wrappers/SP_wrapper.py +++ b/marketsim/wrappers/SP_wrapper.py @@ -4,12 +4,12 @@ import math import random -from marketsim.fourheap.constants import BUY, SELL -from marketsim.market.market import Market -from marketsim.fundamental.lazy_mean_reverting import LazyGaussianMeanReverting -from marketsim.agent.zero_intelligence_agent import ZIAgent -from marketsim.agent.spoofer import SpoofingAgent -from marketsim.wrappers.metrics import volume_imbalance, queue_imbalance, signed_volume, realized_volatility, relative_strength_index, midprice_move +from fourheap.constants import BUY, SELL +from market.market import Market +from fundamental.lazy_mean_reverting import LazyGaussianMeanReverting +from agent.zero_intelligence_agent import ZIAgent +from agent.spoofer import SpoofingAgent +from wrappers.metrics import volume_imbalance, queue_imbalance, signed_volume, realized_volatility, relative_strength_index, midprice_move import torch.distributions as dist import torch from collections import defaultdict From 4a62ce7a6f11a52abdf3aab48a85d7564e8c76ba Mon Sep 17 00:00:00 2001 From: wangyzh Date: Thu, 20 Jun 2024 21:47:17 -0400 Subject: [PATCH 18/34] "recover from marketsim" --- marketsim/MM/RLMM_example.py | 2 +- marketsim/MM/simMM.py | 12 ++++++------ marketsim/MM/simMM_example.py | 21 +++++++++++++++++---- marketsim/agent/market_maker_beta.py | 8 ++++---- marketsim/wrappers/MM_wrapper.py | 12 ++++++------ marketsim/wrappers/SP_wrapper.py | 12 ++++++------ 6 files changed, 40 insertions(+), 27 deletions(-) diff --git a/marketsim/MM/RLMM_example.py b/marketsim/MM/RLMM_example.py index 5b93e1ac..793d58d0 100644 --- a/marketsim/MM/RLMM_example.py +++ b/marketsim/MM/RLMM_example.py @@ -22,7 +22,7 @@ from tianshou.utils.space_info import SpaceInfo #MM -from wrappers.MM_wrapper import MMEnv +from marketsim.wrappers.MM_wrapper import MMEnv def get_args() -> argparse.Namespace: diff --git a/marketsim/MM/simMM.py b/marketsim/MM/simMM.py index 4d74dc16..04f98bcd 100644 --- a/marketsim/MM/simMM.py +++ b/marketsim/MM/simMM.py @@ -1,10 +1,10 @@ import random -from fourheap.constants import BUY, SELL -from market.market import Market -from fundamental.lazy_mean_reverting import LazyGaussianMeanReverting -from agent.zero_intelligence_agent import ZIAgent -from agent.market_maker import MMAgent -from agent.market_maker_beta import MMAgent as MMbetaAgent +from marketsim.fourheap.constants import BUY, SELL +from marketsim.market.market import Market +from marketsim.fundamental.lazy_mean_reverting import LazyGaussianMeanReverting +from marketsim.agent.zero_intelligence_agent import ZIAgent +from marketsim.agent.market_maker import MMAgent +from marketsim.agent.market_maker_beta import MMAgent as MMbetaAgent import torch.distributions as dist import torch from collections import defaultdict diff --git a/marketsim/MM/simMM_example.py b/marketsim/MM/simMM_example.py index 6fb4a151..d1d05029 100644 --- a/marketsim/MM/simMM_example.py +++ b/marketsim/MM/simMM_example.py @@ -1,12 +1,25 @@ -from MM.simMM import SimulatorSampledArrival_MM +import os +import sys + +# Get the current script's directory +current_dir = os.path.dirname(os.path.abspath(__file__)) + +# Get the parent directory +parent_dir = os.path.dirname(current_dir) + +# Add the parent directory to the sys.path +sys.path.append(parent_dir) + + + +from marketsim.MM.simMM import SimulatorSampledArrival_MM import numpy as np from absl import app from absl import flags import datetime -from MM.utils import write_to_csv +from marketsim.MM.utils import write_to_csv from utils import replace_inf_with_nearest_2d -import os -import sys + FLAGS = flags.FLAGS flags.DEFINE_string("game_name", "LadderMM", "Game name.") diff --git a/marketsim/agent/market_maker_beta.py b/marketsim/agent/market_maker_beta.py index 43fe6917..46de1e5e 100644 --- a/marketsim/agent/market_maker_beta.py +++ b/marketsim/agent/market_maker_beta.py @@ -1,10 +1,10 @@ import random import numpy as np import scipy -from agent.agent import Agent -from market import Market -from fourheap.order import Order -from fourheap.constants import BUY, SELL +from marketsim.agent.agent import Agent +from marketsim.market import Market +from marketsim.fourheap.order import Order +from marketsim.fourheap.constants import BUY, SELL from typing import List, Optional, Any """ diff --git a/marketsim/wrappers/MM_wrapper.py b/marketsim/wrappers/MM_wrapper.py index 9cb309fd..48e32e49 100644 --- a/marketsim/wrappers/MM_wrapper.py +++ b/marketsim/wrappers/MM_wrapper.py @@ -4,12 +4,12 @@ import math import random -from fourheap.constants import BUY, SELL -from market.market import Market -from fundamental.lazy_mean_reverting import LazyGaussianMeanReverting -from agent.zero_intelligence_agent import ZIAgent -from agent.market_maker_beta import MMAgent -from wrappers.metrics import volume_imbalance, queue_imbalance, realized_volatility, relative_strength_index, midprice_move +from marketsim.fourheap.constants import BUY, SELL +from marketsim.market.market import Market +from marketsim.fundamental.lazy_mean_reverting import LazyGaussianMeanReverting +from marketsim.agent.zero_intelligence_agent import ZIAgent +from marketsim.agent.market_maker_beta import MMAgent +from marketsim.wrappers.metrics import volume_imbalance, queue_imbalance, realized_volatility, relative_strength_index, midprice_move import torch.distributions as dist import torch from collections import defaultdict diff --git a/marketsim/wrappers/SP_wrapper.py b/marketsim/wrappers/SP_wrapper.py index f0001d37..3d0b2b9c 100644 --- a/marketsim/wrappers/SP_wrapper.py +++ b/marketsim/wrappers/SP_wrapper.py @@ -4,12 +4,12 @@ import math import random -from fourheap.constants import BUY, SELL -from market.market import Market -from fundamental.lazy_mean_reverting import LazyGaussianMeanReverting -from agent.zero_intelligence_agent import ZIAgent -from agent.spoofer import SpoofingAgent -from wrappers.metrics import volume_imbalance, queue_imbalance, signed_volume, realized_volatility, relative_strength_index, midprice_move +from marketsim.fourheap.constants import BUY, SELL +from marketsim.market.market import Market +from marketsim.fundamental.lazy_mean_reverting import LazyGaussianMeanReverting +from marketsim.agent.zero_intelligence_agent import ZIAgent +from marketsim.agent.spoofer import SpoofingAgent +from marketsim.wrappers.metrics import volume_imbalance, queue_imbalance, signed_volume, realized_volatility, relative_strength_index, midprice_move import torch.distributions as dist import torch from collections import defaultdict From 05d0d259c56f42cf8259bb235683466cb78c56c1 Mon Sep 17 00:00:00 2001 From: wangyzh Date: Thu, 20 Jun 2024 21:51:49 -0400 Subject: [PATCH 19/34] "recover from marketsim" --- marketsim/MM/simMM_example.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/marketsim/MM/simMM_example.py b/marketsim/MM/simMM_example.py index d1d05029..023f7bfb 100644 --- a/marketsim/MM/simMM_example.py +++ b/marketsim/MM/simMM_example.py @@ -1,17 +1,6 @@ import os import sys -# Get the current script's directory -current_dir = os.path.dirname(os.path.abspath(__file__)) - -# Get the parent directory -parent_dir = os.path.dirname(current_dir) - -# Add the parent directory to the sys.path -sys.path.append(parent_dir) - - - from marketsim.MM.simMM import SimulatorSampledArrival_MM import numpy as np from absl import app From 7e17fd5b513b186dbd368d154ce1d9ea5199c642 Mon Sep 17 00:00:00 2001 From: wangyzh Date: Fri, 28 Jun 2024 17:40:23 -0400 Subject: [PATCH 20/34] "add sys to import from parent class" --- marketsim/MM/simMM_example.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/marketsim/MM/simMM_example.py b/marketsim/MM/simMM_example.py index 023f7bfb..a40acbd8 100644 --- a/marketsim/MM/simMM_example.py +++ b/marketsim/MM/simMM_example.py @@ -1,6 +1,18 @@ import os import sys +# getting the name of the directory +# where the this file is present. +current = os.path.dirname(os.path.realpath(__file__)) + +# Getting the parent directory name +# where the current directory is present. +parent = os.path.dirname(current) + +# adding the parent directory to +# the sys.path. +sys.path.append(parent) + from marketsim.MM.simMM import SimulatorSampledArrival_MM import numpy as np from absl import app From a4284335277ded6e11b962040935e6f3abc65de3 Mon Sep 17 00:00:00 2001 From: wangyzh Date: Fri, 28 Jun 2024 17:52:58 -0400 Subject: [PATCH 21/34] "add sys to import from parent class" --- marketsim/MM/simMM_example.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/marketsim/MM/simMM_example.py b/marketsim/MM/simMM_example.py index a40acbd8..061be82f 100644 --- a/marketsim/MM/simMM_example.py +++ b/marketsim/MM/simMM_example.py @@ -1,17 +1,18 @@ import os import sys -# getting the name of the directory -# where the this file is present. -current = os.path.dirname(os.path.realpath(__file__)) +# Get the current script's directory +current_dir = os.path.dirname(os.path.abspath(__file__)) -# Getting the parent directory name -# where the current directory is present. -parent = os.path.dirname(current) +# Get the parent directory +parent_dir = os.path.dirname(current_dir) + +# Get the grandparent directory +grandparent_dir = os.path.dirname(parent_dir) + +# Add the grandparent directory to the sys.path +sys.path.append(grandparent_dir) -# adding the parent directory to -# the sys.path. -sys.path.append(parent) from marketsim.MM.simMM import SimulatorSampledArrival_MM import numpy as np From d8ea579c56064a54e8b9b7b8f271df39bdf825cb Mon Sep 17 00:00:00 2001 From: wangyzh Date: Fri, 28 Jun 2024 18:06:34 -0400 Subject: [PATCH 22/34] "add sys to import from parent class" --- marketsim/agent/market_maker_beta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/marketsim/agent/market_maker_beta.py b/marketsim/agent/market_maker_beta.py index 46de1e5e..1d5dd691 100644 --- a/marketsim/agent/market_maker_beta.py +++ b/marketsim/agent/market_maker_beta.py @@ -2,7 +2,7 @@ import numpy as np import scipy from marketsim.agent.agent import Agent -from marketsim.market import Market +from marketsim.market.market import Market from marketsim.fourheap.order import Order from marketsim.fourheap.constants import BUY, SELL from typing import List, Optional, Any From c6d25f2ba5d0776ac8b4e68f777480ec7ad0dabd Mon Sep 17 00:00:00 2001 From: wangyzh Date: Fri, 28 Jun 2024 18:11:58 -0400 Subject: [PATCH 23/34] "update bash" --- marketsim/MM/run_static_beta.sh | 54 ++++++++++++------------ marketsim/MM/scripts/generate_scripts.py | 2 +- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/marketsim/MM/run_static_beta.sh b/marketsim/MM/run_static_beta.sh index 6585adba..efff9ad2 100644 --- a/marketsim/MM/run_static_beta.sh +++ b/marketsim/MM/run_static_beta.sh @@ -1,27 +1,27 @@ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000.0 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5 \ No newline at end of file +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5 \ No newline at end of file diff --git a/marketsim/MM/scripts/generate_scripts.py b/marketsim/MM/scripts/generate_scripts.py index 16cd5291..b9b1cda3 100644 --- a/marketsim/MM/scripts/generate_scripts.py +++ b/marketsim/MM/scripts/generate_scripts.py @@ -3,7 +3,7 @@ root_result_folder_list = ["./root_result_static_beta"] num_iteration_list = [10000] num_background_agents_list = [100] -sim_time_list = [1e5] +sim_time_list = [100000] lam_list = [5e-3] lamMM_list = [5e-2] omega_list = [10, 30, 60] From 3ccee8c7ea520cdbf6fde5a3356644c6cd72c436 Mon Sep 17 00:00:00 2001 From: wangyzh Date: Fri, 28 Jun 2024 18:15:28 -0400 Subject: [PATCH 24/34] "update bash" --- marketsim/MM/run_static_beta.sh | 54 ++++++++++++------------ marketsim/MM/scripts/generate_scripts.py | 2 +- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/marketsim/MM/run_static_beta.sh b/marketsim/MM/run_static_beta.sh index efff9ad2..7e47cbbd 100644 --- a/marketsim/MM/run_static_beta.sh +++ b/marketsim/MM/run_static_beta.sh @@ -1,27 +1,27 @@ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5 \ No newline at end of file +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5, --a_buy=5, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5, --a_buy=5, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5, --a_buy=5, b_buy=5 \ No newline at end of file diff --git a/marketsim/MM/scripts/generate_scripts.py b/marketsim/MM/scripts/generate_scripts.py index b9b1cda3..d20d9577 100644 --- a/marketsim/MM/scripts/generate_scripts.py +++ b/marketsim/MM/scripts/generate_scripts.py @@ -74,7 +74,7 @@ f"--k_min={k_min} " f"--k_max={k_max} " f"--max_position={max_position} " - f"--agents_only={agents_only}" + f"--agents_only={agents_only} " ) bash_script_content += param + "&& \\\n" From 0455058cba9a6c6546b66eeac0f7742fe24b5b2d Mon Sep 17 00:00:00 2001 From: wangyzh Date: Fri, 28 Jun 2024 18:18:18 -0400 Subject: [PATCH 25/34] "update bash" --- marketsim/MM/run_static_beta.sh | 54 ++++++++++++------------ marketsim/MM/scripts/generate_scripts.py | 18 ++++---- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/marketsim/MM/run_static_beta.sh b/marketsim/MM/run_static_beta.sh index 7e47cbbd..33707dfb 100644 --- a/marketsim/MM/run_static_beta.sh +++ b/marketsim/MM/run_static_beta.sh @@ -1,27 +1,27 @@ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5, --a_buy=5, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5, --a_buy=5, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1, --a_buy=1, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2, --a_buy=1, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5, --a_buy=1, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1, --a_buy=2, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2, --a_buy=2, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5, --a_buy=2, b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1, --a_buy=5, b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2, --a_buy=5, b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5, --a_buy=5, b_buy=5 \ No newline at end of file +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1 --a_buy=1 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2 --a_buy=1 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5 --a_buy=1 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1 --a_buy=2 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2 --a_buy=2 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5 --a_buy=2 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1 --a_buy=5 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2 --a_buy=5 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5 --a_buy=5 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1 --a_buy=1 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2 --a_buy=1 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5 --a_buy=1 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1 --a_buy=2 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2 --a_buy=2 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5 --a_buy=2 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1 --a_buy=5 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2 --a_buy=5 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5 --a_buy=5 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1 --a_buy=1 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2 --a_buy=1 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5 --a_buy=1 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1 --a_buy=2 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2 --a_buy=2 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5 --a_buy=2 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1 --a_buy=5 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2 --a_buy=5 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5 --a_buy=5 --b_buy=5 \ No newline at end of file diff --git a/marketsim/MM/scripts/generate_scripts.py b/marketsim/MM/scripts/generate_scripts.py index d20d9577..4dfbcb16 100644 --- a/marketsim/MM/scripts/generate_scripts.py +++ b/marketsim/MM/scripts/generate_scripts.py @@ -13,15 +13,15 @@ beta_MM_list = ["True"] inv_driven_list = ["False"] beta_params = [ - "--a_sell=1 --b_sell=1, --a_buy=1, b_buy=1", - "--a_sell=1 --b_sell=2, --a_buy=1, b_buy=2", - "--a_sell=1 --b_sell=5, --a_buy=1, b_buy=5", - "--a_sell=2 --b_sell=1, --a_buy=2, b_buy=1", - "--a_sell=2 --b_sell=2, --a_buy=2, b_buy=2", - "--a_sell=2 --b_sell=5, --a_buy=2, b_buy=5", - "--a_sell=5 --b_sell=1, --a_buy=5, b_buy=1", - "--a_sell=5 --b_sell=2, --a_buy=5, b_buy=2", - "--a_sell=5 --b_sell=5, --a_buy=5, b_buy=5" + "--a_sell=1 --b_sell=1 --a_buy=1 --b_buy=1", + "--a_sell=1 --b_sell=2 --a_buy=1 --b_buy=2", + "--a_sell=1 --b_sell=5 --a_buy=1 --b_buy=5", + "--a_sell=2 --b_sell=1 --a_buy=2 --b_buy=1", + "--a_sell=2 --b_sell=2 --a_buy=2 --b_buy=2", + "--a_sell=2 --b_sell=5 --a_buy=2 --b_buy=5", + "--a_sell=5 --b_sell=1 --a_buy=5 --b_buy=1", + "--a_sell=5 --b_sell=2 --a_buy=5 --b_buy=2", + "--a_sell=5 --b_sell=5 --a_buy=5 --b_buy=5" ] w0_list = [5] p_list = [2] From 5c5304a37434f4f3b9fd10df93ae5a5f53af0be7 Mon Sep 17 00:00:00 2001 From: wangyzh Date: Fri, 28 Jun 2024 22:18:07 -0400 Subject: [PATCH 26/34] "update bash" --- marketsim/MM/run_static_beta.sh | 54 ++++++++++++------------ marketsim/MM/scripts/generate_scripts.py | 2 +- marketsim/MM/simMM_example.py | 2 +- marketsim/agent/market_maker_beta.py | 37 ++++++++++++---- 4 files changed, 58 insertions(+), 37 deletions(-) diff --git a/marketsim/MM/run_static_beta.sh b/marketsim/MM/run_static_beta.sh index 33707dfb..f5b58548 100644 --- a/marketsim/MM/run_static_beta.sh +++ b/marketsim/MM/run_static_beta.sh @@ -1,27 +1,27 @@ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1 --a_buy=1 --b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2 --a_buy=1 --b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5 --a_buy=1 --b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1 --a_buy=2 --b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2 --a_buy=2 --b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5 --a_buy=2 --b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1 --a_buy=5 --b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2 --a_buy=5 --b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5 --a_buy=5 --b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1 --a_buy=1 --b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2 --a_buy=1 --b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5 --a_buy=1 --b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1 --a_buy=2 --b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2 --a_buy=2 --b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5 --a_buy=2 --b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1 --a_buy=5 --b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2 --a_buy=5 --b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5 --a_buy=5 --b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1 --a_buy=1 --b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2 --a_buy=1 --b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5 --a_buy=1 --b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1 --a_buy=2 --b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2 --a_buy=2 --b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5 --a_buy=2 --b_buy=5&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1 --a_buy=5 --b_buy=1&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2 --a_buy=5 --b_buy=2&& \ -python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=10000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5 --a_buy=5 --b_buy=5 \ No newline at end of file +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1 --a_buy=1 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2 --a_buy=1 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5 --a_buy=1 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1 --a_buy=2 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2 --a_buy=2 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5 --a_buy=2 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1 --a_buy=5 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2 --a_buy=5 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=10 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5 --a_buy=5 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1 --a_buy=1 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2 --a_buy=1 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5 --a_buy=1 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1 --a_buy=2 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2 --a_buy=2 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5 --a_buy=2 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1 --a_buy=5 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2 --a_buy=5 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=30 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5 --a_buy=5 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=1 --a_buy=1 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=2 --a_buy=1 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=1 --b_sell=5 --a_buy=1 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=1 --a_buy=2 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=2 --a_buy=2 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=2 --b_sell=5 --a_buy=2 --b_buy=5&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=1 --a_buy=5 --b_buy=1&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=2 --a_buy=5 --b_buy=2&& \ +python simMM_example.py --game_name=LadderMM --root_result_folder=./root_result_static_beta --num_iteration=5000 --num_background_agents=100 --sim_time=100000 --lam=0.005 --lamMM=0.05 --omega=60 --K=10 --n_levels=11 --total_volume=50 --beta_MM=True --inv_driven=False --w0=5 --p=2 --k_min=5 --k_max=20 --max_position=20 --agents_only=False --a_sell=5 --b_sell=5 --a_buy=5 --b_buy=5 \ No newline at end of file diff --git a/marketsim/MM/scripts/generate_scripts.py b/marketsim/MM/scripts/generate_scripts.py index 4dfbcb16..055f1a98 100644 --- a/marketsim/MM/scripts/generate_scripts.py +++ b/marketsim/MM/scripts/generate_scripts.py @@ -1,7 +1,7 @@ # Define the list of variables game_name_list = ["LadderMM"] root_result_folder_list = ["./root_result_static_beta"] -num_iteration_list = [10000] +num_iteration_list = [5000] num_background_agents_list = [100] sim_time_list = [100000] lam_list = [5e-3] diff --git a/marketsim/MM/simMM_example.py b/marketsim/MM/simMM_example.py index 061be82f..7405c801 100644 --- a/marketsim/MM/simMM_example.py +++ b/marketsim/MM/simMM_example.py @@ -75,7 +75,7 @@ def run(argv): os.makedirs(checkpoint_dir) # Save the original standard output - # sys.stdout = open(checkpoint_dir + '/stdout.txt', 'w+') + sys.stdout = open(checkpoint_dir + '/stdout.txt', 'w+') print("========== Parameters ==========") print(f"game_name: {FLAGS.game_name}") diff --git a/marketsim/agent/market_maker_beta.py b/marketsim/agent/market_maker_beta.py index 1d5dd691..36dae715 100644 --- a/marketsim/agent/market_maker_beta.py +++ b/marketsim/agent/market_maker_beta.py @@ -28,6 +28,27 @@ def quantise_scaledbetadist(total_volume, n_levels, a, b): return order_profile +# v2 is the original version, which could be faster. +def ScaledBetaDist_v2(x, n_levels, a, b): + dist = scipy.stats.beta(a, b) + return 1 / n_levels * dist.pdf(x / n_levels) + + +def quantise_scaledbetadist_v2(total_volume, n_levels, a, b): + probs = [] + for i in range(1, n_levels + 1): + x = i - 0.5 + prob = ScaledBetaDist_v2(x, n_levels, a, b) + probs.append(prob) + + probs = np.array(probs) / np.sum(probs) + order_profile = np.round(probs * total_volume) + + return order_profile + + + + class MMAgent(Agent): def __init__(self, @@ -101,15 +122,15 @@ def take_action(self, action=None): a_sell = self.beta_params['a_sell'] b_sell = self.beta_params['b_sell'] - buy_orders = quantise_scaledbetadist(total_volume=self.total_volume, - n_levels=self.n_levels, - a=a_buy, - b=b_buy) + buy_orders = quantise_scaledbetadist_v2(total_volume=self.total_volume, + n_levels=self.n_levels, + a=a_buy, + b=b_buy) - sell_orders = quantise_scaledbetadist(total_volume=self.total_volume, - n_levels=self.n_levels, - a=a_sell, - b=b_sell) + sell_orders = quantise_scaledbetadist_v2(total_volume=self.total_volume, + n_levels=self.n_levels, + a=a_sell, + b=b_sell) # Get the best bid and best ask best_ask = self.market.order_book.get_best_ask() From 7e32b585f3c2942d356cd88b849036003131f2ec Mon Sep 17 00:00:00 2001 From: wangyzh Date: Fri, 28 Jun 2024 22:31:46 -0400 Subject: [PATCH 27/34] "update bash" --- marketsim/MM/simMM_example.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/marketsim/MM/simMM_example.py b/marketsim/MM/simMM_example.py index 7405c801..67f4d747 100644 --- a/marketsim/MM/simMM_example.py +++ b/marketsim/MM/simMM_example.py @@ -1,5 +1,7 @@ import os import sys +import functools +print = functools.partial(print, flush=True) # Get the current script's directory current_dir = os.path.dirname(os.path.abspath(__file__)) @@ -67,7 +69,7 @@ def run(argv): seed = np.random.randint(0, 10000) checkpoint_dir = FLAGS.game_name - checkpoint_dir = checkpoint_dir + "agonly_" + str(FLAGS.agents_only) + "se_" + str( + checkpoint_dir = checkpoint_dir + "_agonly_" + str(FLAGS.agents_only) + "_se_" + str( seed) + '_' + datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S') checkpoint_dir = os.path.join(os.getcwd(), FLAGS.root_result_folder, checkpoint_dir) From 36fa608a954e781393219dd5252555c70a056727 Mon Sep 17 00:00:00 2001 From: wangyzh Date: Sat, 27 Jul 2024 16:17:16 -0400 Subject: [PATCH 28/34] "update reward" --- marketsim/wrappers/MM_wrapper.py | 187 ++++++++++++++++++++++--------- 1 file changed, 135 insertions(+), 52 deletions(-) diff --git a/marketsim/wrappers/MM_wrapper.py b/marketsim/wrappers/MM_wrapper.py index 48e32e49..f1f2e59f 100644 --- a/marketsim/wrappers/MM_wrapper.py +++ b/marketsim/wrappers/MM_wrapper.py @@ -7,7 +7,8 @@ from marketsim.fourheap.constants import BUY, SELL from marketsim.market.market import Market from marketsim.fundamental.lazy_mean_reverting import LazyGaussianMeanReverting -from marketsim.agent.zero_intelligence_agent import ZIAgent +from marketsim.agent.noise_ZI_agent import ZIAgent +from marketsim.agent.informed_ZI import ZIAgent as InformedZIAgent from marketsim.agent.market_maker_beta import MMAgent from marketsim.wrappers.metrics import volume_imbalance, queue_imbalance, realized_volatility, relative_strength_index, midprice_move import torch.distributions as dist @@ -25,18 +26,20 @@ def __init__(self, num_assets: int = 1, lam: float = 75e-3, lamMM: float = 5e-3, + informedZI = False, mean: float = 1e5, r: float = 0.05, shock_var: float = 5e6, q_max: int = 10, + est_var: float = 1e6, pv_var: float = 5e6, shade=None, - n_levels: int=101, + n_levels: int=21, total_volume: int=100, - xi: float = 100, # rung size - omega: float = 64, #spread + xi: float = 50, # rung size + omega: float = 10, #spread beta_params: dict = None, - policy=None, + policy=False, normalizers=None ): @@ -80,14 +83,25 @@ def __init__(self, self.arrivals[self.arrival_times[self.arrival_index].item()].append(agent_id) self.arrival_index += 1 - self.agents[agent_id] = ( - ZIAgent( - agent_id=agent_id, - market=self.markets[0], - q_max=q_max, - shade=shade, - pv_var=pv_var - )) + if informedZI and agent_id >= int(num_background_agents / 2): + self.agents[agent_id] = ( + InformedZIAgent( + agent_id=agent_id, + market=self.markets[0], + q_max=q_max, + shade=shade, + pv_var=pv_var + )) + else: + self.agents[agent_id] = ( + ZIAgent( + agent_id=agent_id, + market=self.markets[0], + q_max=q_max, + shade=shade, + pv_var=pv_var, + est_var=est_var + )) # Set up for market makers. self.arrivals_MM[self.arrival_times_MM[self.arrival_index_MM].item()].append(self.num_agents) @@ -103,6 +117,14 @@ def __init__(self, policy=policy ) + # Metrics + self.spreads = [] + self.midprices = [] + self.inventory = [] + self.value_MM = 0 + self.total_quantity = 0 + self.MM_quantity = 0 + # Gym Setup """ Given a market state s when the self agent arrives at time t, @@ -119,12 +141,18 @@ def __init__(self, 9.Volatility, 10.Relative strength index, """ - self.observation_space = spaces.Box(low=np.array([0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0]), - high=np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]), - shape=(10,), - dtype=np.float64) # Need rescale the obs. + # self.observation_space = spaces.Box(low=np.array([0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0]), + # high=np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]), + # shape=(10,), + # dtype=np.float64) # Need rescale the obs. + + self.observation_space = spaces.Box(low=np.array([0.0, 0.0, 0.0, 0.0, -1.0]), + high=np.array([1.0, 1.0, 1.0, 1.0, 1.0]), + shape=(5,), + dtype=np.float64) # Need rescale the obs. - self.action_space = spaces.Box(low=0.0, high=1.0, shape=(4,), dtype=np.float64) # a_buy, b_buy, a_sell, b_sell + # self.action_space = spaces.Box(low=0.0, high=1.0, shape=(4,), dtype=np.float64) # a_buy, b_buy, a_sell, b_sell + self.action_space = spaces.Box(low=-1.0, high=1.0, shape=(2,), dtype=np.float64) def get_obs(self): return self.observation @@ -168,7 +196,7 @@ def normalization(self, if self.normalizers is None: print("No normalizer warning!") - return np.array([time_left, fundamental_value, best_ask, best_bid, MMinvt, MMcash]) + return np.array([time_left, fundamental_value, best_ask, best_bid, MMinvt]) time_left /= self.sim_time fundamental_value /= self.normalizers["fundamental"] @@ -188,16 +216,22 @@ def normalization(self, midprice_delta /= 1e2 # TODO: need to tune rsi /= 100 + # return np.array([time_left, + # fundamental_value, + # best_ask, + # best_bid, + # MMinvt, + # midprice_delta, + # vol_imbalance * 10, + # que_imbalance * 10, + # vr, + # rsi]) + return np.array([time_left, fundamental_value, best_ask, best_bid, - MMinvt, - midprice_delta, - vol_imbalance * 10, - que_imbalance * 10, - vr, - rsi]) + MMinvt]) def reset(self, seed=None, options=None): @@ -220,16 +254,26 @@ def reset(self, seed=None, options=None): # Reset MM self.MM.reset() + # Metrics + self.spreads = [] + self.midprices = [] + self.inventory = [] + self.value_MM = 0 + self.total_quantity = 0 + self.MM_quantity = 0 + # Reset Arrivals self.reset_arrivals() # Run until the MM enters. - self.run_agents_only() - end = self.run_until_next_MM_arrival() + # self.run_agents_only() #TODO: run agent only could exclude the arrival of MM. + _, end = self.run_until_next_MM_arrival() if end: raise ValueError("An episode without MM. Length of an episode should be set large.") + + # print("OBS RET:", self.get_obs()) return self.get_obs(), {} @@ -254,15 +298,12 @@ def reset_arrivals(self): def step(self, action): - print("----midprices:", self.MM.market.get_midprices()) - print("----Best ask:", self.MM.market.order_book.get_best_ask()) - print("----Best bid:", self.MM.market.order_book.get_best_bid()) if self.time < self.sim_time: self.MM_step(action) self.agents_step() - reward = self.market_step(agent_only=False) + self.market_step(agent_only=False) self.time += 1 - end = self.run_until_next_MM_arrival() + reward, end = self.run_until_next_MM_arrival() if end: return self.end_sim() return self.get_obs(), reward, False, False, {} @@ -293,6 +334,7 @@ def MM_step(self, action): market.event_queue.set_time(self.time) market.withdraw_all(self.num_agents) orders = self.MM.take_action(action) + # print("MM orders:", len(orders), action) market.add_orders(orders) if self.arrival_index_MM == self.arrivals_sampled: @@ -302,11 +344,9 @@ def MM_step(self, action): self.arrival_index_MM += 1 def market_step(self, agent_only=True, verbose=False): - if verbose: - print("----Last Best ask:", self.MM.market.order_book.get_best_ask()) - print("----Last Best bid:", self.MM.market.order_book.get_best_bid()) for market in self.markets: new_orders = market.step() + z = 0 for matched_order in new_orders: agent_id = matched_order.order.agent_id quantity = matched_order.order.order_type * matched_order.order.quantity @@ -316,22 +356,35 @@ def market_step(self, agent_only=True, verbose=False): else: self.agents[agent_id].update_position(quantity, cash) + # Record + self.total_quantity += abs(quantity) + if agent_id == self.num_agents: + # print(abs(quantity)) + z += abs(quantity) + self.MM_quantity += abs(quantity) + + print(z) + # Record stats + best_ask = market.order_book.get_best_ask() + best_bid = market.order_book.get_best_bid() + self.spreads.append(best_ask - best_bid) + self.midprices.append((best_ask + best_bid) / 2) + self.inventory.append(self.MM.position) + if not agent_only: - fundamental_val = self.markets[0].get_final_fundamental() - current_value = self.MM.position * fundamental_val + self.MM.cash - reward = current_value - self.MM.last_value if verbose: + print("----midprice:", (best_ask + best_bid) / 2) + print("----fundamental:", self.MM.estimate_fundamental()) + print("----final fundamental:", market.get_final_fundamental()) print("----matched orders:", new_orders) - print("----current_value:", current_value) print("----self.MM.last_value:", self.MM.last_value) - print("----Best ask:", self.MM.market.order_book.get_best_ask()) - print("----Best bid:", self.MM.market.order_book.get_best_bid()) - print("----Bids:", self.MM.market.order_book.buy_unmatched) - print("----Asks:", self.MM.market.order_book.sell_unmatched) - self.MM.last_value = current_value + print("----Position:", self.MM.position) + print("----Cash:", self.MM.cash) + # print("----Best ask:", self.MM.market.order_book.get_best_ask()) + # print("----Best bid:", self.MM.market.order_book.get_best_bid()) + # print("----Bids:", self.MM.market.order_book.buy_unmatched) + # print("----Asks:", self.MM.market.order_book.sell_unmatched) - # Assume single market, so reward is a scalar. - return reward / self.normalizers["fundamental"] # TODO: Check if this normalizer works. def end_sim_summarize(self): fundamental_val = self.markets[0].get_final_fundamental() @@ -344,24 +397,34 @@ def end_sim_summarize(self): # print(f'At the end of the simulation we get {values}') def end_sim(self): - estimated_fundamental = self.MM.estimate_fundamental() - current_value = self.MM.position * estimated_fundamental + self.MM.cash + fundamental_val = self.markets[0].get_final_fundamental() + current_value = self.MM.position * fundamental_val + self.MM.cash reward = current_value - self.MM.last_value - return self.get_obs(), reward, True, False, {} + self.MM.last_value = current_value + self.value_MM = current_value + + return self.get_obs(), reward / self.normalizers["reward"], True, False, {} def run_until_next_MM_arrival(self): while len(self.arrivals_MM[self.time]) == 0 and self.time < self.sim_time: self.agents_step() self.market_step(agent_only=True) - # print(self.markets[0].order_book.observe()) self.time += 1 if self.time >= self.sim_time: - return True + return 0, True else: + fundamental_val = self.markets[0].get_final_fundamental() + current_value = self.MM.position * fundamental_val + self.MM.cash + reward = current_value - self.MM.last_value + self.MM.last_value = current_value self.update_obs() - return False + + return reward / self.normalizers["reward"], False + + + def run_agents_only(self): for t in range(int(0.01 * self.sim_time)): @@ -370,5 +433,25 @@ def run_agents_only(self): self.market_step(agent_only=True) self.time += 1 + def get_stats(self): + stats = {} + stats["spreads"] = self.spreads.copy() + stats["midprices"] = self.midprices.copy() + stats["inventory"] = self.inventory.copy() + stats["total_quantity"] = self.total_quantity + stats["MM_quantity"] = self.MM_quantity + stats["MM_value"] = self.value_MM + + return stats + + def compute_social_welfare(self): + values = [] + fundamental_val = self.markets[0].get_final_fundamental() + for agent_id in self.agents: + agent = self.agents[agent_id] + values.append(agent.get_pos_value() + agent.position * fundamental_val + agent.cash) + + values.append(self.MM.position * fundamental_val + self.MM.cash) + return sum(values) From 8abf5af78686f75f991329da528b3586e5ac3813 Mon Sep 17 00:00:00 2001 From: Rishith Seelam Date: Wed, 26 Jun 2024 15:01:29 -0400 Subject: [PATCH 29/34] partial random seeding --- marketsim/agent/extented_zi_agent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/marketsim/agent/extented_zi_agent.py b/marketsim/agent/extented_zi_agent.py index c70dc882..c72a4827 100644 --- a/marketsim/agent/extented_zi_agent.py +++ b/marketsim/agent/extented_zi_agent.py @@ -8,7 +8,7 @@ class ZIAgent(Agent): - def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: int, offset: float, eta: float, shade: List, random_seed: int = 0): + def __init__(self, agent_id: int, market: Market, q_max: int, offset: float, eta: float, shade: List, random_seed: int = 0): if random_seed != 0: # torch.manual_seed(random_seed) From f5f04ef5cb9d575e96402245a605cbf03ad7c4db Mon Sep 17 00:00:00 2001 From: Rishith Seelam Date: Wed, 26 Jun 2024 15:43:52 -0400 Subject: [PATCH 30/34] full random seeding - must add test for consistency --- marketsim/agent/spoofer.py | 1 + marketsim/event/event_queue.py | 2 ++ marketsim/private_values/private_values.py | 7 ++++++- marketsim/simulator/sampled_arrival_simulator.py | 6 +++--- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/marketsim/agent/spoofer.py b/marketsim/agent/spoofer.py index a1cf0950..326f291e 100644 --- a/marketsim/agent/spoofer.py +++ b/marketsim/agent/spoofer.py @@ -14,6 +14,7 @@ def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: float, ord random.seed(random_seed) # np.random.seed(random_seed) + self.agent_id = agent_id self.market = market self.pv = PrivateValues(q_max, pv_var, random_seed=random.randint(1,4096)) diff --git a/marketsim/event/event_queue.py b/marketsim/event/event_queue.py index ef1a140d..077c65ba 100644 --- a/marketsim/event/event_queue.py +++ b/marketsim/event/event_queue.py @@ -12,6 +12,8 @@ def __init__(self, random_seed: int = 0): # torch.manual_seed(random_seed) random.seed(random_seed) # np.random.seed(random_seed) + + # self.rand = random.Random(rand_seed) self.scheduled_activities = defaultdict(list) self.current_time = 0 diff --git a/marketsim/private_values/private_values.py b/marketsim/private_values/private_values.py index b287caaa..635200ce 100644 --- a/marketsim/private_values/private_values.py +++ b/marketsim/private_values/private_values.py @@ -14,13 +14,18 @@ class PrivateValues: as well as calculate the cumulative value up to a given position. """ - def __init__(self, q_max: int, val_var=5e6): + def __init__(self, q_max: int, val_var=5e6, random_seed: int = 0): """ Initialize the PrivateValues object. :param q_max: The maximum quantity. :param val_var: The variance of the values (default: 1). """ + if random_seed != 0: + torch.manual_seed(random_seed) + # random.seed(random_seed) + # np.random.seed(random_seed) + self.values = torch.randn(2 * q_max) * torch.sqrt(torch.tensor(val_var)) self.values, _ = self.values.sort(descending=True) diff --git a/marketsim/simulator/sampled_arrival_simulator.py b/marketsim/simulator/sampled_arrival_simulator.py index 2fb73616..d14d2e43 100644 --- a/marketsim/simulator/sampled_arrival_simulator.py +++ b/marketsim/simulator/sampled_arrival_simulator.py @@ -55,8 +55,8 @@ def __init__(self, self.markets = [] for _ in range(num_assets): - fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random.randint(1,4096)) - self.markets.append(Market(fundamental=fundamental, time_steps=sim_time, random_seed=random.randint(1,4096))) + fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random_seed) + self.markets.append(Market(fundamental=fundamental, time_steps=sim_time)) self.agents = {} # TEMP FOR HBL TESTING @@ -72,7 +72,7 @@ def __init__(self, shade=shade, pv_var=pv_var, eta=eta, - random_seed=random.randint(1,4096) + random_seed=random_seed )) # expanded_zi # else: From e8fa6c2d7da13ef45746a3b727040ab9de5c14ff Mon Sep 17 00:00:00 2001 From: Rishith Seelam Date: Mon, 1 Jul 2024 10:20:28 -0400 Subject: [PATCH 31/34] completed random seeding --- marketsim/MM/simMM.py | 6 + marketsim/agent/extented_zi_agent.py | 2 +- marketsim/intro_notebook.ipynb | 305 ++++++++++++++------------- marketsim/test_event_queue.ipynb | 260 ++++++++++++----------- test_sim.ipynb | 218 ++++++++++--------- 5 files changed, 424 insertions(+), 367 deletions(-) diff --git a/marketsim/MM/simMM.py b/marketsim/MM/simMM.py index 04f98bcd..6f5de7c5 100644 --- a/marketsim/MM/simMM.py +++ b/marketsim/MM/simMM.py @@ -39,6 +39,12 @@ def __init__(self, max_position=100 ): + if random_seed != 0: + torch.manual_seed(random_seed) + random.seed(random_seed) + # np.random.seed(random_seed) + + if random_seed != 0: torch.manual_seed(random_seed) random.seed(random_seed) diff --git a/marketsim/agent/extented_zi_agent.py b/marketsim/agent/extented_zi_agent.py index c72a4827..c70dc882 100644 --- a/marketsim/agent/extented_zi_agent.py +++ b/marketsim/agent/extented_zi_agent.py @@ -8,7 +8,7 @@ class ZIAgent(Agent): - def __init__(self, agent_id: int, market: Market, q_max: int, offset: float, eta: float, shade: List, random_seed: int = 0): + def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: int, offset: float, eta: float, shade: List, random_seed: int = 0): if random_seed != 0: # torch.manual_seed(random_seed) diff --git a/marketsim/intro_notebook.ipynb b/marketsim/intro_notebook.ipynb index ba79e69c..b2d6b5cb 100644 --- a/marketsim/intro_notebook.ipynb +++ b/marketsim/intro_notebook.ipynb @@ -5,11 +5,11 @@ "execution_count": 1, "id": "initial_id", "metadata": { - "collapsed": true, "ExecuteTime": { "end_time": "2024-02-15T04:09:48.703057400Z", "start_time": "2024-02-15T04:09:48.664059300Z" - } + }, + "collapsed": true }, "outputs": [], "source": [ @@ -20,6 +20,15 @@ }, { "cell_type": "code", + "execution_count": 2, + "id": "94fd9db23a88d5c5", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:09:49.138070Z", + "start_time": "2024-02-15T04:09:49.136069300Z" + }, + "collapsed": false + }, "outputs": [], "source": [ "# Let's start with order\n", @@ -28,41 +37,43 @@ "order2 = Order(price=32, order_type=SELL, quantity=22, time=1, agent_id=1, order_id=2)\n", "order3 = Order(price=7, order_type=SELL, quantity=7, time=1, agent_id=1, order_id=3)\n", "order4 = Order(price=9, order_type=SELL, quantity=8, time=1, agent_id=1, order_id=4)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:09:49.138070Z", - "start_time": "2024-02-15T04:09:49.136069300Z" - } - }, - "id": "94fd9db23a88d5c5", - "execution_count": 2 + ] }, { "cell_type": "code", - "outputs": [], - "source": [ - "# Now let's see initialize the fourheap\n", - "\n", - "fh = FourHeap() " - ], + "execution_count": 3, + "id": "cc7b3ae1ebf76ee1", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2024-02-15T04:09:49.335085500Z", "start_time": "2024-02-15T04:09:49.333084400Z" - } + }, + "collapsed": false }, - "id": "cc7b3ae1ebf76ee1", - "execution_count": 3 + "outputs": [], + "source": [ + "# Now let's see initialize the fourheap\n", + "\n", + "fh = FourHeap() " + ] }, { "cell_type": "code", + "execution_count": 4, + "id": "361113b24009b04e", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:09:49.582092300Z", + "start_time": "2024-02-15T04:09:49.577092900Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "{1: Order(price=12, order_type=1, quantity=12, agent_id=1, time=1, order_id=1, asset_id=1)}" + "text/plain": [ + "{1: Order(price=12, order_type=1, quantity=12, agent_id=1, time=1, order_id=1, asset_id=1)}" + ] }, "execution_count": 4, "metadata": {}, @@ -74,23 +85,25 @@ "\n", "fh.insert(order1)\n", "fh.buy_unmatched.order_dict" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:09:49.582092300Z", - "start_time": "2024-02-15T04:09:49.577092900Z" - } - }, - "id": "361113b24009b04e", - "execution_count": 4 + ] }, { "cell_type": "code", + "execution_count": 5, + "id": "ebe4a5b482eb8d70", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:09:49.844940900Z", + "start_time": "2024-02-15T04:09:49.791936400Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "{2: Order(price=32, order_type=-1, quantity=22, agent_id=1, time=1, order_id=2, asset_id=1)}" + "text/plain": [ + "{2: Order(price=32, order_type=-1, quantity=22, agent_id=1, time=1, order_id=2, asset_id=1)}" + ] }, "execution_count": 5, "metadata": {}, @@ -105,19 +118,19 @@ "# Because it's price is higher than the buy price this won't cause a match\n", "\n", "fh.sell_unmatched.order_dict" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:09:49.844940900Z", - "start_time": "2024-02-15T04:09:49.791936400Z" - } - }, - "id": "ebe4a5b482eb8d70", - "execution_count": 5 + ] }, { "cell_type": "code", + "execution_count": 6, + "id": "5b93a62e48ad867e", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:09:50.031942Z", + "start_time": "2024-02-15T04:09:49.985942100Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -141,19 +154,19 @@ "# Since order 1 is larger some will be matched and some will be unmatched\n", "print(fh.buy_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:09:50.031942Z", - "start_time": "2024-02-15T04:09:49.985942100Z" - } - }, - "id": "5b93a62e48ad867e", - "execution_count": 6 + ] }, { "cell_type": "code", + "execution_count": 7, + "id": "ae2bfd9555f5e434", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:09:50.303405Z", + "start_time": "2024-02-15T04:09:50.253396300Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -175,19 +188,19 @@ "print(fh.sell_matched.order_dict)\n", "print(fh.buy_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:09:50.303405Z", - "start_time": "2024-02-15T04:09:50.253396300Z" - } - }, - "id": "ae2bfd9555f5e434", - "execution_count": 7 + ] }, { "cell_type": "code", + "execution_count": 8, + "id": "3ea852481fc4c008", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:09:50.524404700Z", + "start_time": "2024-02-15T04:09:50.482405500Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -208,19 +221,19 @@ "print(fh.sell_matched.order_dict)\n", "print(fh.sell_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:09:50.524404700Z", - "start_time": "2024-02-15T04:09:50.482405500Z" - } - }, - "id": "3ea852481fc4c008", - "execution_count": 8 + ] }, { "cell_type": "code", + "execution_count": 9, + "id": "a13c3435bf208848", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:09:50.906926200Z", + "start_time": "2024-02-15T04:09:50.864927100Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -242,19 +255,19 @@ "print(fh.sell_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n", "print(fh.buy_unmatched.order_dict)\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:09:50.906926200Z", - "start_time": "2024-02-15T04:09:50.864927100Z" - } - }, - "id": "a13c3435bf208848", - "execution_count": 9 + ] }, { "cell_type": "code", + "execution_count": 11, + "id": "bcd1634ff00877e8", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:11:22.295305500Z", + "start_time": "2024-02-15T04:11:22.248306800Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -285,19 +298,19 @@ "print(fh.sell_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n", "print(fh.buy_unmatched.order_dict)\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:11:22.295305500Z", - "start_time": "2024-02-15T04:11:22.248306800Z" - } - }, - "id": "bcd1634ff00877e8", - "execution_count": 11 + ] }, { "cell_type": "code", + "execution_count": 12, + "id": "fe3c9bd1cdefe8d8", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:11:56.266000300Z", + "start_time": "2024-02-15T04:11:56.220995Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -317,19 +330,19 @@ "print(fh.sell_unmatched.order_dict)\n", "print(fh.buy_matched.order_dict)\n", "print(fh.buy_unmatched.order_dict)\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:11:56.266000300Z", - "start_time": "2024-02-15T04:11:56.220995Z" - } - }, - "id": "fe3c9bd1cdefe8d8", - "execution_count": 12 + ] }, { "cell_type": "code", + "execution_count": 7, + "id": "d49d7335bdfc4f4d", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:35:44.877998600Z", + "start_time": "2024-02-15T04:35:44.870998500Z" + }, + "collapsed": false + }, "outputs": [], "source": [ "from fundamental.lazy_mean_reverting import LazyGaussianMeanReverting\n", @@ -337,23 +350,25 @@ "# Let's look at the fundamental next\n", "\n", "f = LazyGaussianMeanReverting(final_time=100, mean=12, r=.2, shock_var=.01)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:35:44.877998600Z", - "start_time": "2024-02-15T04:35:44.870998500Z" - } - }, - "id": "d49d7335bdfc4f4d", - "execution_count": 7 + ] }, { "cell_type": "code", + "execution_count": 8, + "id": "cc2bd7a5d3a7ad3f", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:35:46.433997800Z", + "start_time": "2024-02-15T04:35:46.430998500Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "{0: 12}" + "text/plain": [ + "{0: 12}" + ] }, "execution_count": 8, "metadata": {}, @@ -364,19 +379,19 @@ "# The fundamental starts at the mean\n", "\n", "f.fundamental_values" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:35:46.433997800Z", - "start_time": "2024-02-15T04:35:46.430998500Z" - } - }, - "id": "cc2bd7a5d3a7ad3f", - "execution_count": 8 + ] }, { "cell_type": "code", + "execution_count": 9, + "id": "b902e6769c663d52", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:35:46.900183400Z", + "start_time": "2024-02-15T04:35:46.897184600Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -392,19 +407,19 @@ "f.get_value_at(12)\n", "\n", "print(f.fundamental_values)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:35:46.900183400Z", - "start_time": "2024-02-15T04:35:46.897184600Z" - } - }, - "id": "b902e6769c663d52", - "execution_count": 9 + ] }, { "cell_type": "code", + "execution_count": 10, + "id": "6bdef9c2a15fd033", + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-15T04:35:47.745318600Z", + "start_time": "2024-02-15T04:35:47.742319600Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -420,25 +435,17 @@ "f.get_final_fundamental()\n", "\n", "print(f.fundamental_values)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-02-15T04:35:47.745318600Z", - "start_time": "2024-02-15T04:35:47.742319600Z" - } - }, - "id": "6bdef9c2a15fd033", - "execution_count": 10 + ] }, { "cell_type": "code", - "outputs": [], - "source": [], + "execution_count": null, + "id": "ba5a64455c821680", "metadata": { "collapsed": false }, - "id": "ba5a64455c821680" + "outputs": [], + "source": [] } ], "metadata": { @@ -457,7 +464,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.6" + "version": "3.9.12" } }, "nbformat": 4, diff --git a/marketsim/test_event_queue.ipynb b/marketsim/test_event_queue.ipynb index 4e514273..e18e461d 100644 --- a/marketsim/test_event_queue.ipynb +++ b/marketsim/test_event_queue.ipynb @@ -5,11 +5,11 @@ "execution_count": 1, "id": "initial_id", "metadata": { - "collapsed": true, "ExecuteTime": { "end_time": "2023-11-02T02:00:54.071626Z", "start_time": "2023-11-02T02:00:52.890317Z" - } + }, + "collapsed": true }, "outputs": [], "source": [ @@ -23,62 +23,72 @@ { "cell_type": "code", "execution_count": 2, - "outputs": [], - "source": [ - "e = EventQueue()" - ], + "id": "adf6ffdda3d8a689", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:00:55.364165Z", "start_time": "2023-11-02T02:00:55.357739Z" - } + }, + "collapsed": false }, - "id": "adf6ffdda3d8a689" + "outputs": [], + "source": [ + "e = EventQueue()" + ] }, { "cell_type": "code", "execution_count": 3, - "outputs": [], - "source": [ - "order1 = Order(price=1, quantity=1, time=1, agent_id=1, order_id=1, order_type=BUY)\n", - "order2 = Order(price=1, quantity=1, time=1, agent_id=1, order_id=2, order_type=BUY)\n", - "order3 = Order(price=1, quantity=1, time=3, agent_id=1, order_id=3, order_type=SELL)\n" - ], + "id": "acd56cd67811e74d", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:00:55.631574Z", "start_time": "2023-11-02T02:00:55.627375Z" - } + }, + "collapsed": false }, - "id": "acd56cd67811e74d" + "outputs": [], + "source": [ + "order1 = Order(price=1, quantity=1, time=1, agent_id=1, order_id=1, order_type=BUY)\n", + "order2 = Order(price=1, quantity=1, time=1, agent_id=1, order_id=2, order_type=BUY)\n", + "order3 = Order(price=1, quantity=1, time=3, agent_id=1, order_id=3, order_type=SELL)\n" + ] }, { "cell_type": "code", "execution_count": 4, - "outputs": [], - "source": [ - "e.schedule_activity(order1)\n", - "e.schedule_activity(order2)\n", - "e.schedule_activity(order3)\n" - ], + "id": "e81b92116b7c7b9d", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:00:55.846956Z", "start_time": "2023-11-02T02:00:55.845125Z" - } + }, + "collapsed": false }, - "id": "e81b92116b7c7b9d" + "outputs": [], + "source": [ + "e.schedule_activity(order1)\n", + "e.schedule_activity(order2)\n", + "e.schedule_activity(order3)\n" + ] }, { "cell_type": "code", "execution_count": 5, + "id": "2b15b5866d781227", + "metadata": { + "ExecuteTime": { + "end_time": "2023-11-02T02:00:56.086065Z", + "start_time": "2023-11-02T02:00:56.051275Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "[]" + "text/plain": [ + "[]" + ] }, "execution_count": 5, "metadata": {}, @@ -87,23 +97,26 @@ ], "source": [ "e.step()" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2023-11-02T02:00:56.086065Z", - "start_time": "2023-11-02T02:00:56.051275Z" - } - }, - "id": "2b15b5866d781227" + ] }, { "cell_type": "code", "execution_count": 6, + "id": "eba7945d5a7f5263", + "metadata": { + "ExecuteTime": { + "end_time": "2023-11-02T02:00:56.227455Z", + "start_time": "2023-11-02T02:00:56.224831Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "[Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=1, asset_id=1),\n Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=2, asset_id=1)]" + "text/plain": [ + "[Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=1, asset_id=1),\n", + " Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=2, asset_id=1)]" + ] }, "execution_count": 6, "metadata": {}, @@ -112,23 +125,25 @@ ], "source": [ "e.step()" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2023-11-02T02:00:56.227455Z", - "start_time": "2023-11-02T02:00:56.224831Z" - } - }, - "id": "eba7945d5a7f5263" + ] }, { "cell_type": "code", "execution_count": 7, + "id": "8ac0f93a500647fb", + "metadata": { + "ExecuteTime": { + "end_time": "2023-11-02T02:00:56.439237Z", + "start_time": "2023-11-02T02:00:56.434962Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "[]" + "text/plain": [ + "[]" + ] }, "execution_count": 7, "metadata": {}, @@ -137,55 +152,57 @@ ], "source": [ "e.step()" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2023-11-02T02:00:56.439237Z", - "start_time": "2023-11-02T02:00:56.434962Z" - } - }, - "id": "8ac0f93a500647fb" + ] }, { "cell_type": "code", "execution_count": 8, - "outputs": [], - "source": [ - "f = GaussianMeanReverting(mean=100, r=0.2, final_time=100, shock_var=10)" - ], + "id": "88cbe58aba097195", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:00:56.645679Z", "start_time": "2023-11-02T02:00:56.640489Z" - } + }, + "collapsed": false }, - "id": "88cbe58aba097195" + "outputs": [], + "source": [ + "f = GaussianMeanReverting(mean=100, r=0.2, final_time=100, shock_var=10)" + ] }, { "cell_type": "code", "execution_count": 9, - "outputs": [], - "source": [ - "m = Market(f)" - ], + "id": "b19ca32418bbd288", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:00:57.178505Z", "start_time": "2023-11-02T02:00:57.176993Z" - } + }, + "collapsed": false }, - "id": "b19ca32418bbd288" + "outputs": [], + "source": [ + "m = Market(f)" + ] }, { "cell_type": "code", "execution_count": 10, + "id": "910dcd209c37965", + "metadata": { + "ExecuteTime": { + "end_time": "2023-11-02T02:00:57.896940Z", + "start_time": "2023-11-02T02:00:57.883064Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "100.0" + "text/plain": [ + "100.0" + ] }, "execution_count": 10, "metadata": {}, @@ -194,57 +211,64 @@ ], "source": [ "m.get_fundamental_value()" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2023-11-02T02:00:57.896940Z", - "start_time": "2023-11-02T02:00:57.883064Z" - } - }, - "id": "910dcd209c37965" + ] }, { "cell_type": "code", "execution_count": 13, - "outputs": [], - "source": [ - "m.add_order(order1)\n", - "m.add_order(order2)\n", - "m.add_order(order3)\n" - ], + "id": "fecf8d0b5d2b0d76", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:01:34.513870Z", "start_time": "2023-11-02T02:01:34.507170Z" - } + }, + "collapsed": false }, - "id": "fecf8d0b5d2b0d76" + "outputs": [], + "source": [ + "m.add_order(order1)\n", + "m.add_order(order2)\n", + "m.add_order(order3)\n" + ] }, { "cell_type": "code", "execution_count": 24, - "outputs": [], - "source": [ - "m.step()" - ], + "id": "5592a8bef91a39dd", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-02T02:02:15.127481Z", "start_time": "2023-11-02T02:02:15.119847Z" - } + }, + "collapsed": false }, - "id": "5592a8bef91a39dd" + "outputs": [], + "source": [ + "m.step()" + ] }, { "cell_type": "code", "execution_count": 25, + "id": "3ec35fc46b4dfdaf", + "metadata": { + "ExecuteTime": { + "end_time": "2023-11-02T02:02:15.439666Z", + "start_time": "2023-11-02T02:02:15.435653Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "defaultdict(list,\n {1: [Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=1, asset_id=1),\n Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=2, asset_id=1)],\n 3: [Order(price=1, order_type=-1, quantity=1, agent_id=1, time=3, order_id=3, asset_id=1)],\n 0: [],\n 2: []})" + "text/plain": [ + "defaultdict(list,\n", + " {1: [Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=1, asset_id=1),\n", + " Order(price=1, order_type=1, quantity=1, agent_id=1, time=1, order_id=2, asset_id=1)],\n", + " 3: [Order(price=1, order_type=-1, quantity=1, agent_id=1, time=3, order_id=3, asset_id=1)],\n", + " 0: [],\n", + " 2: []})" + ] }, "execution_count": 25, "metadata": {}, @@ -253,23 +277,25 @@ ], "source": [ "m.event_queue.scheduled_activities" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2023-11-02T02:02:15.439666Z", - "start_time": "2023-11-02T02:02:15.435653Z" - } - }, - "id": "3ec35fc46b4dfdaf" + ] }, { "cell_type": "code", "execution_count": 26, + "id": "f226ab58891b1b9f", + "metadata": { + "ExecuteTime": { + "end_time": "2023-11-02T02:02:16.395887Z", + "start_time": "2023-11-02T02:02:16.353163Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": "4" + "text/plain": [ + "4" + ] }, "execution_count": 26, "metadata": {}, @@ -278,25 +304,17 @@ ], "source": [ "m.get_time()" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2023-11-02T02:02:16.395887Z", - "start_time": "2023-11-02T02:02:16.353163Z" - } - }, - "id": "f226ab58891b1b9f" + ] }, { "cell_type": "code", "execution_count": null, - "outputs": [], - "source": [], + "id": "2747f8bda9e21ed1", "metadata": { "collapsed": false }, - "id": "2747f8bda9e21ed1" + "outputs": [], + "source": [] } ], "metadata": { @@ -315,7 +333,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.6" + "version": "3.9.12" } }, "nbformat": 4, diff --git a/test_sim.ipynb b/test_sim.ipynb index 7aa739d6..2c073b3c 100644 --- a/test_sim.ipynb +++ b/test_sim.ipynb @@ -2,16 +2,29 @@ "cells": [ { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "initial_id", "metadata": { - "collapsed": true, "ExecuteTime": { "end_time": "2024-03-27T23:39:39.806325Z", "start_time": "2024-03-27T23:39:37.947319Z" - } + }, + "collapsed": true }, - "outputs": [], + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'fourheap'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mmarketsim\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01msimulator\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01msampled_arrival_simulator\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m SimulatorSampledArrival\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mtqdm\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mnotebook\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m tqdm\n", + "File \u001b[0;32m~/Code/SURE-SRG/market-sim-py/marketsim/simulator/sampled_arrival_simulator.py:2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mrandom\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfourheap\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mconstants\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m BUY, SELL\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mmarket\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mmarket\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Market\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mfundamental\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mlazy_mean_reverting\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m LazyGaussianMeanReverting\n", + "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'fourheap'" + ] + } + ], "source": [ "from marketsim.simulator.sampled_arrival_simulator import SimulatorSampledArrival\n", "from tqdm.notebook import tqdm" @@ -20,34 +33,44 @@ { "cell_type": "code", "execution_count": 3, + "id": "72ae6676eeab193e", + "metadata": { + "ExecuteTime": { + "end_time": "2024-03-25T08:07:38.106565700Z", + "start_time": "2024-03-25T08:07:38.103557300Z" + }, + "collapsed": false + }, "outputs": [], "source": [ "# %%timeit\n", "# \n", "# sim = Simulator(num_agents=66, sim_time=60000, lam=1e-4, mean=1e7, r=.05, shock_var=1e6)\n", "# sim.run()" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-25T08:07:38.106565700Z", - "start_time": "2024-03-25T08:07:38.103557300Z" - } - }, - "id": "72ae6676eeab193e" + ] }, { "cell_type": "code", "execution_count": 21, + "id": "a68010fcb5fc866b", + "metadata": { + "ExecuteTime": { + "end_time": "2024-03-25T08:38:17.892762800Z", + "start_time": "2024-03-25T08:35:52.049473800Z" + }, + "collapsed": false + }, "outputs": [ { "data": { - "text/plain": " 0%| | 0/10000 [00:00", - "image/png": "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GxsLX19fAICvry/S0tJw7NgxqWbPnj3Izc2Fj4+PVHPgwAFkZ2dLNVFRUahdu7beFX9ERET06iozAWrEiBH4559/MH36dFy8eBFr167F8uXLERYWBgBQKBQIDw/HtGnTsHXrVpw5cwZ9+/aFq6srQkJCADzZYxUUFIRBgwbh8OHDOHjwIIYNG4bu3bvD1dUVANCzZ09YWFggNDQUZ8+exfr16zF//nyMHDnSWEMnIiKi0kaUIdu2bRNeXl5CqVSKOnXqiOXLl+stz83NFRMnThROTk5CqVSKNm3aiISEBL2aO3fuiB49eoiKFSsKGxsbMWDAAJGRkaFXc+rUKdGsWTOhVCrFa6+9Jr766itZ/dRqtQKA0Gq1LzZQIiIiKnFyvr/LzDxQZQnngSIiIip7yuU8UERERESlBQMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERyWRm7A4QERGVlJxcgcOJqUjJyISjtQpNPOxhaqIwdreoDGKAIiKiV0JkXBKmbDuHJG2m1OaiViGigyeCvFyM2DMqi3gIj4iIyr3IuCQM/fm4XngCAI02E0N/Po7IuCQj9YzKKgYoIiIq13JyBaZsOwdhYJmubcq2c8jJNVRBZBgDFBERlWuHE1Pz7Hl6mgCQpM3E4cTUkusUlXkMUEREVK6lZOQfnl6kjghggCIionLO0VpVpHVEAAMUERGVc0087OGiViG/yQoUeHI1XhMP+5LsFpVxDFBERFSumZooENHBEwDyhCjd/YgOnpwPimRhgCIionIvyMsFS3p7w1mtf5jOWa3Ckt7enAeKZCuzAeqrr76CQqFAeHi41JaZmYmwsDBUqlQJFStWRKdOnZCcnKy33rVr1xAcHIwKFSrA0dERY8aMwePHj/Vq9u3bB29vbyiVStSsWRMrV64sgREREVFxCvJywd9j38Evg97G/O4N8cugt/H32HcYnuiFlMkAdeTIESxbtgxv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e8LCwgKhoaE4e/Ys1q9fj/nz52PkyJFSzfDhwxEZGYm5c+ciPj4ekydPxtGjRzFs2DAAgEKhQHh4OKZNm4atW7fizJkz6Nu3L1xdXRESElLSwyYiIqJSyqh7oAorKioKFy9exMWLF1GlShW9ZbpZGNRqNf7880+EhYWhUaNGqFy5MiZNmoTBgwdLtX5+fli7di2++OILfP7556hVqxa2bNkCLy8vqeazzz7D/fv3MXjwYKSlpaFZs2aIjIyESqUqmcESERFRqVdm54EqzTgPFBERUdnzSswDRURERGQsDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQylYl5oIjKg5xcgcOJqUjJyISjtQpNPOxhaqIwdreIiOgFMEARlYDIuCRM3noWmvQsqc3ZRonJ79VDkJdLAWsSEVFpxEN4RMUsMi4JQ34+rheeAECTnoUhPx9HZFySkXpGREQvigGKqBjl5AqM23SmwJpxm84gJ5c/CEBEVJYwQBEVo38u3UHag+wCa9IeZOOfS3dKqEdERFQUGKCIitHBS7eLtI6IiEoHBiiiYnQ99WGR1hERUenAAEVUjBL/u1ekdUREVDowQBEVq8LO88T5oIiIyhIGKKJi1MBNXaR1RERUOjBAERWj8W09i7SOiIhKBwYoomJ05qa2SOuIiKh0YIAiKkYpGZlFWkdERKUDAxRRMXK0VhVpHRERlQ4MUETFqImHPVzUqnyvsVMAcFGr0MTDviS7RUREL4kBiqgYmZooENHhyQniz4Yo3f2IDp4wNeE0BkREZQkDFFExC/JywZLe3nBW6x+mc1arsKS3N4K8XIzUMyIielFmxu4A0asgyMsF73o643BiKlIyMuFo/eSwHfc8ERGVTQxQRCXE1EQB3xqVjN0NIiIqAjyER0RERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCRTmQtQWVlZaNiwIRQKBU6ePKm37PTp02jevDlUKhXc3Nwwa9asPOtv2LABderUgUqlQv369bFz50695UIITJo0CS4uLrC0tIS/vz8uXLhQnEMiIiKiMqbMBajPPvsMrq6uedrT09MREBAAd3d3HDt2DLNnz8bkyZOx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8uRJXLhwAQ8fPsSqVaugUCieu96HH36Iy5cvo0+fPjhz5gwaN26MBQsWFHt/zc3N9e4rFArk5uYW++MS0cthgCKicsXKygo1a9ZE1apVYWb25CyFunXr4vHjx4iNjZXq7ty5g4SEBHh6ekptbm5uGDJkCDZt2oRRo0bhu+++M/gYFhYWyMnJKbAfdevWxfXr13H9+nWp7dy5c0hLS9N7TCIqmxigiKjcq1WrFjp27IhBgwbh77//xqlTp9C7d2+89tpr6NixIwAgPDwcu3btQmJiIo4fP469e/eibt26BrdXrVo13Lt3D9HR0fjvv//w4MGDPDX+/v6oX78+evXqhePHj+Pw4cPo27cvWrZsicaNGxfreImo+DFAEdErYcWKFWjUqBHat28PX19fCCGwc+dO6RBaTk4OwsLCULduXQQFBeH111/H4sWLDW7Lz88PQ4YMQbdu3eDg4IBZs2blqVEoFPj9999hZ2eHFi1awN/fH9WrV8f69euLdZxEVDIUQghh7E4QERERlSXcA0VEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcn0/wARYlezvwXQIQAAAABJRU5ErkJggg==" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlAAAAHHCAYAAABwaWYjAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABj1klEQVR4nO3deVxU1f8/8NewzSDCAMqaiLikIqahSeCeBCialPu+kKZhiVtqpqgf01zL3G1RM00zl9zCELdSwn1BhVxwZ8BEBlxAhPP7w9/cryMDchUYwNfz8ZhHzbnve+ecWZwXdzmjEEIIEBEREVGhmRi7A0RERERlDQMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFJU7/fv3R7Vq1QpVO3nyZCgUiuLtUDlRrVo19O/f39jdKFJHjhyBn58frKysoFAocPLkyRJ9fDnv1VfBvn37oFAosG/fPmN3hei5GKBKocWLF0OhUMDHx8fYXTFo8eLFWLlyZaHrFQqFdDMxMYGrqysCAgJK7B/JBw8eYPLkya/MP8rz5s2DQqHA7t2786357rvvoFAosHXr1hLsWfG6desWJk+eXOgQlJ2djS5duiA1NRVff/01Vq9eDXd39+LtZDk3ffp0bNmypdgf5969e4iIiEBQUBDs7e2hUCgK/Dfp/PnzCAoKQsWKFWFvb48+ffrg9u3bejW3bt1C7969Ubt2bVhbW8PW1hZNmjTBqlWr8OwvniUkJGDEiBHw8/ODSqWCQqHAlStXDD52ZmYmZsyYAU9PT1SoUAGvvfYaunTpgrNnz+rVRUdHY+DAgXj99ddRoUIFVK9eHR9++CGSkpIK9Zxs3rwZgYGBcHV1hVKpRJUqVdC5c2fExcXlqR0xYgS8vb1hb2+PChUqoG7dupg8eTLu3bunV6cLtIZu//zzj15tdnY2pkyZgurVq0OpVKJ69eqYNm0aHj9+rFd39uxZdOnSBdWrV0eFChVQuXJltGjRAtu2bcvTz/weW6FQ4N1335Xqrly5km/dunXrCvX8vQizYtsyvbA1a9agWrVqOHz4MC5evIiaNWsau0t6Fi9ejMqVK8vaG/Huu++ib9++EEIgMTERixcvxjvvvIMdO3agbdu2Rdq/7777Drm5udL9Bw8eYMqUKQCAVq1a6dV+8cUXGDduXJE+vrF1794dY8aMwdq1a+Hv72+wZu3atahUqVKRP/fGdOvWLUyZMgXVqlVDw4YNn1t/6dIlXL16Fd999x0+/PDD4u/gK2D69Ono3LkzQkJCivVx/vvvP0ydOhVVq1ZFgwYNCvzj6MaNG2jRogXUajWmT5+Oe/fuYc6cOThz5gwOHz4MCwsLaZs3btxA586dUbVqVWRnZyMqKgr9+/dHQkICpk+fLm0zJiYG3377LTw9PVG3bt0CQ3uvXr2wdetWDBo0CN7e3rh16xYWLVoEX19fnDlzRgrtY8eORWpqKrp06YJatWrh8uXLWLhwIbZv346TJ0/C2dm5wOfkzJkzsLOzw/Dhw1G5cmVoNBr8+OOPaNKkCWJiYtCgQQOp9siRI2jevDkGDBgAlUqFEydO4KuvvsLu3btx4MABmJjo71v59NNP8dZbb+m1Pfu91Lt3b2zYsAEDBw5E48aN8c8//2DixIm4du0ali9fLtVdvXoVGRkZ6NevH1xdXfHgwQNs3LgR7733HpYtW4bBgwdLtatXr84zzqNHj2L+/PkICAjIs6xHjx5o166dXpuvr2+Bz9tLEVSqXL58WQAQmzZtEg4ODmLy5MnG7lIe9erVEy1btix0PQARFham13b69GkBQAQEBBRx7/K6ffu2ACAiIiKK/bFKizZt2gi1Wi0yMzPzLLtx44YwMTERQ4YMkbVNd3d30a9fvyLqYdE7cuSIACBWrFhRqPr9+/cLAGLDhg3F27EC9OvXT7i7uxvt8YualZXVS71H9u7dKwCIvXv3FliXmZkpkpKShBDPf92HDh0qLC0txdWrV6W2qKgoAUAsW7bsuX1q3769sLKyEo8fP5ba7ty5I9LT04UQQsyePVsAEImJiXnWvXHjhgAgRo8erde+Z88eAUDMmzdPatu/f7/IycnRq9O9RydMmPDcfhqi0WiEmZmZ+Oijj55bO2fOHAFAxMTESG261+N5n5HDhw8LAGLixIl67aNGjRIKhUKcOnWqwPUfP34sGjRoIGrXrv3cfoaGhgqFQiGuX78utSUmJgoAYvbs2c9dvyjxEF4ps2bNGtjZ2SE4OBidO3fGmjVrDNbduXMHffr0gY2NDWxtbdGvXz+cOnXK4K7s+Ph4dO7cGfb29lCpVGjcuHGeQzcrV66EQqHAwYMHMXLkSDg4OMDKygrvv/++3q7uatWq4ezZs9i/f7+0i/TZvTqFUb9+fVSuXBmJiYlS2549e9C8eXNYWVnB1tYWHTt2xPnz5/XWy8jIQHh4OKpVqwalUglHR0e8++67OH78uFTz9HklV65cgYODAwBgypQpUp8nT54MwPA5UI8fP8b//vc/1KhRA0qlEtWqVcPnn3+OrKwsvbpq1aqhffv2+Pvvv9GkSROoVCpUr14dP/30U4Fjz87Ohr29PQYMGJBnWXp6OlQqFUaPHi21LViwAPXq1UOFChVgZ2eHxo0bY+3atQU+Ru/evaHVarFjx448y9atW4fc3Fz06tULADBnzhz4+fmhUqVKsLS0RKNGjfDbb78VuH0g//PHdO+lZw9p/PHHH9Lra21tjeDg4DyHMQxJTU3F6NGjUb9+fVSsWBE2NjZo27YtTp06JdXs27dP+gt5wIAB0uuc32Gd/v37o2XLlgCALl266L2PW7VqZfA9/ez5SrrDBnPmzMHy5cul98tbb72FI0eO5Fl/y5Yt8PLygkqlgpeXFzZv3mywb4V9PRQKBYYNG4YNGzbA09MTlpaW0l4NAFi2bBlq1qwJlUqFVq1aGTzEFBsbi6CgIKjValSoUAEtW7bEwYMH9Wp0r/PFixfRv39/2NraQq1WY8CAAXjw4IFef+7fv49Vq1ZJz79uL/XVq1fx8ccfo3bt2rC0tESlSpXQpUuXfA97PY9SqXzuHhmdjRs3on379qhatarU5u/vj9dffx2//vrrc9evVq0aHjx4gEePHklt9vb2sLa2fu66GRkZAAAnJye9dhcXFwCApaWl1NaiRYs8e35atGgBe3v7PP8OFpajoyMqVKiAtLS059bq3tv51WZkZOQ5HKfz119/AXiy9/tp3bt3hxAC69evL/CxTU1N4ebm9tx+ZmVlYePGjWjZsiWqVKlisOb+/ft6r1WxKtG4Rs9Vp04dERoaKoQQ4sCBAwKAOHz4sF5NTk6O8PX1FaampmLYsGFi4cKF4t133xUNGjTI85dYXFycUKvVwtPTU8ycOVMsXLhQtGjRQigUCrFp0yapbsWKFQKAePPNN8U777wjFixYIEaNGiVMTU1F165dpbrNmzeLKlWqiDp16ojVq1eL1atXiz///LPAMcHAHqjU1FRhamoq3n77bSHEk78IzczMxOuvvy5mzZolpkyZIipXrizs7Oz0/rLr2bOnsLCwECNHjhTff/+9mDlzpujQoYP4+eefpZqn/6q/d++eWLJkiQAg3n//fanPur+IIiIixLMfg379+gkAonPnzmLRokWib9++AoAICQnRq3N3dxe1a9cWTk5O4vPPPxcLFy4U3t7eQqFQiLi4uAKfk4EDBwpbW1uRlZWl175q1SoBQBw5ckQIIcTy5culvixbtkzMnz9fhIaGik8//bTA7Wu1WqFSqUSnTp3yLPP29hbu7u4iNzdXCCFElSpVxMcffywWLlwo5s2bJ5o0aSIAiO3bt+cZ79N7Fww9d0L833vp6dftp59+EgqFQgQFBYkFCxaImTNnimrVqglbW1uDf7k/7ciRI6JGjRpi3LhxYtmyZWLq1KnitddeE2q1Wty8eVMI8eQv7alTpwoAYvDgwdLrfOnSJYPbPHTokPj8888FAPHpp5/qvY9btmxpcA/rs3uLdH/1vvnmm6JmzZpi5syZYtasWaJy5cqiSpUq4tGjR1Ltrl27hImJifDy8hLz5s0TEyZMEGq1WtSrVy/PHqjCvh4AxBtvvCHc3NzEV199Jb766iuhVqtF1apVxcKFC4Wnp6eYO3eu+OKLL4SFhYVo3bq13vrR0dHCwsJC+Pr6irlz54qvv/5avPHGG8LCwkLExsZKdbrX+c033xQffPCBWLx4sfjwww8FAPHZZ59JdatXrxZKpVI0b95cev4PHTokhBBiw4YNokGDBmLSpEli+fLl4vPPPxd2dnbC3d1d3L9/X9pGYfdAPa2gPVC6PUAzZ87Ms6x3797C3t4+T/uDBw/E7du3RWJioli5cqWwsrISfn5++T5+QXugHj16JKpUqSKcnZ3F1q1bxfXr10VsbKxo2bKl8PDwEHfv3i1wbBkZGcLCwkIMHjy4wLqn3b17V6SkpIjTp0+LgQMHCgBi+fLleeqys7PF7du3xc2bN8WuXbtEnTp1hLW1tbhz545Uo3s9KlasKAAIU1NT0apVK+nfJ53p06cLAOLy5ct67WfPnhUARGBgYJ7Hv3fvnrh9+7a4ePGimDdvnjA1NRU9e/YscGybNm0SAMR3332n1677LOr6qVAoROPGjcWuXbue+3y9DAaoUuTo0aMCgIiKihJCCJGbmyuqVKkihg8frle3ceNGAUB88803UltOTo5455138vxD0qZNG1G/fn29Qzm5ubnCz89P1KpVS2rTfen5+/tLX6xCCDFixAhhamoq0tLSpLYXOYQXGhoqbt++LVJSUkRsbKxo06aNACDmzp0rhBCiYcOGwtHRUe/De+rUKWFiYiL69u0rtanV6jxh7FnPftEVdAjv2RBw8uRJAUB8+OGHenWjR48WAMSePXukNnd3dwFAHDhwQGpLSUkRSqVSjBo1qsA+7tq1SwAQ27Zt02tv166dqF69unS/Y8eOol69egVuKz9dunQRKpVKaLVaqS0+Pl4AEOPHj5faHjx4oLfeo0ePhJeXl3jnnXf02l80QGVkZAhbW1sxaNAgvTqNRiPUanWe9mdlZmbmObSRmJgolEqlmDp1qtQm9xBefocn5AaoSpUqidTUVKn9999/z/PaNmzYULi4uOh9jv78808BIE+AKuzrAUAolUq9L+5ly5YJAMLZ2Vk6xCSEEOPHj9d7TXJzc0WtWrVEYGCg3uf9wYMHwsPDQ7z77rtSm+51HjhwoN7jv//++6JSpUp6bfkdwnt2TEIIERMTIwCIn376SWor6gClW/b0Y+iMGTNGAMhzmHvGjBkCgHRr06aNuHbtWr6PX1CAEkKI2NhYUaNGDb1tNmrUSDoEWZD//e9/AoCIjo5+bq1O7dq1pcepWLGi+OKLL/J8foT4v+dfd6tdu3ae5/3gwYOiU6dO4ocffhC///67mDFjhqhUqZJQqVTi+PHjUp3uO2n16tV66y9dulQAEF5eXnke/6OPPpIe28TERHTu3Fnvc2RIp06dhFKpzBM8r169KgICAsSSJUvE1q1bxTfffCOqVq0qTExM8vzhUZR4CK8UWbNmDZycnNC6dWsAT3aJd+vWDevWrUNOTo5UFxkZCXNzcwwaNEhqMzExQVhYmN72UlNTsWfPHnTt2hUZGRn477//8N9//+HOnTsIDAzEhQsXcPPmTb11Bg8erHdYpnnz5sjJycHVq1dfamw//PADHBwc4OjoCB8fH+lQYXh4OJKSknDy5En0798f9vb20jpvvPEG3n33XezcuVNqs7W1RWxsLG7duvVS/cmP7rFGjhyp1z5q1CgAyHNIzNPTE82bN5fuOzg4oHbt2rh8+XKBj/POO++gcuXKeru27969i6ioKHTr1k1qs7W1xY0bNwweEnqe3r17IzMzE5s2bZLadIf+dIfvAP3DCHfv3oVWq0Xz5s31Dou+jKioKKSlpaFHjx7Se/C///6DqakpfHx8sHfv3gLXVyqV0qGNnJwc3LlzBxUrVkTt2rWLrI8vo1u3brCzs5Pu694PuveA7v3dr18/qNVqqe7dd9+Fp6dnnu3JeT3atGmjd1hRd+Vup06d9A4x6dp1fTp58iQuXLiAnj174s6dO9Jrcv/+fbRp0wYHDhzQuxADAIYMGaJ3v3nz5rhz5w7S09MLeHbyjik7Oxt37txBzZo1YWtrW6yv4cOHDwE8eQ89S6VS6dXo9OjRA1FRUVi7di169uxpsEYOOzs7NGzYEOPGjcOWLVswZ84cXLlyBV26dEFmZma+6x04cABTpkxB165d8c477xT68VasWIHIyEgsXrwYdevWxcOHD/W+P3Q8PT0RFRWFLVu24LPPPoOVlVWeq/D8/Pzw22+/YeDAgXjvvfcwbtw4/PPPP1AoFBg/frxU165dO7i7u2P06NHYtGkTrl69il9//RUTJkyAmZmZwecvPDwcUVFRWLVqFdq2bYucnJwCD72lp6djx44daNeuHWxtbfWWVa1aFbt27cKQIUPQoUMHDB8+HCdOnICDg4P0b3dx4FV4pUROTg7WrVuH1q1b650X5OPjg7lz5yI6Olq66uDq1atwcXFBhQoV9Lbx7FURFy9ehBACEydOxMSJEw0+bkpKCl577TXp/tPnCQCQvhju3r374oMD0LFjRwwbNgwKhQLW1taoV68erKyspPEAQO3atfOsV7duXezatQv379+HlZUVZs2ahX79+sHNzQ2NGjVCu3bt0LdvX1SvXv2l+qdz9epVmJiY5HkunZ2dYWtrmydIPvt8AU+es+c9X2ZmZujUqRPWrl2LrKwsKJVKbNq0CdnZ2XoBauzYsdi9ezeaNGmCmjVrIiAgAD179kTTpk2fO5a2bdvC3t4ea9eulc5F+eWXX9CgQQPUq1dPqtu+fTumTZuGkydP6p3nVVTzY124cAEA8v0SsLGxKXD93NxczJ8/H4sXL0ZiYqLel0GlSpWKpI8v43mfGd17platWnnWNRQC5bwezz62LqC5ubkZbNf1Sfea9OvXL99xabVavWBY0Dif9xo+fPgQM2bMwIoVK3Dz5k29aQG0Wm2B674MXXB79vxFAFJ4eTrcAYC7u7t0ZVyPHj0wePBg+Pv7IyEhIU/t8+jC75gxY/S+yBs3boxWrVphxYoVGDp0aJ714uPj8f7778PLywvff/+9rMd8+qqz7t27o27dugCenFv3NBsbG+kq3Y4dO2Lt2rXo2LEjjh8/rnfF3rNq1qyJjh07YtOmTcjJyYGpqSlUKhV27NiBrl27olOnTgCehNZZs2bhyy+/RMWKFfNsp06dOqhTpw4AoG/fvggICECHDh0QGxtr8L2+ceNGZGZm6v3xVxDdeaZfffUVbty4ke85Uy+DAaqU2LNnD5KSkrBu3TqD81asWbPG4GWbBdH9BTl69GgEBgYarHk2KJiamhqse/ofvBdRpUqVfC+pl6Nr165o3rw5Nm/ejD///BOzZ8/GzJkzsWnTpiK9JL+w4eFlnq/u3btj2bJl+OOPPxASEoJff/0VderU0fvHq27dukhISMD27dsRGRmJjRs3YvHixZg0aZI0NUN+zM3N0bVrV3z33XdITk7GtWvXcOHCBcyaNUuq+euvv/Dee++hRYsWWLx4MVxcXGBubo4VK1Y890T1/J6jZ//a1b0PV69ebfDEXzOzgv8Zmj59OiZOnIiBAwfif//7H+zt7WFiYoLw8PA8e0mKgkKhMPj6GforHijaz4zc1yO/x35en3TP2+zZs/Od8uHZL72XGecnn3yCFStWIDw8HL6+vlCr1VAoFOjevXuxvIY6upO1Dc2llJSUBHt7e4N7p57WuXNnfPfddzhw4EC+/47mZ+PGjUhOTsZ7772n196yZUvY2Njg4MGDeQLU9evXERAQALVajZ07dxbqZPX82NnZ4Z133sGaNWvyBKhnffDBB+jTpw/WrVtXYIACngT0R48e4f79+1J4rlevHuLi4nDu3DncvXtXurBhxIgR0gUbBencuTM++ugj/Pvvvwb/mF6zZg3UajXat2//3G093U/gydEYBqhybM2aNXB0dMSiRYvyLNu0aRM2b96MpUuXwtLSEu7u7ti7dy8ePHigtxfq4sWLeuvp9sqYm5sXSXjRKeqZu3V/7SUkJORZFh8fj8qVK0t7q4An/yh+/PHH+Pjjj5GSkgJvb298+eWX+QYoOf11d3dHbm4uLly4IP3lBgDJyclIS0sr0okWW7RoARcXF6xfvx7NmjXDnj17MGHChDx1VlZW6NatG7p164ZHjx7hgw8+wJdffonx48dLhyHy06tXLyxduhTr169HYmIiFAoFevToIS3fuHEjVCoVdu3apfdFsmLFiuf2X7cHIi0tTW+X+rN76WrUqAHgyRVBL/I+/O2339C6dWv88MMPeu1paWmoXLmydL+o3pd2dnYGD8G+6GFs3XtGt9fnac++51/m9ZBD95o8vReiKOT3Gvz222/o168f5s6dK7VlZmYW6uqwl/Haa6/BwcEBR48ezbPs8OHDhZovTHf46UX2lCUnJwPIG76FEMjJyclzVdudO3cQEBCArKwsREdHSwHwZTx8+LBQfc/KykJubm6hai9fvgyVSpUnZCsUCr292zt37kRubm6h3mMFPc9JSUnYu3cv+vfv/9zA+2w/AUhXYhc1ngNVCjx8+BCbNm1C+/bt0blz5zy3YcOGISMjQ5p6IDAwENnZ2fjuu++kbeTm5uYJX46OjmjVqhWWLVtm8C+wZ2fiLSwrK6si/YfPxcUFDRs2xKpVq/S2GxcXhz///FOaGC0nJyfPh8vR0RGurq4Gd9Hr6EJmYfqse6xvvvlGr33evHkAgODg4Oduo7BMTEzQuXNnbNu2DatXr8bjx4/1Dt8BT/5BfZqFhQU8PT0hhEB2dvZzH6Np06aoVq0afv75Z6xfvz7P5b+mpqZQKBR6/8BfuXKlULNJ676EDxw4ILXpLmN/WmBgIGxsbDB9+nSDfX7e+9DU1DTPXo4NGzbkOX9PF7Jf9r1Zo0YNxMfH6/Xr1KlTeS7vL6yn399Pv3+joqJw7tw5vdqXeT3kaNSoEWrUqIE5c+bkOe8FKPp/Gwy9hgsWLMh3r15R6tSpE7Zv347r169LbdHR0fj333/RpUsXqS2/Mf/www9QKBTw9vaW/divv/46AOQ5qrB161bcv38fb775ptR2//59tGvXDjdv3sTOnTsNHvLVuXbtGuLj4/XaUlJS8tRduXIF0dHRaNy4sdSWlpZm8HOoO1T4dK2h5+TUqVPYunUrAgIC8ky78LSHDx9i4sSJcHFx0fujzVA/s7Oz8dNPP8HS0tLgeYHPTr3yLEP9vHnzJn788Ue88cYbRRJEDeEeqFJg69atyMjIyLObV+ftt9+Gg4MD1qxZg27duiEkJARNmjTBqFGjcPHiRdSpUwdbt25FamoqAP2/AhctWoRmzZqhfv36GDRoEKpXr47k5GTExMTgxo0benPpFFajRo2wZMkSTJs2DTVr1oSjo6OskxwNmT17Ntq2bQtfX1+Ehobi4cOHWLBgAdRqtTRnU0ZGhvTzBA0aNEDFihWxe/duHDlyRO8v22fpPpTr16/H66+/Dnt7e3h5ecHLyytPbYMGDdCvXz8sX74caWlpaNmyJQ4fPoxVq1YhJCREOsG/qHTr1g0LFixAREQE6tevr7fXCwACAgLg7OyMpk2bwsnJCefPn8fChQsRHBxcqF37CoUCPXv2lGZRnjp1qt7y4OBgzJs3D0FBQejZsydSUlKwaNEi1KxZE6dPny5w2wEBAahatSpCQ0MxZswYmJqa4scff4SDgwOuXbsm1dnY2GDJkiXo06cPvL290b17d6lmx44daNq0KRYuXJjv47Rv3x5Tp07FgAED4OfnhzNnzmDNmjV5znurUaMGbG1tsXTpUlhbW8PKygo+Pj7w8PB47vP0tIEDB2LevHkIDAxEaGgoUlJSsHTpUtSrV69QJ0wbMmPGDAQHB6NZs2YYOHAgUlNTpfm9ng4wL/N6yGFiYoLvv/8ebdu2Rb169TBgwAC89tpruHnzJvbu3QsbGxuDP63xPI0aNcLu3bsxb948uLq6wsPDAz4+Pmjfvj1Wr14NtVoNT09PxMTEYPfu3S91DtvChQuRlpYmXVCybds23LhxA8CTQ4a6874+//xzbNiwAa1bt8bw4cNx7949zJ49G/Xr19ebi+3LL7/EwYMHERQUhKpVqyI1NRUbN27EkSNH8Mknn+id7qDVarFgwQIAkIL1woULYWtrC1tbWwwbNgwA0KFDB9SrVw9Tp07F1atX8fbbb+PixYtYuHAhXFxcEBoaKm2zV69eOHz4MAYOHIjz58/rzf1UsWJFvdnd+/bti/379+uF0vr166NNmzZo2LAh7OzscOHCBfzwww/Izs7GV199JdXt27cPn376KTp37oxatWrh0aNH+Ouvv7Bp0yY0btwYvXv3lmq7desGS0tL+Pn5wdHREefOncPy5ctRoUIFvW0CT06vcHV1haenJ9LT0/Hjjz/i8uXL2LFjh96/VR999BHS09PRokULvPbaa9BoNFizZg3i4+Mxd+5cg+dLrVmzBq6urvnOOfjZZ5/h0qVLaNOmDVxdXXHlyhUsW7YM9+/fx/z58w2uUySK7fo+KrQOHToIlUqlNx/Ks/r37y/Mzc3Ff//9J4R4cml+z549hbW1tVCr1aJ///7i4MGDAoBYt26d3rqXLl0Sffv2Fc7OzsLc3Fy89tpron379uK3336TanSXnj87v4ehy4o1Go0IDg4W1tbWAsBzpzSAgXmgDNm9e7do2rSpsLS0FDY2NqJDhw7i3Llz0vKsrCwxZswY0aBBA2FtbS2srKxEgwYNxOLFi/W2Y2h250OHDolGjRoJCwsLvSkNDF2Kn52dLaZMmSI8PDyEubm5cHNzE+PHj89zubO7u7sIDg7OM478LoM3JDc3V7i5uQkAYtq0aXmWL1u2TLRo0UJUqlRJKJVKUaNGDTFmzBi9qQmeRzcXi6HLf4UQ4ocffhC1atUSSqVS1KlTR6xYscLg82JoJvJjx44JHx8fYWFhIapWrSrmzZtncB4oIZ68lwIDA4VarRYqlUrUqFFD9O/fXxw9erTA/mdmZopRo0YJFxcXYWlpKZo2bSpiYmIMPs+///678PT0FGZmZs+d0qCgWZZ//vlnUb16dWFhYSEaNmwodu3ale80BoZmP376PaazceNGUbduXaFUKoWnp6fYtGmTwfdqYV8PQ5+r/PqU31hPnDghPvjgA+n95e7uLrp27ap32bzusW/fvq23rqHXOT4+XrRo0UJYWloKANL75e7du2LAgAGicuXKomLFiiIwMFDEx8fneU/JmcZAN42Ioduz7724uDgREBAgKlSoIGxtbUWvXr2ERqPRq/nzzz9F+/bthaurqzA3NxfW1taiadOmYsWKFXpTPTz9PBu6Pft6pqamihEjRojXX39dKJVKUblyZdG9e/c8cyYVNJ5nt9myZcs874eIiAjRuHFjYWdnJ8zMzISrq6vo3r27OH36tF7dxYsXRd++fUX16tWFpaWlUKlUol69eiIiIkLcu3dPr3b+/PmiSZMmwt7eXpiZmQkXFxfRu3dvceHChTyvx8yZM0WdOnWESqUSdnZ24r333hMnTpzIU/fLL78If39/4eTkJMzMzISdnZ3w9/cXv//+e55aIf5v6pWRI0caXC6EEGvXrhUtWrQQDg4OwszMTFSuXFm8//774tixY/muUxQUQrzk2cFUamzZsgXvv/8+/v7770JdpUVEREQvhgGqjHr48KHeJbU5OTkICAjA0aNHodFoZF9uS0RERIXHc6DKqE8++QQPHz6Er68vsrKysGnTJhw6dAjTp09neCIiIipm3ANVRq1duxZz587FxYsXkZmZiZo1a2Lo0KHSyYtERERUfBigiIiIiGTiPFBEREREMjFAEREREcnEk8iLQW5uLm7dugVra+si/9kTIiIiKh5CCGRkZMDV1bXAmdYBBqhicevWrTy/hk5ERERlw/Xr15/7A8QMUMVAN2399evXpV+qJiIiotItPT0dbm5uhfqpLAaoYqA7bGdjY8MARUREVMYU5vQbnkROREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCQTZyInIiKiMiEnV+BwYipSMjLhaK1CEw97mJo8f9bw4sAARURERKVeZFwSpmw7hyRtptTmolYhooMngrxcSrw/PIRHREREpVpkXBKG/nxcLzwBgEabiaE/H0dkXFKJ94kBioiIiEqtnFyBKdvOQRhYpmubsu0ccnINVRQfBigiIiIqtQ4npubZ8/Q0ASBJm4nDiakl1ymUoQCVk5ODiRMnwsPDA5aWlqhRowb+97//QYj/S5xCCEyaNAkuLi6wtLSEv78/Lly4oLed1NRU9OrVCzY2NrC1tUVoaCju3bunV3P69Gk0b94cKpUKbm5umDVrVomMkYiIiPSlZOQfnl6krqiUmQA1c+ZMLFmyBAsXLsT58+cxc+ZMzJo1CwsWLJBqZs2ahW+//RZLly5FbGwsrKysEBgYiMzM/3tSe/XqhbNnzyIqKgrbt2/HgQMHMHjwYGl5eno6AgIC4O7ujmPHjmH27NmYPHkyli9fXqLjJSIiIsDRWlWkdUVFIZ7ehVOKtW/fHk5OTvjhhx+ktk6dOsHS0hI///wzhBBwdXXFqFGjMHr0aACAVquFk5MTVq5cie7du+P8+fPw9PTEkSNH0LhxYwBAZGQk2rVrhxs3bsDV1RVLlizBhAkToNFoYGFhAQAYN24ctmzZgvj4+EL1NT09HWq1GlqtFjY2NkX8TBAREb06cnIFms3cU+BhPBe1Cn+PfeelpzSQ8/1dZvZA+fn5ITo6Gv/++y8A4NSpU/j777/Rtm1bAEBiYiI0Gg38/f2lddRqNXx8fBATEwMAiImJga2trRSeAMDf3x8mJiaIjY2Valq0aCGFJwAIDAxEQkIC7t69a7BvWVlZSE9P17sRERHRyzM1UeC9BgVPU/BeA5cSnw+qzASocePGoXv37qhTpw7Mzc3x5ptvIjw8HL169QIAaDQaAICTk5Peek5OTtIyjUYDR0dHveVmZmawt7fXqzG0jacf41kzZsyAWq2Wbm5ubi85WiIiIgKe7IHaeqrgaQq2nkriVXj5+fXXX7FmzRqsXbsWx48fx6pVqzBnzhysWrXK2F3D+PHjodVqpdv169eN3SUiIqJy4XlX4QHGuQqvzMxEPmbMGGkvFADUr18fV69exYwZM9CvXz84OzsDAJKTk+Hi8n+7+pKTk9GwYUMAgLOzM1JSUvS2+/jxY6SmpkrrOzs7Izk5Wa9Gd19X8yylUgmlUvnygyQiIiI9vArvJT148AAmJvrdNTU1RW5uLgDAw8MDzs7OiI6Olpanp6cjNjYWvr6+AABfX1+kpaXh2LFjUs2ePXuQm5sLHx8fqebAgQPIzs6WaqKiolC7dm3Y2dkV2/iIiIgor9J6FV6ZCVAdOnTAl19+iR07duDKlSvYvHkz5s2bh/fffx8AoFAoEB4ejmnTpmHr1q04c+YM+vbtC1dXV4SEhAAA6tati6CgIAwaNAiHDx/GwYMHMWzYMHTv3h2urq4AgJ49e8LCwgKhoaE4e/Ys1q9fj/nz52PkyJHGGjoREdErq4mHPVzUKuR3irgCT67Ca+JhX5LdKjvTGGRkZGDixInYvHkzUlJS4Orqih49emDSpEnSFXNCCERERGD58uVIS0tDs2bNsHjxYrz++uvSdlJTUzFs2DBs27YNJiYm6NSpE7799ltUrFhRqjl9+jTCwsJw5MgRVK5cGZ988gnGjh1b6L5yGgMiIqKio/stPAB6P+miC1VLensXyQ8Ky/n+LjMBqixhgCIiIipakXFJmLLtnN4J5S5qFSI6eBZJeALkfX+XmZPIiYiI6NUV5OWCdz2dcTgxFSkZmXC0fnLYrqTnf9JhgCIiIqIywdREAd8alYzdDQBl6CRyIiIiotKCAYqIiIhIJgYoIiIiIpkYoIiIiIhkYoAiIiIikokBioiIiEgmBigiIiIimRigiIiIiGRigCIiIiKSiQGKiIiISCYGKCIiIiKZGKCIiIiIZGKAIiIiIpKJAYqIiIhIJgYoIiIiIpkYoIiIiIhkYoAiIiIikokBioiIiEgmBigiIiIimRigiIiIiGRigCIiIiKSyczYHSAiIiIqjJxcgcOJqUjJyISjtQpNPOxhaqIwSl8YoIiIiKjUi4xLwpRt55CkzZTaXNQqRHTwRJCXS4n3h4fwiIiIqFSLjEvC0J+P64UnANBoMzH05+OIjEsq8T4xQBEREVGplZMrMGXbOQgDy3RtU7adQ06uoYriwwBFREREpdbhxNQ8e56eJgAkaTNxODG15DoFBigiIiIqxVIy8g9PL1JXVBigiIiIqNRytFYVaV1RYYAiIiKiUquJhz1c1CrkN1mBAk+uxmviYV+S3WKAIiIiotLL1ESBiA6eAJAnROnuR3TwLPH5oBigiIiIqFQL8nLBkt7ecFbrH6ZzVquwpLe3UeaB4kSaREREVOoFebngXU9nzkROREREJIepiQK+NSoZuxsAeAiPiIiISDYGKCIiIiKZGKCIiIiIZCpTAermzZvo3bs3KlWqBEtLS9SvXx9Hjx6VlgshMGnSJLi4uMDS0hL+/v64cOGC3jZSU1PRq1cv2NjYwNbWFqGhobh3755ezenTp9G8eXOoVCq4ublh1qxZJTI+IiIiKhvKTIC6e/cumjZtCnNzc/zxxx84d+4c5s6dCzs7O6lm1qxZ+Pbbb7F06VLExsbCysoKgYGByMz8v+nde/XqhbNnzyIqKgrbt2/HgQMHMHjwYGl5eno6AgIC4O7ujmPHjmH27NmYPHkyli9fXqLjJSIiotJLIYQo2Z8vfkHjxo3DwYMH8ddffxlcLoSAq6srRo0ahdGjRwMAtFotnJycsHLlSnTv3h3nz5+Hp6cnjhw5gsaNGwMAIiMj0a5dO9y4cQOurq5YsmQJJkyYAI1GAwsLC+mxt2zZgvj4+EL1NT09HWq1GlqtFjY2NkUweiIiIipucr6/y8weqK1bt6Jx48bo0qULHB0d8eabb+K7776TlicmJkKj0cDf319qU6vV8PHxQUxMDAAgJiYGtra2UngCAH9/f5iYmCA2NlaqadGihRSeACAwMBAJCQm4e/euwb5lZWUhPT1d70ZERETlV5kJUJcvX8aSJUtQq1Yt7Nq1C0OHDsWnn36KVatWAQA0Gg0AwMnJSW89JycnaZlGo4Gjo6PecjMzM9jb2+vVGNrG04/xrBkzZkCtVks3Nze3lxwtERERlWZlJkDl5ubC29sb06dPx5tvvonBgwdj0KBBWLp0qbG7hvHjx0Or1Uq369evG7tLREREVIzKTIBycXGBp6enXlvdunVx7do1AICzszMAIDk5Wa8mOTlZWubs7IyUlBS95Y8fP0ZqaqpejaFtPP0Yz1IqlbCxsdG7ERERUflVZgJU06ZNkZCQoNf277//wt3dHQDg4eEBZ2dnREdHS8vT09MRGxsLX19fAICvry/S0tJw7NgxqWbPnj3Izc2Fj4+PVHPgwAFkZ2dLNVFRUahdu7beFX9ERET06iozAWrEiBH4559/MH36dFy8eBFr167F8uXLERYWBgBQKBQIDw/HtGnTsHXrVpw5cwZ9+/aFq6srQkJCADzZYxUUFIRBgwbh8OHDOHjwIIYNG4bu3bvD1dUVANCzZ09YWFggNDQUZ8+exfr16zF//nyMHDnSWEMnIiKi0kaUIdu2bRNeXl5CqVSKOnXqiOXLl+stz83NFRMnThROTk5CqVSKNm3aiISEBL2aO3fuiB49eoiKFSsKGxsbMWDAAJGRkaFXc+rUKdGsWTOhVCrFa6+9Jr766itZ/dRqtQKA0Gq1LzZQIiIiKnFyvr/LzDxQZQnngSIiIip7yuU8UERERESlBQMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERyWRm7A4QERGVlJxcgcOJqUjJyISjtQpNPOxhaqIwdreoDGKAIiKiV0JkXBKmbDuHJG2m1OaiViGigyeCvFyM2DMqi3gIj4iIyr3IuCQM/fm4XngCAI02E0N/Po7IuCQj9YzKKgYoIiIq13JyBaZsOwdhYJmubcq2c8jJNVRBZBgDFBERlWuHE1Pz7Hl6mgCQpM3E4cTUkusUlXkMUEREVK6lZOQfnl6kjghggCIionLO0VpVpHVEAAMUERGVc0087OGiViG/yQoUeHI1XhMP+5LsFpVxDFBERFSumZooENHBEwDyhCjd/YgOnpwPimRhgCIionIvyMsFS3p7w1mtf5jOWa3Ckt7enAeKZCuzAeqrr76CQqFAeHi41JaZmYmwsDBUqlQJFStWRKdOnZCcnKy33rVr1xAcHIwKFSrA0dERY8aMwePHj/Vq9u3bB29vbyiVStSsWRMrV64sgREREVFxCvJywd9j38Evg97G/O4N8cugt/H32HcYnuiFlMkAdeTIESxbtgxv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e8LCwgKhoaE4e/Ys1q9fj/nz52PkyJFSzfDhwxEZGYm5c+ciPj4ekydPxtGjRzFs2DAAgEKhQHh4OKZNm4atW7fizJkz6Nu3L1xdXRESElLSwyYiIqJSyqh7oAorKioKFy9exMWLF1GlShW9ZbpZGNRqNf7880+EhYWhUaNGqFy5MiZNmoTBgwdLtX5+fli7di2++OILfP7556hVqxa2bNkCLy8vqeazzz7D/fv3MXjwYKSlpaFZs2aIjIyESqUqmcESERFRqVdm54EqzTgPFBERUdnzSswDRURERGQsDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQylYl5oIjKg5xcgcOJqUjJyISjtQpNPOxhaqIwdreIiOgFMEARlYDIuCRM3noWmvQsqc3ZRonJ79VDkJdLAWsSEVFpxEN4RMUsMi4JQ34+rheeAECTnoUhPx9HZFySkXpGREQvigGKqBjl5AqM23SmwJpxm84gJ5c/CEBEVJYwQBEVo38u3UHag+wCa9IeZOOfS3dKqEdERFQUGKCIitHBS7eLtI6IiEoHBiiiYnQ99WGR1hERUenAAEVUjBL/u1ekdUREVDowQBEVq8LO88T5oIiIyhIGKKJi1MBNXaR1RERUOjBAERWj8W09i7SOiIhKBwYoomJ05qa2SOuIiKh0YIAiKkYpGZlFWkdERKUDAxRRMXK0VhVpHRERlQ4MUETFqImHPVzUqnyvsVMAcFGr0MTDviS7RUREL4kBiqgYmZooENHhyQniz4Yo3f2IDp4wNeE0BkREZQkDFFExC/JywZLe3nBW6x+mc1arsKS3N4K8XIzUMyIielFmxu4A0asgyMsF73o643BiKlIyMuFo/eSwHfc8ERGVTQxQRCXE1EQB3xqVjN0NIiIqAjyER0RERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcnEAEVEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCRTmQtQWVlZaNiwIRQKBU6ePKm37PTp02jevDlUKhXc3Nwwa9asPOtv2LABderUgUqlQv369bFz50695UIITJo0CS4uLrC0tIS/vz8uXLhQnEMiIiKiMqbMBajPPvsMrq6uedrT09MREBAAd3d3HDt2DLNnz8bkyZOx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8uRJXLhwAQ8fPsSqVaugUCieu96HH36Iy5cvo0+fPjhz5gwaN26MBQsWFHt/zc3N9e4rFArk5uYW++MS0cthgCKicsXKygo1a9ZE1apVYWb25CyFunXr4vHjx4iNjZXq7ty5g4SEBHh6ekptbm5uGDJkCDZt2oRRo0bhu+++M/gYFhYWyMnJKbAfdevWxfXr13H9+nWp7dy5c0hLS9N7TCIqmxigiKjcq1WrFjp27IhBgwbh77//xqlTp9C7d2+89tpr6NixIwAgPDwcu3btQmJiIo4fP469e/eibt26BrdXrVo13Lt3D9HR0fjvv//w4MGDPDX+/v6oX78+evXqhePHj+Pw4cPo27cvWrZsicaNGxfreImo+DFAEdErYcWKFWjUqBHat28PX19fCCGwc+dO6RBaTk4OwsLCULduXQQFBeH111/H4sWLDW7Lz88PQ4YMQbdu3eDg4IBZs2blqVEoFPj9999hZ2eHFi1awN/fH9WrV8f69euLdZxEVDIUQghh7E4QERERlSXcA0VEREQkEwMUERERkUwMUEREREQyMUARERERycQARURERCQTAxQRERGRTAxQRERERDIxQBERERHJxABFREREJBMDFBEREZFMDFBEREREMjFAEREREcn0/wARYlezvwXQIQAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] }, "metadata": {}, "output_type": "display_data" @@ -275,19 +305,19 @@ "plt.ylabel('Value')\n", "plt.title(f'Agent Position vs Value at fundamental {fundamental_val}')\n", "plt.show()\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-26T20:44:46.314860800Z", - "start_time": "2024-03-26T20:44:46.196664700Z" - } - }, - "id": "da028cd7fb618978", - "execution_count": 32 + ] }, { "cell_type": "code", + "execution_count": 38, + "id": "44a74cbe8acf673", + "metadata": { + "ExecuteTime": { + "end_time": "2024-03-26T20:44:58.709570600Z", + "start_time": "2024-03-26T20:44:58.596987100Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -298,8 +328,10 @@ }, { "data": { - "text/plain": "
", - "image/png": "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ssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyZ9ZANHv2bLRs2RKOjo5wdXVFr169cPnyZYM+nTp1gkKhMHiMGTPGoE9CQgKCg4NRqVIluLq6YvLkyXj8+LFBn0OHDqF58+ZQKpWoXbs2Vq1aVdqzR0REROWEWQPR4cOHER4ejt9++w1RUVHIyclBQEAAHjx4YNBv9OjRSExMlB5z586VhuXm5iI4OBjZ2dk4duwYVq9ejVWrVuHjjz+W+sTHxyM4OBidO3fG6dOnMX78eLzxxhvYt2+fyeaViIiIyi6FEEKYuwi927dvw9XVFYcPH0aHDh0APNlC1KxZMyxcuDDP1/z000/o3r07bt26BTc3NwBAZGQkpkyZgtu3b8PGxgZTpkzB7t27ERcXJ71uwIABSEtLw969e19Yl1arhVqtRnp6OlQqVfFnlIiIiEpdYb6/y9QxROnp6QAAZ2dng/Z169ahatWqaNSoEaZOnYqHDx9Kw2JiYtC4cWMpDAFAYGAgtFotzp8/L/Xx9/c3GGdgYCBiYmLyrCMrKwtardbgQURERBWXlbkL0NPpdBg/fjzatm2LRo0aSe2DBg1C9erV4eHhgbNnz2LKlCm4fPkytmzZAgBISkoyCEMApOdJSUnP7aPVavHo0SPY2dkZDJs9ezamT59e4vNIREREZVOZCUTh4eGIi4vDr7/+atD+5ptvSv9v3Lgx3N3d8corr+DatWuoVatWqdQydepUTJw4UXqu1Wrh6elZ4tPJ1QnExqciJSMTro62aOXtDEsLRYlPh4iIiJ6vTASisWPHYteuXThy5AiqVav23L6+vr4AgKtXr6JWrVrQaDSIjY016JOcnAwA0Gg00r/6tqf7qFQqo61DAKBUKqFUKos8PwWxNy4R03deQGJ6ptTmrrZFRA8fBDVyL9VpExERkSGzHkMkhMDYsWOxdetWHDhwAN7e3i98zenTpwEA7u5PQoOfnx/OnTuHlJQUqU9UVBRUKhV8fHykPtHR0QbjiYqKgp+fXwnNSeHsjUtE2NpTBmEIAJLSMxG29hT2xiWapS4iIiK5MmsgCg8Px9q1a7F+/Xo4OjoiKSkJSUlJePToEQDg2rVr+OSTT3Dy5Elcv34dO3bswLBhw9ChQwc0adIEABAQEAAfHx8MHToUZ86cwb59+/Dhhx8iPDxc2sozZswY/PXXX3jvvfdw6dIlLFmyBJs2bcKECRNMPs+5OoHpOy8gr1P79G3Td15Arq7MnPxHRERU4Zk1EC1duhTp6eno1KkT3N3dpcfGjRsBADY2Nti/fz8CAgJQv359TJo0CSEhIdi5c6c0DktLS+zatQuWlpbw8/PDkCFDMGzYMMyYMUPq4+3tjd27dyMqKgpNmzbF/Pnz8c033yAwMNDk8xwbn2q0ZehpAkBieiZi41NNVxQREZHMmfUYohddAsnT0xOHDx9+4XiqV6+OPXv2PLdPp06d8McffxSqvtKQkpF/GCpKPyIiIiq+MnUdIjlwdbQt0X5ERERUfAxEJtbK2xnualvkd3K9Ak/ONmvl7ZxPDyIiIippDEQmZmmhQESPJ2e/PRuK9M8jevjwekREREQmxEBkBkGN3LF0SHNo1Ia7xTRqWywd0pzXISIiIjKxMnFhRjkKauSOrj4aXqmaiIioDGAgMiNLCwX8alUxdxlERESyx11mREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQke1bmLoCIiIjkK1cnEBufipSMTLg62qKVtzMsLRQmr4OBiIiIiMxib1wipu+8gMT0TKnNXW2LiB4+CGrkbtJauMuMiIiITG5vXCLC1p4yCEMAkJSeibC1p7A3LtGk9TAQERERkUnl6gSm77wAkccwfdv0nReQq8urR+lgICIiIiKTio1PNdoy9DQBIDE9E7HxqSariYGIiIiITColI/8wVJR+JYGBiIiIiEzK1dG2RPuVBAYiIiIiMqlW3s5wV9siv5Pr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9erVQ79+/VClShX89ttvcHFxAQB88cUX6N69O0JCQtChQwdoNBps2bJFer2lpSV27doFS0tL+Pn5YciQIRg2bBhmzJhhrlkiIio03qzYdF50ALsAD2CvqBRCCL6rL6DVaqFWq5Gens7jiYjIbHgdotIXc+0uBq747YX9vh/dmgewlwOF+f4u02eZERHR//BmxaUvSVuwA9ML2o/KDwYiIqJyhDcrLl2p97NKtB+VH2X6GCIiIiJTcrYv2C2dCtqPyg8GIiIiov/SqAt20d+C9qPyg4GIiIjov/SXOHgeXuKgYmIgIiIi+i9LCwVea/r8M/Zea+rOA9krIAYiIiKi/8rVCew48/wLL+44k8jrEFVAPMuMiEpE9mMd1sRcx9+pD1HduRKG+tWAjRV/c1H58qIb6QK8kW5FxUBERMU2e88FrPglHk//aJ655yJGt/fG1Fd530AqP3gjXfliICKiYpm95wKWHYk3atcJSO0MRVRe8Ea68sXt2URUZNmPdVj+i3EYetryX+KR/VhnooqIioc30pUvBiIiKrLVx67jRXdDFOJJP6LygDfSlS8GIiIqshPX75ZoP6KyIKiRO5YOaQ7NM9cj0qhtsXRIc95It4LiMUREVGSVbAr2EVLQfkRlBW+kKz/8lCKiIgtpXg3bTt8qUD+i8oY30pUX7jIjoiJrU7sqKtlYPrePvY0l2tSuaqKKiIiKhoGIiIrM0kKBBf2aPrfP/H5NuZuBiMo8BiIiKpagRu6IHNIcbo5Kg3aNSolIHoBKROUEjyEiomLjAahEVN4xEBFRieABqERUnnGXGREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREcmelbkLICKigrutzcLrS35F6oMcONtbY+tb7eCiUpq7LKJyT1ZbiBYvXowaNWrA1tYWvr6+iI2NNXdJREQF1mTaPrSctR830zLxMCcXN9My0XLWfjSZts/cpRGVe7IJRBs3bsTEiRMRERGBU6dOoWnTpggMDERKSoq5SyMieqEm0/ZBm/k4z2HazMcMRUTFJJtAtGDBAowePRojRoyAj48P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" + "image/png": "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ssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyx0BEREREssdARERERLLHQERERESyZ9ZANHv2bLRs2RKOjo5wdXVFr169cPnyZYM+nTp1gkKhMHiMGTPGoE9CQgKCg4NRqVIluLq6YvLkyXj8+LFBn0OHDqF58+ZQKpWoXbs2Vq1aVdqzR0REROWEWQPR4cOHER4ejt9++w1RUVHIyclBQEAAHjx4YNBv9OjRSExMlB5z586VhuXm5iI4OBjZ2dk4duwYVq9ejVWrVuHjjz+W+sTHxyM4OBidO3fG6dOnMX78eLzxxhvYt2+fyeaViIiIyi6FEEKYuwi927dvw9XVFYcPH0aHDh0APNlC1KxZMyxcuDDP1/z000/o3r07bt26BTc3NwBAZGQkpkyZgtu3b8PGxgZTpkzB7t27ERcXJ71uwIABSEtLw969e19Yl1arhVqtRnp6OlQqVfFnlIiIiEpdYb6/y9QxROnp6QAAZ2dng/Z169ahatWqaNSoEaZOnYqHDx9Kw2JiYtC4cWMpDAFAYGAgtFotzp8/L/Xx9/c3GGdgYCBiYmLyrCMrKwtardbgQURERBWXlbkL0NPpdBg/fjzatm2LRo0aSe2DBg1C9erV4eHhgbNnz2LKlCm4fPkytmzZAgBISkoyCEMApOdJSUnP7aPVavHo0SPY2dkZDJs9ezamT59e4vNIREREZVOZCUTh4eGIi4vDr7/+atD+5ptvSv9v3Lgx3N3d8corr+DatWuoVatWqdQydepUTJw4UXqu1Wrh6elZ4tPJ1QnExqciJSMTro62aOXtDEsLRYlPh4iIiJ6vTASisWPHYteuXThy5AiqVav23L6+vr4AgKtXr6JWrVrQaDSIjY016JOcnAwA0Gg00r/6tqf7qFQqo61DAKBUKqFUKos8PwWxNy4R03deQGJ6ptTmrrZFRA8fBDVyL9VpExERkSGzHkMkhMDYsWOxdetWHDhwAN7e3i98zenTpwEA7u5PQoOfnx/OnTuHlJQUqU9UVBRUKhV8fHykPtHR0QbjiYqKgp+fXwnNSeHsjUtE2NpTBmEIAJLSMxG29hT2xiWapS4iIiK5MmsgCg8Px9q1a7F+/Xo4OjoiKSkJSUlJePToEQDg2rVr+OSTT3Dy5Elcv34dO3bswLBhw9ChQwc0adIEABAQEAAfHx8MHToUZ86cwb59+/Dhhx8iPDxc2sozZswY/PXXX3jvvfdw6dIlLFmyBJs2bcKECRNMPs+5OoHpOy8gr1P79G3Td15Arq7MnPxHRERU4Zk1EC1duhTp6eno1KkT3N3dpcfGjRsBADY2Nti/fz8CAgJQv359TJo0CSEhIdi5c6c0DktLS+zatQuWlpbw8/PDkCFDMGzYMMyYMUPq4+3tjd27dyMqKgpNmzbF/Pnz8c033yAwMNDk8xwbn2q0ZehpAkBieiZi41NNVxQREZHMmfUYohddAsnT0xOHDx9+4XiqV6+OPXv2PLdPp06d8McffxSqvtKQkpF/GCpKPyIiIiq+MnUdIjlwdbQt0X5ERERUfAxEJtbK2xnualvkd3K9Ak/ONmvl7ZxPDyIiIippDEQmZmmhQESPJ2e/PRuK9M8jevjwekREREQmxEBkBkGN3LF0SHNo1Ia7xTRqWywd0pzXISIiIjKxMnFhRjkKauSOrj4aXqmaiIioDGAgMiNLCwX8alUxdxlERESyx11mREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQke1bmLoCIiIjkK1cnEBufipSMTLg62qKVtzMsLRQmr4OBiIiIiMxib1wipu+8gMT0TKnNXW2LiB4+CGrkbtJauMuMiIiITG5vXCLC1p4yCEMAkJSeibC1p7A3LtGk9TAQERERkUnl6gSm77wAkccwfdv0nReQq8urR+lgICIiIiKTio1PNdoy9DQBIDE9E7HxqSariYGIiIiITColI/8wVJR+JYGBiIiIiEzK1dG2RPuVBAYiIiIiMqlW3s5wV9siv5Pr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9erVQ79+/VClShX89ttvcHFxAQB88cUX6N69O0JCQtChQwdoNBps2bJFer2lpSV27doFS0tL+Pn5YciQIRg2bBhmzJhhrlkiIio03qzYdF50ALsAD2CvqBRCCL6rL6DVaqFWq5Gens7jiYjIbHgdotIXc+0uBq747YX9vh/dmgewlwOF+f4u02eZERHR//BmxaUvSVuwA9ML2o/KDwYiIqJyhDcrLl2p97NKtB+VH2X6GCIiIiJTcrYv2C2dCtqPyg8GIiIiov/SqAt20d+C9qPyg4GIiIjov/SXOHgeXuKgYmIgIiIi+i9LCwVea/r8M/Zea+rOA9krIAYiIiKi/8rVCew48/wLL+44k8jrEFVAPMuMiEpE9mMd1sRcx9+pD1HduRKG+tWAjRV/c1H58qIb6QK8kW5FxUBERMU2e88FrPglHk//aJ655yJGt/fG1Fd530AqP3gjXfliICKiYpm95wKWHYk3atcJSO0MRVRe8Ea68sXt2URUZNmPdVj+i3EYetryX+KR/VhnooqIioc30pUvBiIiKrLVx67jRXdDFOJJP6LygDfSlS8GIiIqshPX75ZoP6KyIKiRO5YOaQ7NM9cj0qhtsXRIc95It4LiMUREVGSVbAr2EVLQfkRlBW+kKz/8lCKiIgtpXg3bTt8qUD+i8oY30pUX7jIjoiJrU7sqKtlYPrePvY0l2tSuaqKKiIiKhoGIiIrM0kKBBf2aPrfP/H5NuZuBiMo8BiIiKpagRu6IHNIcbo5Kg3aNSolIHoBKROUEjyEiomLjAahEVN4xEBFRieABqERUnnGXGREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREcmelbkLICKigrutzcLrS35F6oMcONtbY+tb7eCiUpq7LKJyT1ZbiBYvXowaNWrA1tYWvr6+iI2NNXdJREQF1mTaPrSctR830zLxMCcXN9My0XLWfjSZts/cpRGVe7IJRBs3bsTEiRMRERGBU6dOoWnTpggMDERKSoq5SyMieqEm0/ZBm/k4z2HazMcMRUTFJJtAtGDBAowePRojRoyAj48P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", + "text/plain": [ + "
" + ] }, "metadata": {}, "output_type": "display_data" @@ -345,19 +377,19 @@ "plt.ylabel('Value')\n", "plt.title(f'Agent Position vs Value at fundamental {fundamental_val}')\n", "plt.show()\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-26T20:44:58.709570600Z", - "start_time": "2024-03-26T20:44:58.596987100Z" - } - }, - "id": "44a74cbe8acf673", - "execution_count": 38 + ] }, { "cell_type": "code", + "execution_count": 5, + "id": "31f002d1c196705a", + "metadata": { + "ExecuteTime": { + "end_time": "2024-03-27T23:40:00.547410Z", + "start_time": "2024-03-27T23:40:00.470896Z" + }, + "collapsed": false + }, "outputs": [ { "name": "stdout", @@ -368,8 +400,10 @@ }, { "data": { - "text/plain": "
", - "image/png": "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rl69irNnzyIyMhJxcXEYNWoUrly5gvfeew+nTp3C1atXsWvXLowdOxbdunVDy5YtAQBBQUFQq9UYM2YM/vjjD+zbtw9z5sxBREQEbG1tAQCTJk3Cn3/+ibfeegsXLlzAypUr8f3332P69OlmO+8QP0+sGt0GHir9bjEPlR1WjW6DED9PM2VGREQkT2addj9+/HgcOHAA6enpUKlUaNmyJWbPno3evXvj+vXrGD16NJKSknD37l14e3tj4MCBmDNnjl4X1rVr1zB58mTExcXB0dERYWFh+Oijj1Cjxv8Nj4qLi8P06dORnJyMevXqYe7cuQgPDzc4T2NOu38YV6omIiKqOpX5/ba4dYgsUVUVRERERFR1quU6RERERETmwoKIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPbMWRKtWrULLli2hVCqhVCoREBCAn376Sdqfn5+PiIgI1K5dG05OThg8eDAyMzP1niM1NRWhoaFwcHCAm5sbZs2ahQcPHujFxMXFoU2bNrC1tUXjxo0RHR1titMjIiKiasKsBVG9evXw0Ucf4dSpUzh58iR69eqF/v3749y5cwCA6dOnIyYmBj/88AMOHz6MtLQ0DBo0SHp8cXExQkNDUVhYiCNHjmDdunWIjo7GvHnzpJiUlBSEhoaiZ8+eSExMxLRp0zBhwgTs27fP5OdLRERElkkhhBDmTuJhrq6uWLJkCYYMGYK6deti06ZNGDJkCADgwoULaN68ORISEtCxY0f89NNP6Nu3L9LS0uDu7g4AWL16NWbPno2bN2/CxsYGs2fPxp49e5CUlCQdY8SIEcjJycHevXsNykmj0UClUiE3NxdKpdL4J01ERERGV5nfb4sZQ1RcXIzNmzfj7t27CAgIwKlTp1BUVITAwEApplmzZqhfvz4SEhIAAAkJCfD395eKIQAIDg6GRqORWpkSEhL0nkMXo3uOshQUFECj0ejdiIiI6Nll9oLo7NmzcHJygq2tLSZNmoTt27dDrVYjIyMDNjY2cHFx0Yt3d3dHRkYGACAjI0OvGNLt1+2rKEaj0eD+/ftl5rRw4UKoVCrp5u3tbYxTJSIiIgtl9oKoadOmSExMxLFjxzB58mSEhYUhOTnZrDlFRkYiNzdXul2/ft2s+RAREVHVqmHuBGxsbNC4cWMAQNu2bXHixAl89tlnGD58OAoLC5GTk6PXSpSZmQkPDw8AgIeHB44fP673fLpZaA/HPDozLTMzE0qlEvb29mXmZGtrC1tbW6OcHxEREVk+s7cQPUqr1aKgoABt27ZFzZo1ceDAAWnfxYsXkZqaioCAAABAQEAAzp49i6ysLCkmNjYWSqUSarVainn4OXQxuucgIiIiMmsLUWRkJPr06YP69esjLy8PmzZtQlxcHPbt2weVSoXx48djxowZcHV1hVKpxNSpUxEQEICOHTsCAIKCgqBWqzFmzBgsXrwYGRkZmDNnDiIiIqQWnkmTJuGLL77AW2+9hVdeeQUHDx7E999/jz179pjz1ImIiMiCmLUgysrKwtixY5Geng6VSoWWLVti37596N27NwDg008/hZWVFQYPHoyCggIEBwdj5cqV0uOtra2xe/duTJ48GQEBAXB0dERYWBjeffddKcbX1xd79uzB9OnT8dlnn6FevXr4z3/+g+DgYJOfLxEREVkmi1uHyBJxHSIiIqLqp1quQ0RERERkLiyIiIiISPZYEBEREZHssSAiIiIi2WNBRERERLLHgoiIiIhkjwURERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSAiIiIi2WNBRERERLLHgoiIiIhkjwURERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSAiIiIi2WNBRERERLLHgoiIiIhkjwURERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSAiIiIi2WNBRERERLLHgoiIiIhkjwURERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSAiIiIi2TNrQbRw4UI8//zzcHZ2hpubGwYMGICLFy/qxfTo0QMKhULvNmnSJL2Y1NRUhIaGwsHBAW5ubpg1axYePHigFxMXF4c2bdrA1tYWjRs3RnR0dFWfHhEREVUTZi2IDh8+jIiICBw9ehSxsbEoKipCUFAQ7t69qxc3ceJEpKenS7fFixdL+4qLixEaGorCwkIcOXIE69atQ3R0NObNmyfFpKSkIDQ0FD179kRiYiKmTZuGCRMmYN++fSY7VyIiIrJcCiGEMHcSOjdv3oSbmxsOHz6Mbt26AShpIWrdujWWLVtW5mN++ukn9O3bF2lpaXB3dwcArF69GrNnz8bNmzdhY2OD2bNnY8+ePUhKSpIeN2LECOTk5GDv3r2PzUuj0UClUiE3NxdKpfLpT5SIiIiqXGV+vy1qDFFubi4AwNXVVW/7xo0bUadOHfj5+SEyMhL37t2T9iUkJMDf318qhgAgODgYGo0G586dk2ICAwP1njM4OBgJCQll5lFQUACNRqN3IyIiomdXDXMnoKPVajFt2jR07twZfn5+0vaRI0fCx8cHXl5eOHPmDGbPno2LFy9i27ZtAICMjAy9YgiAdD8jI6PCGI1Gg/v378Pe3l5v38KFC7FgwQKjnyMRERFZJospiCIiIpCUlIRff/1Vb/urr74q/dvf3x+enp544YUXcOXKFTRq1KhKcomMjMSMGTOk+xqNBt7e3lVyLCIiIjI/i+gymzJlCnbv3o1Dhw6hXr16FcZ26NABAHD58mUAgIeHBzIzM/VidPc9PDwqjFEqlaVahwDA1tYWSqVS70ZERETPLrMWREIITJkyBdu3b8fBgwfh6+v72MckJiYCADw9PQEAAQEBOHv2LLKysqSY2NhYKJVKqNVqKebAgQN6zxMbG4uAgAAjnQkRERFVZ2YtiCIiIrBhwwZs2rQJzs7OyMjIQEZGBu7fvw8AuHLlCt577z2cOnUKV69exa5duzB27Fh069YNLVu2BAAEBQVBrVZjzJgx+OOPP7Bv3z7MmTMHERERsLW1BQBMmjQJf/75J9566y1cuHABK1euxPfff4/p06eb7dyJiIjIcph12r1CoShz+9q1axEeHo7r169j9OjRSEpKwt27d+Ht7Y2BAwdizpw5et1Y165dw+TJkxEXFwdHR0eEhYXho48+Qo0a/zdEKi4uDtOnT0dycjLq1auHuXPnIjw83KA8Oe2eiIio+qnM77dFrUNkqVgQERERVT/Vdh0iIiIiInNgQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItmrYe4ESL6KtQLHU7KRlZcPN2c7tPd1hbWVwtxpERGRDLEgIrPYm5SOBTHJSM/Nl7Z5quwQ1U+NED9PM2ZGRERyZNYus4ULF+L555+Hs7Mz3NzcMGDAAFy8eFEvJj8/HxEREahduzacnJwwePBgZGZm6sWkpqYiNDQUDg4OcHNzw6xZs/DgwQO9mLi4OLRp0wa2trZo3LgxoqOjq/r0qBx7k9IxecNpvWIIADJy8zF5w2nsTUo3U2ZERCRXZi2IDh8+jIiICBw9ehSxsbEoKipCUFAQ7t69K8VMnz4dMTEx+OGHH3D48GGkpaVh0KBB0v7i4mKEhoaisLAQR44cwbp16xAdHY158+ZJMSkpKQgNDUXPnj2RmJiIadOmYcKECdi3b59Jz5dKuskWxCRDlLFPt21BTDKKtWVFEBERVQ2FEMJifnlu3rwJNzc3HD58GN26dUNubi7q1q2LTZs2YciQIQCACxcuoHnz5khISEDHjh3x008/oW/fvkhLS4O7uzsAYPXq1Zg9ezZu3rwJGxsbzJ49G3v27EFSUpJ0rBEjRiAnJwd79+59bF4ajQYqlQq5ublQKpVVc/IykXDlFl5ec/Sxcd9N7IiARrVNkBERET2rKvP7bVGzzHJzcwEArq6uAIBTp06hqKgIgYGBUkyzZs1Qv359JCQkAAASEhLg7+8vFUMAEBwcDI1Gg3PnzkkxDz+HLkb3HGQ6WXn5jw+qRBwREZExWMygaq1Wi2nTpqFz587w8/MDAGRkZMDGxgYuLi56se7u7sjIyJBiHi6GdPt1+yqK0Wg0uH//Puzt7fX2FRQUoKCgQLqv0Wie/gQJAODmbGfUOCIiImOwmBaiiIgIJCUlYfPmzeZOBQsXLoRKpZJu3t7e5k7pmdHe1xWeKjuUN7legZLZZu19XU2ZFhERyZxFFERTpkzB7t27cejQIdSrV0/a7uHhgcLCQuTk5OjFZ2ZmwsPDQ4p5dNaZ7v7jYpRKZanWIQCIjIxEbm6udLt+/fpTnyOVsLZSIKqfGgBKFUW6+1H91FyPiIiITMqsBZEQAlOmTMH27dtx8OBB+Pr66u1v27YtatasiQMHDkjbLl68iNTUVAQEBAAAAgICcPbsWWRlZUkxsbGxUCqVUKvVUszDz6GL0T3Ho2xtbaFUKvVuZDwhfp5YNboNPFT63WIeKjusGt2G6xAREZHJmXWW2WuvvYZNmzZh586daNq0qbRdpVJJLTeTJ0/Gjz/+iOjoaCiVSkydOhUAcOTIEQAl0+5bt24NLy8vLF68GBkZGRgzZgwmTJiADz/8EEDJtHs/Pz9ERETglVdewcGDB/H6669jz549CA4OfmyenGVWNbhSNRERVaXK/H6btSBSKMr+8Vu7di3Cw8MBlCzM+Oabb+K7775DQUEBgoODsXLlSqk7DACuXbuGyZMnIy4uDo6OjggLC8NHH32EGjX+b8x4XFwcpk+fjuTkZNSrVw9z586VjvE4LIiIiIiqn2pTEFUXLIiIiIiqn2q7DhERERGRObAgIiIiItmzmIUZSX44qJqIiCwFCyIyi71J6VgQk6x3xXtPlR2i+qk57Z6IiEzuibrMHjx4gP379+PLL79EXl4eACAtLQ137twxanL0bNqblI7JG07rFUMAkJGbj8kbTmNvUrqZMiMiIrmqdAvRtWvXEBISgtTUVBQUFKB3795wdnbGokWLUFBQgNWrV1dFnvSMKNYKLIhJRllTGwVKVqteEJOM3moPdp8REZHJVLqF6I033kC7du1w+/ZtvcteDBw4sNRq0ESPOp6SXapl6GECQHpuPo6nZJsuKSIikr1KtxD98ssvOHLkCGxsbPS2N2jQAH/99ZfREqNnU1Ze+cXQk8QREREZQ6VbiLRaLYqLi0ttv3HjBpydnY2SFD273JztHh9UiTgiIiJjqHRBFBQUhGXLlkn3FQoF7ty5g6ioKLz44ovGzI2eQe19XeGpsit1pXsdBUpmm7X3dTVlWmZTrBVIuHILOxP/QsKVWyjWcuF4IiJzqPSlO27cuIHg4GAIIXDp0iW0a9cOly5dQp06dRAfHw83N7eqytVseOkO49LNMgOgN7haVyTJ5Yr3XHqAiKhqVfm1zB48eIDNmzfjzJkzuHPnDtq0aYNRo0bpDbJ+lrAgMj65FwO6ovDR/3xyKwqJiKoSL+5qZCyIqoZcV6ou1gp0WXSw3Nl2CgAeKjv8OruXLF4PIqKqUpnf70rPMvv2228r3D927NjKPiXJlLWVAgGNaps7DZOrzNIDcnx9iIjModIF0RtvvKF3v6ioCPfu3YONjQ0cHBxYEBE9BpceICKyPJWeZXb79m292507d3Dx4kV06dIF3333XVXkSPRMcbW3eXxQJeKIiOjpPdG1zB7VpEkTfPTRR6Vaj4iotAuZeUaNIyKip2eUgggAatSogbS0NGM9HdEz6/rte0aNIyKip1fpMUS7du3Suy+EQHp6Or744gt07tzZaIkRPat8XB2MGkdERE+v0gXRgAED9O4rFArUrVsXvXr1wieffGKsvIieWWMCGuCDH8+jokWprRQlcUREZBqVLoi0Wm1V5EEkGzY1rDCxqy++jE8pN2ZiV1/Y1DBajzYRET0Gv3GJzCDyRTV6q8u+zE1vtRsiX1SbOCMiInkzqIVoxowZBj/h0qVLnzgZIrnYm5SO/clZZe7bn5yFvUnpvHQHEZEJGVQQ/f777wY9mULBywwQPU6xVmBBTHKp65g9bEFMMnqrPXjpDiIiEzGoIDp06FBV50EkG7x0BxGR5eEYIiIT46U7iIgsT6VnmQHAyZMn8f333yM1NRWFhYV6+7Zt22aUxIieVW7OdkaNIyKip1fpFqLNmzejU6dOOH/+PLZv346ioiKcO3cOBw8ehEqlqoociZ4p7X1d4amyQ3mjgxQAPFV2aO/rasq0iIhkrdIF0YcffohPP/0UMTExsLGxwWeffYYLFy5g2LBhqF+/flXkSPRMsbZSIKpfybT6R4si3f2ofmoOqCYiMqFKF0RXrlxBaGgoAMDGxgZ3796FQqHA9OnT8dVXXxk9QaJnUYifJ1aNbgMPlX63mIfKDqtGt+GUeyIiE6v0GKJatWohL6/kKtz/+Mc/kJSUBH9/f+Tk5ODePV6MkshQIX6e6K32wPGUbGTl5cPNuaSbjC1DRESmZ3BBlJSUBD8/P3Tr1g2xsbHw9/fH0KFD8cYbb+DgwYOIjY3FCy+8UJW5Ej1zrK0UnFpPRGQBDC6IWrZsieeffx4DBgzA0KFDAQD//ve/UbNmTRw5cgSDBw/GnDlzqixRIiIioqqiEEJUtGCu5JdffsHatWuxdetWaLVaDB48GBMmTEDXrl2rOkez02g0UKlUyM3NhVKpNHc6REREZIDK/H4bPKi6a9eu+Oabb5Ceno7ly5fj6tWr6N69O5577jksWrQIGRkZT504ERERkTkY3EJUlsuXL2Pt2rVYv349MjIyEBISgl27dhkzP4vAFiKqKsVawUHVRERVpEpaiMrSuHFjvPPOO5gzZw6cnZ2xZ8+eSj0+Pj4e/fr1g5eXFxQKBXbs2KG3Pzw8HAqFQu8WEhKiF5OdnY1Ro0ZBqVTCxcUF48ePx507d/Rizpw5g65du8LOzg7e3t5YvHjxE50vkTHtTUpHl0UH8fKao3hjcyJeXnMUXRYdxN6kdHOnRkQkO09cEMXHxyM8PBweHh6YNWsWBg0ahN9++61Sz3H37l20atUKK1asKDcmJCQE6enp0u27777T2z9q1CicO3cOsbGx2L17N+Lj4/Hqq69K+zUaDYKCguDj44NTp05hyZIlmD9/PtdMIrPam5SOyRtOl7rIa0ZuPiZvOM2iiIjIxCq1DlFaWhqio6MRHR2Ny5cvo1OnTvj8888xbNgwODo6Vvrgffr0QZ8+fSqMsbW1hYeHR5n7zp8/j7179+LEiRNo164dAGD58uV48cUX8fHHH8PLywsbN25EYWEhvvnmG9jY2KBFixZITEzE0qVL9QonIlMp1gosiElGWX3VAiWrVS+ISUZvtQe7z4iITMTgFqI+ffrAx8cHy5cvx8CBA3H+/Hn8+uuvGDdu3BMVQ4aKi4uDm5sbmjZtismTJ+PWrVvSvoSEBLi4uEjFEAAEBgbCysoKx44dk2K6desGGxsbKSY4OBgXL17E7du3qyxvovIcT8ku1TL0MAEgPTcfx1OyTZcUEZHMGdxCVLNmTWzduhV9+/aFtbV1VeYkCQkJwaBBg+Dr64srV67gnXfeQZ8+fZCQkABra2tkZGTAzc1N7zE1atSAq6urNOstIyMDvr6+ejHu7u7Svlq1apU6bkFBAQoKCqT7Go3G2KdGMpaVV34x9CRxRET09AwuiMwxe2zEiBHSv/39/dGyZUs0atQIcXFxVboq9sKFC7FgwYIqe36SNzdnu8cHVSKOiIie3lPNMjO1hg0bok6dOrh8+TIAwMPDA1lZWXoxDx48QHZ2tjTuyMPDA5mZmXoxuvvljU2KjIxEbm6udLt+/bqxT4VkrL2vKzxVdqWudK+jAOCpKpmCT0REplGtCqIbN27g1q1b8PQsuRJ4QEAAcnJycOrUKSnm4MGD0Gq16NChgxQTHx+PoqIiKSY2NhZNmzYts7sMKBnIrVQq9W5ExmJtpUBUPzUAlCqKdPej+qk5oJqIyITMWhDduXMHiYmJSExMBACkpKQgMTERqampuHPnDmbNmoWjR4/i6tWrOHDgAPr374/GjRsjODgYANC8eXOEhIRg4sSJOH78OH777TdMmTIFI0aMgJeXFwBg5MiRsLGxwfjx43Hu3Dls2bIFn332GWbMmGGu0yZCiJ8nVo1uAw+VfreYh8oOq0a3QYifp5kyIyKSp6daqfppxcXFoWfPnqW2h4WFYdWqVRgwYAB+//135OTkwMvLC0FBQXjvvfekQdFAycKMU6ZMQUxMDKysrDB48GB8/vnncHJykmLOnDmDiIgInDhxAnXq1MHUqVMxe/Zsg/PkStVUVQofaLE+4SquZd+Dj6sDxgQ0gE2NatVwS0RksSrz+23Wgqi6YEFEVWFvUjoWxCTrTcH3VNkhqp+aLUREREZgskt3ENGTKW+l6nSuVE1EZBYsiIhMrKKVqoGShRkXxCSjWMvGWyIiU2FBRGRij1upGuBK1UREpsaCiMjEMnLvGzWOiIieHgsiIhPLvlto1DgiInp6LIiITMzVydaocURE9PRYEBGZmIfSsGuUGRpHRERPjwURkYnprmVWEV7LjIjItFgQEZmYtZUCL7WqeOHFl1p58lpmREQmxIKIyMSKtQK7/qh44cVdf6RzHSIiIhNiQURkYlyHiIjI8rAgIjKxrLyKi6HKxhER0dOrYe4EiOTGzdmw2WOGxhFR9VWsFTieko2svHy4OZdMpuD4QfNgQURkYrpZZhm5+WVez0wBwIOzzIieeXuT0rEgJlmvC91TZYeofmqE+FU88YKMj11mRCZmbaVAVD81gJLi52G6+1H91PwrkegZtjcpHZM3nC41njAjNx+TN5zG3qSKJ16Q8bEgIjKDED9PrBrdBh6PrEfkobLDqtFt+Nch0TOsWCuwICa5zBZi3bYFMcmcaWpi7DIjMpMQP0/0Vntw/ACRzDxupqnA/800DWhU23SJyRwLIiIzsrZS8AuPSGY409QyscuMiIjIhDjT1DKxICIiIjIh3UzT8jrHFeD1DM2BBREREZEJcaapZWJBREREZGKcaWp5OKiaiIjIDDjT1LKwICIiIjITzjS1HOwyIyIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI/XMiMiIiKzKdYKi7jArVlbiOLj49GvXz94eXlBoVBgx44devuFEJg3bx48PT1hb2+PwMBAXLp0SS8mOzsbo0aNglKphIuLC8aPH487d+7oxZw5cwZdu3aFnZ0dvL29sXjx4qo+NSIiInqMvUnp6LLoIF5ecxRvbE7Ey2uOosuig9iblG7yXMxaEN29exetWrXCihUryty/ePFifP7551i9ejWOHTsGR0dHBAcHIz8/X4oZNWoUzp07h9jYWOzevRvx8fF49dVXpf0ajQZBQUHw8fHBqVOnsGTJEsyfPx9fffVVlZ8fERERlW1vUjombziN9Nx8ve0ZufmYvOG0yYsihRBCmPSI5VAoFNi+fTsGDBgAoKR1yMvLC2+++SZmzpwJAMjNzYW7uzuio6MxYsQInD9/Hmq1GidOnEC7du0AAHv37sWLL76IGzduwMvLC6tWrcK///1vZGRkwMbGBgDw9ttvY8eOHbhw4YJBuWk0GqhUKuTm5kKpVBr/5ImISJYspbvI1Iq1Al0WHSxVDOkoAHio7PDr7F5P9XpU5vfbYgdVp6SkICMjA4GBgdI2lUqFDh06ICEhAQCQkJAAFxcXqRgCgMDAQFhZWeHYsWNSTLdu3aRiCACCg4Nx8eJF3L59u8xjFxQUQKPR6N2IiIiMyZK6i0zteEp2ucUQAAgA6bn5OJ6SbbKcLLYgysjIAAC4u7vrbXd3d5f2ZWRkwM3NTW9/jRo14OrqqhdT1nM8fIxHLVy4ECqVSrp5e3s//QkRERH9j6V1F5laVl75xdCTxBmDxRZE5hQZGYnc3Fzpdv36dXOnREREz4hircCCmGSUNV5Ft21BTDKKtRYxoqVKuDnbGTXOGCy2IPLw8AAAZGZm6m3PzMyU9nl4eCArK0tv/4MHD5Cdna0XU9ZzPHyMR9na2kKpVOrdiIiIjMESu4tMrb2vKzxVdihvdJACgKeqZEyVqVhsQeTr6wsPDw8cOHBA2qbRaHDs2DEEBAQAAAICApCTk4NTp05JMQcPHoRWq0WHDh2kmPj4eBQVFUkxsbGxaNq0KWrVqmWisyEiIiphid1FpmZtpUBUPzUAlCqKdPej+qlNOsDcrAXRnTt3kJiYiMTERAAlA6kTExORmpoKhUKBadOm4f3338euXbtw9uxZjB07Fl5eXtJMtObNmyMkJAQTJ07E8ePH8dtvv2HKlCkYMWIEvLy8AAAjR46EjY0Nxo8fj3PnzmHLli347LPPMGPGDDOdNRERyZkldheZQ4ifJ1aNbgMPlf55eqjssGp0G4T4eZo0H7NOu4+Li0PPnj1LbQ8LC0N0dDSEEIiKisJXX32FnJwcdOnSBStXrsRzzz0nxWZnZ2PKlCmIiYmBlZUVBg8ejM8//xxOTk5SzJkzZxAREYETJ06gTp06mDp1KmbPnm1wnpx2T0RExqKbcp6Rm1/mOCJjTTmvLqpy6YHK/H5bzDpElowFERERGZNulhkAvaJIVwaYo4XkWfRMrENERET0rLK07iLixV2JyIzkukovEVBSFPVWe/D/gIVgQUREZrE3KR0LYpL1ph97quwQ1U/Nv45JNqytFAhoVNvcaRDYZUZEZiD3VXqJyPKwICIik+IqvURkiVgQEZFJcZVeIrJELIiIyKS4Si8RWSIWRERkUlyll4gsEQsiIjKptj618LhZxVaKkjgiIlNhQUREJnXq2m08bry0VpTEERGZCgsiIjIpjiEiIkvEgoiITIpjiIjIErEgIiKTau/rCk+VHcobRqRAyYrV7X1dTZkWEckcCyIiMilrKwWi+qkrjInqp+b1nIjIpFgQEZHJhfh5wr+essx9/vWUvJYZEZkcCyIiMrmJ357AmRuaMveduaHBxG9PmDgjIvMo1gokXLmFnYl/IeHKLV6yxox4tXsiMqn7hcWITc6qMCY2OQv3C4thb2NtoqyITG9vUjoWxCTrXcrGU2WHqH5qtpKaAVuIiMikPvwx2ahxRNXR3qR0TN5wutR1/TJy8zF5w2nsTUo3U2byxYKIiEzq6q17Ro0jqm6KtQILYpJRVueYbtuCmGR2n5kYCyIiMinvWvZGjSOqbo6nZJdqGXqYAJCem4/jKdmmS4pYEBGRadVzMazQMTSOqLrhau2WiQUREZlU4o1co8YRVTdcrd0ycZYZEZmUg4EzxwyNo+qtWCtwPCUbWXn5cHMuWaH8WV+UU7dae0ZufpnjiBQAPLhau8mxICIyIzn+GAz+Zz3sSEwzKI6ebXKddq5brX3yhtNQAHpFke5/P1drNz0WRERmItcfgw6Nahs1jqon3bTzR1tIdNPOV41u80z/Pwjx88Sq0W1KfQd4yOA7wFKxICIyAzn/GJwwcObMiZRsdG5Sp4qzIXN43LRzBUqmnfdWezzTrSQhfp7orfaQXSuxpeKgaiITk/saJAl//m3UOKp+OO38/1hbKRDQqDb6t/4HAhrVZjFkRiyIiExM7j8GhhZ6z2pBSJx2TpaJBRGRicn9xyDnXpFR46j64bRzskQsiIhMTO4/Bpcy84waR9WPbtp5eZ1DCpRMMOC0czIlFkREJib3HwNDO8LYYfbs0k07rwinnctHsVYg4cot7Ez8CwlXbpmtu5yzzIhMTO5rkDzn7oRTqTkGxdGzK8TPE69288WaX1Lw8O+flQKY2NX3mZ1lSfosafkRthARmYFuDRIPlX63mIfK7pmecg8AKgcbo8ZR9bQ3KR1fxesXQwAgBPBVfAr2JqWbJzEyGd3yI49OMtEtP2LqzwBbiIjMRK5rkNQw8PwMjaPqh+sQkSV+BthCRGRGclyDpEMDA1eqNjCOqh+5Lz1BlvkZYEFERKZlaM337NeGsiX3pSfIMj8DFl0QzZ8/HwqFQu/WrFkzaX9+fj4iIiJQu3ZtODk5YfDgwcjMzNR7jtTUVISGhsLBwQFubm6YNWsWHjx4YOpTIaL/OZZyy6hxVP3IfekJsszPgEUXRADQokULpKenS7dff/1V2jd9+nTExMTghx9+wOHDh5GWloZBgwZJ+4uLixEaGorCwkIcOXIE69atQ3R0NObNm2eOUyEiAGwiIrkvPUGW+Rmw+IKoRo0a8PDwkG516pRc7DE3Nxdff/01li5dil69eqFt27ZYu3Ytjhw5gqNHjwIAfv75ZyQnJ2PDhg1o3bo1+vTpg/feew8rVqxAYWGhOU+LSLYCDLyKvaFxVP08vA7Roz+Iclh64mGWsgaPqVniZ8DiC6JLly7By8sLDRs2xKhRo5CamgoAOHXqFIqKihAYGCjFNmvWDPXr10dCQgIAICEhAf7+/nB3d5digoODodFocO7cuXKPWVBQAI1Go3cjIuPo2LA2XBxqVhhTy6EmOjZkQfQs0y094a6U39ITOnuT0tFl0UG8vOYo3ticiJfXHEWXRQdls+SApS0/YtHT7jt06IDo6Gg0bdoU6enpWLBgAbp27YqkpCRkZGTAxsYGLi4ueo9xd3dHRkYGACAjI0OvGNLt1+0rz8KFC7FgwQLjngwRASj5y/CjQf6YtOF0uTELB/nLonWAgEfXJBdCHi0kujV4Hj1b3Ro8cikKLWn5EYtuIerTpw+GDh2Kli1bIjg4GD/++CNycnLw/fffV+lxIyMjkZubK92uX79epccjkpsQP0+sHt0GHo+0Dniq7LBaJj8EcqcrCDI0BXrbMzUFZlmUz5QetwYPULIGj5y6zyxh+RGLbiF6lIuLC5577jlcvnwZvXv3RmFhIXJycvRaiTIzM+Hh4QEA8PDwwPHjx/WeQzcLTRdTFltbW9ja2hr/BIhIYkl/GZJpWeKifKZUmTV4OJbOdCy6hehRd+7cwZUrV+Dp6Ym2bduiZs2aOHDggLT/4sWLSE1NRUBAAAAgICAAZ8+eRVZWlhQTGxsLpVIJtbriCwsSUdWzlL8MybQscVE+U7LENXjIwluIZs6ciX79+sHHxwdpaWmIioqCtbU1Xn75ZahUKowfPx4zZsyAq6srlEolpk6dioCAAHTs2BEAEBQUBLVajTFjxmDx4sXIyMjAnDlzEBERwRYgIiIzkXtBUMfJsN8fQ+PIOCy6ILpx4wZefvll3Lp1C3Xr1kWXLl1w9OhR1K1bFwDw6aefwsrKCoMHD0ZBQQGCg4OxcuVK6fHW1tbYvXs3Jk+ejICAADg6OiIsLAzvvvuuuU6JiEj2LHFRPlPSFhs2NsjQODIOhZDLkP6noNFooFKpkJubC6VSae50iIiqtWKtQJdFB5GRm1/mOCIFSqZe/zq71zPZjfrxvgv44tCVx8ZN6dkIM4ObPTaOyleZ3+9qNYaIiIiqP92ifOX9NS7wrC/MyNXaLRELIiIiIhPiau2WiQURERGZlG7afXl00+6f1XV4uFq7ZWJBREREJiX3afe61dorwtXaTY8FERERmZTcp90DXK3dEln0tHsiInr21HE0cB0eA+OqK67WbllYEBERkUlpDVztxdC46ky3WjuZH7vMiIjIpI5cuWXUOCJjYAsRERGZ1Nm/cowaV50VawW7zCwECyIiIjIp+5rWRo2rrvYmpWP+rnPI0BRI2zyUtpj/UgsOqjYDdpkREZFJtfd1NWpcdbQ3KR2TNpzWK4YAIENTgEkbTmNvUrqZMpMvFkRERGRSozs2MGpcdVOsFXh729kKY97edvaZXZjSUrEgIiIik0q8nmPUuOrm6JVbyLlXVGFMzr0iHOWgcpNiQURERCaVnnPfqHHVTcKffxs1joyDBREREZnU79dvGzWuujG0I4wdZqbFgoiIiEyq2MAFFw2Nq26UdhVf2LWycWQcLIiIiMikrBWGrbNjaFx1o7lf8fihysaRcbAgIiIik/qndy2jxlU3CgMLPUPjyDhYEBERkUl5utgbNa66MfTaZbzGmWmxICIiIpNq7+sKF4eKx8fUcqj5zC7M2LFhbYPOv2NDFkSmxIKIiIgszrM5nLqEtZUCHw3yrzBm4SB/XtPMxFgQERGRSR1PyTZoYcLjKdkmysj0Qvw8sXp0G3go7fS2e6rssHp0G17LzAx4cVciIjKprLx8o8ZVVyF+nuit9uDV7i0ECyIiIjIpN2e7xwdVIq46s7ZScPC0hWCXGRERmZQhg6pdnuFB1WSZWBAREZHFYacRmRoLIiIiMilDBlXffsYHVZPlYUFEREQmlWbgVewNjSMyBhZERERkUr+nGni1ewPjiIyBBREREZlUWu49o8YRGQMLIiIiMqksTaFR44iMgQURERGZlIfKsPWFDI0jMgYWREREZFIdfA1biNDQOCJjYEFEREQmFdapwWPXGVL8L47IVFgQERGRSVlbKWBvY11hjL2NNa/pRSbFa5kREZnRhsOXMOen/yfdf7/PcxjdvYkZM6p6x1Oyca+wuMKYe4XFOJ6Szet8kcnIqoVoxYoVaNCgAezs7NChQwccP37c3CkRkYw1eHuPXjEEAHN++n9o8PYeM2VkGrzaPVki2RREW7ZswYwZMxAVFYXTp0+jVatWCA4ORlZWlrlTIyIZelzR8ywXRbzaPVki2RRES5cuxcSJEzFu3Dio1WqsXr0aDg4O+Oabb8ydGhHJzIbDl4waV92093WFp8qu3IHVCgCeKjte7Z5MShYFUWFhIU6dOoXAwEBpm5WVFQIDA5GQkFAqvqCgABqNRu9GRGQsj3aTPW1cdWNtpUBUPzWA0le1192P6qfmoGoyKVkURH///TeKi4vh7u6ut93d3R0ZGRml4hcuXAiVSiXdvL29TZUqEZEshPh5YtXoNqUWX/RQ2WHV6DYI8fM0U2YkV5xlVobIyEjMmDFDuq/RaFgUEREZWYifJ3qrPXA8JRtZeflwcy7pJmPLEJmDLAqiOnXqwNraGpmZmXrbMzMz4eHhUSre1tYWtra2pkqPiGTm/T7PGdQd9n6f50yQjXlZWyk4tZ4sgiy6zGxsbNC2bVscOHBA2qbVanHgwAEEBASYMTMikiND1xl61tcjIrIksiiIAGDGjBlYs2YN1q1bh/Pnz2Py5Mm4e/cuxo0bZ+7UiEiGrn4U+lT7ici4ZNFlBgDDhw/HzZs3MW/ePGRkZKB169bYu3dvqYHWRESmsDcpHQoAoox9iv/t58BiItNRCCHK+v9ID9FoNFCpVMjNzYVSqTR3OkRUzRVrBbosOoj03LJXYlagZLbVr7N7cYAx0VOozO+3bLrMiIgsxfGU7HKLIaCk1Sg9Nx/HU7JNlxSRzLEgIiIyMV7Li8jysCAiIjIxXsuLyPKwICIiMjFey4vI8rAgIiIyMV7Li8jysCAiIjIDXsuLyLLIZh0iIiJLw2t5EVkOFkRERGbEa3kRWQZ2mREREZHssSAiIiIi2WNBRERERLLHgoiIiIhkjwURERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHscaVqAwghAAAajcbMmRAREZGhdL/but/xirAgMkBeXh4AwNvb28yZEBERUWXl5eVBpVJVGKMQhpRNMqfVapGWlgZnZ2coFMa96KJGo4G3tzeuX78OpVJp1OeuDuR+/gBfA7mfP8DXgOcv7/MHqu41EEIgLy8PXl5esLKqeJQQW4gMYGVlhXr16lXpMZRKpWz/IwA8f4CvgdzPH+BrwPOX9/kDVfMaPK5lSIeDqomIiEj2WBARERGR7LEgMjNbW1tERUXB1tbW3KmYhdzPH+BrIPfzB/ga8Pzlff6AZbwGHFRNREREsscWIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSCyQAUFBWjdujUUCgUSExPNnY5JvfTSS6hfvz7s7Ozg6emJMWPGIC0tzdxpmcTVq1cxfvx4+Pr6wt7eHo0aNUJUVBQKCwvNnZrJfPDBB+jUqRMcHBzg4uJi7nRMYsWKFWjQoAHs7OzQoUMHHD9+3NwpmUx8fDz69esHLy8vKBQK7Nixw9wpmdTChQvx/PPPw9nZGW5ubhgwYAAuXrxo7rRMatWqVWjZsqW0IGNAQAB++ukns+TCgsgCvfXWW/Dy8jJ3GmbRs2dPfP/997h48SL++9//4sqVKxgyZIi50zKJCxcuQKvV4ssvv8S5c+fw6aefYvXq1XjnnXfMnZrJFBYWYujQoZg8ebK5UzGJLVu2YMaMGYiKisLp06fRqlUrBAcHIysry9ypmcTdu3fRqlUrrFixwtypmMXhw4cRERGBo0ePIjY2FkVFRQgKCsLdu3fNnZrJ1KtXDx999BFOnTqFkydPolevXujfvz/OnTtn+mQEWZQff/xRNGvWTJw7d04AEL///ru5UzKrnTt3CoVCIQoLC82dilksXrxY+Pr6mjsNk1u7dq1QqVTmTqPKtW/fXkREREj3i4uLhZeXl1i4cKEZszIPAGL79u3mTsOssrKyBABx+PBhc6diVrVq1RL/+c9/TH5cthBZkMzMTEycOBHr16+Hg4ODudMxu+zsbGzcuBGdOnVCzZo1zZ2OWeTm5sLV1dXcaVAVKCwsxKlTpxAYGChts7KyQmBgIBISEsyYGZlLbm4uAMj2/3xxcTE2b96Mu3fvIiAgwOTHZ0FkIYQQCA8Px6RJk9CuXTtzp2NWs2fPhqOjI2rXro3U1FTs3LnT3CmZxeXLl7F8+XL861//MncqVAX+/vtvFBcXw93dXW+7u7s7MjIyzJQVmYtWq8W0adPQuXNn+Pn5mTsdkzp79iycnJxga2uLSZMmYfv27VCr1SbPgwVRFXv77behUCgqvF24cAHLly9HXl4eIiMjzZ2y0Rn6GujMmjULv//+O37++WdYW1tj7NixENV4QfXKnj8A/PXXXwgJCcHQoUMxceJEM2VuHE9y/kRyExERgaSkJGzevNncqZhc06ZNkZiYiGPHjmHy5MkICwtDcnKyyfPgpTuq2M2bN3Hr1q0KYxo2bIhhw4YhJiYGCoVC2l5cXAxra2uMGjUK69atq+pUq4yhr4GNjU2p7Tdu3IC3tzeOHDliliZUY6js+aelpaFHjx7o2LEjoqOjYWVVvf9ueZL3Pzo6GtOmTUNOTk4VZ2c+hYWFcHBwwNatWzFgwABpe1hYGHJycmTXMqpQKLB9+3a910IupkyZgp07dyI+Ph6+vr7mTsfsAgMD0ahRI3z55ZcmPW4Nkx5NhurWrYu6des+Nu7zzz/H+++/L91PS0tDcHAwtmzZgg4dOlRlilXO0NegLFqtFkDJUgTVVWXO/6+//kLPnj3Rtm1brF27ttoXQ8DTvf/PMhsbG7Rt2xYHDhyQigCtVosDBw5gypQp5k2OTEIIgalTp2L79u2Ii4tjMfQ/Wq3WLN/5LIgsRP369fXuOzk5AQAaNWqEevXqmSMlkzt27BhOnDiBLl26oFatWrhy5Qrmzp2LRo0aVdvWocr466+/0KNHD/j4+ODjjz/GzZs3pX0eHh5mzMx0UlNTkZ2djdTUVBQXF0vrcDVu3Fj6P/EsmTFjBsLCwtCuXTu0b98ey5Ytw927dzFu3Dhzp2YSd+7cweXLl6X7KSkpSExMhKura6nvxGdRREQENm3ahJ07d8LZ2VkaO6ZSqWBvb2/m7EwjMjISffr0Qf369ZGXl4dNmzYhLi4O+/btM30yJp/XRgZJSUmR3bT7M2fOiJ49ewpXV1dha2srGjRoICZNmiRu3Lhh7tRMYu3atQJAmTe5CAsLK/P8Dx06ZO7Uqszy5ctF/fr1hY2NjWjfvr04evSouVMymUOHDpX5foeFhZk7NZMo7//72rVrzZ2aybzyyivCx8dH2NjYiLp164oXXnhB/Pzzz2bJhWOIiIiISPaq/wAFIiIioqfEgoiIiIhkjwURERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSAiIlmKi4uDQqF47PXSGjRogGXLlpkkJyIyHxZERGTRwsPDoVAooFAoYGNjg8aNG+Pdd9/FgwcPnup5O3XqhPT0dKhUKgAlF5R1cXEpFXfixAm8+uqrT3UsIrJ8vJYZEVm8kJAQrF27FgUFBfjxxx8RERGBmjVrIjIy8omf08bGxqBrxPHCtETywBYiIrJ4tra28PDwgI+PDyZPnozAwEDs2rULt2/fxtixY1GrVi04ODigT58+uHTpkvS4a9euoV+/fqhVqxYcHR3RokUL/PjjjwD0u8zi4uIwbtw45ObmSq1R8+fPB1C6yyw1NRX9+/eHk5MTlEolhg0bhszMTGn//Pnz0bp1a6xfvx4NGjSASqXCiBEjkJeXZ5LXioieDAsiIqp27O3tUVhYiPDwcJw8eRK7du1CQkIChBB48cUXUVRUBKDkauIFBQWIj4/H2bNnsWjRIjg5OZV6vk6dOmHZsmVQKpVIT09Heno6Zs6cWSpOq9Wif//+yM7OxuHDhxEbG4s///wTw4cP14u7cuUKduzYgd27d2P37t04fPgwPvroo6p5MYjIKNhlRkTVhhACBw4cwL59+9CnTx/s2LEDv/32Gzp16gQA2LhxI7y9vbFjxw4MHToUqampGDx4MPz9/QEADRs2LPN5bWxsoFKpoFAoKuxGO3DgAM6ePYuUlBR4e3sDAL799lu0aNECJ06cwPPPPw+gpHCKjo6Gs7MzAGDMmDE4cOAAPvjgA6O9FkRkXGwhIiKLt3v3bjg5OcHOzg59+vTB8OHDER4ejho1aqBDhw5SXO3atdG0aVOcP38eAPD666/j/fffR+fOnREVFYUzZ848VR7nz5+Ht7e3VAwBgFqthouLi3RMoKSbTVcMAYCnpyeysrKe6thEVLVYEBGRxevZsycSExNx6dIl3L9/H+vWrYNCoXjs4yZMmIA///wTY8aMwdmzZ9GuXTssX768yvOtWbOm3n2FQgGtVlvlxyWiJ8eCiIgsnqOjIxo3boz69eujRo2Snv7mzZvjwYMHOHbsmBR369YtXLx4EWq1Wtrm7e2NSZMmYdu2bXjzzTexZs2aMo9hY2OD4uLiCvNo3rw5rl+/juvXr0vbkpOTkZOTo3dMIqp+WBARUbXUpEkT9O/fHxMnTsSvv/6KP/74A6NHj8Y//vEP9O/fHwAwbdo07Nu3DykpKTh9+jQOHTqE5s2bl/l8DRo0wJ07d3DgwAH8/fffuHfvXqmYwMBA+Pv7Y9SoUTh9+jSOHz+OsWPHonv37mjXrl2Vni8RVS0WRERUba1duxZt27ZF3759ERAQACEEfvzxR6nLqri4GBEREWjevDlCQkLw3HPPYeXKlWU+V6dOnTBp0iQMHz4cdevWxeLFi0vFKBQK7Ny5E7Vq1UK3bt0QGBiIhg0bYsuWLVV6nkRU9RRCCGHuJIiIiIjMiS1EREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItn7/wCYNM8gs66DAAAAAElFTkSuQmCC" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkQAAAHHCAYAAABeLEexAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABdlklEQVR4nO3deXxM9/4/8NckZM9MBNmuiFiKkeCiiJ1GEg21L7Ulil4aWpRqehG6KVrVqqV1W1FLaV1baGkskbZib0oEPzSEZlORTCxZZD6/P3LnfI0sJkxmJs7r+XjM42HOec+c95kZM+98tqMQQggQERERyZiVuRMgIiIiMjcWRERERCR7LIiIiIhI9lgQERERkeyxICIiIiLZY0FEREREsseCiIiIiGSPBRERERHJHgsiIiIikj0WRPRMCQ8PR4MGDQyKnT9/PhQKRdUm9Ixo0KABwsPDzZ2GUZ04cQKdOnWCo6MjFAoFEhMTTXr8ynxW5SAuLg4KhQJxcXHmToVkigWRhVm5ciUUCgU6dOhg7lTKtHLlSkRHRxscr1AopJuVlRW8vLwQFBRksi+9e/fuYf78+bL5kl26dCkUCgX2799fbsyaNWugUCiwa9cuE2ZWtdLS0jB//nyDi5qioiIMHToU2dnZ+PTTT7F+/Xr4+PhUbZLPuA8//BA7duwwybFOnTqFkJAQKJVKODs7IygoqMz3vqioCAsWLEDDhg1ha2uLhg0b4v3338eDBw/04sLDw/W+qx69/fXXXwBKvk9WrFiBoKAgeHp6wtnZGf/85z+xatUqFBcXlzr+Bx98gJdeegnu7u5QKBSYP3/+E5/zBx98AIVCAT8/P73tVZnT/v370bNnT9SpUwcuLi5o37491q9frxcTHR1d4Wu3ceNGKVb3R+ijNzs7uyd+XYxKkEXp1KmTaNCggQAgLl26ZO50SmnRooXo3r27wfEARO/evcX69evFt99+KxYsWCDc3d2FQqEQP/74o9HzKywsFPn5+dL9mzdvCgAiKiqqVGxRUZG4f/++0XMwp7/++ktYWVmJcePGlRvTo0cPUbt2bVFYWGjw8/r4+IiwsDAjZFg1Tpw4IQCItWvXGhR//vx5AUCsWbOmahOrQFhYmPDx8THb8Y3N0dHxqT4jhw4dEgDEoUOHKow7deqUsLOzE02aNBEff/yxWLx4sWjQoIFQKpXiwoULerHDhg0TCoVCjB8/XqxatUqEhYUJAGLixIl6cUeOHBHr16/Xu3377bfCwcFBqNVqKe7s2bNCoVCIwMBAsXjxYrF69WoxcOBAAUCMHTu2VK4AhIeHhwgODi73e8gQ169fFw4ODsLR0VG0aNFCb19V5bRz506hUChEp06dxPLly8UXX3whunXrJgCIpUuXSnFXrlwp9dqtX79etGnTRlhbW4v09HQpNioqSgAQq1at0ovdtGnTE70uxsaCyIL8+eefAoDYtm2bqFu3rpg/f765UyrlSQqiiIgIvW1nzpwRAERQUJCRsyutooLoWfXCCy8IlUqlVxjq3LhxQ1hZWYlJkyZV6jmftYLo8OHDAoD44YcfqjaxCrAg0mdoQfTiiy+KWrVqib///lvalpaWJpycnMSgQYOkbcePHxcAxNy5c/Ue/+abbwqFQiH++OOPCo/zyy+/CADigw8+kLbdvHlTJCUllYodN25cmX/EpqSkSI97mu+h4cOHi169eonu3buXKoiqKqfevXsLLy8vve+RoqIi0ahRI9GyZcsK8713755wdnYWvXv31tuuK4hu3rxZ4ePNhV1mFmTjxo2oVasWQkNDMWTIEL2mxofdunULY8aMgVKphIuLC8LCwvDHH39AoVCU6s66cOEChgwZAldXV9jZ2aFdu3alukp0TZ6//fYbZsyYgbp168LR0REDBw7EzZs3pbgGDRrg3LlzOHz4sNTU2aNHj0qfp7+/P+rUqYOUlBRp28GDB9G1a1c4OjrCxcUF/fv3x/nz5/Uel5eXh2nTpqFBgwawtbWFm5sbevfujdOnT0sxD4/LuHr1KurWrQsAWLBggZSzrom4rDFEDx48wHvvvYdGjRrB1tYWDRo0wDvvvIOCggK9uAYNGqBv37749ddf0b59e9jZ2aFhw4b49ttvKzz3oqIiuLq6Yty4caX2aTQa2NnZYebMmdK25cuXo0WLFnBwcECtWrXQrl07bNq0qcJjjB49Grm5udizZ0+pfZs3b4ZWq8WoUaMAAB9//DE6deqE2rVrw97eHm3btsXWrVsrfH6g/PFXus/S1atX9bb/9NNP0vvr7OyM0NBQnDt37rHHyc7OxsyZM+Hv7w8nJycolUr06dMHf/zxhxQTFxeH559/HgAwbtw46X0ur2s3PDwc3bt3BwAMHTpU73Pco0ePMj/Tj473uXr1KhQKBT7++GN89dVX0ufl+eefx4kTJ0o9fseOHfDz84OdnR38/Pywffv2MnMz9P1QKBSYMmUKfvjhB6jVatjb2yMgIABnz54FAHz55Zdo3Lgx7Ozs0KNHj1LvBwAcO3YMISEhUKlUcHBwQPfu3fHbb7/pxeje58uXLyM8PBwuLi5QqVQYN24c7t27p5fP3bt3sW7dOun11405u3btGl577TU0bdoU9vb2qF27NoYOHVpmTob45ZdfEBgYiNq1a0vbPD090b17d+zevRt37tyR4gBgxIgReo8fMWIEhBDYsmVLhcfZtGkTFAoFRo4cKW2rU6cOWrRoUSp24MCBAFDqO8sYY8Ti4+OxdetWLFu2rMz9VZWTRqNBrVq1YGtrK22rUaMG6tSpA3t7+wofGxMTg7y8POl75lFCCGg0GgghDMrFVFgQWZCNGzdi0KBBsLGxwcsvv4xLly6V+nLVarXo168fvvvuO4SFheGDDz5Aeno6wsLCSj3fuXPn0LFjR5w/fx5vv/02PvnkEzg6OmLAgAFlfiFPnToVf/zxB6KiojB58mTExMRgypQp0v5ly5ahXr16aNasGdavX4/169fj3//+d6XP8/bt27h9+7b0hbZ//34EBwcjKysL8+fPx4wZM3DkyBF07txZ70tz0qRJWLVqFQYPHoyVK1di5syZsLe3L/UfXqdu3bpYtWoVgJIvB13OgwYNKje3CRMmYN68eWjTpg0+/fRTdO/eHQsXLiz1pQoAly9fxpAhQ9C7d2988sknqFWrFsLDwyv8oa9ZsyYGDhyIHTt2oLCwUG/fjh07UFBQIB1rzZo1eP3116FWq7Fs2TIsWLAArVu3xrFjx8p9fgAYNGgQ7OzsyiycNm3aBB8fH3Tu3BkA8Nlnn+Gf//wn3n33XXz44YeoUaMGhg4dWmYx9aTWr1+P0NBQODk5YdGiRZg7dy6Sk5PRpUuXx/4o/vnnn9ixYwf69u2LpUuXYtasWTh79iy6d++OtLQ0AEDz5s3x7rvvAgBeffVV6X3u1q1bmc/5r3/9C++88w4A4PXXX3/izzFQ8nouWbIE//rXv/D+++/j6tWrGDRoEIqKiqSYn3/+GYMHD4ZCocDChQsxYMAAjBs3DidPniz1fJV5P3755Re8+eabCAsLw/z583H+/Hn07dsXK1aswOeff47XXnsNs2bNQkJCAl555RW9xx48eBDdunWDRqNBVFQUPvzwQ+Tk5KBXr144fvx4qWMNGzYMeXl5WLhwIYYNG4bo6GgsWLBA2r9+/XrY2tqia9eu0uv/r3/9C0DJ4PUjR45gxIgR+PzzzzFp0iQcOHAAPXr00CuqDFVQUFDmD7KDgwMKCwuRlJQkxQEoFevg4ACgZBxSeYqKivD999+jU6dOBhUQGRkZAEqKE2MqLi7G1KlTMWHCBPj7+1fqsU+bU48ePXDu3DnMnTsXly9fxpUrV/Dee+/h5MmTeOuttyp87MaNG2Fvb1/ud23Dhg2hUqng7OyM0aNHIzMz84lyNDozt1DR/5w8eVIAELGxsUIIIbRarahXr55444039OL++9//CgBi2bJl0rbi4mLRq1evUl0GL7zwgvD399dr8tRqtaJTp06iSZMm0ra1a9cKACIwMFBotVpp+/Tp04W1tbXIycmRtj1Jl9n48ePFzZs3RVZWljh27Jh44YUXBADxySefCCGEaN26tXBzcxO3bt2SHvfHH38IKysrvT5wlUpVqvvtUY92Q1TULKxrvtVJTEwUAMSECRP04mbOnCkAiIMHD0rbfHx8BAARHx8vbcvKyhK2trbizTffrDDHffv2CQAiJiZGb/uLL74oGjZsKN3v379/qeZxQw0dOlTY2dmJ3NxcaduFCxcEABEZGSltu3fvnt7jCgsLhZ+fn+jVq5fe9ke7zB597XR0nyVds3xeXp5wcXEpNWYjIyNDqFSqUtsflZ+fL4qLi/W2paSkCFtbW/Huu+9K2yrbZabrnnm0y6x79+5lfr4f/VylpKQIAKJ27doiOztb2r5z585S723r1q2Fp6en3v+jn3/+WQAo1WVm6PsBQNja2kqvsxBCfPnll9L4EI1GI22PjIzUe0+0Wq1o0qSJCA4O1vv/fu/ePeHr66vXzaF7n1955RW94w8cOFDUrl1bb1t5XWaPnpMQQiQkJAgA4ttvv5W2Gdpl5u/vL5577jnx4MEDaVtBQYGoX7++ACC2bt0qhPi/78r169frPX716tUCgPDz8yv3GDExMQKAWLlyZYW56I6tVquFr6+vKCoqKjPmSbvMvvjiC6FSqURWVpYQQpTZZVZVOd25c0cagwVAABAODg5ix44dFR771q1bwsbGRgwbNqzUvmXLlokpU6aIjRs3iq1bt4o33nhD1KhRQzRp0kTvu8pc2EJkITZu3Ah3d3f07NkTQEkT9PDhw7F582a9mQJ79+5FzZo1MXHiRGmblZUVIiIi9J4vOzsbBw8elP6y+/vvv/H333/j1q1bCA4OxqVLl6SZEzqvvvqqXjdI165dUVxcjGvXrj3VuX399deoW7cu3Nzc0KFDB6lrbtq0aUhPT0diYiLCw8Ph6uoqPaZly5bo3bs3fvzxR2mbi4sLjh07JrUMGJvuWDNmzNDb/uabbwJAqb/S1Wo1unbtKt2vW7cumjZtij///LPC4/Tq1Qt16tTRa7K/ffs2YmNjMXz4cGmbi4sLbty4UWYXzOOMHj0a+fn52LZtm7RN12L0cDP2w3893759G7m5uejatateN+TTiI2NRU5ODl5++WXpM/j333/D2toaHTp0wKFDhyp8vK2tLaysSr6miouLcevWLTg5OaFp06ZGy/FpDB8+HLVq1ZLu6z4Pus+A7vMdFhYGlUolxfXu3RtqtbrU81Xm/XjhhRf0Wi90M1MHDx4MZ2fnUtt1OSUmJuLSpUsYOXIkbt26Jb0nd+/exQsvvID4+HhotVq9Y02aNEnvfteuXXHr1i1oNJoKXp3S51RUVIRbt26hcePGcHFxeaL38LXXXsP/+3//D+PHj0dycjKSkpIwduxYpKenAwDu378PAHjxxRfh4+ODmTNnYtu2bbh27Rq+//57/Pvf/0aNGjWkuLJs2rQJNWvWxLBhwx6bz5QpU5CcnIwvvvgCNWrUqPT5lOfWrVuYN28e5s6dK3X9G8oYOdna2uK5557DkCFD8N1332HDhg1o164dRo8ejaNHj5b7uK1bt6KwsLDM7rI33ngDy5cvx8iRIzF48GAsW7YM69atw6VLl7By5conytOYWBBZgOLiYmzevBk9e/ZESkoKLl++jMuXL6NDhw7IzMzEgQMHpNhr167B09NTavbVady4sd79y5cvQwgh/Wd6+BYVFQUAyMrK0ntM/fr19e7rvuhv3779VOfXv39/xMbGYv/+/Th27Bj+/vtvfPLJJ7CyspKKraZNm5Z6XPPmzaUvagBYvHgxkpKS4O3tjfbt22P+/PmPLT4q49q1a7Cysir1Wnp4eMDFxaVUYfjo6wWUvGaPe71q1KiBwYMHY+fOnVKz/rZt21BUVKRXEM2ePRtOTk5o3749mjRpgoiIiFJjPMrTp08fuLq66nWbfffdd2jVqpXeeIPdu3ejY8eOsLOzg6urq9TNmJuba9BxHufSpUsASorARz+HP//8c6nP4KO0Wi0+/fRTNGnSBLa2tqhTpw7q1q2LM2fOGC3Hp/G4/zO6z0yTJk1KPbasz3xl3o9Hj60ruLy9vcvcrstJ956EhYWVek/+85//oKCgoNTxnua74f79+5g3bx68vb313sOcnJwneg8nTZqEd955B5s2bUKLFi3g7++PK1euSN04Tk5OAAA7Ozvs2bMHtWvXxuDBg9GgQQOMHTsW8+bNg6urqxT3qDt37mDnzp0IDg7WG6dUliVLlmDNmjV477338OKLL1b6XCoyZ84cuLq6YurUqZV6nLFymjJlCmJiYrB582aMGDECo0aNwv79++Hp6Yk33nij3Mdt3LgRrq6u6NOnj0HHGTlyJDw8PCpcKsRUjFfO0hM7ePAg0tPTsXnzZmzevLnU/o0bNyIoKKhSz6n7C2/mzJkIDg4uM+bRH35ra+sy48RTDnyrV68eAgMDn+o5gJJxDF27dsX27dvx888/Y8mSJVi0aBG2bdtm8H8+Qxi6WOPTvF4jRozAl19+iZ9++gkDBgzA999/j2bNmqFVq1ZSTPPmzXHx4kXs3r0be/fuxX//+1+sXLkS8+bN0xu/URbdX7dr1qxBZmYmUlNTcenSJSxevFiK+eWXX/DSSy+hW7duWLlyJTw9PVGzZk2sXbv2sQO3y3uNHl33RPc5XL9+PTw8PErFP+6v1w8//BBz587FK6+8gvfeew+urq6wsrLCtGnTSrViGINCoSjz/StrPRfAuP9nKvt+lHfsx+Wke92WLFmC1q1blxn7aLHwNOc5depUrF27FtOmTUNAQABUKhUUCgVGjBjxxO/hBx98gJkzZ+LcuXNQqVTw9/eXxoU999xzUlyLFi2QlJSE5ORk3L59WxqAPn36dGlg/aN27NiBe/fulTsgWCc6OhqzZ8/GpEmTMGfOnCc6j/JcunQJX331FZYtW6bXIp6fn4+ioiJcvXoVSqVSr1XdmDkVFhbi66+/xltvvSW10AIl3yt9+vTBF198gcLCQtjY2Og9LjU1Fb/88gteffVV1KxZ0+DjeXt7Izs7+4nzNRYWRBZg48aNcHNzw4oVK0rt27ZtG7Zv347Vq1fD3t4ePj4+OHToEO7du6fXSnT58mW9xzVs2BBAyQfYGMWIjrFXdtYthnfx4sVS+y5cuIA6derA0dFR2ubp6YnXXnsNr732GrKystCmTRt88MEH5RZElcnXx8cHWq0Wly5dQvPmzaXtmZmZyMnJMerCfd26dYOnpye2bNmCLl264ODBg2UO7HV0dMTw4cMxfPhwFBYWYtCgQfjggw8QGRn52MXMRo0ahdWrV2PLli1ISUmBQqHAyy+/LO3/73//Czs7O+zbt09vJsnatWsfm7+uhSAnJwcuLi7S9kdb0Ro1agQAcHNze6LP4datW9GzZ098/fXXettzcnL0Bosa63NZq1atMlsdn7TbWPeZ0bXKPOzRz/zTvB+VoXtPlEqlSb4btm7dirCwMHzyySfStvz8fOTk5DzV8WrVqoUuXbpI9/fv3y9N+ng0r4dbRX/88Udotdpyz33jxo1wcnLCSy+9VO6xd+7ciQkTJmDQoEFlfm8/rb/++gtarRavv/46Xn/99VL7fX198cYbb+jNPDNmTrdu3cKDBw/K/EOgqKgIWq22zH3fffcdhBCPLSYfJoTA1atX8c9//vOpcjYGdpmZ2f3797Ft2zb07dsXQ4YMKXWbMmUK8vLypKnywcHBKCoqwpo1a6Tn0Gq1pf4DuLm5oUePHvjyyy+lvvWHPTydvjIcHR2f+ovsYZ6enmjdujXWrVun97xJSUn4+eefpSbf4uLiUs3rbm5u8PLyKjUl/mG6otGQnHXHenR669KlSwEAoaGhj30OQ1lZWWHIkCGIiYnB+vXr8eDBA73uMqDkS+lhNjY2UKvVEELozWIqT+fOndGgQQNs2LABW7ZsQffu3VGvXj1pv7W1NRQKhd4X29WrVw1abVj3oxofHy9t0027flhwcDCUSiU+/PDDMnN+3OfQ2tq6VCvEDz/8UGr8m65oftrPZqNGjXDhwgW9vP744w+Duyof9fDn++HPb2xsLJKTk/Vin+b9qIy2bduiUaNG+Pjjj6Up6g8z9ndDWe/h8uXLy211exJbtmzBiRMnMG3aNL0WjUfdv38fc+fOhaenp94fBzo3b97E/v37MXDgwFLDEnTi4+MxYsQIdOvWDRs3bqzweIb6+++/ceHCBWnWnW5phkdvLVq0QP369bF9+3aMHz++ynJyc3ODi4sLtm/frjcb9s6dO4iJiUGzZs3KnOm3adMm1K9fX69QfVhZn61Vq1bh5s2bCAkJeaqcjYEtRGa2a9cu5OXllfvXSMeOHVG3bl1s3LgRw4cPx4ABA9C+fXu8+eabuHz5Mpo1a4Zdu3ZJzY0P/5W2YsUKdOnSBf7+/pg4cSIaNmyIzMxMJCQk4MaNG3pruRiqbdu2WLVqFd5//300btwYbm5u6NWr15Od/P8sWbIEffr0QUBAAMaPH4/79+9j+fLlUKlU0ppBeXl5qFevHoYMGYJWrVrByckJ+/fvx4kTJ/T+8nyUvb091Go1tmzZgueeew6urq7w8/Mrtfw9ALRq1QphYWH46quvkJOTg+7du+P48eNYt24dBgwYIA14N5bhw4dj+fLliIqKgr+/v16rFAAEBQXBw8MDnTt3hru7O86fP48vvvgCoaGheoNmy6NbQ+XDDz8EAGlquk5oaCiWLl2KkJAQjBw5EllZWVixYgUaN26MM2fOVPjcQUFBqF+/PsaPH49Zs2bB2toa33zzDerWrYvU1FQpTqlUYtWqVRgzZgzatGmDESNGSDF79uxB586d8cUXX5R7nL59++Ldd9/FuHHj0KlTJ5w9exYbN26UWkB1GjVqBBcXF6xevRrOzs5wdHREhw4d4Ovr+9jX6WGvvPIKli5diuDgYIwfPx5ZWVlYvXo1WrRoYdAA4rIsXLgQoaGh6NKlC1555RVkZ2dL60s9XJA8zftRGVZWVvjPf/6DPn36oEWLFhg3bhz+8Y9/4K+//sKhQ4egVCoRExNT6edt27Yt9u/fj6VLl8LLywu+vr7o0KED+vbti/Xr10OlUkGtViMhIQH79+9/7Pic8sTHx+Pdd99FUFAQateujaNHj2Lt2rUICQkpNbZl2LBh8PLyglqthkajwTfffIM///wTe/bsKfP/0JYtW/DgwYNyWziuXbuGl156CQqFAkOGDMEPP/ygt79ly5Zo2bKldH/9+vW4du2aVOjEx8fj/fffBwCMGTNGakH84osvsGDBAhw6dAg9evRAnTp1MGDAgFLH1/2x9vC+qsjJ2toaM2fOxJw5c9CxY0eMHTsWxcXF+Prrr3Hjxg1s2LChVG5JSUk4c+YM3n777XJbC318fDB8+HD4+/vDzs4Ov/76KzZv3ozWrVtLyzSYlXkmt5FOv379hJ2dnbh79265MeHh4aJmzZrSyqw3b94UI0eOFM7OzkKlUonw8HDx22+/CQBi8+bNeo+9cuWKGDt2rPDw8BA1a9YU//jHP0Tfvn2lqalC/N9U6RMnTug9tqxpsBkZGSI0NFQ4OzsLAI+dgo8yVqouy/79+0Xnzp2Fvb29UCqVol+/fiI5OVnaX1BQIGbNmiVatWolnJ2dhaOjo2jVqlWpabFlrf575MgR0bZtW2FjY6M3zbSsqeNFRUViwYIFwtfXV9SsWVN4e3uLyMjIUqs++/j4iNDQ0FLnUd607bJotVrh7e0tAIj333+/1P4vv/xSdOvWTdSuXVvY2tqKRo0aiVmzZlVqeuq5c+ekKdq3b98utf/rr78WTZo0Eba2tqJZs2Zi7dq1Zb4uZa1UferUKdGhQwdhY2Mj6tevL5YuXVpq2r3OoUOHRHBwsFCpVMLOzk40atRIhIeHi5MnT1aYf35+vnjzzTeFp6ensLe3F507dxYJCQllvs47d+4UarVa1KhR47FT8Mubdi+EEBs2bBANGzYUNjY2onXr1mLfvn3lTrtfsmRJqcejjKnM//3vf0Xz5s2Fra2tUKvVYtu2bWV+Vg19P8r6f1VeTuWd6++//y4GDRokfb58fHzEsGHDxIEDB6SY8lYWLut9vnDhgujWrZuwt7cXAKTPy+3bt8W4ceNEnTp1hJOTkwgODhYXLlwo9ZkydNr95cuXRVBQkKhTp470Oi1cuFAUFBSUil20aJFo1qyZsLOzE7Vq1RIvvfSS+P3338t97o4dOwo3Nze9Kf0P0+VY3u3R97179+7lxj58nrrX+XHnXta0+6rKSQghNm7cKNq3by9cXFyEvb296NChg95vx8PefvttAUCcOXOm3PwnTJgg1Gq1cHZ2FjVr1hSNGzcWs2fP1lsmwpwUQljYUpH0RHbs2IGBAwfi119/lRbdIyIiIsOwIKqG7t+/r9d/W1xcjKCgIJw8eRIZGRmPXVadiIiI9HEMUTU0depU3L9/HwEBASgoKMC2bdtw5MgRfPjhhyyGiIiIngBbiKqhTZs24ZNPPsHly5eRn5+Pxo0bY/LkyXrXHSMiIiLDsSAiIiIi2eM6RERERCR7LIiIiIhI9jio2gBarRZpaWlwdnY2+qUriIiIqGoIIZCXlwcvL6/HruDNgsgAaWlppa4gTURERNXD9evX9S5dVBYWRAbQLfF+/fp1KJVKM2dDREREhtBoNPD29jbockcsiAyg6yZTKpUsiIiIiKoZQ4a7cFA1ERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSAiIiIi2WNBRERERLLHgoiIiIhkjwURERERyR5XqjajYq3A8ZRsZOXlw83ZDu19XWFtxYvHEhERmZpZW4hWrVqFli1bSpfECAgIwE8//STt79GjBxQKhd5t0qRJes+RmpqK0NBQODg4wM3NDbNmzcKDBw/0YuLi4tCmTRvY2tqicePGiI6ONsXpVWhvUjq6LDqIl9ccxRubE/HymqPosugg9ialmzs1IiIi2TFrQVSvXj189NFHOHXqFE6ePIlevXqhf//+OHfunBQzceJEpKenS7fFixdL+4qLixEaGorCwkIcOXIE69atQ3R0NObNmyfFpKSkIDQ0FD179kRiYiKmTZuGCRMmYN++fSY914ftTUrH5A2nkZ6br7c9IzcfkzecZlFERERkYgohhDB3Eg9zdXXFkiVLMH78ePTo0QOtW7fGsmXLyoz96aef0LdvX6SlpcHd3R0AsHr1asyePRs3b96EjY0NZs+ejT179iApKUl63IgRI5CTk4O9e/calJNGo4FKpUJubu5TX9y1WCvQZdHBUsWQjgKAh8oOv87uxe4zIiKip1CZ32+LGVRdXFyMzZs34+7duwgICJC2b9y4EXXq1IGfnx8iIyNx7949aV9CQgL8/f2lYggAgoODodFopFamhIQEBAYG6h0rODgYCQkJ5eZSUFAAjUajdzOW4ynZ5RZDACAApOfm43hKttGOSURERBUz+6Dqs2fPIiAgAPn5+XBycsL27duhVqsBACNHjoSPjw+8vLxw5swZzJ49GxcvXsS2bdsAABkZGXrFEADpfkZGRoUxGo0G9+/fh729famcFi5ciAULFhj9XAEgK6/8YuhJ4oiIiOjpmb0gatq0KRITE5Gbm4utW7ciLCwMhw8fhlqtxquvvirF+fv7w9PTEy+88AKuXLmCRo0aVVlOkZGRmDFjhnRfo9HA29vbKM/t5mxn1DgiIiJ6embvMrOxsUHjxo3Rtm1bLFy4EK1atcJnn31WZmyHDh0AAJcvXwYAeHh4IDMzUy9Gd9/Dw6PCGKVSWWbrEADY2tpKM990N2Np7+sKT5UdyhsdpADgqSqZgk9ERESmYfaC6FFarRYFBQVl7ktMTAQAeHp6AgACAgJw9uxZZGVlSTGxsbFQKpVSt1tAQAAOHDig9zyxsbF645RMydpKgah+Jbk9WhTp7kf1U3NANRERkQmZtSCKjIxEfHw8rl69irNnzyIyMhJxcXEYNWoUrly5gvfeew+nTp3C1atXsWvXLowdOxbdunVDy5YtAQBBQUFQq9UYM2YM/vjjD+zbtw9z5sxBREQEbG1tAQCTJk3Cn3/+ibfeegsXLlzAypUr8f3332P69OlmO+8QP0+sGt0GHir9bjEPlR1WjW6DED9PM2VGREQkT2addj9+/HgcOHAA6enpUKlUaNmyJWbPno3evXvj+vXrGD16NJKSknD37l14e3tj4MCBmDNnjl4X1rVr1zB58mTExcXB0dERYWFh+Oijj1Cjxv8Nj4qLi8P06dORnJyMevXqYe7cuQgPDzc4T2NOu38YV6omIiKqOpX5/ba4dYgsUVUVRERERFR1quU6RERERETmwoKIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPbMWRKtWrULLli2hVCqhVCoREBCAn376Sdqfn5+PiIgI1K5dG05OThg8eDAyMzP1niM1NRWhoaFwcHCAm5sbZs2ahQcPHujFxMXFoU2bNrC1tUXjxo0RHR1titMjIiKiasKsBVG9evXw0Ucf4dSpUzh58iR69eqF/v3749y5cwCA6dOnIyYmBj/88AMOHz6MtLQ0DBo0SHp8cXExQkNDUVhYiCNHjmDdunWIjo7GvHnzpJiUlBSEhoaiZ8+eSExMxLRp0zBhwgTs27fP5OdLRERElkkhhBDmTuJhrq6uWLJkCYYMGYK6deti06ZNGDJkCADgwoULaN68ORISEtCxY0f89NNP6Nu3L9LS0uDu7g4AWL16NWbPno2bN2/CxsYGs2fPxp49e5CUlCQdY8SIEcjJycHevXsNykmj0UClUiE3NxdKpdL4J01ERERGV5nfb4sZQ1RcXIzNmzfj7t27CAgIwKlTp1BUVITAwEAp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", + "text/plain": [ + "
" + ] }, "metadata": {}, "output_type": "display_data" @@ -414,25 +448,17 @@ "plt.ylabel('Value')\n", "plt.title(f'Agent Position vs Value at fundamental {fundamental_val}')\n", "plt.show()\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-27T23:40:00.547410Z", - "start_time": "2024-03-27T23:40:00.470896Z" - } - }, - "id": "31f002d1c196705a", - "execution_count": 5 + ] }, { "cell_type": "code", - "outputs": [], - "source": [], + "execution_count": null, + "id": "d8c2f016f622c77c", "metadata": { "collapsed": false }, - "id": "d8c2f016f622c77c" + "outputs": [], + "source": [] } ], "metadata": { @@ -444,14 +470,14 @@ "language_info": { "codemirror_mode": { "name": "ipython", - "version": 2 + "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" + "pygments_lexer": "ipython3", + "version": "3.9.12" } }, "nbformat": 4, From 55c36f3f4e7ad0c5d283bfe724d0c43a677023a3 Mon Sep 17 00:00:00 2001 From: Rishith Seelam Date: Mon, 1 Jul 2024 14:40:25 -0400 Subject: [PATCH 32/34] added random sampling to each agent to prevent identical private values --- marketsim/private_values/private_values.py | 1 + marketsim/simulator/sampled_arrival_simulator.py | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/marketsim/private_values/private_values.py b/marketsim/private_values/private_values.py index 635200ce..2bfda673 100644 --- a/marketsim/private_values/private_values.py +++ b/marketsim/private_values/private_values.py @@ -34,6 +34,7 @@ def __init__(self, q_max: int, val_var=5e6, random_seed: int = 0): self.extra_buy = min(self.values[-1].item(), 0) self.extra_sell = max(self.values[0].item(), 0) + def value_for_exchange(self, position: int, order_type: int) -> float: """ Calculates the value associated with a given trade and order type. diff --git a/marketsim/simulator/sampled_arrival_simulator.py b/marketsim/simulator/sampled_arrival_simulator.py index d14d2e43..50808100 100644 --- a/marketsim/simulator/sampled_arrival_simulator.py +++ b/marketsim/simulator/sampled_arrival_simulator.py @@ -55,8 +55,8 @@ def __init__(self, self.markets = [] for _ in range(num_assets): - fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random_seed) - self.markets.append(Market(fundamental=fundamental, time_steps=sim_time)) + fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random.randint(1,2048)) + self.markets.append(Market(fundamental=fundamental, time_steps=sim_time, random_seed=random.randint(1,2048))) self.agents = {} # TEMP FOR HBL TESTING @@ -72,7 +72,7 @@ def __init__(self, shade=shade, pv_var=pv_var, eta=eta, - random_seed=random_seed + random_seed=random.randint(1,2048) )) # expanded_zi # else: @@ -138,9 +138,13 @@ def end_sim(self): return values def run(self): + X = [] + Y = [] counter = 0 for t in range(self.sim_time): if self.arrivals[t]: + X.append(t) + Y.append(self.markets[0].order_book.get_best_ask()) try: self.step() except KeyError: @@ -150,6 +154,8 @@ def run(self): self.time += 1 self.step() + return X, Y + def sample_arrivals(p, num_samples): geometric_dist = dist.Geometric(torch.tensor([p])) From a466011214bfd6a09df50e19857cba33a7c763bb Mon Sep 17 00:00:00 2001 From: Rishith Seelam Date: Mon, 1 Jul 2024 15:33:41 -0400 Subject: [PATCH 33/34] cleanup --- marketsim/agent/spoofer.py | 1 - marketsim/event/event_queue.py | 2 -- marketsim/simulator/sampled_arrival_simulator.py | 10 +++------- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/marketsim/agent/spoofer.py b/marketsim/agent/spoofer.py index 326f291e..a1cf0950 100644 --- a/marketsim/agent/spoofer.py +++ b/marketsim/agent/spoofer.py @@ -14,7 +14,6 @@ def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: float, ord random.seed(random_seed) # np.random.seed(random_seed) - self.agent_id = agent_id self.market = market self.pv = PrivateValues(q_max, pv_var, random_seed=random.randint(1,4096)) diff --git a/marketsim/event/event_queue.py b/marketsim/event/event_queue.py index 077c65ba..ef1a140d 100644 --- a/marketsim/event/event_queue.py +++ b/marketsim/event/event_queue.py @@ -12,8 +12,6 @@ def __init__(self, random_seed: int = 0): # torch.manual_seed(random_seed) random.seed(random_seed) # np.random.seed(random_seed) - - # self.rand = random.Random(rand_seed) self.scheduled_activities = defaultdict(list) self.current_time = 0 diff --git a/marketsim/simulator/sampled_arrival_simulator.py b/marketsim/simulator/sampled_arrival_simulator.py index 50808100..c18191e0 100644 --- a/marketsim/simulator/sampled_arrival_simulator.py +++ b/marketsim/simulator/sampled_arrival_simulator.py @@ -55,8 +55,8 @@ def __init__(self, self.markets = [] for _ in range(num_assets): - fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random.randint(1,2048)) - self.markets.append(Market(fundamental=fundamental, time_steps=sim_time, random_seed=random.randint(1,2048))) + fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time, r=r, shock_var=shock_var, random_seed=random.randint(1,4096)) + self.markets.append(Market(fundamental=fundamental, time_steps=sim_time, random_seed=random.randint(1,4096))) self.agents = {} # TEMP FOR HBL TESTING @@ -72,7 +72,7 @@ def __init__(self, shade=shade, pv_var=pv_var, eta=eta, - random_seed=random.randint(1,2048) + random_seed=random.randint(1,4096) )) # expanded_zi # else: @@ -138,8 +138,6 @@ def end_sim(self): return values def run(self): - X = [] - Y = [] counter = 0 for t in range(self.sim_time): if self.arrivals[t]: @@ -154,8 +152,6 @@ def run(self): self.time += 1 self.step() - return X, Y - def sample_arrivals(p, num_samples): geometric_dist = dist.Geometric(torch.tensor([p])) From 63998e2ee4b11d6a7c84bfd340e0668f9ca79e81 Mon Sep 17 00:00:00 2001 From: Rishith Seelam Date: Wed, 31 Jul 2024 17:29:18 -0400 Subject: [PATCH 34/34] rebased, changed seeding for PR --- marketsim/MM/simMM.py | 25 ++++++++----------- marketsim/agent/extented_zi_agent.py | 8 ++---- marketsim/agent/hbl_agent.py | 8 +++--- marketsim/agent/market_maker.py | 7 ++---- marketsim/agent/market_maker_beta.py | 6 ++++- marketsim/agent/spoofer.py | 11 +++----- marketsim/agent/zero_intelligence_agent.py | 12 ++++----- marketsim/event/event_queue.py | 8 +++--- marketsim/fundamental/constant.py | 11 ++++---- marketsim/fundamental/lazy_mean_reverting.py | 9 +++---- marketsim/fundamental/mean_reverting.py | 9 +++---- marketsim/market/market.py | 11 +++----- marketsim/private_values/private_values.py | 12 ++++----- .../simulator/sampled_arrival_simulator.py | 12 ++++----- marketsim/simulator/simulator.py | 9 +++---- 15 files changed, 64 insertions(+), 94 deletions(-) diff --git a/marketsim/MM/simMM.py b/marketsim/MM/simMM.py index 6f5de7c5..c8470a28 100644 --- a/marketsim/MM/simMM.py +++ b/marketsim/MM/simMM.py @@ -36,19 +36,12 @@ def __init__(self, p=2, k_min=5, k_max=20, - max_position=100 + max_position=100, + random_seed: int = None ): - if random_seed != 0: - torch.manual_seed(random_seed) - random.seed(random_seed) - # np.random.seed(random_seed) - - - if random_seed != 0: - torch.manual_seed(random_seed) - random.seed(random_seed) - # np.random.seed(random_seed) + random.seed(random_seed) + torch.seed(random.randint(1, 4096)) if shade is None: shade = [250, 500] @@ -82,8 +75,8 @@ def __init__(self, self.markets = [] for _ in range(num_assets): - fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time+1, r=r, shock_var=shock_var) - self.markets.append(Market(fundamental=fundamental, time_steps=sim_time)) + fundamental = LazyGaussianMeanReverting(mean=mean, final_time=sim_time+1, r=r, shock_var=shock_var, random_seed=random.randint(1, 4096)) + self.markets.append(Market(fundamental=fundamental, time_steps=sim_time, random_seed=random.randint(1, 4096))) self.agents = {} for agent_id in range(num_background_agents): @@ -98,7 +91,8 @@ def __init__(self, shade=shade, pv_var=pv_var, random_seed=random.randint(1,4096) - )) + ) + ) self.arrivals_MM[self.arrival_times_MM[self.arrival_index_MM].item()].append(self.num_background_agents) self.arrival_index_MM += 1 @@ -118,7 +112,8 @@ def __init__(self, p=p, k_min=k_min, k_max=k_max, - max_position=max_position + max_position=max_position, + random_seed=random.randint(1,4096) ) else: # ladder policy self.MM = MMAgent( diff --git a/marketsim/agent/extented_zi_agent.py b/marketsim/agent/extented_zi_agent.py index c70dc882..47ac3d05 100644 --- a/marketsim/agent/extented_zi_agent.py +++ b/marketsim/agent/extented_zi_agent.py @@ -8,13 +8,9 @@ class ZIAgent(Agent): - def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: int, offset: float, eta: float, shade: List, random_seed: int = 0): + def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: int, offset: float, eta: float, shade: List, random_seed: int = None): - if random_seed != 0: - # torch.manual_seed(random_seed) - random.seed(random_seed) - # np.random.seed(random_seed) - + random.seed(random_seed) self.agent_id = agent_id self.market = market diff --git a/marketsim/agent/hbl_agent.py b/marketsim/agent/hbl_agent.py index 159032b1..b0663740 100644 --- a/marketsim/agent/hbl_agent.py +++ b/marketsim/agent/hbl_agent.py @@ -15,12 +15,10 @@ class HBLAgent(Agent): def __init__(self, agent_id: int, market: Market, q_max: int, shade: List, L: int, pv_var: float, - arrival_rate: float, random_seed: int = 0): + arrival_rate: float, random_seed: int = None): - if random_seed != 0: - # torch.manual_seed(random_seed) - random.seed(random_seed) - np.random.seed(random_seed) + random.seed(random_seed) + np.random.seed(random.randint(1,4096)) self.agent_id = agent_id self.market = market diff --git a/marketsim/agent/market_maker.py b/marketsim/agent/market_maker.py index 72760918..7b7ef784 100644 --- a/marketsim/agent/market_maker.py +++ b/marketsim/agent/market_maker.py @@ -8,12 +8,9 @@ class MMAgent(Agent): - def __init__(self, agent_id: int, market: Market, xi: float, K: int, omega: float, random_seed: int = 0): + def __init__(self, agent_id: int, market: Market, xi: float, K: int, omega: float, random_seed: int = None): - if random_seed != 0: - # torch.manual_seed(random_seed) - random.seed(random_seed) - # np.random.seed(random_seed) + random.seed(random_seed) self.agent_id = agent_id self.market = market diff --git a/marketsim/agent/market_maker_beta.py b/marketsim/agent/market_maker_beta.py index 36dae715..6354bdce 100644 --- a/marketsim/agent/market_maker_beta.py +++ b/marketsim/agent/market_maker_beta.py @@ -65,7 +65,11 @@ def __init__(self, p=2, k_min=5, k_max=20, - max_position=15): + max_position=15, + random_seed: int = None): + + random.seed(random_seed) + np.random.seed(random.randint(1,4096)) self.agent_id = agent_id self.market = market diff --git a/marketsim/agent/spoofer.py b/marketsim/agent/spoofer.py index a1cf0950..0e566abb 100644 --- a/marketsim/agent/spoofer.py +++ b/marketsim/agent/spoofer.py @@ -7,12 +7,9 @@ class SpoofingAgent(Agent): - def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: float, order_size:int, spoofing_size: int, normalizers: dict, random_seed: int = 0): - - if random_seed != 0: - # torch.manual_seed(random_seed) - random.seed(random_seed) - # np.random.seed(random_seed) + def __init__(self, agent_id: int, market: Market, q_max: int, pv_var: float, order_size:int, spoofing_size: int, normalizers: dict, random_seed: int = None): + + random.seed(random_seed) self.agent_id = agent_id self.market = market @@ -81,7 +78,7 @@ def get_pos_value(self) -> float: return self.pv.value_at_position(self.position) def reset(self): - self.pv = PrivateValues(self.q_max, self.pv_var) + self.pv = PrivateValues(self.q_max, self.pv_var, random_seed=random.randint(1,4096)) self.position = 0 self.cash = 0 self.last_value = 0 diff --git a/marketsim/agent/zero_intelligence_agent.py b/marketsim/agent/zero_intelligence_agent.py index d8308d0a..955a6171 100644 --- a/marketsim/agent/zero_intelligence_agent.py +++ b/marketsim/agent/zero_intelligence_agent.py @@ -9,18 +9,16 @@ class ZIAgent(Agent): - def __init__(self, agent_id: int, market: Market, q_max: int, shade: List, pv_var: float, eta: float = 1.0, random_seed: int = 0): + def __init__(self, agent_id: int, market: Market, q_max: int, shade: List, pv_var: float, eta: float = 1.0, random_seed: int = None): - if random_seed != 0: - # torch.manual_seed(random_seed) - random.seed(random_seed) - np.random.seed(random_seed) + random.seed(random_seed) + np.random.seed(random.randint(1, 4096)) self.agent_id = agent_id self.market = market self.q_max = q_max self.pv_var = pv_var - self.pv = PrivateValues(q_max, pv_var) + self.pv = PrivateValues(q_max, pv_var, random_seed=random.randint(1, 4096)) self.position = 0 self.shade = shade self.cash = 0 @@ -92,5 +90,5 @@ def get_pos_value(self) -> float: def reset(self): self.position = 0 self.cash = 0 - self.pv = PrivateValues(self.q_max, self.pv_var) + self.pv = PrivateValues(self.q_max, self.pv_var, random_seed=random.randint(1, 4096)) diff --git a/marketsim/event/event_queue.py b/marketsim/event/event_queue.py index ef1a140d..a38b0b36 100644 --- a/marketsim/event/event_queue.py +++ b/marketsim/event/event_queue.py @@ -6,12 +6,9 @@ class EventQueue: - def __init__(self, random_seed: int = 0): + def __init__(self, random_seed: int = None): - if random_seed != 0: - # torch.manual_seed(random_seed) - random.seed(random_seed) - # np.random.seed(random_seed) + random.seed(random_seed) self.scheduled_activities = defaultdict(list) self.current_time = 0 @@ -32,3 +29,4 @@ def get_current_time(self): def set_time(self, t): self.current_time = t + \ No newline at end of file diff --git a/marketsim/fundamental/constant.py b/marketsim/fundamental/constant.py index 3cc58bc7..18fca49d 100644 --- a/marketsim/fundamental/constant.py +++ b/marketsim/fundamental/constant.py @@ -1,15 +1,14 @@ +import random import torch from fundamental_abc import Fundamental class Constant(Fundamental): - def __init__(self, final_time: int, value: float, random_seed: int = 0): - - if random_seed != 0: - torch.manual_seed(random_seed) - # random.seed(random_seed) - # np.random.seed(random_seed) + def __init__(self, final_time: int, value: float, random_seed: int = None): + + random.seed(random_seed) + torch.manual_seed(random.randint(1, 4096)) self.fundamental_values = torch.ones(final_time, dtype=torch.float32)*value diff --git a/marketsim/fundamental/lazy_mean_reverting.py b/marketsim/fundamental/lazy_mean_reverting.py index 55eb6432..58cec09c 100644 --- a/marketsim/fundamental/lazy_mean_reverting.py +++ b/marketsim/fundamental/lazy_mean_reverting.py @@ -1,3 +1,4 @@ +import random import torch from marketsim.fundamental.fundamental_abc import Fundamental @@ -13,12 +14,10 @@ class LazyGaussianMeanReverting(Fundamental): shock_var (float): The variance of the Gaussian shocks. shock_mean (float, optional): The mean of the Gaussian shocks. Default is 0. """ - def __init__(self, final_time: int, mean: float, r: float, shock_var: float, shock_mean: float = 0, random_seed: int = 0): + def __init__(self, final_time: int, mean: float, r: float, shock_var: float, shock_mean: float = 0, random_seed: int = None): - if random_seed != 0: - torch.manual_seed(random_seed) - # random.seed(random_seed) - # np.random.seed(random_seed) + random.seed(random_seed) + torch.manual_seed(random.randint(1, 4096)) self.final_time = final_time self.mean = torch.tensor(mean, dtype=torch.float32) diff --git a/marketsim/fundamental/mean_reverting.py b/marketsim/fundamental/mean_reverting.py index 25cb8eab..43e947a7 100644 --- a/marketsim/fundamental/mean_reverting.py +++ b/marketsim/fundamental/mean_reverting.py @@ -1,14 +1,13 @@ +import random import torch from .fundamental_abc import Fundamental class GaussianMeanReverting(Fundamental): - def __init__(self, final_time: int, mean: float, r: float, shock_var: float, shock_mean: float = 0, random_seed: int = 0): + def __init__(self, final_time: int, mean: float, r: float, shock_var: float, shock_mean: float = 0, random_seed: int = None): - if random_seed != 0: - torch.manual_seed(random_seed) - # random.seed(random_seed) - # np.random.seed(random_seed) + random.seed(random_seed) + torch.manual_seed(random.randint(1, 4096)) self.final_time = final_time self.mean = torch.tensor(mean, dtype=torch.float32) diff --git a/marketsim/market/market.py b/marketsim/market/market.py index 8b9685eb..75e119ad 100644 --- a/marketsim/market/market.py +++ b/marketsim/market/market.py @@ -6,12 +6,9 @@ class Market: - def __init__(self, fundamental: Fundamental, time_steps, random_seed: int = 0): - - if random_seed != 0: - # torch.manual_seed(random_seed) - random.seed(random_seed) - # np.random.seed(random_seed) + def __init__(self, fundamental: Fundamental, time_steps, random_seed: int = None): + + random.seed(random_seed) self.order_book = FourHeap() self.matched_orders = [] @@ -65,5 +62,5 @@ def get_midprices(self): def reset(self, fundamental): self.order_book = FourHeap() self.matched_orders = [] - self.event_queue = EventQueue() + self.event_queue = EventQueue(random_seed=random.randint(1,4096)) self.fundamental = fundamental diff --git a/marketsim/private_values/private_values.py b/marketsim/private_values/private_values.py index 2bfda673..2894f35a 100644 --- a/marketsim/private_values/private_values.py +++ b/marketsim/private_values/private_values.py @@ -1,3 +1,4 @@ +import random import torch from marketsim.fourheap.constants import BUY, SELL @@ -5,8 +6,6 @@ class PrivateValues: """ A class representing private values for a trading scenario. - """ - A class representing private values for a trading scenario. The PrivateValues class generates and manages a set of private values for buy and sell orders. The private values are generated from a normal distribution with a specified variance. @@ -14,17 +13,16 @@ class PrivateValues: as well as calculate the cumulative value up to a given position. """ - def __init__(self, q_max: int, val_var=5e6, random_seed: int = 0): + def __init__(self, q_max: int, val_var=5e6, random_seed: int = None): """ Initialize the PrivateValues object. :param q_max: The maximum quantity. :param val_var: The variance of the values (default: 1). """ - if random_seed != 0: - torch.manual_seed(random_seed) - # random.seed(random_seed) - # np.random.seed(random_seed) + + random.seed(random_seed) + torch.manual_seed(random.randint(1, 4096)) self.values = torch.randn(2 * q_max) * torch.sqrt(torch.tensor(val_var)) self.values, _ = self.values.sort(descending=True) diff --git a/marketsim/simulator/sampled_arrival_simulator.py b/marketsim/simulator/sampled_arrival_simulator.py index c18191e0..7ce17853 100644 --- a/marketsim/simulator/sampled_arrival_simulator.py +++ b/marketsim/simulator/sampled_arrival_simulator.py @@ -25,13 +25,13 @@ def __init__(self, eta: float = 0.2, hbl_agent: bool = False, lam_r: float = None, - random_seed: int = 0 + random_seed: int = None ): - if random_seed != 0: - torch.manual_seed(random_seed) - random.seed(random_seed) - np.random.seed(random_seed) + + random.seed(random_seed) + torch.manual_seed(random.randint(1, 4096)) + np.random.seed(random.randint(1, 4096)) if shade is None: @@ -141,8 +141,6 @@ def run(self): counter = 0 for t in range(self.sim_time): if self.arrivals[t]: - X.append(t) - Y.append(self.markets[0].order_book.get_best_ask()) try: self.step() except KeyError: diff --git a/marketsim/simulator/simulator.py b/marketsim/simulator/simulator.py index 67e64d1f..1fead966 100644 --- a/marketsim/simulator/simulator.py +++ b/marketsim/simulator/simulator.py @@ -17,15 +17,12 @@ def __init__(self, shock_var=10, q_max: int = 10, zi_shade: List = [10, 30], - random_seed: int = 0 + random_seed: int = None ): - if random_seed != 0: - # torch.manual_seed(random_seed) - random.seed(random_seed) - # np.random.seed(random_seed) + + random.seed(random_seed) - self.num_agents = num_background_agents self.num_assets = num_assets self.sim_time = sim_time