The Ricardian Trade Model

One in a series of python jupyter notebooks on Trade models by Jonathan Conning

Notes: the plots and simulations below are written in python. This notebook can be run interactively on a jupyter server. Much of the code is in a separate econteach module. You can also view this notebook in slideshow mode (Alt-R) if the proper extension is installed.

import sys
from ipywidgets import interact, interact_manual, fixed
%matplotlib inline
%load_ext autoreload
%autoreload 2
sys.path.insert(0,"..")
from ricardo import *

Warm up: budget lines and indifference curves

You have I=$100 income.

You can buy good X or good Y where might refer to food nutrition bars and good Y to manufactured trinkets.

  • \(p_x\) – Price of one unit of good X measured in $ per unit

  • \(p_y\) – Price of one unit of good Y measured in $ per unit

  • \(\frac{p_x}{p_y}\) – Relative price of good X measured in terms of good Y.

Interactive: move the sliders to change parameter values.

interact(budget,px=(0.3,3,0.1),py=(0.3,3,0.1),I=(50,150,10),show=fixed(True) );

Ricardian model

Linear Production Technologies

Labor is the only input.

Good \(X\) and good \(Y\) are produced with linear production technologies:

\[Q_X = MPL_X \cdot L_X\]
\[Q_Y = MPL_Y \cdot L_Y\]

where \(MPL_X\) and \(MPL_X\) are the constant marginal product of labor productivity parameters in the \(X\) and the \(Y\) sector, respectively.

The marginal product of good \(X\) is measured in units of good \(X\) per unit labor.

The labor resource constraint

The sum of labor demands in the two sectors cannot exceed the economy’s total labor supply \(\bar L\):

\[L_X + L_Y = \bar L\]

Minimum labor requirements

We can invert the \(X\) production function to find the minimum labor required to produce any quantity \(Q_X\):

\[L_X = \frac{1}{MPL_X} Q_X\]

\(a_{LX}=\frac{1}{MPL_X}\) is the constant unit labor requirement to produce each additional unit of \(Q_X\).

The minimum labor required to produce any quantity \(Q_Y\) is

\[L_Y = \frac{1}{MPL_Y} Q_Y\]

\(a_{LY}=\frac{1}{MPL_Y}\) is the constant unit labor requirement to produce each additional unit of \(Q_Y\).

The Production Possibility Frontier (PPF)

Tells us what is feasible to produce given available technology and resource constraints.

The economy’s labor resource constraint

\[L_X + L_Y = \bar L\]

can be rewritten (using our minimum labor requirement functions) to find:

\[\frac{1}{MPL_X} Q_X + \frac{1}{MPL_Y} Q_Y = \bar L\]

le us re-arrange the PPF constraint further to obtain an expression easy to plot:

\[Q_Y = MPL_Y \cdot \bar L - \frac{MPL_Y}{MPL_X} Q_X\]

Example: If \(MPL_X = 2\), \(MPL_Y = 1\) and \(\bar L = 200\) then the PPF curve is given by:

\[Q_Y = 200 - \frac{1}{2} Q_X\]
rppf(mplx=2,mply=1,lbar=200)
../_images/Ricardian_Trade_20_0.png

The PPF has:

  • \(Y\) intercept: \(MPL_Y \cdot \bar L = 1 \cdot 200 = 200\)

  • \(X\) intercept: \(MPL_X \cdot \bar L = 2 \cdot 200 = 400\)

The negative slope shows that there is a tradeoff:

  • We need \(\frac{1}{MPL_X}=1/2\) workers to produce one more unit of good X.

  • With full employment we can only get this labor by pulling them out of Y production.

  • Each worker there would have produced \(MPL_Y=1\) units of Y, so withdrawing \(\frac{1}{MPL_X}\) workers will reduce Y output by

\[ \frac{MPL_Y}{MPL_X} = \frac{2}{1} \left ( \frac{\text{units of Y}}{\text{units of X}} \right ) \]

