# Agent Based Modeling: A Simple Market

I was reading Nate Silver’s The Signal and the Noise today and I ran across his idea of Bayesland, a place where people walk around with sandwich boards listing things on which they would place a bet. If they meet a person whose odds on an event differs substantially from their own odds on that event, then the two will make a bet.

I thought that it would be neat to simulate this idea and see what would happen. In my example, we have three agents that bet on the probability of a coin coming up heads. The coin is simulated through a Bernoulli process, and the true probability or heads is 60%.

I created an agent class that would be initialized with a key, a hypothesis regarding the probability of heads, a bankroll, and some idea of the past events. When two agents meet, they compare keys. If they have the same keys, and a difference of opinion regarding the probability of a heads, then they make a bet. Each participant is willing to bet 5% of their bankroll, and when they meet and bet, they just bet the average of whatever they’re willing to wager. (That’s not a very important detail.)

Another arbitrary implementation detail was the fact that each agent has a slightly different recollection of past events. This is controlled in a probabilistic manner. I thought that agents with perfect knowledge would be less interesting. This could also be interpreted as a form of irrationality. Anyway, what I was hoping to see was the bettors converging around the actual value of the probability of heads, which I set at 60%. This sort of happened most of the time.

# Code

```import scipy.stats
import numpy as np
import random
```

Define an Agent class with a number of randomly assigned parameters, and a means of learning about the environment.

```class Agent:
def __init__( self ):
# two agents will interact if they have the same key
self.key = random.randint(1,5)
# select a random probability of heads
self.hypothesis = scipy.stats.uniform(0,1).rvs()
self.bank = 100
# set the bet at 5% of the bankroll
self.bet = self.bank * 0.05
# initialize the "memory"
self.memory = [ scipy.stats.uniform(0,1).rvs() ]
# set some recollection accuracy
self.accuracy = scipy.stats.uniform(0,0.1).rvs()
def inform( self, outcome ):
# if u is less than the recollection accuracy
# then the agent "forgets" the outcome of the flip
u = scipy.stats.uniform(0,1).rvs()
if u < self.accuracy:
self.memory.append( outcome )
# take the mean of the observations
observations = np.mean( self.memory )
# update the hypothesis based on the observations
self.hypothesis = np.mean( [ self.hypothesis, observations ] )
def update( self ):
# reset the key
self.key = random.randint(1,5)
# reset the recollection accuracy
self.accuracy = scipy.stats.uniform(0,0.1).rvs()
# update the bet
self.bet = self.bank * 0.05
```

A loop to pit the agents against each other in a random fashion according to the “key” each agent holds, which is changed at the end of each iteration.

```# create a list of three agents
a = [ Agent() for i in range(3) ]

# create three clunky lists
A, B, C = list(), list(), list()

# go for 500 turns
for i in range( 500 ):

# flip a coin with a 60% chance of landing heads up
flip = scipy.stats.bernoulli(0.6).rvs()

# for each agent..
for j in range( len( a ) ):
# for each remaining agent..
for k in range( j+1, len(a) ):

# if they meet by chance (have the same key)
if a[j].key == a[k].key:

# and if their opinions differ greatly enough..
h0, h1 = a[j].hypothesis, a[k].hypothesis
if np.abs( h0 - h1 ) > 0.1:

# the greater hypothesis bets heads
# the lesser hypothesis bets tails
if h0 > h1:
tail = a[k]
bet = np.mean( [ a[j].bet, a[k].bet ] )
elif h1 > h0:
tail = a[j]
bet = np.mean( [ a[j].bet, a[k].bet ] )

# if the flip was a heads..
if flip == 1:
tail.bank -= bet
elif flip == 0:
tail.bank += bet

# inform the agents of the flip
# change their keys and recollection probability
for agent in a:
agent.inform( flip )
agent.update()

# clunkily record the results
A.append( [ a.hypothesis, a.bank ] )
B.append( [ a.hypothesis, a.bank ] )
C.append( [ a.hypothesis, a.bank ] )
```

Now, plot the results!

```# convert to NumPy arrays
A = np.array( A ).T
B = np.array( B ).T
C = np.array( C ).T

# begin plotting
fig, axs = subplots(2,1)
axs.set_ylabel("Prediction")
axs.plot( A )
axs.plot( B )
axs.plot( C )
axs.set_ylim(0,1)

axs.set_ylabel('Bankroll')
axs.plot( A )
axs.plot( B )
axs.plot( C )

savefig("market_bets.png",dpi=200,bbox_inches='tight')
``` 