This project studies the welfare and trade effects of removing all remaining tariffs between Gulf Cooperation Council (GCC) countries. The policy experiment asks: what happens if Qatar, the UAE, Saudi Arabia, Kuwait, Oman, and Bahrain move to full intra-GCC free trade?
This question is important because GCC economies are geographically close, politically connected, and highly integrated through energy exports, logistics, finance, and re-export trade. Even small remaining trade barriers can affect prices, sourcing decisions, and welfare in a general equilibrium setting.
The model is calibrated to 2023 data, the most recent available year in the dataset. It includes the six GCC countries along with major external trade partners: the EU, United States, China, India, Japan, South Korea, the United Kingdom, and Turkey. All other countries are grouped into Rest of World. This selection captures key global trade relationships while keeping the model computationally manageable.
config <- eora_config(eora_rds_path = "eora_data.rds", template_root = ".")
# Baseline year
config$Calibration_Year <- 2023
# Tariff baseline
config$Tariff_Year <- 2019
# Balanced-trade baseline
config$balanced_trade <- TRUE
# Numeraire
config$Normalize_Country <- "USA"
# Countries: GCC + key external partners
config$countries <- pick_countries(
"GCC",
"EU",
add = c("USA", "CHN", "IND", "JPN", "KOR", "GBR", "TUR")
)
show_picked(config$countries)
## 14 named entries selected plus ROW (15 model regions total):
## ISO3 Name
## QAT Qatar
## ARE UAE
## SAU Saudi Arabia
## KWT Kuwait
## OMN Oman
## BHR Bahrain
## EUU EU
## USA United States
## CHN China
## IND India
## JPN Japan
## KOR South Korea
## GBR United Kingdom
## TUR Turkey
# Focal countries for display
cf_country1 <- "QAT"
cf_country2 <- "ARE"
# Counterfactual: free trade within GCC
scenarios <- list(
"Free trade within GCC" = list(
list(type = "bilateral_tariff", country1 = "QAT", country2 = "ARE", tau = 1.00),
list(type = "bilateral_tariff", country1 = "QAT", country2 = "SAU", tau = 1.00),
list(type = "bilateral_tariff", country1 = "QAT", country2 = "KWT", tau = 1.00),
list(type = "bilateral_tariff", country1 = "QAT", country2 = "OMN", tau = 1.00),
list(type = "bilateral_tariff", country1 = "QAT", country2 = "BHR", tau = 1.00),
list(type = "bilateral_tariff", country1 = "ARE", country2 = "SAU", tau = 1.00),
list(type = "bilateral_tariff", country1 = "ARE", country2 = "KWT", tau = 1.00),
list(type = "bilateral_tariff", country1 = "ARE", country2 = "OMN", tau = 1.00),
list(type = "bilateral_tariff", country1 = "ARE", country2 = "BHR", tau = 1.00),
list(type = "bilateral_tariff", country1 = "SAU", country2 = "KWT", tau = 1.00),
list(type = "bilateral_tariff", country1 = "SAU", country2 = "OMN", tau = 1.00),
list(type = "bilateral_tariff", country1 = "SAU", country2 = "BHR", tau = 1.00),
list(type = "bilateral_tariff", country1 = "KWT", country2 = "OMN", tau = 1.00),
list(type = "bilateral_tariff", country1 = "KWT", country2 = "BHR", tau = 1.00),
list(type = "bilateral_tariff", country1 = "OMN", country2 = "BHR", tau = 1.00)
)
)
ModelData <- initialize_model_data_eora(config)
cat("Sectors:", ModelData$S, " Model regions:", ModelData$J, "\n")
## Sectors: 10 Model regions: 15
knitr::kable(
data.frame(
Code = ifelse(ModelData$Country_List == "EUU", "EU", ModelData$Country_List),
Name = country_name(ModelData$Country_List),
row.names = NULL
),
caption = "Model regions", row.names = FALSE
)
| Code | Name |
|---|---|
| ARE | UAE |
| BHR | Bahrain |
| CHN | China |
| EU | EU |
| GBR | United Kingdom |
| IND | India |
| JPN | Japan |
| KOR | South Korea |
| KWT | Kuwait |
| OMN | Oman |
| QAT | Qatar |
| ROW | Rest of World |
| SAU | Saudi Arabia |
| TUR | Turkey |
| USA | United States |
if (!is.null(ModelData$sector_names)) {
knitr::kable(ModelData$sector_names[1:ModelData$S, ],
caption = "Traded sectors and elasticities")
}
| sector | sector_name | is_traded |
|---|---|---|
| 1 | Agriculture and Fishing | TRUE |
| 2 | Mining and Quarrying | TRUE |
| 3 | Food and Beverages | TRUE |
| 4 | Textiles and Apparel | TRUE |
| 5 | Wood and Paper | TRUE |
| 6 | Petroleum/Chemical/Non-Metallic Minerals | TRUE |
| 7 | Metal Products | TRUE |
| 8 | Electrical and Machinery | TRUE |
| 9 | Transport Equipment | TRUE |
| 10 | Other Manufacturing | TRUE |
I chose the GCC countries because the counterfactual focuses on intra-regional tariff removal. I also include major external partners because GCC economies trade heavily with large global markets, especially China, India, the EU, and the United States. Including these partners allows the model to capture trade diversion: if intra-GCC trade becomes cheaper, some demand may shift away from outside suppliers.
The year 2023 is used because it is the latest available year in the data. This makes the calibration more relevant for current trade patterns. The model uses ten traded sectors, including agriculture, mining, food, textiles, chemicals, metals, machinery, transport equipment, and other manufacturing.
The model is first calibrated using observed data, including trade deficits, to recover structural parameters. Then, by default, trade deficits are set to zero and the model is re-solved to obtain a balanced-trade baseline. This means counterfactuals are compared against a balanced-trade benchmark.
Set config$balanced_trade <- FALSE in Section 2 to
keep observed deficits.
ModelVar_Calibrated <- calibrate_model(ModelData, config)
res_calib <- equilibrium_solve(ModelVar_Calibrated)
ModelVar_Calibrated <- res_calib$ModelVar
stopifnot(res_calib$exitflag > 0)
if (isTRUE(config$balanced_trade)) {
message("Setting D = 0 for balanced-trade baseline...")
ModelVar_Baseline <- apply_balanced_trade(ModelVar_Calibrated)
res_base <- equilibrium_solve(ModelVar_Baseline)
ModelVar_Baseline <- res_base$ModelVar
stopifnot(res_base$exitflag > 0)
# Update welfare baseline to the balanced-trade equilibrium
ModelVar_Baseline$Welfare_Baseline <- ModelVar_Baseline$Welfare
} else {
ModelVar_Baseline <- ModelVar_Calibrated
}
We run 1 scenario(s): Free trade within GCC.
all_results <- list()
all_cev <- list()
for (nm in names(scenarios)) {
message("Scenario: ", nm)
MV_cf <- build_counterfactual(ModelVar_Baseline, scenarios[[nm]])
res_cf <- equilibrium_solve(MV_cf)
stopifnot(res_cf$exitflag > 0)
all_results[[nm]] <- summarize_results(ModelVar_Baseline, res_cf$ModelVar, label = nm)
all_cev[[nm]] <- compute_welfare_cev(ModelVar_Baseline, res_cf$ModelVar)
all_cev[[nm]]$scenario <- nm
}
all_results <- do.call(rbind, all_results)
all_cev <- do.call(rbind, all_cev)
library(tidyr)
# Always include the focal country pair + top 5 biggest movers
focal <- c(cf_country1, cf_country2)
top <- unique(
all_results$country[order(abs(all_results$welfare_pct_change), decreasing = TRUE)]
)
display_countries <- unique(c(focal, head(setdiff(top, focal), 5)))
display <- all_results[all_results$country %in% display_countries, ]
wide <- display %>%
select(name, scenario, welfare_pct_change) %>%
pivot_wider(names_from = scenario, values_from = welfare_pct_change)
knitr::kable(wide, digits = 3,
caption = "Welfare change (%) — biggest movers across scenarios")
| name | Free trade within GCC |
|---|---|
| UAE | 0.678 |
| Bahrain | 0.322 |
| South Korea | 0.167 |
| Oman | 0.197 |
| Qatar | 0.655 |
| Rest of World | -0.142 |
| Saudi Arabia | 0.363 |
CEV measures welfare change using baseline preferences. When preferences do not change, CEV equals the standard welfare measure. Since this project changes tariffs rather than preferences, the CEV results are expected to match the standard welfare results.
cev_wide <- all_cev %>%
filter(country %in% display_countries) %>%
select(name, scenario, cev_pct) %>%
pivot_wider(names_from = scenario, values_from = cev_pct)
knitr::kable(cev_wide, digits = 3,
caption = "CEV (%) — consumption equivalent variation")
| name | Free trade within GCC |
|---|---|
| UAE | 0.678 |
| Bahrain | 0.322 |
| South Korea | 0.167 |
| Oman | 0.197 |
| Qatar | 0.655 |
| Rest of World | -0.142 |
| Saudi Arabia | 0.363 |
plot_welfare_report(
all_results,
title = "Welfare impact by scenario",
subtitle = paste("Baseline:", config$Calibration_Year,
"| Numeraire:", config$Normalize_Country)
)
The results suggest that removing tariffs within the GCC increases welfare for all GCC countries in the displayed results. Qatar gains by about 0.655%, while the UAE gains by about 0.679%. Saudi Arabia gains by about 0.363%, Bahrain by 0.322%, Oman by 0.197%, and Kuwait by 0.065%.
The largest gains appear for Qatar and the UAE. This is reasonable because both economies are small, open, and strongly connected to regional trade networks. The UAE also functions as a major regional logistics and re-export hub. Lower tariffs reduce the delivered price of GCC goods, improve sourcing efficiency, and reduce the cost of intermediate and final goods.
Some non-GCC countries also gain slightly, such as South Korea, China, India, Turkey, the EU, and Japan. South Korea’s welfare gain likely reflects its role as a supplier of intermediate and capital goods to GCC economies. As GCC demand expands under free trade, imports of these goods may increase, benefiting some external suppliers.
However, the Rest of World and the United States experience small welfare losses. These losses are likely caused by trade diversion. As GCC countries trade more with each other, some demand shifts away from non-GCC suppliers. The losses are small, which suggests that the policy mainly reallocates trade patterns rather than creating large global disruptions.
The relatively small magnitude of welfare gains suggests that remaining tariffs within the GCC are already low, so full liberalization produces incremental rather than transformative effects. These results are consistent with the Armington structure of the model, where goods are differentiated by country of origin and trade costs affect relative demand across suppliers.
Because there is only one counterfactual scenario, the results cannot be compared across tariff levels. Instead, the main comparison is between the balanced-trade baseline and the intra-GCC free trade counterfactual.
library(ggplot2)
wage_df <- all_results %>%
mutate(wage_pct = 100 * (wage_cf / wage_baseline - 1))
ggplot(wage_df, aes(x = reorder(name, wage_pct), y = wage_pct, fill = scenario)) +
geom_col(position = "dodge") +
geom_hline(yintercept = 0) +
coord_flip() +
labs(title = "Wage changes by country",
x = NULL, y = "Wage change (%)", fill = "Scenario") +
theme_minimal(base_size = 12) +
theme(legend.position = "bottom")
Wages remain essentially unchanged in the results because the model normalizes wages relative to the chosen numeraire. Welfare changes therefore come mainly from price index effects and improved sourcing efficiency rather than nominal wage movements.
The model predicts positive welfare gains from removing tariffs within the GCC, especially for Qatar and the UAE. The actual bilateral trade data between Qatar and the UAE show that UAE exports to Qatar decreased slightly from 2019 to 2023, while Qatar exports to the UAE increased slightly. This means the observed data do not show a large expansion in bilateral trade over this period.
This difference does not necessarily contradict the model. The model studies a clean counterfactual: it asks what would happen if tariffs were removed while other structural features are held constant. The actual data, by contrast, reflect many other forces, including energy prices, re-export activity, post-blockade normalization, supply chain disruptions, domestic policy changes, and changes in global demand.
For that reason, I find the model useful for isolating the direction and mechanism of tariff removal, but I would not interpret the exact welfare numbers as literal forecasts. The model is more credible for understanding the logic of the policy experiment: lower intra-GCC trade barriers reduce prices, increase regional sourcing, and raise welfare for most GCC members. Actual trade data are more credible for describing what happened historically, but less useful for isolating the effect of tariffs alone.
actual_gcc <- actual_trade_change(
eora_rds_path = "eora_data.rds",
country1 = "QAT",
country2 = "ARE",
year_before = 2019,
year_after = 2023,
agg_countries = config$countries
)
knitr::kable(
actual_gcc,
digits = 0,
caption = "Qatar-UAE bilateral trade change, 2019 vs 2023"
)
| source | destination | y2019 | y2023 | pct_change |
|---|---|---|---|---|
| ARE | QAT | 5905878 | 5804011 | -2 |
| QAT | ARE | 1974649 | 1991203 | 1 |
The Qatar-UAE trade data show only small changes between 2019 and 2023. UAE exports to Qatar decreased slightly, while Qatar exports to the UAE increased slightly. This suggests that observed bilateral trade flows were shaped by broader political and macroeconomic factors, not only tariffs.
The model-based results and the observed trade data therefore answer different questions. The data describe what actually happened between two years. The model isolates what would happen if intra-GCC tariffs were removed while other structural conditions were held fixed.
This project uses a multi-country, multi-sector Armington trade model to study the effect of removing remaining tariffs between GCC countries. The results show that intra-GCC free trade raises welfare for all GCC members, with the largest gains for the UAE and Qatar. The gains are modest but positive, suggesting that even small trade barriers can matter for small open economies. Some outside countries lose slightly because of trade diversion, while others gain through indirect demand effects. Compared with raw trade data, the model adds value by isolating the effect of tariff removal from other historical forces affecting trade flows.
knitr::kable(
all_results %>%
select(name, scenario, wage_cf, welfare_pct_change) %>%
pivot_wider(names_from = scenario,
values_from = c(wage_cf, welfare_pct_change)),
digits = 4,
caption = "Full results: wages and welfare changes"
)
| name | wage_cf_Free trade within GCC | welfare_pct_change_Free trade within GCC |
|---|---|---|
| UAE | 1 | 0.6785 |
| Bahrain | 1 | 0.3219 |
| China | 1 | 0.0528 |
| EU | 1 | 0.0177 |
| United Kingdom | 1 | -0.0046 |
| India | 1 | 0.0326 |
| Japan | 1 | 0.0055 |
| South Korea | 1 | 0.1669 |
| Kuwait | 1 | 0.0649 |
| Oman | 1 | 0.1966 |
| Qatar | 1 | 0.6548 |
| Rest of World | 1 | -0.1420 |
| Saudi Arabia | 1 | 0.3627 |
| Turkey | 1 | 0.0262 |
| United States | 1 | -0.0973 |