Every formula, every parameter, every assumption, and the five errors caught before launch.
Three independent levers, each 0–100 and each moved on its own. An earlier version drove all three from one severity dial; the engine's own note on the change says it plainly — “one dial governing all three was a metaphor, not a model” — because it forced a country closing its border to capital to be closing it to goods and people in fixed proportion, which is not how policy is made. Retaliation is not a lever the reader sets; it is a modelled response to the tariff, on by default.
| Lever | Policy | Primary channel |
|---|---|---|
| Tariffs | Universal ad-valorem duty on all imports | Import prices up, volume down |
| Capital leaving | A share of the inward direct-investment POSITION withdrawn, spread over the repatriation horizon | Investment down |
| Migration cap | Arrivals blocked at the border | Labour force down |
| Retaliation — partners impose the same duty in return; a modelled response to the tariff lever, not a separate control. Export volume down. | ||
Magnitudes are anchored to things that actually happened, so they cannot be dismissed as invented. Piecewise linear between anchors, so each is hit exactly.
| Dial | Tariff | Historical anchor |
|---|---|---|
| 25 | 10% | The universal baseline tariff floated in policy debate |
| 50 | 25% | US average duty on Chinese goods, 2019 |
| 100 | 60% | Smoot-Hawley territory — roughly 59% on dutiable imports, 1930 |
In MY COUNTRY the tariff is universal: every supplier taxed alike, no escape hatch — which has a second consequence that is easy to miss and expensive to get wrong, discussed under parameters below. In THE WORLD it is universal by default, and can be targeted at one partner (the P2 shock) — and then trade diversion is exactly what a targeted tariff produces, so the model models it: see the targeted subsection of section 8.
Do not compute GDP from Y = C + I + G + X − M. Imports enter with a minus
sign, so cutting imports mechanically raises measured GDP. But the imports that fell
were the consumption and investment, so C and I fall too and the terms cancel. A model
built on the identity reports that a trade war is good for you.
Prices faced by domestic buyers, with near-full pass-through — the strongest empirical finding from 2018–19 is that foreign exporters did not cut their prices:
The Harberger triangle, incremental over the existing tariff. Note the τ²: this component genuinely is quadratic.
A tariff is a tax on your own producers' imported inputs. This is the channel naive models miss entirely, and in open manufacturing economies it rivals the consumer-side loss.
The v_x term separates a real model from a fake one. Vietnam's exports are
roughly half imported components, so losing a dollar of Vietnamese exports destroys only about
fifty cents of Vietnamese GDP. Omit it and every assembly economy looks two to three times more
damaged than it is.
Investment falls for two reasons: the capital screen directly, and trade-policy uncertainty, which is well documented and separate from the tariff itself. Firms delay capital spending when they do not know next quarter's rules.
A large economy is big enough to push down the world price of what it buys. A small one is not. This is mainstream trade theory, and it means the model does not treat every country identically. Size is real, and the United States gets a partial offset that Vietnam does not.
The Harberger formula already nets out tariff revenue and producer surplus. Revenue is a transfer from consumers to government; producer gains are a transfer from consumers to protected firms. Both sit inside the rectangle, and the triangles are what remains. Adding revenue back double-counts. Terms of trade is different — it is a transfer from foreigners to residents, a genuine national gain, and it does enter the sum.
The Taylor rule is applied to changes, not levels. A level rule re-decides policy from scratch and then disagrees with the observed baseline rate whenever inflation is away from target — and reports a rate move at dial zero, when nothing has happened.
The currency is decomposed rather than ranged. Two opposing forces are shown
separately: weaker growth pushing it down, higher policy rates pulling it up, and the point
where the sign flips. flex is 1.0 for a float, 0.4 for a managed rate, 0 for a peg.
A peg cannot absorb the shock, so the adjustment goes into output instead — which is why
the model applies an additional penalty to export losses under a peg.
GDP per capita is the output that lets the model concede the opposing case. The visa lever
hits both numerator and denominator. Whether it falls by more or less than GDP depends
entirely on whether excluded workers produced above or below the resident average. With
π_m < 1 the per-capita path sits above the GDP path — a real result, in
the mainstream literature, displayed rather than hidden.
Every parameter carries a distribution, not just a value, because the Monte Carlo needs the second moment. Every parameter also carries a tier, shown next to the number it produces.
| Symbol | Meaning | Value | SD | Tier |
|---|---|---|---|---|
| psi | tariff pass-through | 0.95 | 0.05 | calibrated |
| eps | aggregate import elasticity | -0.8 | 0.4 | calibrated |
| eps_x | export demand elasticity | -1.35 | 0.35 | calibrated |
| phi_I | input-cost transmission | 0.55 | 0.15 | calibrated |
| eps_supply | input-margin supply elasticity | 1 | 0.4 | calibrated |
| kappa | retaliation intensity | 1 | 0.2 | assumed |
| lambda_unc | uncertainty drag on investment | 0.09 | 0.04 | calibrated |
| eta_tot | terms-of-trade gain | 0.35 | 0.15 | calibrated |
| a | Taylor: inflation weight | 1.5 | 0.3 | calibrated |
| b | Taylor: output weight | 0.5 | 0.2 | calibrated |
| rho | Taylor: rate smoothing | 0.75 | 0.1 | calibrated |
| gamma_g | FX: growth channel | 1.8 | 0.9 | assumed |
| gamma_i | FX: rate channel | 2.2 | 1.1 | assumed |
| peg_penalty | peg rigidity penalty | 0.3 | 0.12 | assumed |
| mu_redeploy | resource redeployment | 0.7 | 0.15 | calibrated |
| mig_rel_prod | migrant relative productivity | 0.9 | 0.12 | calibrated |
| theta_dom | domestic substitution share | 0.45 | 0.15 | calibrated |
| mu_single | single-market redeployment | 0.5 | 0.15 | calibrated |
| phillips | Phillips slope | 0.15 | 0.08 | calibrated |
| erpt_ae | FX pass-through (advanced) | 0.1 | 0.04 | calibrated |
| erpt_em | FX pass-through (emerging) | 0.3 | 0.1 | calibrated |
| erpt_li | FX pass-through (low-income) | 0.45 | 0.15 | calibrated |
| okun | Okun coefficient | 0.5 | 0.12 | calibrated |
| mps | marginal propensity to save | 0.25 | 0.08 | calibrated |
| reloc_share | capital that relocates | 0.6 | 0.15 | assumed |
| reloc_yield | output yield on arriving capital | 0.35 | 0.15 | calibrated |
| remit_elast | remittance response | 0.85 | 0.2 | calibrated |
| accel | investment accelerator | 1.5 | 0.5 | calibrated |
| fdi_repatriation_horizon_years | FDI repatriation horizon | 5 | 2 | assumed |
| delta_divert | diverted share (targeted) | 0.5 | 0.15 | calibrated |
eps is the aggregate import demand elasticity — foreign versus
domestic. It is not the Armington substitution elasticity — foreign versus foreign —
which is three to five times larger.
The substitution elasticity is the easier one to estimate, the better-identified one, and the one a gravity regression naturally hands you. It also answers a question this model does not ask. A universal tariff hits every supplier equally and therefore switches the substitution margin off by construction. Plug σ ≈ −5 into a universal shock and the trade collapse is overstated roughly fourfold.
The hard part is not computation. It is identification. Tariffs are not randomly assigned: protection is granted to industries already dying, heavy traders lobby their tariffs down, and growing economies import more and liberalise at once. A naive cross-country regression returns a confident wrong sign — with more apparent authority than an honest calibration.
| Parameter | Design | Identifying variation |
|---|---|---|
| Pass-through ψ | Event study on duty-exclusive unit values, product-source and source-time fixed effects | Timing of the 2018–19 tariff waves, driven by trade politics rather than conditions in the affected markets |
| Import elasticity ε | PPML in levels, country and year fixed effects, clustered | Within-country tariff variation after absorbing common trends |
| Growth response θ | Shift-share: exposure = pre-period export shares × partner tariffs | Export shares are predetermined and cannot respond to the shock |
| Taylor a, b, ρ | Partial-adjustment rule on BIS policy-rate data | Within-country variation in inflation and the output gap |
| Retaliation κ | None — assumed | Not estimable. N is about five |
| Exchange rate γ | None — assumed, decomposed | FX is near a random walk at short horizons |
PPML, not OLS on logged trade. Log-linearising gravity is biased under heteroskedasticity, and it silently drops every zero trade flow — precisely the flows a large tariff creates. Santos Silva and Tenreyro settled this in 2006.
The shift-share design is also the narrative. Exposure varies across countries because their pre-existing trade structure varies. That is not merely an identification strategy; it is literally the story the tool tells — the same shock lands differently because the countries were built differently. The econometrics and the narrative are the same object.
Nothing ships until the gate passes. Four layers.
Additional duties collected were roughly $75bn a year on about $3.1tn of US goods imports, equivalent to a universal increment of about 2.3 percentage points. Only China retaliated at scale, and China took roughly 8% of US goods exports, so retaliation coverage for this episode is about 0.08 rather than the ~0.75 the tool uses for a universal war.
The model returns a net welfare loss of 0.1664% of GDP. Published estimates span roughly 0.04% (Fajgelbaum, Goldberg, Kennedy and Khandelwal 2020, static, after revenue and producer gains) to 0.3–0.5% once investment and uncertainty channels are included. The model lands inside that range without having been fitted to it.
Dial zero is an exact no-op across every output. Damage is monotone. Deadweight loss is convex. Dial anchors hit exactly.
The model exists twice — Python for testing, JavaScript for the browser. The two are compared across 4,160 domestic scenarios (208 countries × 10 dial positions × retaliation on and off) on 34 output fields, plus 266 world scenarios covering every usable shock origin, with every world field compared. The largest relative disagreement is 1.6 × 10⁻¹⁴. The sampler is compared too, draw for draw, so the browser's uncertainty stream is the same stream Python validated. This check found a bug neither engine would have revealed alone.
The estimators are run first on synthetic data with known true parameters. A broken pipeline on real data looks exactly like a working one; a broken pipeline on synthetic data with a known answer does not.
Five errors were caught by the validation infrastructure. All five would have shipped silently and all five produced plausible output. The process that caught them is more informative than the final numbers.
The migration variable was defined as a share of population growth but used as though it were a growth rate, producing a 48-percentage-point movement in Germany. Behind the units error sat a real omission: the lever shrank population without shrinking output, so excluding workers improved output per head at no cost. The fix adds a labour-supply channel and makes the effect depend on migrant relative productivity — which is the economically meaningful quantity and the reason the result is interesting at all.
Imports passing straight through into exports were charged in both the input-cost and export channels. Singapore's loss came out at 33% before the fix.
Applied to levels, the rule re-decided policy from scratch and disagreed with the observed baseline whenever inflation was away from target. Nigeria's rate moved 6 percentage points when nothing had happened. Found by the Python–JavaScript parity check.
The recovery test reported the import elasticity as recovered when the estimate was −4.73 against a truth of −1.20, because the tolerance was scaled to a standard error of 2,821. The fault was in the PPML implementation, which absorbed fixed effects inside each iteration but formed fitted values from undemeaned regressors. The test now requires both closeness and a sane standard error.
Total damage was described throughout development as growing with the square of the tariff. Plotting it showed the headline curve is close to linear: the quadratic deadweight term is swamped by four channels linear in ln(1+τ). Doubling the tariff roughly doubles total damage while quadrupling the deadweight component. The claim was corrected rather than the chart.
Every one produced output that looked reasonable. None would have been caught by reading the code. Each was found by a check that asked the model a question with a known answer: does nothing happen when nothing happens; do two implementations agree; can the estimator find a parameter it was told; does the historical episode reproduce.
Everything above describes one country absorbing its own shock. THE WORLD asks the other question: an origin country closes, and what does that do to everyone selling to it? The answer is accounting, not equilibrium, and the distinction is the whole of its honesty.
Only the tariff dial reaches other countries. The origin's goods imports contract by
dlnM = ε × ψ × ln(1 + Δτ)
— one elasticity, one pass-through, the log of the tariff change — and that contraction is what partners feel. The capital and migration dials act on the origin alone, through its own domestic run; no partner sees them. Three dials sit side by side in the interface, and only one of them crosses a border.
The contraction is allocated pro-rata by each partner's share of the origin's goods imports, taken from the IMF bilateral file. That partner's slice is then measured against its own GDP, which is why the ranking is dominated by small, exposed economies rather than large ones: Germany loses more dollars than Mauritania when Canada closes, and Mauritania loses more of itself. The export loss is scaled by the partner's domestic value-added share — a country that re-exports imported content loses less of its own output than the gross flow suggests — and by mu_single, which credits an exporter with re-routing part of a blocked flow to other buyers.
Adding-up. The partner flow changes, plus the explicit rest-of-world residual, sum to the origin's total import change. Exactly — the gate holds it to 1×10⁻⁹ across every usable origin. Demand does not appear or vanish in transit.
Terms-of-trade conservation. When the origin buys less, it also pays less per unit, and that gain is a transfer, not new wealth. The same dollars are debited to partners pro-rata. Origin gain equals partner debits, to the same tolerance. A model that let the origin gain without anyone paying for it would be manufacturing welfare.
The podium reports the three countries losing the largest share of their own GDP, each with a deterministic reason string assembled from the exposure decomposition — no prose is written at runtime. Beside it sits a rank-stability figure: the whole model is re-run repeatedly with the bilateral cells and value-added shares redrawn from their disclosed distributions, and the figure is how often that country keeps its place.
Read it for what it is. It resamples the model's inputs with the model's structure held fixed. Everything in section 9 — no general equilibrium, no second round, no substitution between partners, no trade diversion — is not varied at all and contributes nothing to that percentage. It is an input-sensitivity measure, not a robustness claim, and it is reported in five-point steps because the sample cannot resolve a whole percent.
Where a country's podium place rests on a single flow that is large for its economy and small in absolute terms, the card says so and that country's draws are widened. Nothing in this build carries a commodity dimension, so the model cannot tell a diversified trading relationship from one mine, and ore re-routes rather than evaporating when a buyer closes.
The tariff can hit one partner instead of everyone. The targeted flow contracts by the same elasticity arithmetic; a share δ of the abandoned demand — the delta_divert parameter, calibrated on the 2018–19 reallocation — re-routes to the untargeted suppliers, and the remainder vanishes as the aggregate demand response. The recipients’ weights are an assumed rule, stated as one: pro-rata over their existing shares, because nothing in this build carries product detail, so who substitutes for whom cannot be estimated, only asserted. Gains keep their full value-added content; the origin’s own dashboard runs at the universal-equivalent rate (Δτ × the target’s import share); and both identities are restated and gated: losses sum to the targeted contraction, gains to the diverted pool, and the terms-of-trade debit re-bases onto the post-shock composition so conservation stays exact.
This is what makes the 2018–19 shape testable at last: the US targeting China at the episode’s bilateral magnitude produces a double-digit bilateral contraction, an aggregate fall an order of magnitude smaller, and Vietnam and Mexico on the gaining side — and the gate asserts all three. Under a universal wall diversion stays OFF by doctrine: every supplier faces the same tariff, so there is no untaxed alternative to divert to, and no country can gain.
The world gate runs thirty checks. Most are internal — identities, sign conventions, drift tests; they prove the arithmetic is consistent with itself, which is worth having and is not the same as being right. The empirical ones anchor the origin’s aggregate contraction and, in targeted mode, the partner-incidence shape above, with deliberately loose bands: the shape is the claim, not the decimal.