Does Sustainability Pay? ESG Risk Ratings, Stock Returns and Risk

Project Paper — Investment Analytics and Technology Application

Author
Affiliation

Solongo

Department of Finance, Asia University

Published

November 8, 2026

1 Introduction

Environmental, social and governance (ESG) information has moved from the margins of investing to the centre of it. Asset managers now screen, tilt and engage on ESG criteria, and rating agencies such as MSCI, Refinitiv (LSEG) and Morningstar Sustainalytics sell firm-level scores to almost every institutional investor. Yet the basic investment question remains open: do companies with better ESG profiles deliver better stock performance, lower risk, or neither?

Theory gives two competing answers. If investors have a taste for sustainable firms, they bid up their prices and accept lower expected returns (Pástor et al., 2021; Pedersen et al., 2021). If instead ESG strength reflects good management and lower exposure to regulatory, legal and reputational shocks, sustainable firms should be less risky and may outperform when those risks materialise (Albuquerque et al., 2019; Giese et al., 2019). Empirical results are mixed, partly because ESG ratings from different providers disagree (Berg et al., 2022).

1.1 Problem statement

This project tests whether a firm’s ESG risk — the Sustainalytics measure of unmanaged exposure to material ESG issues, where a lower score is better — is related to its stock returns and risk among large U.S. listed firms (S&P 500 constituents) over 2021–2025.

Research questions

  1. RQ1 (Return): Do low-ESG-risk firms earn different raw and risk-adjusted returns than high-ESG-risk firms?
  2. RQ2 (Risk): Do low-ESG-risk firms have lower total volatility, systematic risk (beta), idiosyncratic risk and downside risk?
  3. RQ3 (Pillars): Which ESG pillar — Environmental, Social or Governance — drives any relationship found?

Hypotheses

  • H1: The Low-minus-High ESG-risk portfolio has a risk-adjusted alpha different from zero (taste theory predicts negative; risk-mitigation theory predicts zero or positive).
  • H2: ESG risk is positively related to total, systematic, idiosyncratic and downside risk, after controlling for sector and size.
  • H3: The risk relation is strongest for the Environmental pillar.

2 Literature Review

The literature is organised around the three research questions: (1) ESG and returns, (2) ESG and risk, and (3) measurement problems in ESG ratings.

2.1 ESG and stock returns: two competing theories

Aggregated evidence. Friede et al. (2015) combine about 2,200 empirical studies and find that roughly 90% report a non-negative ESG–financial performance link, with most positive. This large body of work motivates the question but mostly uses accounting performance, not stock returns.

Taste-based (lower expected return) view. Hong and Kacperczyk (2009) show that “sin” stocks (alcohol, tobacco, gaming), shunned by norm-constrained investors, earn higher returns — a cost of exclusion borne by ethical investors. Pástor et al. (2021) formalise this in equilibrium: green assets have lower expected returns because investors enjoy holding them and because they hedge climate risk. Pedersen et al. (2021) derive an ESG-efficient frontier and show the cost of ESG investing depends on which investors hold which stocks. Bolton and Kacperczyk (2021) find that high-carbon firms earn a return premium, consistent with investors demanding compensation for carbon risk.

Realised returns can still favour green firms. Pástor et al. (2022) show that green stocks outperformed brown stocks in 2012–2020 mainly because climate concerns rose unexpectedly — a realised, not expected, premium. This distinction is important for interpreting any short-sample result such as ours.

2.2 ESG and firm risk

Systematic risk. Albuquerque et al. (2019) model corporate social responsibility (CSR) as a product-differentiation strategy that makes demand less sensitive to the business cycle, and find that high-CSR firms have lower systematic risk and higher value. Giese et al. (2019) trace three transmission channels in MSCI data: cash-flow, idiosyncratic-risk and valuation, and find that high-ESG firms show lower tail and systematic risk.

Crisis and downside risk. Lins et al. (2017) show that high-CSR firms earned 4–7 percentage points higher returns during the 2008–2009 financial crisis, interpreting CSR as trust-building social capital. Albuquerque et al. (2020) find similar resilience for environmental and social stocks in the COVID-19 crash of 2020. Hoepner et al. (2024) show that ESG engagement by an institutional investor reduces target firms’ downside risk, mainly through environmental issues. Ilhan et al. (2021) find that option markets price higher tail risk for carbon-intensive firms, supporting H3.

