Voting on Staggered Boards

Data step

# Connect to PostgreSQL database
library(RPostgreSQL) 
drv <- dbDriver("PostgreSQL")
pg <- dbConnect(drv, dbname = "crsp")

rs <- dbGetQuery(pg, "SET work_mem='20GB'")

# Get data including a measure of shareholder support relative to "base"
# (e.g., shares outstanding) specified for each vote.
declassify <- dbGetQuery(pg, "
    DROP TABLE IF EXISTS destagger.votes; --

    CREATE TABLE destagger.votes AS
    WITH 
    gvkeys AS (
        SELECT DISTINCT gvkey, cusip 
        FROM comp.secm),
    permnos AS (
        SELECT DISTINCT permno, ncusip 
        FROM crsp.stocknames),
    relevant_votes AS (
      SELECT DISTINCT instid, itemonagendaid
      FROM issvoting.fund_votes
      WHERE mgtrec != 'For' AND (itemdesc ILIKE '%declassify %' OR 
      issagendaitemid IN ('M0215', 'S0201'))),
    fund_num_votes AS (
      SELECT instid, count(*) AS num_votes 
      FROM relevant_votes
      GROUP BY instid),
    fund_rank AS (
      SELECT instid, num_votes, 
            rank() OVER (ORDER BY num_votes DESC) AS fund_rank
      FROM fund_num_votes),
    fund_rank_against AS (
        SELECT itemonagendaid, min(fund_rank) AS rank_fund_against
        FROM issvoting.fund_votes AS a
        INNER JOIN fund_rank AS b
        USING (instid)
        WHERE fundvote='Against' 
        GROUP BY itemonagendaid),
    votes AS (
      SELECT *,
        CASE WHEN base='Outstanding' AND outstandingshares>0 THEN votedfor/outstandingshares
          WHEN base='F+A' AND votedfor+votedagainst>0
            THEN votedfor/(votedfor+votedagainst)
          WHEN base='F+A+AB' AND votedfor+votedagainst+votedabstain>0 
          THEN votedfor/(votedfor+votedagainst+votedabstain)
        END AS percent_for
      FROM issvoting.compvotes
      LEFT JOIN fund_rank_against
      USING (itemonagendaid)
      WHERE mgtrec != 'For' AND (itemdesc ILIKE '%declassify %' OR 
                    issagendaitemid IN ('M0215', 'S0201'))
    ORDER BY issagendaitemid),
    votes_w_gvkeys AS (
      SELECT a.*, b.gvkey
      FROM votes AS a
      LEFT JOIN gvkeys AS b
      ON a.cusip=b.cusip)
    SELECT a.*, b.permno
    FROM votes_w_gvkeys AS a
    LEFT JOIN permnos AS b
    ON b.ncusip=substr(a.cusip,1,8)")
dbDisconnect(pg)
## [1] TRUE
library(RPostgreSQL)
drv <- dbDriver("PostgreSQL")
pg <- dbConnect(drv, dbname = "crsp")

# Pull data into R
declassify <- dbGetQuery(pg, "SELECT * FROM destagger.votes")

# Get returns around meeting dates
dropbox.path <- path.expand("~/Dropbox/research/activism/")
source(paste(dropbox.path,"code/getEventReturnsDaily.R",sep="")) 
ret_data <- getEventReturns(declassify$permno, declassify$meetingdate,
                            days.before=0, days.after=1)
# Drop duplicates (multiple votes at a single meeting)
ret_data$row.names <- NULL
ret_data <- unique(ret_data) 

# Put return data back in the database
rs <- dbWriteTable(pg, c("destagger", "ret_data"), ret_data,
                   overwrite=TRUE, row.names=FALSE)

declassify <- dbGetQuery(pg, "
  SELECT *
  FROM destagger.votes AS a
  LEFT JOIN destagger.ret_data AS b
  USING (permno)
  WHERE a.meetingdate=b.event_date AND result IN ('Fail', 'Pass')")
dbDisconnect(pg)
## [1] TRUE

Some descriptive statistics

Does ISS ever vary in its recommendation? Rarely so; it almost always recommends shareholders vote to declassify.

with(declassify, table(mgtrec, issrec))
##          issrec
## mgtrec    Against Do Not Vote For NULL
##   Abstain       0           0   1    0
##   Against       4           6 387    1
##   None          0           0  24    0
# subset(declassify, issrec=='Against')

There are 423 votes on declassification in the sample, with 27.66% being rejections by shareholders. Here they are by year.

## Descriptive statistics
declassify$year <- format(declassify$meetingdate, "%Y")
with(declassify, table(year, result))
##       result
## year   Fail Pass
##   2001   17   26
##   2002   16   28
##   2003   13   33
##   2004    7   31
##   2005    6   33
##   2006    8   44
##   2007   11   22
##   2008   16   51
##   2009   23   38

The votes are fairly well dispersed around the cutoff. Note that these are only shareholder-sponsored votes.

# Produce a histogram of (SVT - allowable cap)
library(ggplot2)
qplot(percent_for - voterequirement, 
      data=subset(declassify,
                  percent_for <1 & percent_for > 0.01), 
      binwidth=.01,
      main="Histogram: Shareholder support minus vote requirement",
      xlab="Shareholder support minus vote requirement")

plot of chunk unnamed-chunk-1

But there's virtually no response by the market to the result of the vote.

qplot(percent_for - voterequirement, ret_mkt,
      data=subset(declassify, 
                  percent_for <1 & percent_for > 0.01 & issrec!="NULL"),
      main="Market-adjusted Stock Returns: Days (0,1) Around Meeting Dates",
      xlab="Shareholder support minus vote requirement")

plot of chunk unnamed-chunk-2


qplot(percent_for - voterequirement, ret_mkt,
      data=subset(declassify, 
                  percent_for <1 & percent_for > 0.01),
      main="Market-adjusted Stock Returns: Days (0,1) Around Meeting Dates",
      xlab="Shareholder support minus vote requirement",
      color=mgtrec)

plot of chunk unnamed-chunk-2

Estimation and inference

source("~/Dropbox/research/rdd/rd_opt_bw.R")
### source('http://iangow.me/~iangow/rd_opt_bw.R') (4) Calculate the
### treatment effect and standard errors.
table(declassify$rank_fund_against)
## 
##   1   3   5   6   7   8   9  11  12  14  18  21  26  27  54  60  79  82 
##   4   1   1  15   4  47 107   1   1   3   3   4   2   1   2   1   4   3 
##  85  86  90  95  97 104 148 165 190 
##   1   1   2   8  52   6   2   1   2
rd_data <- subset(declassify, subset = percent_for < 1 & percent_for > 0.01, 
    select = c(ret_mkt, percent_for, voterequirement))
rd_data$fundvote <- 1
# with(rd_data, ifelse(is.na(top_fund_against), 1,
# ifelse(top_fund_against, -1, 1)))

table(rd_data$fundvote)
## 
##   1 
## 423
rd_data$x <- (rd_data$percent_for - rd_data$voterequirement) * rd_data$fundvote
rd_data$y <- rd_data$ret_mkt

# First, get bandwidth
h <- with(rd_data, rd_opt_bw(y, x, c = 0))
X <- rd_data$x
c <- 0

## Weights based on triangular kernel
wgts <- with(rd_data, (1 - abs(X - c)/h) * (abs(X - c) <= h))
local.lm <- lm(y ~ (x >= c) * x, weights = wgts, data = rd_data)

rd.est <- coef(local.lm)[[2]]
sd.est <- sqrt(vcov(local.lm)[2, 2])

## Output
out <- c(h, rd.est, sd.est, rd.est/sd.est)
names(out) <- c("Optimal Bandwidth", "RD Estimate", "Standard Error", "t-statistic")
print(out)
## Optimal Bandwidth       RD Estimate    Standard Error       t-statistic 
##          0.182897         -0.002490          0.007823         -0.318217

A plot of the data with fitted values

# A function to estimate local linear regression around a point (x_i)
# using bandwidth h, the triangular kernel and limiting observations to
# those on the same side of the cutoff c. In some sense, this is purely
# visual, as the IK bandwidth is optimized for x \in [c-h, c+h] and other
# data are not involved.
ll <- function(x_i, y, x, h, c) {
    wgts <- (1 - abs(x - x_i)/h) * (abs(x - x_i) <= h) * (sign(x_i - c) == sign(x - 
        c) | x_i == c)
    lm.fitted <- lm(y ~ x, weights = wgts)
    if (sum(wgts > 0) > 10) {
        # Require 10 observations around x_i
        return(predict(lm.fitted, newdata = data.frame(x = x_i)))
    } else {
        return(NA)
    }
}

# Add the fitted values to the dataset
library(parallel)
rd_data$y_fitted <- with(rd_data, unlist(mclapply(X, ll, y, X, h, c, mc.cores = 8)))

# Make a plot
library(ggplot2)
ggplot(rd_data, aes(x)) + geom_point(aes(y = y, color = x > c)) + geom_line(aes(y = y_fitted, 
    color = x > c))

plot of chunk plot

Fund voting behavior

While there is essentially no variation in how ISS recommends its clients vote on shareholder proposals to declassify boards, it seems there is quite a bit of variation in how mutual funds vote. Some funds mostly side with management, others go with ISS (though it is very difficult to argue causality without additional evidence), while others mix it up. It might be interesting to see whether the ones that mix it up do so in a way consistent with shareholder-value maximization, but inconsistent with the view of ISS (and Bebchuk) of a one-size-fits-all solution here. For example, if we looked at stock returns around the time of the vote, is there a relationship (say, using RDD) between the outcome of the vote, stock returns, and how these mutual funds voted. More specifically, if the “horses for courses” shareholders voted to reject the shareholder proposal, did the market react positively (negatively) to a failed (passed) proposal? (Note that it's not clear exactly how to measure how “horses for courses” shareholders voted, as it's unlikely that all such shareholders voted in the same way on each measure.)

##                                 institutionname percent_for num_votes
## 1                Fidelity Management & Research     0.98452       326
## 2             Northern Trust Global Investments     0.88660       295
## 3                          Vanguard Group, Inc.     0.99303       289
## 4                TIAA-CREF Asset Management LLC     0.99262       276
## 5           T. Rowe Price Associates, Inc. (MD)     0.98540       276
## 6        Jackson National Asset Management, LLC     0.97368       270
## 7          Rodney Square Management Corporation     0.03419       265
## 8                             Rydex Investments     0.42213       263
## 9                      BlackRock Advisors, Inc.     0.86454       255
## 10            Barclays Global Investors NA (CA)     0.98795       249
## 11                            EQ ADVISORS TRUST     0.85000       247
## 12                      John Hancock Funds, LLC     0.79741       246
## 13   Charles Schwab Investment Management, Inc.     0.97021       238
## 14                         Prudential Financial     0.91204       226
## 15                AST Investment Services, Inc.     0.85581       222
## 16        AIG SunAmerica Asset Management Corp.     0.94737       217
## 17                   IQ Investment Advisors LLC     0.98104       217
## 18                  RiverSource Investments LLC     1.00000       215
## 19                           Transamerica Funds     0.84135       212
## 20      Variable Annuity Life Insurance Company     0.97525       205
## 21                 State Street Global Advisors     0.71144       203
## 22                    Munder Capital Management     0.97030       202
## 23            Wells Fargo Funds Management, LLC     0.93000       201
## 24              Dimensional Fund Advisors, Inc.     0.98964       199
## 25 Federated Investors, Inc. (Asset Management)     0.14136       194
## 26              Summit Investment Partners, Inc     0.35135       192
## 27                     Russell Investment Group     0.98396       189
## 28                    Northwestern Mutual Funds     0.96703       183
## 29 American Century Investment Management, Inc.     0.98876       179
## 30                     Nationwide Fund Advisors     0.94167       124
## 31                  Nationwide Fund<a0>Advisors     0.82051        78
## 32                     Nationwide Fund Advisors     0.91781        74
## 33     Charles Schwab Investment Management, In     0.97727        45
## 34      American Century Investment Management,     1.00000        30
## 35     Federated Investors, Inc. (Asset Managem     0.00000        13