Econophysics

Names of group members

// put your names here!

Goals of this assignment

  • Witness what we call "emergent behavior"; large patterns manifesting from the simple interactions of individual agents
  • Develop a graphical way to show the dispersion of money across a society (i.e., collection of agents).
  • Create a working implementation of an econophysics game that you'll design

Econophysics

The term "econophysics" refers to an interdisciplinary research field that uses tools and theories developed by physicists to solve problems relating to economics and finance. These types of models often use statistical methods, or tools developed to describe chaotic systems.

In this exercise, we're going to revisit something you did on the first day of class - the "In for a penny, in for a pound" example of economic transactions. We'll first play two variants of the game, and then we'll figure out how to implement it as a piece of software.

Playing "In For a Penny"

In this model, each "agent" starts with one penny. Some number of rounds are played, and during each round:

  1. Agents with money find each other.
  2. Each agent wagers one penny, and by some random but fair process (flipping a coin, paper-rock-scissors, etc.) pick a winner.
  3. The winner gets the loser's penny.

Before playing, think a bit about the following questions:

  • What will the distribution of money be before the game starts?
  • What about after one round?
  • What about after several rounds of the game? (Say, 5 rounds.)
  • How much money do you personally expect to end up with?

Now, play the game!

Make some notes about how the outcome agreed with your predictions:

Put your answers here!

Playing "In for a pound"

Now, let's change the game. What happens when, instead of starting with 1 penny apiece, we start with $N > 1$ pennies apiece?

Make predictions with your group (answering the questions above).

Now, play the game!

Make some notes about how the outcome agreed with your predictions:

put your answers here!

Now, let's implement this in software.

Write a program to implement the model described above, with:

  • A user-specified number of agents, number_of_agents
  • A user-specified amount of starting money, starting_money
  • A user-specified number of rounds, number_of_rounds

Also, plot out how much money each agent has once the model is run.

First, put together a pseudo-code version of your implementation to think through your logic. What operations need to take place? Check with an instructor before going on!

Then, implement your code.

After that, test your code by reproducing the two models you've implemented above. Is the behavior like what you'd expect?

Finally, make a prediction about something that's impractical to do as a physical experiment. In this case, let's see what would happen with a large number of agents (say, 250 agents) that have lots of money (say, 10 coins) after 100 rounds. Try plotting a histogram to see the distribution of money!


In [ ]:
# Put your code here!
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import numpy.random as rand

def econophysics_game(number_of_agents = 16, starting_money = 1, number_of_rounds = 5):
    '''
    Plays the game.
    Inputs:  
        number_of_agents: number of agents playing the game (default 16)
        starting_money: starting amount of money in integer units (default 1)
        number_of_rounds: number of rounds in the game (default 5)
        
    Returns: numpy array with final distribution of money among agents
    '''
    
    # gives everybody money
    agent_money = np.full(number_of_agents, starting_money, dtype='int64')

    turn = 0
    
    print("starting:", agent_money)

    # loop for the number of rounds we want to play
    while turn < number_of_rounds:

        # assign partners
        partners = find_partners(agent_money)
        
        # flip a coin to hand out money
        agent_money = make_trades(agent_money, partners)
    
        turn += 1

    print("final:   ", agent_money)

    return agent_money


def find_partners(agent_money):
    '''
    Finds partners for each agent that has money.
    Input: array of money per agent
    Returns: array of identical size with lists of partners (w/o partner has value of -1)
    '''

    # make our partner array and set all the values to -1
    partners = np.full_like(agent_money,-1)
    
    # loop over all of the partners
    for i in range(partners.size):

        # if this agent has money and does not yet have a partner,
        # then find it a partner.
        if agent_money[i] > 0 and partners[i] < 0:
            
            # try a bunch of times to find a partner for this agent.
            # we're giving a hard upper bound of number of tries, which
            # is the number of agents squared.  (This is arbitrary.)
            for j in range(partners.size**2):

                # randomly pick a possible partner for my agent
                part=rand.randint(0,partners.size)

                # if the potential partner has money and doesn't yet have a
                # partner, make it my partner and break the loop.
                if agent_money[part] > 0 and partners[part] < 0 and part != i:
                    partners[i] = part
                    partners[part] = i
                    break

    return partners

def make_trades(agent_money, partners, amount_per_bet = 1):
    '''
    Actually makes the trades.
    Inputs: 
        array of amount of money that the agents have
        array of partners
        and amount per bet.
    Output: new array of money that agents have
    '''

    # loop over the partners
    for i in range(partners.size):
        
        # if the agent has money and the partner has an index greater than the partner
        # (which ensures that we only hit each pair one time), then we flip a coin
        if agent_money[i] > 0 and partners[i] > i:
            
            # flip a coin.  If it comes up 0, this agent wins and takes amount_per_bet
            # from its partner.  If it comes up 1, it goes the other way.
            if rand.randint(0,2) > 0:
                agent_money[i] += amount_per_bet
                agent_money[partners[i]] -= amount_per_bet
            else:
                agent_money[i] -= amount_per_bet
                agent_money[partners[i]] += amount_per_bet
            
            # regardless of the outcome, these partners have now bet and we're done.
            partners[i] = partners[partners[i]] = -1

    return agent_money

In [ ]:
num_agents = 256
start_money = 10
num_rounds = 100

agent_money = econophysics_game(number_of_agents = num_agents,
                                starting_money=start_money,
                                number_of_rounds=num_rounds)

plt.subplot(1, 2, 1)
plt.plot([0,num_agents],[start_money,start_money],'r-',linewidth=2,alpha=0.5)
plt.plot([0,num_agents],[0,0],'k-',alpha=0.1,linewidth=3)
plt.plot(agent_money,'bD')
plt.ylim(-1,agent_money.max()+1)
plt.xlim(-1,num_agents+1)

plt.subplot(1,2,2)
plt.hist(agent_money)

Assignment wrapup

Please fill out the form that appears when you run the code below. You must completely fill this out in order to receive credit for the assignment!


In [ ]:
from IPython.display import HTML
HTML(
"""
<iframe 
	src="https://goo.gl/forms/ruc09jXCzGfbap6V2?embedded=true" 
	width="80%" 
	height="1200px" 
	frameborder="0" 
	marginheight="0" 
	marginwidth="0">
	Loading...
</iframe>
"""
)

Turn it in!

Turn this assignment in to the Day 22 dropbox in the "in-class activities" folder.