2.3 Measuring ESG: rating disagreement

Berg et al. (2022) show that correlations among six major ESG ratings are only 0.38–0.71, driven by differences in scope, measurement and weights. Gibson Brandon et al. (2021) find that greater disagreement is associated with higher stock returns, and Avramov et al. (2022) show that ESG rating uncertainty weakens the demand for green stocks and the predicted green-return relation. These findings justify (a) choosing one clearly defined rating — Sustainalytics risk scores — and (b) treating results as rating-specific.

2.4 Research gap and contribution

Most evidence uses data up to 2020 and ESG performance scores (MSCI, Refinitiv). This project uses Sustainalytics ESG risk scores and the post-COVID period 2021–2025, which includes the 2022 energy shock and rate-hike bear market — an environment in which the hedging role of low-ESG-risk stocks can be re-tested.

Theme Key study Main finding Link to this project
Aggregated evidence Friede et al. (2015) ~90% of studies find non-negative ESG–performance link Motivation
Taste / expected return Pástor et al. (2021); Pedersen et al. (2021) Green stocks have lower expected returns H1 (negative alpha)
Carbon premium Bolton & Kacperczyk (2021) High-carbon firms earn higher returns H1, H3
Realised green returns Pástor et al. (2022) Green outperformance from climate-concern shocks Interpreting H1
Systematic risk Albuquerque et al. (2019) CSR lowers beta H2
Crisis resilience Lins et al. (2017); Albuquerque et al. (2020) High-CSR firms fall less in crashes H2 (downside)
Downside / tail risk Hoepner et al. (2024); Ilhan et al. (2021) ESG/E lowers downside and tail risk H2, H3
Rating divergence Berg et al. (2022); Avramov et al. (2022) Ratings disagree; uncertainty matters Data choice, limits

3 Data

3.1 Data sources

Data Source Variables Frequency
ESG risk ratings Morningstar Sustainalytics ESG Risk Ratings for S&P 500 firms (as published on Yahoo Finance; compiled in the Kaggle data set S&P 500 ESG Risk Ratings) Total ESG risk, Environment / Social / Governance risk, controversy level, sector Cross-section (latest snapshot)
Stock prices Yahoo Finance via R package quantmod Adjusted close → monthly total returns Monthly, 2021-01 to 2025-12
Risk factors Kenneth R. French Data Library Mkt-RF, SMB, HML, RMW, CMA, RF (Fama–French 5 factors) Monthly
Size control Yahoo Finance Market capitalisation (log) Latest

Sustainalytics ESG risk is measured on an open scale (most firms 0–50): 0–10 negligible, 10–20 low, 20–30 medium, 30–40 high, 40+ severe. A lower score means better ESG.

3.2 Test data set

