1. Data and Question

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.

2. Setup

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)
  )
)

2.1 Load and inspect the data

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
)
Model regions
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")
}
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.

3. Counterfactual and Results

3.1 Calibrate and solve the baseline

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
}

3.2 Run counterfactuals

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)

3.3 Results table

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")
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

3.4 Consumption Equivalent Variation (CEV)

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")
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

3.5 Welfare chart

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.

3.6 Wage changes

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.

4. Comparison to Other Sources

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.

4.1 What does the data show?

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"
)
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.

4.2 Executive summary

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.

Appendix: Full Results

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"
)
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