Let's Build an Economy

Jan 29, 2019

One of the best ways to learn about something is to build it. When you build something for the first time you are forced to think of intimate details that you might not have thought of in advance, because it’s something that is strange or counter-intuitive but absolutely essential to how that thing functions. Repeatedly you will stumble across several seemingly minor details and are forced to stop for a moment to think about how you’re going to tweak things to incorporate them. Sometimes this will only require some minor changes, but other times it will require a major rethink on how you’re doing what you’re doing.

As part of this series, we’re going to take this idea and apply it to building an economy. Over the course of several tutorial posts, we’re going to outline a design to build an economy on the computer, write the code that will follow the rules in our design, and run it to see what happens. We’ll create some output using a database, from which we can construct charts and run statistics to have an idea on what is going on inside our new virtual world. Through this, hopefully we’ll learn all sorts of interesting things about economies that we may not have known already, either because it came out of the simulation, or we had to do some research into existing work to see how other people have solved this problem in the past.

On the way, in addition to learning plenty about economics, we’ll become quite familiar with the tools we use to build the economy: computer programming, software engineering, and mathematics. These on their own are very interesting and useful tools, so it’s worth the exercise even if we aren’t particularly concerned about the economics side of things.

I hope you enjoy this journey, and learn plenty along the way!

The Baseline Overview

Mar 3, 2019

Before we get started building any sort of more complex economy, the first thing we’ll want to do is confirm that it actually works by comparing the results of a simple virtual economy with what economic theory predicts will happen. We’ll do this by writing out a mathematical model of a very simple economy using standard economic theory, and see what sort of results it gives out. This will give us a prediction on what we’d expect to see, and then we can compare what we get from the simulation. If they match up then we have a good idea that our simulation works well, and we have more faith in it as we scale it up to larger economies. If they don’t match up it will probably indicate that we have a bug, but it could also point to something interesting in the way we’re doing our simulation.

As mentioend, this first version of our economy is going to be very simple, since as we scale up we probably won’t be able to do the same mathematical analysis - the number of variables and equations makes solutions impossible to find very quickly. Over time we’ll add complexity to add more interesting ideas, but because we started from a solid mathematical base and tested each step thoroughly, we can have a reasonable assurance that we didn’t make a mistake somewhere.

Let’s start off by describing our mathematical model of the economy. Imagine a very basic economy where we have some firms and some workers. We’ll say that in this imaginary economy, firms produce a good: biscuits. The firms own the means of production (the ovens) but don’t know how to actually make the biscuits, where the workers know how to make them but don’t have ovens and have no possibility of getting them. Firms pay their workers in biscuits instead of with money (which doesn’t exist in this fictional world).

This means that workers don’t actually have much thinking to do. They just work. The whole process is determined entirely by the firms, who have some sort of profit maximizing objective:

\begin{equation} \max_L \pi(w) = Q(L) - wL \end{equation}

Given a market wage $w$, the firm chooses the amount of labour $L$ that they hire in order to produce a certain amount of goods, determined by a production function $Q$. For simplicity we can just use the standard Cobb-Douglas production function:

\begin{equation} Q = AL^\alpha \end{equation}

Here $A$ is a technology multiplier, and $\alpha$ is a factor that determines the returns to scale of labour. We’ll want to restrict this to be between 0 and 1, which means that as you add more labour you get more quantity but the amount you get for each additional person declines over time (aka diminishing marginal product of labour).

Lastly, we’ll say that our economy is finite. There are $F$ firms and $N$ workers in our world.

This gives us our labour supply and demand curves:

\begin{equation} L_s = N \end{equation} \begin{equation} L_d = F\left (\frac{w}{A\alpha} \right )^{\frac{1}{\alpha - 1}} \end{equation}

In equilibrium, we get the following for the market wage:

\begin{equation} w = A\alpha\left (\frac{N}{F}\right)^{\alpha - 1} \end{equation}

The workers should be evenly distributed among the firms, there will be $\frac{N}{F}$ workers per firm.

Note that there is one degenerate case here: profits should never be negative, or firms will not demand any labour at all. In a Cobb-Douglas world it is never possible for profits to be negative unless $\alpha$ > 1, which is ruled out by assumption.

Now that we have our prediction, we can build our economy and see if it lines up.

The first thing we have to think about now that we didn’t have to in the mathematical analysis is: how do we get to equilibrium? Instead of just plugging the formula into the code which would make for a very boring simulation but also very unscalable to more complicated models, we want to have each agent make their own decisions and hope that we’ll arrive at the same value. We’ll have to come up with some sort of decision process that each agent follows.

The next thing we’ll have to think about is how do firms and workers connect with one another? From the mathematical analysis it’s easy for us to say that each firm will have $\frac{N}{F}$ workers, but we have no idea how those workers got there in the first place. We’ll have to build some mechanism for matching workers with firms.

Lastly, we’ll have to think about time. The mathematical analysis assumes we’re in equilibrium, which means that time doesn’t actually matter any more - the system has settled to a stable state, and all time after that point is the same. In our simulation though we aren’t going to start off in equilibrium, so we’ll need to think about how things change over time from the initial state to when it settles to equilibrium.

We’ll address the issue of time first, since it’s the easiest. We’ll just split up time into discrete steps, call them “days”. Each day all firms and workers will make their decisions, and absolutely none of them will be binding the next day - workers will not stay at a firm. This simplifies things because firms won’t have to decide about firing workers, and workers won’t have to decide about finding a new job.

Next we’ll decide how firms and workers get matched up with one another. There are many ways we can do this, but for this model we’ll use a market mechanism. It’s a relatively simple but flexible mechanism that we’ll be able to re-use when we start making our economy more complex.