Hence (negative of) the slope tells us the opportunity cost of an extra unit of good X, measured in terms of units of good Y which must be given up.

Competitive Prices and Wages

Firms will earn profit and want to hire more workers so long as the marginal value product of labor exceeds the market wage. Competition between firms and workers moving across firms and sectors in search of the highest wage will drive profits to zero at which the following market equilibrium conditions must hold:

\[P_X \cdot MPL_X = w = P_Y \cdot MPL_Y \]

All workers are paid the same wage which will be equal to their marginal value product, which is equalized across firms and sectors.

Real wages

The nominal wage \(w\) is measured in dollars. From the zero profit condition we can determine real wages:

\[\frac{w}{P_X} = MPL_X \, \,\,\, \text{(units of good X per unit of labor)}\]
\[\frac{w}{P_Y} = MPL_Y\, \,\,\, \text{(units of good Y per unit of labor)}\]

these measure the purchasing power of this nominal wage in terms of good \(X\) and good \(Y\) respectively.

\[\frac{w}{P_X}=MPL_X=2 \text{ and } \frac{w}{P_Y}=MPL_Y=1\]

In this competitive economy workers are paid a real wage equal to their marginal product. Workers are the only factor of production and firm profits are driven to zero so workers get all of the output in the economy.

Important Note:

\(\frac{w}{P_X}\) and \(\frac{w}{P_Y}\) are not different wages for workers in each sector, they are just two different ways to measure the real purchasing power of a worker’s wage.

There is only one wage in the economy and all workers earn the same wage no matter what sector or firm they work in!

It is easy to determine real wages just from eyeballing the PPF graph, if you know the size of the labor force. In the plot real GDP measured in terms of good X is 400 units and since there are 100 workers each worker gets paid a real wage of 4 units of X. If real GDP is measured instead in terms of good Y real GDP is 200 units of Y and since there are 100 workers each worker gets paid a real wage of 2 units of Y.

rppf(mplx=2,mply=1,lbar=200)
../_images/Ricardian_Trade_30_0.png

We could also define a real wage in terms of any arbitrary basket of goods. For example, let

\[P_B = P_X + P_Y\]

be the price of a basket with one unit of good \(X\) and one of good \(Y\). The wage \(w\) can purchase \(\frac{w}{P_B}\) such baskets.

Prices in the closed economy

To produce one unit of \(X\) requires \(a_{LX}=\frac{1}{MPL_X}\) units of labor. Each unit of labor costs \(w\). Hence the marginal cost of producing \(X\) is

\[MC_X = \frac{w}{MPL_X}\]

Cmpetitive firms maximize profits where \(P_X=MC_x\) and hence:

\[P_X = \frac{w}{MPL_X}\]

Similarly in sector \(Y\), firms price at:

\[P_Y = \frac{w}{MPL_Y}\]

So the domestic (or closed economy) relative price of \(X\) measured in terms of good \(Y\) is

\[\frac{P_X}{P_Y} = \frac{MPL_Y}{MPL_X}\]

which is equal to the slope of the PPF. Relative prices reflect opportunity costs.

Note that in this Ricardian model with linear production technologies we have determined equilibrium relative prices without having to specify consumer preferences or demand! This will not be the case in more general models.

Interactive diagram

Visible/interactive if running a jupyter server.

interact(rppf, mplx=(0.25,4,0.25), mply=(0.25,4,0.25), lbar=(25, 200, 5),show=fixed(True), title=fixed('Home'));

Home opens to Trade – Gains to Trade

Suppose Home has these technologies and resources:

\[\begin{split} MPL_X^* = 1 \text{ units of X/worker} \\ MPL_Y^* = 2 \text{ units of X/worker} \\ \bar L^* = 100 \text{ workers} \end{split}\]

Then the opportunity cost of producing one unit of good X measured in terms of good Y at Home is:

\[\frac{P_X}{P_Y}=\frac{MPL_Y}{MPL_X}= \frac{1}{2}\]

