0, 'fund_vol': 1e-8, 'megashock_lambda_a': 2.77778e-13, 'megashock_mean': 1e3, 'megashock_var': 5e4, 'random_state': np.random.RandomState( seed=np.random.randint(low=0, high=2**32, dtype='uint64')) } } oracle = SparseMeanRevertingOracle(mkt_open, mkt_close, symbols) # 1) Exchange Agent agents.extend([ ExchangeAgent( id=0, name="EXCHANGE_AGENT", type="ExchangeAgent", mkt_open=mkt_open, mkt_close=mkt_close, symbols=[symbol], log_orders=True, pipeline_delay=0, computation_delay=0, stream_history=10, book_freq=book_freq,
def generateMidPrices(self, sigma_n): if not self.seed: self.seed = int( pd.Timestamp.now().timestamp() * 1000000) % (2**32 - 1) np.random.seed(self.seed) # Note: sigma_s is no longer used by the agents or the fundamental (for sparse discrete simulation). symbols = { self.symbol: { 'r_bar': self.r_bar, 'kappa': self.kappa, 'agent_kappa': 1e-15, 'sigma_s': 0., 'fund_vol': self.sigma_s, 'megashock_lambda_a': 1e-15, 'megashock_mean': 0., 'megashock_var': 1e-15, "random_state": np.random.RandomState( seed=np.random.randint(low=0, high=2**32, dtype='uint64')) } } util.silent_mode = True LimitOrder.silent_mode = True OrderBook.tqdm_used = False kernel = CalculationKernel( "Calculation Kernel", random_state=np.random.RandomState( seed=np.random.randint(low=0, high=2**32, dtype='uint64'))) ### Configure the agents. When conducting "agent of change" experiments, the ### new agents should be added at the END only. agent_count = 0 agents = [] agent_types = [] # Let's open the exchange at 9:30 AM. mkt_open = self.midnight + pd.to_timedelta('09:30:00') # And close it at 4:00 PM. mkt_close = self.midnight + pd.to_timedelta('16:00:00') # Configure an appropriate oracle for all traded stocks. # All agents requiring the same type of Oracle will use the same oracle instance. oracle = SparseMeanRevertingOracle(mkt_open, mkt_close, symbols) # Create the exchange. num_exchanges = 1 agents.extend([ ExchangeAgent( j, "Exchange Agent {}".format(j), "ExchangeAgent", mkt_open, mkt_close, [s for s in symbols], log_orders=False, book_freq=self.freq, pipeline_delay=0, computation_delay=0, stream_history=10, random_state=np.random.RandomState( seed=np.random.randint(low=0, high=2**32, dtype='uint64'))) for j in range(agent_count, agent_count + num_exchanges) ]) agent_types.extend(["ExchangeAgent" for j in range(num_exchanges)]) agent_count += num_exchanges symbol = self.symbol # Some value agents. # agents.extend([ValueAgent(j, "Value Agent {}".format(j), # "ValueAgent {}".format(j), # random_state=np.random.RandomState( # seed=np.random.randint(low=0, high=2 ** 32, dtype='uint64')), # log_orders=False, symbol=symbol, starting_cash=self.starting_cash, # sigma_n=sigma_n, r_bar=s['r_bar'], kappa=s['agent_kappa'], # sigma_s=s['fund_vol'], # lambda_a=self.lambda_a) for j in range(agent_count, agent_count + self.num_agents)]) # agent_types.extend(["ValueAgent {}".format(j) for j in range(self.num_agents)]) # agent_count += self.num_agents agents.extend([ GuessAgent( j, "Guess Agent {}".format(j), "GuessAgent {}".format(j), random_state=np.random.RandomState( seed=np.random.randint(low=0, high=2**32, dtype='uint64')), log_orders=False, symbol=symbol, starting_cash=self.starting_cash, sigma_n=sigma_n, lambda_a=self.lambda_a) for j in range(agent_count, agent_count + self.num_agents) ]) agent_types.extend( ["GuessAgent {}".format(j) for j in range(self.num_agents)]) agent_count += self.num_agents # Config the latency model latency = None noise = None latency_model = None USE_NEW_MODEL = True ### BEGIN OLD LATENCY ATTRIBUTE CONFIGURATION ### ### Configure a simple message latency matrix for the agents. Each entry is the minimum ### nanosecond delay on communication [from][to] agent ID. # Square numpy array with dimensions equal to total agent count. Most agents are handled # at init, drawn from a uniform distribution from: # Times Square (3.9 miles from NYSE, approx. 21 microseconds at the speed of light) to: # Pike Place Starbucks in Seattle, WA (2402 miles, approx. 13 ms at the speed of light). # Other agents can be explicitly set afterward (and the mirror half of the matrix is also). if not USE_NEW_MODEL: # This configures all agents to a starting latency as described above. latency = np.random.uniform(low=21000, high=13000000, size=(len(agent_types), len(agent_types))) # Overriding the latency for certain agent pairs happens below, as does forcing mirroring # of the matrix to be symmetric. for i, t1 in zip(range(latency.shape[0]), agent_types): for j, t2 in zip(range(latency.shape[1]), agent_types): # Three cases for symmetric array. Set latency when j > i, copy it when i > j, same agent when i == j. if j > i: # Presently, strategy agents shouldn't be talking to each other, so we set them to extremely high latency. if (t1 == "ZeroIntelligenceAgent" and t2 == "ZeroIntelligenceAgent"): latency[ i, j] = 1000000000 * 60 * 60 * 24 # Twenty-four hours. elif i > j: # This "bottom" half of the matrix simply mirrors the top. latency[i, j] = latency[j, i] else: # This is the same agent. How long does it take to reach localhost? In our data center, it actually # takes about 20 microseconds. latency[i, j] = 20000 # Configure a simple latency noise model for the agents. # Index is ns extra delay, value is probability of this delay being applied. noise = [0.25, 0.25, 0.20, 0.15, 0.10, 0.05] ### END OLD LATENCY ATTRIBUTE CONFIGURATION ### ### BEGIN NEW LATENCY MODEL CONFIGURATION ### else: # Get a new-style cubic LatencyModel from the networking literature. pairwise = (len(agent_types), len(agent_types)) model_args = { 'connected': True, # All in NYC. 'min_latency': np.random.uniform(low=21000, high=100000, size=pairwise), 'jitter': 0.3, 'jitter_clip': 0.05, 'jitter_unit': 5, } latency_model = LatencyModel( latency_model='cubic', random_state=np.random.RandomState( seed=np.random.randint(low=0, high=2**31)), kwargs=model_args) # Start the kernel running. with HiddenPrints(): midprices = kernel.runner( agents=agents, startTime=self.kernelStartTime, stopTime=self.kernelStopTime, agentLatencyModel=latency_model, agentLatency=latency, latencyNoise=noise, defaultComputationDelay=self.defaultComputationDelay, oracle=oracle, log_dir=None, return_value={self.symbol: "midprices"}) midprices_df = midprices[self.symbol] if len(midprices_df) == 390: new_row = pd.DataFrame( {"price": midprices_df.iloc[0, 0]}, index=[midprices_df.index[0] - pd.Timedelta("1min")]) midprices_df = pd.concat([new_row, midprices_df]) return midprices_df