This market will be a double auction modelled off of the stock market: workers (the sellers of labour) submit the minimum wage that they are willing to work for, and firms (the buyers of labour) submit the maximum wage they are willing to pay and the amount of workers they want to hire. This will potentially result in an overlap in wage values, so the market will match all the workers and firms who are in that overlap and notify them using a callback mechanism to say that they were matched. The market will track the high $w_h$ and the low $w_l$ of the overlap and expose those values for firms and workers so they can use them in future decision processes; ideally in equilibrium the high and low values will converge to a value that we can call the market wage1.

Lastly, the decision processes of firms and workers. Workers are very simple: they are trying to get the highest wage possible while remaining employed. If the agent was unemployed2 last round, it will try to guarantee itself a job by undercutting the market and offer a wage equal to $w_l - \tau$ ($\tau$ being an adjustment factor, provided as a parameter to the simulation). If they were employed then it’s possible they offered too low a wage, so they will offer $w_h$ as their wage.

Firms are slightly more complex because they are looking to fill a number of workers rather than just a single one, and are optimizing over a curve instead of a binary value. So firms will first decide on a wage to offer the market. A firm that did not get enough employees last period will try to lure workers from competitors by offering a wage of $w_h + \tau$; a firm that satisfied its requirements last period will attempt to offer $w_l$. Based on the chosen wage, the firm knows they can maximize their profits by using the individual labour demand function, so this will result in the number of workers to hire (with a few exceptions, they need to submit discrete values so they’ll choose the value of $floor(L)$ and $ceil(L)$ that maximizes profits).

There is one degenerate case for firms: if the wage they decide on results in them making negative profits, they will instead choose to hire no workers. In this model this should theoretically never be the case, but we’ll add it to the code anyway for two reasons: (1) we’re not 100% sure what will happen outside of equilibrium, so adding this condition avoids going off into non-sensical outcomes; and (2) as we make our models more complex this could become a realistic outcome for some firms, so we can add it now so we don’t forget to add it later.

We now have an outline for a simple virtual economy. The next few articles we’ll actually be writing some code for these, which will lay some framework for future simulations. Lastly, we’ll define a way we can extract results from this model and compare to the mathematical version. I’m looking forward to it!

  1. In practice because there is a bit of uncertainty and randomness involved in a simulation, we may see the high and the low remain separate with a difference of $\tau$. [return]
  2. An unemployed worker is one whose market order was not filled in the last period. [return]


Mar 9, 2019

Now we’re going to describe how we’ll build our markets. Before we get started though, I’d like to distinguish two concepts in our simulations. The first element is an agent, which is an entity in our simulation that attempts to make an intelligent decision to accomplish some kind of goal. Individuals attempt to maximize their utility/happiness, firms attempt to maximize profits, governments attempt to maximize…something. Contrast with the second concept, a mechanism, which is an element that simply follows a set of mechanical rules. An example of this is the double-auction market that we’ll describe in this article; it simply accepts orders and in all cases it follows a set of well-defined rules. It does not have any sort of objective.

It’s important to distinguish this because our simulations are decentralized: there is no auctioneer or benevolent overlord guiding the system. We expect to see a true invisible hand at work. If we had some sort of agent managing the interaction between other agents, then we don’t really have a decentralized system.

Now with that out of the way, let’s talk a bit about double-auction markets. These are markets where participants submit orders to buy or sell a certain quantity of a good with a certain price called the limit price. As the market receives these orders, it will compare them to the existing orders it has received and execute a match if possible. It will then notify both the buyer and the seller of a fill which says that the owner has traded a certain amount at a certain value.

Let’s run through an example. There are some existing orders already placed in the market; one buy order at $\$$5, a sell order at $\$$5.50, and a sell order at $\$$6. In this case the bid, the highest buy order price, is $\$$5; and the ask, the lowest sell order price, is $\$$5.50.

Suppose someone comes along and submits a buy order with a limit price of $\$$5.51. Since this is greater than the ask, the order will execute with a price of $\$$5.50 (the price is based on the order that was already in the market). What happens next depends on the sizes of the orders. If the buy order has a greater size than the sell order then the entire sell order will be filled, the buy order will be partially filled, the new bid will be $\$$5.51, and the new ask will be $\$$6 to match the sell order remaining in the market. If the sell order has a greater size, then the buy order will be completely filled, the sell order will be partially filled, and the bid/ask prices will remain the same. If the sizes are equal, then both orders will be filled and the new ask will be $\$$6.

The way we’ll implement this is with two heaps: one for buy orders and one for sell orders. These heaps will be indexed by the price of the orders. When each order comes in, we’ll check against the heap containing the opposite types of orders, and pop orders off and fill them until we either no longer have a price overlap, or the size of the new order has been reduced to zero. As mentioned earlier, there will be a callback that is sent to the owner of each order to let them know they have been filled.

That’s it for the primary logic of the system. There are a few edge cases that we haven’t talked about, those are handled in the code and you’re welcome to browse that if you want to know more details. We’ll move on now to how we’re going to code this up.

The code is in two Git repositories called econerra and econerra-main, which is the name I’ve given the virtual economy we’re playing with. The code is written in the Go programming language, a newer language that makes a good trade-off between performance (much faster than Python, Matlab) and ease-of-use (much easier to use than C++, Java, Fortran).

The econerra-main repository is the one where you run things, it will contain all the infrastructure and tools for the project. The actual agents and things are in the econerra repository.

You can run the project easily enough, however you’ll want to follow the instructions for the baseline-2019-03-09 tag since this repo will be liable to change over time as I play around with new ideas. The code for the double auction market is here. Enjoy!