This is Home’s autarky relative price of producing good X

If the world relative price of good X is \(\frac{p_x^w}{p_y^w} = 1\) units of Y then Home is a relatively low cost producer of good X (since 1/2 units of Y per X < 1 units of Y per X). Given Home’s technologies and these world prices Home has a comparative advantage in the production of good X

If it opens up to trade producers will find it profitable to continue to expand X production (at the expense of Y production) until the country becomes specialied in the production of X. At that point the country’s GDP will be \(MPL_X \cdot \bar L\) units of good X which it can trade to the world at the world price of 1 unit of good Y per X. Hence the citizens of the Home country can consume along the consumption possibility frontier given by the world price line running through the specialization point \((q_x=MPL_x\cdot \bar L and q_y = 0)\)

The specialized economy is depicted below.

MX = MPLY
MY=MPLX *1.25
openrppf(mplx=MX, mply=MY, lbar=LBAR, pw=MY/MX)
../_images/Ricardian_Trade_44_0.png

A two country model

Technologies and hence domestic relative prices are different in two countries.

At Home: $\( MPL_X = 2 \\ MPL_Y = 1 \)$

In Foreign: $\( MPL_X^* = 1 \\ MPL_Y^* = 2 \)$

The autarky relative price of X is

At HOME: \(\frac{MPL_Y}{MPL_X} = \frac{1}{2}\) units of good Y per X

In FOREIGN: \(\frac{MPL_Y^*}{MPL_X^*} = \frac{2}{1}\) units of good Y per X

Home has a comparative advantage at producing X as it is the lower cost producer.

tworppf(2, 1, 100, 1, 2, 100)
../_images/Ricardian_Trade_46_0.png

At a world price of \(\frac{p_x^*}{p_y^*}=\frac{3}{4}\) units of good Y per X, Home will specialize at X production and Foreign at Y production, but trade will not balance.

qx, qy, cx, cy = openeq(mplx=2, mply=1, lbar=100, pw=3/4)
print(f'qx = {qx}, qy = {qy}, cx = {cx}, cy = {cy}')
print(f'Home exports {qx-cx} units of good X and imports {cy-qy} units of good Y')
qx = 200, qy = 0, cx = 100.0, cy = 75.0
Home exports 100.0 units of good X and imports 75.0 units of good Y
rtwopane(2, 1, 100, 1, 2, 100, p=0.75)
../_images/Ricardian_Trade_49_0.png

We can try to find the equilibrium price by trial and error – by increasing or decreasng the world relative price until trade balances.

interact(rtwopane, mplx=fixed(2), mply=fixed(1), lbar=fixed(100),  mplfx=(0.5,2,0.1), mplfy=(0.5,2,0.1), 
         lbarf=(50, 200, 10),p=(0.2,3,0.1));

To find a world equilibrium price consistent with balanced trade we only need to find where the market for one good clears. The worldeq function finds this relative price by findind the price at which world excess demand for good X is set to zero.

rworldprice(mplx=2, mply=1, lbar=100, mplfx=1, mplfy=3, lbarf=100)
1.5000000000000002

The worldeq finds the world equilibrium price.

interact_manual(rworldeq, mplx=(0.5,2,0.1), mply=(0.5,2,0.1), lbar=(50, 200, 10),  mplfx=(0.5,2,0.1), mplfy=(0.5,2,0.1), 
         lbarf=(50, 200, 10));

More fun

We can switch to a XKCD comic style of graph, to make them seem more hand drawn.

It’s a good idea however to store current matplotlib settings in case we want to restore things later.

mpl_state = plt.rcParams.copy()
plt.xkcd()  # switch to xkcd look
interact(openrppf, mplx=(0.5,2,0.1),mply=(0.5,2,0.1), lbar=(50,200,10),pw=(0.5, 2, 0.1) );

#Now reset to more standard matplotlib style.

#plt.rcParams.update(mpl_state)