← Reading note · Caselli, Koren, Lisicky & Tenreyro (2020)

From ten data files to 1,728 equilibria

“Diversification through Trade” asks whether cheaper trade made national incomes calmer from 1972 to 2007. Answering it takes two machines. One extracts the model's parameters from trade, output and price data. The other solves a general equilibrium for every year, in 101 possible states of the world, under four scenarios and twelve calibrations. This page follows the numbers through both, using the authors' package and the Julia 1.12 rewrite that reproduces it.

Each cell is one year's equilibrium: 12 calibrations × 4 scenarios × 36 years. Tap a row for what that calibration changes.

Tap any , any data file or constraint, or a marked shape on the drawings, to open its details.

ACT I · EXTRACTION

Ten files become eleven parameters

Section III of the paper turns data into the model's objects without solving any equilibrium. Every step here is a closed-form inversion: if the model were true, these numbers would reproduce the data exactly.

The lineage

Nine vendors, fourteen files, ten read

The package ships processed inputs, not raw data. They were assembled from UN Comtrade, UNIDO, EU KLEMS, UN National Accounts, the World Bank, the Penn World Table and OECD input–output tables, with gaps filled by estimation (). The code reads ten files. Four sit in the folder unused, including the the paper says it deflates by.

Scroll to follow each parameter back to its files. The drawing highlights one at a time.

Reads
Data layout · read_data.jl

Everything is a four-index array

Each input becomes an array indexed : destination, source, sector, year. Where an index does not apply, the dimension stays with length one, a , so arrays multiply against each other without loops.

Bilateral trade fills all four. Value added fills three. The value-added share β ends up one number per sector.

Reads
Imposes
Trade costs · eq. 14

κ comes from how much two countries buy from each other

Take Canada and the United States in motor vehicles. If trade costs are symmetric and buying at home is free, the model says (dnm dmn) / (dmm dnn) = κ2θ. This is the . Productivity cancels, so κ comes straight from four trade shares.

Scroll to move from 1972 to 2007: the cross flows thicken and κ rises toward 1, which is free trade.

Reads
Imposes
Prices · Section III.A.2–3

Only the United States has measured sectoral prices

Sectoral price deflators exist for one country in the code, the United States, from . Every other country's sector price is inferred from its trade shares relative to the US: log Pjm = meann[(1/θ) log(dmn/dUS,n) − log(κmn/κUS,n)] + log PjUS.

The price of services, which has no trade, is the that makes the sector prices add up to the PWT price level. Demand weights invert the expenditure shares at those prices.

Reads
Imposes
Productivity · eq. 15

Twenty-five partners, twenty-five estimates, one average

A country's unit cost φ should look the same from every destination: φn = κmn Pm dmn−1/θ for every buyer m. In the data it doesn't, so the code takes the across all 25. Here: South Korea, radio and TV equipment, 2007.

Productivity then solves the cost equation: A = ξ B (w)β Πk(Pk)γ / φ̄, with wages from value-added shares.

Reads
Imposes
Trend and cycle · Section III.A.4

A seven-weight filter splits trend from shock

The trend of log productivity is what agents expect; the cycle is the shock. The cycle is a : a symmetric moving average whose seven weights sum to zero. At the sample edges the series is extended by , three years each side.

Same series: South Korea, radio and TV. The window slides as you scroll.

Readsno file: the calibrated A
Imposes
Shock decomposition · eq. 16

One matrix of shocks becomes three

Each year's cycles form a 25 × 24 matrix. The column means are the . The weighted row means of what remains are the . The residual is the . Shown for 1974, the first oil shock: watch oil refining and agriculture.

Only μ survives in the “country shocks only” scenarios. Trade can diversify μ across partners; λ hits every country's sector together.

Readsno file: the A cycles
Imposes
Expectations · eq. 12

One hundred worlds that did not happen

Labor is committed to sectors before the year's shocks are known. To form that expectation, each shock gets an , and every year the code draws from last year's value. State 1 is the realised world. The 1972 allocation has no draws at all, so it is chosen under .

Drawn here: λ for oil refining, the most volatile sector shock.

Readsno file: λ, μ, ε series
Imposes
Random numbers · compat06.jl

The same bits as in 2019

To reproduce a Monte Carlo you need the same random numbers. Julia changed two things since version 0.6: how an integer seed is , and how the normal sampler draws its . The rewrite restores both.

Each strip is the 64-bit pattern of one draw: sign, exponent, mantissa. Against the real Julia 0.6.4 binary, the first 3,000,000 draws agree bit for bit.

Checked
ACT II · DATA MEET CONSTRAINTS

Where the model has to overrule the data

An inversion only works if the data are consistent with the model's accounting. Where they are not, the code clips, floors, averages or winsorises. Counting how often each fix binds shows which results lean on it.

Constraint · 0 < dnn ≤ 1

Imports larger than everything a country uses

The domestic share is one minus measured import shares. In 1,157 of 20,700 country-sector-years, measured imports equal or exceed absorption, so the home share would be zero or negative. The code and renormalises.

The cases cluster in small, very open economies: Belgium–Luxembourg (230), the Netherlands (209), Ireland (164). Re-exports are excluded from the trade data, so gateway trade, transit recording and estimated output are the likely culprits. The data cannot say which.

Data
Clipped
Constraint · κ ≤ 1

Trade cheaper than buying at home