Show R code
if (isTRUE(params$use_real_data)) {
  # ---------- REAL DATA (run on a computer with internet) ----------
  library(quantmod)
  raw <- read_csv(params$esg_csv, show_col_types = FALSE)
  names(raw) <- tolower(gsub("[^A-Za-z]+", "_", names(raw)))
  pick <- function(p) raw[[grep(p, names(raw))[1]]]
  esg <- tibble(symbol = gsub("\\.", "-", pick("^symbol")),
                sector = pick("^sector"),
                total_esg_risk   = pick("total_esg"),
                environment_risk = pick("^environment"),
                social_risk      = pick("^social"),
                governance_risk  = pick("^governance"),
                controversy_level = suppressWarnings(as.numeric(pick("controversy_score|controversy_level")))) |>
    filter(!is.na(total_esg_risk))

  get_ret <- function(s) {
    x <- tryCatch(getSymbols(s, src = "yahoo", from = params$start, to = params$end,
                             auto.assign = FALSE), error = function(e) NULL)
    if (is.null(x)) return(NULL)
    m <- monthlyReturn(Ad(x), type = "arithmetic")
    mc <- tryCatch(getQuote(s, what = yahooQF("Market Capitalization"))$`Market Capitalization`,
                   error = function(e) NA)
    tibble(date = as.Date(index(m)), symbol = s, ret = as.numeric(m), mktcap = mc)
  }
  returns <- bind_rows(lapply(esg$symbol, get_ret))
  esg <- esg |> left_join(distinct(returns, symbol, mktcap), by = "symbol") |>
    mutate(log_mktcap = log(mktcap / 1e6)) |> select(-mktcap)
  returns <- returns |> select(-mktcap) |>
    mutate(date = lubridate::ceiling_date(date, "month") - 1)

  # Fama-French 5 factors (monthly, % -> decimal)
  zip <- tempfile(fileext = ".zip")
  download.file("https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/F-F_Research_Data_5_Factors_2x3_CSV.zip",
                zip, mode = "wb")
  lines <- readLines(unz(zip, unzip(zip, list = TRUE)$Name[1]))
  lines <- lines[grepl("^\\s*\\d{6}\\s*,", lines)]
  factors <- read_csv(I(paste(lines, collapse = "\n")), col_names =
                        c("ym", "mkt_rf", "smb", "hml", "rmw", "cma", "rf"),
                      show_col_types = FALSE) |>
    mutate(date = lubridate::ceiling_date(as.Date(paste0(ym, "01"), "%Y%m%d"), "month") - 1,
           across(mkt_rf:rf, ~ .x / 100)) |>
    filter(date >= as.Date(params$start), date <= as.Date(params$end)) |> select(-ym)
  data_label <- "real data (Sustainalytics + Yahoo Finance + Kenneth French)"
} else {
  # ---------- TEST DATA (bundled, simulated) ----------
  esg     <- read_csv("data/test_esg.csv", show_col_types = FALSE)
  returns <- read_csv("data/test_returns.csv", show_col_types = FALSE)
  factors <- read_csv("data/test_factors.csv", show_col_types = FALSE)
  data_label <- "test data set (simulated, same structure as the real sources)"
}

esg <- esg |>
  mutate(esg_group = ntile(total_esg_risk, 3),
         esg_group = factor(c("Low", "Medium", "High")[esg_group],
                            levels = c("Low", "Medium", "High")))
panel <- returns |> inner_join(esg, by = "symbol") |> inner_join(factors, by = "date") |>
  mutate(ex_ret = ret - rf)
Note

This version of the report uses the test data set (simulated, same structure as the real sources). The test data set has 60 firms in 11 sectors observed over 60 months (Jan 2021–Dec 2025), giving 3,600 firm-month observations. It mirrors the structure of the real sources exactly, so every step below runs unchanged on the real data by setting use_real_data: true in the YAML header. In the test data no ESG effect on returns is built in: risk differences come only from sector membership. The test analysis therefore checks the pipeline; the numbers are not evidence for or against the hypotheses.

Show R code
esg |> select(symbol, sector, total_esg_risk, environment_risk, social_risk,
              governance_risk, controversy_level, esg_group) |> head(8)
Table 1: First rows of the firm-level ESG file
symbol sector total_esg_risk environment_risk social_risk governance_risk controversy_level esg_group
T01 Technology 19.3 5.4 8.8 5.1 0 Medium
T02 Technology 12.1 2.0 3.4 6.7 0 Low
T03 Technology 17.6 7.3 3.7 6.6 1 Low
T04 Technology 16.6 4.9 4.9 6.8 2 Low
T05 Technology 14.0 3.7 7.7 2.6 0 Low
T06 Technology 7.0 2.8 2.2 2.0 0 Low
T07 Technology 13.7 4.7 4.7 4.3 0 Low
T08 Technology 12.4 4.7 2.7 5.0 2 Low

3.3 Variable definitions

Variable Definition
total_esg_risk Sustainalytics total ESG risk score (lower = better)
environment_risk, social_risk, governance_risk Pillar risk scores
controversy_level Severity of ESG controversies, 0 (none) to 5 (severe)
esg_group Tercile of total ESG risk: Low / Medium / High
ret, ex_ret Monthly stock return; return minus risk-free rate
beta CAPM market beta from 60 monthly returns
ivol Idiosyncratic volatility: s.d. of Fama–French 3-factor residuals (annualised)
vol Total volatility of monthly returns (annualised)
mdd Maximum drawdown of the cumulative return path
log_mktcap Log of market capitalisation (USD million)

4 Preliminary Data Analysis

4.1 Descriptive statistics

Show R code
desc <- esg |>
  select(`Total ESG risk` = total_esg_risk, `Environment risk` = environment_risk,
         `Social risk` = social_risk, `Governance risk` = governance_risk,
         `Controversy level` = controversy_level, `Log market cap` = log_mktcap) |>
  pivot_longer(everything(), names_to = "Variable") |>
  group_by(Variable = factor(Variable, levels = unique(Variable))) |>
  summarise(N = n(), Mean = mean(value), SD = sd(value), Min = min(value),
            Median = median(value), Max = max(value)) |>
  mutate(across(Mean:Max, ~ round(.x, 2)))
desc
Table 2: Descriptive statistics of ESG variables
Variable N Mean SD Min Median Max
Total ESG risk 60 21.63 6.90 7.00 20.80 37.60
Environment risk 60 7.54 3.56 2.00 7.40 19.10
Social risk 60 7.44 3.84 1.50 6.95 22.00
Governance risk 60 6.66 3.32 1.90 6.55 17.00
Controversy level 60 1.40 1.18 0.00 1.00 5.00
Log market cap 60 11.05 1.06 8.87 10.89 13.24
Show R code
p_sector <- esg |> mutate(sector = reorder(sector, total_esg_risk, median)) |>
  ggplot(aes(total_esg_risk, sector)) +
  annotate("rect", xmin = -Inf, xmax = 20, ymin = -Inf, ymax = Inf, alpha = .06, fill = pal["Low"]) +
  annotate("rect", xmin = 30, xmax = Inf, ymin = -Inf, ymax = Inf, alpha = .06, fill = pal["High"]) +
  geom_boxplot(fill = "grey92", colour = "grey40", outlier.shape = NA, width = .6) +
  geom_jitter(aes(colour = esg_group), height = .15, size = 2, alpha = .85) +
  scale_colour_manual(values = pal, name = "ESG-risk tercile") +
  labs(x = "Sustainalytics total ESG risk score", y = NULL)
p_sector
Figure 1: Total ESG risk by sector (lower = better)

ESG risk differs sharply across sectors: resource-intensive sectors (energy, materials, utilities) sit at the top and real estate and technology at the bottom. Because ESG risk is so strongly linked to sector, sector controls are essential in every test below.

4.2 Portfolio sorts (RQ1)

Firms are sorted into three equal-weighted portfolios by total ESG risk, plus a long–short portfolio that buys Low and sells High ESG-risk firms.

Show R code
port <- panel |> group_by(date, esg_group) |>
  summarise(ret = mean(ret), .groups = "drop") |>
  pivot_wider(names_from = esg_group, values_from = ret) |>
  mutate(`Low - High` = Low - High) |>
  inner_join(factors, by = "date")

mdd <- function(r) { w <- cumprod(1 + r); min(w / cummax(w) - 1) }
perf <- port |> pivot_longer(c(Low, Medium, High, `Low - High`), names_to = "Portfolio", values_to = "r") |>
  group_by(Portfolio = factor(Portfolio, levels = c("Low", "Medium", "High", "Low - High"))) |>
  summarise(`Mean monthly (%)` = 100 * mean(r),
            `Ann. return (%)` = 100 * ((prod(1 + r))^(12 / n()) - 1),
            `Ann. volatility (%)` = 100 * sd(r) * sqrt(12),
            `Sharpe ratio` = ifelse(first(Portfolio) == "Low - High",
                                    mean(r) / sd(r) * sqrt(12),
                                    mean(r - rf) / sd(r) * sqrt(12)),
            `Beta` = coef(lm(I(r - rf * (first(Portfolio) != "Low - High")) ~ mkt_rf))[2],
            `Max drawdown (%)` = 100 * mdd(r)) |>
  mutate(across(-Portfolio, ~ round(.x, 2)))
Show R code
perf
Table 3: Performance of ESG-risk tercile portfolios (equal-weighted)
Portfolio Mean monthly (%) Ann. return (%) Ann. volatility (%) Sharpe ratio Beta Max drawdown (%)
Low 1.41 16.71 16.87 0.81 1.07 -21.37
Medium 1.34 16.08 14.92 0.86 0.96 -18.13
High 1.81 22.65 14.84 1.24 0.92 -18.58
Low - High -0.39 -4.91 7.88 -0.60 0.15 -27.08
Show R code
cum <- port |> select(date, Low, Medium, High) |>
  pivot_longer(-date, names_to = "Portfolio", values_to = "r") |>
  group_by(Portfolio) |> arrange(date) |> mutate(wealth = cumprod(1 + r)) |> ungroup() |>
  mutate(Portfolio = factor(Portfolio, levels = c("Low", "Medium", "High")))
p_cum <- ggplot(cum, aes(date, wealth, colour = Portfolio)) +
  geom_hline(yintercept = 1, colour = "grey60", linewidth = .3) +
  geom_line(linewidth = 1) + scale_colour_manual(values = pal, name = "ESG risk") +
  scale_y_continuous(labels = dollar) + labs(x = NULL, y = "Value of $1")
p_cum
Figure 2: Growth of $1 invested in each ESG-risk tercile portfolio

4.2.1 Risk-adjusted performance of the Low − High portfolio

Show R code
nw <- function(m) coeftest(m, vcov = NeweyWest(m, lag = 3, prewhite = FALSE))
m_capm <- lm(`Low - High` ~ mkt_rf, data = port)
m_ff5  <- lm(`Low - High` ~ mkt_rf + smb + hml + rmw + cma, data = port)
alpha_tab <- bind_rows(
  tidy(nw(m_capm)) |> mutate(Model = "CAPM"),
  tidy(nw(m_ff5))  |> mutate(Model = "Fama-French 5")) |>
  mutate(term = recode(term, `(Intercept)` = "Alpha (monthly)", mkt_rf = "Mkt-RF",
                       smb = "SMB", hml = "HML", rmw = "RMW", cma = "CMA")) |>
  transmute(Model, Term = term, Estimate = round(estimate, 4),
            `t-stat` = round(statistic, 2), `p-value` = round(p.value, 3))
alpha_tab
Table 4: Alphas of the Low − High ESG-risk portfolio (Newey–West t-statistics, 3 lags)
Model Term Estimate t-stat p-value
CAPM Alpha (monthly) -0.0058 -2.26 0.027
CAPM Mkt-RF 0.1497 2.25 0.028
Fama-French 5 Alpha (monthly) -0.0062 -2.45 0.017
Fama-French 5 Mkt-RF 0.1628 2.33 0.024
Fama-French 5 SMB -0.2646 -1.97 0.054
Fama-French 5 HML -0.1606 -1.81 0.075
Fama-French 5 RMW 0.0996 0.90 0.374
Fama-French 5 CMA -0.0554 -0.50 0.619

Because ESG risk is so tied to sector, the raw sort partly bets on sectors (the Low tercile is technology-heavy, the High tercile energy-heavy). A sector-neutral version sorts firms into ESG-risk terciles within each sector, so the long–short portfolio holds the same sectors on both sides.

Show R code
port_sn <- panel |> group_by(sector) |>
  mutate(g = ntile(total_esg_risk, 3)) |> ungroup() |>
  filter(g %in% c(1, 3)) |>
  group_by(date, g) |> summarise(ret = mean(ret), .groups = "drop") |>
  pivot_wider(names_from = g, values_from = ret, names_prefix = "g") |>
  mutate(ls = g1 - g3) |> inner_join(factors, by = "date")
sn_capm <- lm(ls ~ mkt_rf, data = port_sn)
sn_ff5  <- lm(ls ~ mkt_rf + smb + hml + rmw + cma, data = port_sn)
alpha_sn <- bind_rows(
  tidy(nw(sn_capm)) |> mutate(Model = "CAPM"),
  tidy(nw(sn_ff5))  |> mutate(Model = "Fama-French 5")) |>
  filter(term == "(Intercept)") |>
  transmute(Model, Term = "Alpha (monthly)", Estimate = round(estimate, 4),
            `t-stat` = round(statistic, 2), `p-value` = round(p.value, 3))
alpha_sn
Table 5: Alphas of the sector-neutral Low − High portfolio (Newey–West t-statistics, 3 lags)
Model Term Estimate t-stat p-value
CAPM Alpha (monthly) -1e-03 -0.34 0.733
Fama-French 5 Alpha (monthly) -7e-04 -0.24 0.811

4.3 Firm-level risk measures (RQ2, RQ3)

Show R code
firm_risk <- panel |> group_by(symbol) |> group_modify(~ {
  m1 <- lm(ex_ret ~ mkt_rf, data = .x)
  m3 <- lm(ex_ret ~ mkt_rf + smb + hml, data = .x)
  tibble(beta = coef(m1)[2], vol = sd(.x$ret) * sqrt(12),
         ivol = sd(resid(m3)) * sqrt(12), mdd = -mdd(.x$ret),
         mean_ret = mean(.x$ret) * 12)
}) |> ungroup() |> inner_join(esg, by = "symbol")

risk_by_group <- firm_risk |> group_by(`ESG-risk tercile` = esg_group) |>
  summarise(Firms = n(), `Avg ESG risk` = mean(total_esg_risk),
            `Ann. return (%)` = 100 * mean(mean_ret), `Volatility (%)` = 100 * mean(vol),
            `Beta` = mean(beta), `Idio. vol (%)` = 100 * mean(ivol),
            `Max drawdown (%)` = 100 * mean(mdd)) |>
  mutate(across(-c(1, 2), ~ round(.x, 2)), `Avg ESG risk` = round(`Avg ESG risk`, 1))
Show R code
risk_by_group
Table 6: Average firm-level return and risk by ESG-risk tercile
ESG-risk tercile Firms Avg ESG risk Ann. return (%) Volatility (%) Beta Idio. vol (%) Max drawdown (%)
Low 20 14.5 16.94 27.89 1.07 21.85 39.39
Medium 20 20.8 16.08 23.08 0.96 16.81 32.17
High 20 29.6 21.66 25.59 0.92 20.21 31.56
Show R code
p_scatter <- ggplot(firm_risk, aes(total_esg_risk, vol)) +
  geom_smooth(method = "lm", colour = "grey30", fill = "grey85", linewidth = .7) +
  geom_point(aes(colour = esg_group), size = 2.4, alpha = .9) +
  scale_colour_manual(values = pal, name = "ESG-risk tercile") +
  scale_y_continuous(labels = percent) +
  labs(x = "Total ESG risk score", y = "Annualised volatility")
p_scatter
Figure 3: Total ESG risk vs. annualised volatility (each dot is a firm)

4.3.1 Cross-sectional regressions with sector and size controls

Riski=a+bESGRiski+clog(MktCapi)+Sector FE+ei\text{Risk}_i = a + b\,\text{ESGRisk}_i + c\,\log(\text{MktCap}_i) + \text{Sector FE} + e_i

Show R code
dvs <- c(`Ann. return` = "mean_ret", Volatility = "vol", Beta = "beta",
         `Idiosyncratic vol` = "ivol", `Max drawdown` = "mdd")
xsec <- bind_rows(lapply(names(dvs), function(nm) {
  f <- as.formula(paste(dvs[nm], "~ total_esg_risk + log_mktcap + factor(sector)"))
  m <- lm(f, data = firm_risk)
  ct <- coeftest(m, vcov = vcovHC(m, type = "HC1"))["total_esg_risk", ]
  tibble(`Dependent variable` = nm, Coefficient = signif(ct[1], 3),
         `t-stat` = round(ct[3], 2), `p-value` = round(ct[4], 3),
         `Adj. R²` = round(summary(m)$adj.r.squared, 2), N = nobs(m))
}))
xsec
Table 7: Coefficient on Total ESG risk (HC1 robust SE), with sector fixed effects and size control
Dependent variable Coefficient t-stat p-value Adj. R² N
Ann. return 0.002860 0.82 0.417 0.04 60
Volatility -0.000343 -0.19 0.853 0.42 60
Beta -0.009450 -0.76 0.449 0.18 60
Idiosyncratic vol 0.000315 0.16 0.875 0.31 60
Max drawdown 0.000963 0.23 0.815 0.05 60
Show R code
m_p <- lm(vol ~ environment_risk + social_risk + governance_risk + log_mktcap + factor(sector),
          data = firm_risk)
pillars <- tidy(coeftest(m_p, vcov = vcovHC(m_p, type = "HC1"))) |>
  filter(term %in% c("environment_risk", "social_risk", "governance_risk")) |>
  transmute(Pillar = recode(term, environment_risk = "Environment", social_risk = "Social",
                            governance_risk = "Governance"),
            Coefficient = signif(estimate, 3), `t-stat` = round(statistic, 2),
            `p-value` = round(p.value, 3))
pillars
Table 8: Pillar regressions: volatility on E, S and G risk (sector FE, size control, HC1 SE)
Pillar Coefficient t-stat p-value
Environment -0.000183 -0.08 0.934
Social -0.001710 -0.65 0.520
Governance 0.000572 0.23 0.819
Show R code
corr <- firm_risk |> select(`ESG risk` = total_esg_risk, E = environment_risk, S = social_risk,
                            G = governance_risk, Return = mean_ret, Vol = vol, Beta = beta,
                            IVol = ivol, MDD = mdd) |> cor() |> round(2)
as.data.frame(corr)
Table 9: Correlation matrix of ESG and risk variables
ESG risk E S G Return Vol Beta IVol MDD
ESG risk 1.00 0.64 0.70 0.58 0.18 -0.08 -0.16 -0.03 -0.20
E 0.64 1.00 0.17 0.07 0.12 -0.16 -0.20 -0.08 -0.27
S 0.70 0.17 1.00 0.11 0.22 0.00 -0.12 0.07 -0.13
G 0.58 0.07 0.11 1.00 0.00 -0.01 0.03 -0.05 0.03
Return 0.18 0.12 0.22 0.00 1.00 0.35 0.39 0.19 -0.31
Vol -0.08 -0.16 0.00 -0.01 0.35 1.00 0.59 0.87 0.56
Beta -0.16 -0.20 -0.12 0.03 0.39 0.59 1.00 0.13 0.29
IVol -0.03 -0.08 0.07 -0.05 0.19 0.87 0.13 1.00 0.54
MDD -0.20 -0.27 -0.13 0.03 -0.31 0.56 0.29 0.54 1.00

4.4 Summary of preliminary results

  • ESG risk is concentrated by sector. Mean total ESG risk is 21.6 (SD 6.9), highest in energy and basic materials.
  • Returns (RQ1). The raw Low − High portfolio has a monthly five-factor alpha of -0.0062 (t = -2.45, significant at 5%). The sector-neutral Low − High alpha is -0.0007 (t = -0.24, not significant at 5%).
  • Risk (RQ2–RQ3). The raw correlation between ESG risk and volatility is -0.08. With sector and size controls, 0 of 5 risk/return measures load significantly on ESG risk (volatility coefficient -0.0003, t = -0.19); in the pillar regression 0 of 3 pillars is significant.
  • Interpretation. The test data contain no ESG effect by construction, so any significant raw-sort alpha here comes from sector composition and chance, not ESG. This is exactly why the sector-neutral sort and sector fixed effects are part of the design. The real-data run will test H1–H3.

4.5 Next steps

  1. Download the Sustainalytics snapshot and run the report with use_real_data: true.
  2. Extend to value-weighted portfolios and Fama–MacBeth (1973) regressions with monthly cross-sections.
  3. Robustness: alternative ESG measure (pillar scores, controversy level), sub-periods (2022 bear market vs. 2023–2025), and exclusion of the energy sector.
  4. Address limitations: a single ESG snapshot introduces look-ahead bias, and survivorship bias from current S&P 500 membership.

5 References

Albuquerque, R., Koskinen, Y., Yang, S., & Zhang, C. (2020). Resiliency of environmental and social stocks: An analysis of the exogenous COVID-19 market crash. The Review of Corporate Finance Studies, 9(3), 593–621. https://doi.org/10.1093/rcfs/cfaa011

Albuquerque, R., Koskinen, Y., & Zhang, C. (2019). Corporate social responsibility and firm risk: Theory and empirical evidence. Management Science, 65(10), 4451–4469. https://doi.org/10.1287/mnsc.2018.3043

Avramov, D., Cheng, S., Lioui, A., & Tarelli, A. (2022). Sustainable investing with ESG rating uncertainty. Journal of Financial Economics, 145(2), 642–664. https://doi.org/10.1016/j.jfineco.2021.09.009

Berg, F., Kölbel, J. F., & Rigobon, R. (2022). Aggregate confusion: The divergence of ESG ratings. Review of Finance, 26(6), 1315–1344. https://doi.org/10.1093/rof/rfac033

Bolton, P., & Kacperczyk, M. (2021). Do investors care about carbon risk? Journal of Financial Economics, 142(2), 517–549. https://doi.org/10.1016/j.jfineco.2021.05.008

Fama, E. F., & French, K. R. (2015). A five-factor asset pricing model. Journal of Financial Economics, 116(1), 1–22. https://doi.org/10.1016/j.jfineco.2014.10.010

Fama, E. F., & MacBeth, J. D. (1973). Risk, return, and equilibrium: Empirical tests. Journal of Political Economy, 81(3), 607–636. https://doi.org/10.1086/260061

French, K. R. (2026). Data library [Data set]. Tuck School of Business, Dartmouth College. https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html

Friede, G., Busch, T., & Bassen, A. (2015). ESG and financial performance: Aggregated evidence from more than 2000 empirical studies. Journal of Sustainable Finance & Investment, 5(4), 210–233. https://doi.org/10.1080/20430795.2015.1118917

Gibson Brandon, R., Krueger, P., & Schmidt, P. S. (2021). ESG rating disagreement and stock returns. Financial Analysts Journal, 77(4), 104–127. https://doi.org/10.1080/0015198X.2021.1963186

Giese, G., Lee, L.-E., Melas, D., Nagy, Z., & Nishikawa, L. (2019). Foundations of ESG investing: How ESG affects equity valuation, risk, and performance. The Journal of Portfolio Management, 45(5), 69–83. https://doi.org/10.3905/jpm.2019.45.5.069

Hoepner, A. G. F., Oikonomou, I., Sautner, Z., Starks, L. T., & Zhou, X. Y. (2024). ESG shareholder engagement and downside risk. Review of Finance, 28(2), 483–510. https://doi.org/10.1093/rof/rfad034

Hong, H., & Kacperczyk, M. (2009). The price of sin: The effects of social norms on markets. Journal of Financial Economics, 93(1), 15–36. https://doi.org/10.1016/j.jfineco.2008.09.001

Ilhan, E., Sautner, Z., & Vilkov, G. (2021). Carbon tail risk. The Review of Financial Studies, 34(3), 1540–1571. https://doi.org/10.1093/rfs/hhaa071

Lins, K. V., Servaes, H., & Tamayo, A. (2017). Social capital, trust, and firm performance: The value of corporate social responsibility during the financial crisis. The Journal of Finance, 72(4), 1785–1824. https://doi.org/10.1111/jofi.12505

Pástor, Ľ., Stambaugh, R. F., & Taylor, L. A. (2021). Sustainable investing in equilibrium. Journal of Financial Economics, 142(2), 550–571. https://doi.org/10.1016/j.jfineco.2020.12.011

Pástor, Ľ., Stambaugh, R. F., & Taylor, L. A. (2022). Dissecting green returns. Journal of Financial Economics, 146(2), 403–424. https://doi.org/10.1016/j.jfineco.2022.07.007

Pedersen, L. H., Fitzgibbons, S., & Pomorski, L. (2021). Responsible investing: The ESG-efficient frontier. Journal of Financial Economics, 142(2), 572–597. https://doi.org/10.1016/j.jfineco.2020.11.001