A tiny home share makes the Head–Ries ratio explode, implying that shipping abroad is cheaper than selling at home. The model rules that out, so κ is . The cap binds for 56,096 of 496,800 pair-sector-years, 11.3%.

For Belgium–Luxembourg it binds in 31% of its pairs; for the Netherlands 28%, Ireland 26%. For the United States, Japan and France, 6–7%.

Data
Clipped
Constraint · final shares ≥ 0

A quarter of final demand comes out negative

Final expenditure is backed out as total spending, E = R d−1, minus intermediate use. Inverting a 25 × 25 trade matrix amplifies measurement error: 5,398 of 21,600 cells come out negative.

The code smooths the shares with the band-pass trend, them at the smallest positive value across countries, smooths again and normalises. These shares only seed the demand weights ν, which are then averaged across countries.

Data
Clipped
Constraint · β + Σγ = 1

One technology for every country and every year

Value added over gross output varies from 0.011 to 22.7 in the raw panel; 16 of its 21,600 cells exceed one, which is impossible. The code averages it into one per sector, between 0.15 and 0.61.

The input–output shares come from OECD tables for 1995–2007 only, averaged, then rescaled so each sector's column sums to 1 − β exactly. The same coefficients run the economy of 1972.

Data
Imposes
Assumptions that act as constraints

Seven choices, four of them tested

Some constraints are not repairs to the data but modelling choices. The paper tests four in robustness tables: θ (Table IV), σ (Table VI), trade imbalances (Table III) and input–output links (Table VII). Three are never varied: services are nontraded, trade costs are symmetric, and the US is the price anchor.

Services are 75% of world value added. Their shocks reach other countries only through prices, never through trade in services.

Tested
Fixed
Does it matter?

The largest effects sit where the clipping is heaviest

Across countries, the share of κ pairs capped at 1 correlates at r = −0.68 with the diversification effect of Table I. Belgium–Luxembourg, the Netherlands and Austria have the largest falls in volatility. They are also among the most clipped.

This is an association, not a cause. Openness drives both: the 2007 import share correlates at 0.72 with the capped share. What it does show is that the paper's strongest country results rest on the trade data the model had to overrule most.

From
ACT III · THE SOLVER

One year, four nested loops

Given parameters, each year's equilibrium is a fixed point inside a fixed point inside a fixed point. The traces below are real. The nested trace is the authors' own code, re-run under Julia 0.6.4, for 1972 in the baseline. The year-by-year traces come from the rewrite.

Starting values · Appendix A.1

Start from a world without trade costs

Under free trade the model has a closed form. World revenue by sector is the of αβ′ + γ; each country's share of a sector follows from its productivity and labor. The loops start here and walk toward the costly-trade world.

Services take 48% of world revenue in 1972, agriculture and mining 10%, and the 22 manufacturing sectors split the rest.

Uses
The loop structure

1972, iteration by iteration

The sets labor by sector before shocks land. The would let labor move afterwards. The finds expenditure shares, and the finds unit costs that clear every market.

Scroll slowly: the playhead replays the authors' 1972 run, all 7 outer iterations and 20 middle iterations, with the inner-loop count of every call.

Trace
Inner loop · eq. 24

Most of the work happens in the first call

Market clearing gives unit costs in one line: φθ = Σm(κ Pm)θEm / R. Revenue is with weight 0.533, and the loop stops when the trade shares those costs imply move by less than .

The first call of 1972 needs 56 iterations. Once prices are close, calls alternate between real work and a single confirming step. Below: total inner iterations in every year.

Stops at
Middle loop · eq. 10

Expenditure shares settle in a sawtooth

The middle loop recomputes who spends what, final demand plus intermediate use, and damps the update with weight 0.449. Each tooth is one outer iteration: a new labor allocation kicks the shares, and the middle loop walks them back under 3 × 10⁻⁴.

Stops at
Outer loop · eq. 12

Labor follows expected wage bills

Each sector's labor share should equal its expected share of the wage bill, averaged over the 100 drawn states, with the realised one excluded. The update is damped with weight 0.606 and stops below 10⁻³. Every one of the 36 years converges in 5 to 7 steps.

The distances fall in pairs. Two steps in a row barely differ, then the next drops by a factor of four. Real income is reported at the .

Stops at
Why loose tolerances matter

At θ = 2 the last bit decides

At the baseline θ = 4, the rewrite and the authors' code agree on every outer distance, in all 36 years, to five digits. At they agree in only 12 years. Distances sit near the stopping thresholds, so a last-bit difference in a sum decides whether a loop takes one more damped step.

In 1979 both runs agree for two outer iterations. Then one takes an extra middle step, the paths split, and one stops after 6 outer iterations, the other after 7.

Result
ACT IV · TABLES AND CHECKS

1,728 equilibria, three columns

Real income from the realised state of every year becomes a series. Its band-pass cycle has a variance, and four variances make a row of every table.

The decomposition

Four variances for each country

Each calibration runs four times: actual trade costs or , all shocks or . For Canada in the baseline, squares are drawn to area.

Total change = (V − V72)/V72. Diversification = (Vc − Vc72)/V72. Specialization is the difference.

Output
Verification · scripts/verify.jl

Three targets, from deepest to most visible

The , re-run unmodified, pins every calibrated array and single years of the solver. The pin the variances. The pins the cells. All 823 printed cells match, outside the θ = 2 panel.

Reproducing them meant reproducing fourteen things the code does that the paper does not say: