Learn R Programming

antitrust (version 0.99.33)

Sim-Functions: Merger Simulation With User-Supplied Demand Parameters

Description

Simulates the price effects of a merger between two firms with user-supplied demand parameters under the assumption that all firms in the market are playing either a differentiated products Bertrand pricing game, Cournot quantity game, 2nd price (score) auction, or bargaining game.

Let k denote the number of products produced by all firms below.

Usage

sim(
  prices,
  shares = NULL,
  margins = NULL,
  supply = c("bertrand", "cournot", "auction2nd", "bargaining", "bargaining2nd"),
  demand = c("Linear", "AIDS", "LogLin", "Logit", "CES", "LogitNests", "CESNests",
    "LogitCap", "BLP", "LogitBLP", "CournotBLP"),
  demand.param,
  ownerPre,
  ownerPost,
  nests,
  capacities,
  mcDelta = rep(0, length(prices)),
  subset = rep(TRUE, length(prices)),
  insideSize = 1,
  priceOutside,
  priceStart,
  bargpowerPre = rep(0.5, length(prices)),
  bargpowerPost = bargpowerPre,
  labels = paste("Prod", 1:length(prices), sep = ""),
  ...
)

Value

sim returns an instance of the class specified by the ‘demand’ argument.

Arguments

prices

A length k vector of product prices.

shares

A length k vector of product shares. Only used for ‘BLP’ demand. See Details.

margins

An optional length k vector of product margins. Required for demand systems that calibrate costs from observed margins. Ignored for ‘BLP’ demand, where marginal costs are recovered from observed prices and the estimated demand system.

supply

A character string indicating how firms compete with one another. Valid values are "bertrand" (Nash Bertrand), "cournot" (Nash Cournot), "auction2nd" (2nd score auction), "bargaining", or "bargaining2nd".

demand

A character string indicating the type of demand system to be used in the merger simulation. Supported demand systems are linear (‘Linear’), log-linear(‘LogLin’), logit (‘Logit’), nested logit (‘LogitNests’), ces (‘CES’), nested CES (‘CESNests’) and capacity constrained Logit (‘LogitCap’).

demand.param

See Below.

ownerPre

EITHER a vector of length k whose values indicate which firm produced a product pre-merger OR a k x k matrix of pre-merger ownership shares.

ownerPost

EITHER a vector of length k whose values indicate which firm produced a product after the merger OR a k x k matrix of post-merger ownership shares.

nests

A length k vector identifying the nest that each product belongs to. Must be supplied when ‘demand’ equals ‘CESNests’ and ‘LogitNests’.

capacities

A length k vector of product capacities. Must be supplied when ‘demand’ equals ‘LogitCap’.

mcDelta

A vector of length k where each element equals the proportional change in a product's marginal costs due to the merger. Default is 0, which assumes that the merger does not affect any products' marginal cost.

subset

A vector of length k where each element equals TRUE if the product indexed by that element should be included in the post-merger simulation and FALSE if it should be excluded.Default is a length k vector of TRUE.

insideSize

A length 1 vector equal to total units sold if ‘demand’ equals "logit", or total revenues if ‘demand’ equals "ces".

priceOutside

A length 1 vector indicating the price of the outside good. This option only applies to the ‘Logit’ class and its child classes Default for ‘Logit’,‘LogitNests’, and ‘LogitCap’ is 0, and for ‘CES’ and ‘CesNests’ is 1.

priceStart

A length k vector of starting values used to solve for equilibrium price. Default is the ‘prices’ vector for all values of demand except for ‘AIDS’, which is set equal to a vector of 0s.

bargpowerPre

A length k vector of pre-merger bargaining power parameters. Values must be between 0 (sellers have the power) and 1 (buyers the power). Ignored if ‘supply’ not equal to "bargaining" or bargaining2nd.

bargpowerPost

A length k vector of post-merger bargaining power parameters. Values must be between 0 (sellers have the power) and 1 (buyers the power). Default is ‘bargpowerPre’. Ignored if ‘supply’ not equal to "bargaining".

labels

A k-length vector of labels. Default is “Prod#”, where ‘#’ is a number between 1 and the length of ‘prices’.

...

Additional options to feed to the optimizer used to solve for equilibrium prices.

Author

Charles Taragin ctaragin+antitrustr@gmail.com

Details

Using user-supplied demand parameters, sim simulates the effects of a merger in a market where firms are playing a differentiated products pricing game.

The ‘supply’ parameter determines the type of competition. When ‘supply’ equals ‘cournot’, firms compete on quantities rather than prices. Cournot competition is supported for ‘Logit’ and ‘BLP’ demand systems, creating LogitCournot and CournotBLP class objects respectively.

If ‘demand’ equals ‘Linear’, ‘LogLin’, or ‘AIDS’, then ‘demand.param’ must be a list containing:

slopes

A k x k matrix of slope coefficients.

intercepts

A length-k vector of intercepts.

Additionally, if ‘demand’ equals ‘AIDS’, ‘demand.param’ must also contain:

mktElast

An estimate of aggregate market elasticity.

For ‘Linear’ demand models, sim returns an error if any intercepts are negative. For ‘Linear’, ‘LogLin’, and ‘AIDS’ models, sim returns an error if not all diagonal elements of the slopes matrix are negative.

If ‘demand’ equals ‘Logit’ or ‘LogitNests’, then ‘demand.param’ must equal a list containing:

alpha

The price coefficient.

meanval

A length-k vector of mean valuations. If none of the values of ‘meanval’ are zero, an outside good is assumed to exist.

If ‘demand’ equals ‘BLP’, then ‘demand.param’ must equal a list containing:

alpha

The mean price coefficient (or use alphaMean).

meanval

A length-k vector of mean valuations. If none of the values of ‘meanval’ are zero, an outside good is assumed to exist. If ‘meanval’ is not provided, then ‘shares’ must be supplied so that mean valuations can be recovered via BLP contraction mapping.

sigma

The standard deviation of the random coefficient on price, representing consumer heterogeneity in price sensitivity.

sigmaNest

Optional nesting parameter for the outside good: sigmaNest in (0,1] where sigmaNest=1 is flat logit (no nesting) and sigmaNest->0 means products are perfect substitutes within the nest. Default is 1.

piDemog

Optional vector of demographic coefficients for the price coefficient. Each element represents the interaction effect of a demographic variable with price.

demogMean

Optional: Vector of length equal to piDemog length, containing the mean of each demographic variable. Default is 0 (demeaned demographics). If demographics were demeaned in estimation, use 0; otherwise provide the actual mean.

demogCov

Optional: Covariance matrix (square, dimensions = length of piDemog) for demographic variables. Default is identity matrix (unit variance, independent). Should match the variance structure of demographics in your data. For a single demographic with variance sigma^2, use matrix(sigma^2, nrow=1, ncol=1).

nDraws

Number of draws to use for simulating consumer heterogeneity. Default is 1000.

prodChar

Optional: k x L matrix of L product characteristics for k products.

beta

Optional: Length-L vector of mean coefficients on product characteristics.

sigmaChar

Optional: Length-L vector of random coefficient standard deviations on characteristics.

pi

Optional: nDemog x L matrix of demographic interactions with characteristics.

Note: The ‘shares’ argument is only used with ‘BLP’ demand. If supplied for any other demand system, a warning will be issued but the function will proceed (shares will be ignored). For ‘BLP’, either ‘meanval’ must be provided in ‘demand.param’ OR ‘shares’ must be supplied to the sim function to perform BLP contraction mapping.

If ‘demand’ equals ‘CES’ or ‘CESNests’, then ‘demand.param’ must equal a list containing:

gamma

The price coefficient.

alpha

The coefficient on the numeraire good. May instead be calibrated using ‘shareInside’.

meanval

A length-k vector of mean valuations. If none of the values of ‘meanval’ are zero, an outside good is assumed to exist.

shareInside

The budget share of all products in the market. Default is 1, meaning that all consumer wealth is spent on products in the market. May instead be specified using ‘alpha’.

See Also

The S4 class documentation for: Linear, AIDS, LogLin, Logit, LogitNests, CES, CESNests

Examples

Run this code
## Calibration and simulation results from a merger between Budweiser and
## Old Style. Note that the in the following model there is no outside
## good; BUD's mean value has been normalized to zero.

## Source: Epstein/Rubenfeld 2004, pg 80


prodNames <- c("BUD", "OLD STYLE", "MILLER", "MILLER-LITE", "OTHER-LITE", "OTHER-REG")
ownerPre <- c("BUD", "OLD STYLE", "MILLER", "MILLER", "OTHER-LITE", "OTHER-REG")
ownerPost <- c("BUD", "BUD", "MILLER", "MILLER", "OTHER-LITE", "OTHER-REG")
nests <- c("Reg", "Reg", "Reg", "Light", "Light", "Reg")

price <- c(.0441, .0328, .0409, .0396, .0387, .0497)

demand.param <- list(
  alpha = -48.0457,
  meanval = c(0, 0.4149233, 1.1899885, 0.8252482, 0.1460183, 1.4865730)
)

sim.logit <- sim(price,
  supply = "bertrand", demand = "Logit", demand.param = demand.param,
  ownerPre = ownerPre, ownerPost = ownerPost
)


print(sim.logit) # return predicted price change
summary(sim.logit) # summarize merger simulation

elast(sim.logit, TRUE) # returns premerger elasticities
elast(sim.logit, FALSE) # returns postmerger elasticities

diversion(sim.logit, TRUE) # return premerger diversion ratios
diversion(sim.logit, FALSE) # return postmerger diversion ratios


cmcr(sim.logit) # calculate compensating marginal cost reduction
upp(sim.logit) # calculate Upwards Pricing Pressure Index

CV(sim.logit) # calculate representative agent compensating variation

if (FALSE) {
## Philadelphia National Bank Example: Comparing Four Model Types
## Demonstrates Logit, Cournot, LogitBLP, and CournotBLP

# Philadelphia National Bank data (38 products)
prices <- c(
  2.46, 2.21, 2.4, 2.29, 2.05, 2.45, 1.13, 2.39, 2.66, 2.73,
  1.83, 1.84, 2.76, 2.46, 1.1, 2.53, 2.27, 2.31, 2.72, 1.96, 2.26,
  2.63, 2.07, 2.31, 1.33, 2.67, 2.68, 2.59, 2.62, 1.85, 2.63, 1.51,
  1.8, 2.66, 1.4, 2.39, 2.35, 1.82
)

shares <- c(
  0.12499, 0.11462, 0.07748, 0.05231, 0.05168, 0.02918, 0.01622,
  0.01245, 0.00992, 0.00578, 0.00461, 0.00417, 0.00415, 0.00275,
  0.00271, 0.00214, 0.00206, 0.00184, 0.00176, 0.00155, 0.00151,
  0.00146, 0.00146, 0.00103, 0.00101, 0.00095, 8e-04, 0.00066,
  0.00062, 0.00061, 0.00057, 0.00053, 0.00053, 5e-04, 0.00049,
  0.00048, 0.00041, 0.00039
)

ownerPre <- diag(38)
ownerPost <- diag(38)
ownerPost[2, 3] <- 1 # Products 2 and 3 merge
ownerPost[3, 2] <- 1

insideSize <- 4773473000

# Logit parameters (from calibrated model)
logit_params <- list(
  alpha = 0.4296,
  meanval = c(
    -2.265, -2.206, -2.671, -2.972, -2.855, -3.596, -3.494, -4.344,
    -4.709, -5.253, -4.966, -5.059, -5.572, -5.773, -5.128, -6.043,
    -5.933, -6.057, -6.339, -6.027, -6.215, -6.46, -6.146, -6.597,
    -6.131, -6.871, -7.035, -7.169, -7.237, -6.833, -7.318, -6.804,
    -6.939, -7.457, -6.819, -7.328, -7.473, -7.227
  )
)

# BLP parameters
blp_params <- list(
  alpha = 1.0,
  sigma = 0.3,
  sigmaNest = 0.9,
  nDraws = 200
)

# MODEL 1: Logit (Bertrand)
result_logit <- sim(prices,
  supply = "bertrand", demand = "Logit",
  demand.param = logit_params, ownerPre = ownerPre,
  ownerPost = ownerPost, insideSize = insideSize
)
summary(result_logit)

# MODEL 2: Logit (Cournot)
result_cournot <- sim(prices,
  supply = "cournot", demand = "Logit",
  demand.param = logit_params, ownerPre = ownerPre,
  ownerPost = ownerPost, insideSize = insideSize
)
summary(result_cournot)

# MODEL 3: LogitBLP (Bertrand with random coefficients)
result_logitblp <- sim(prices, shares,
  supply = "bertrand", demand = "BLP",
  demand.param = blp_params, ownerPre = ownerPre,
  ownerPost = ownerPost, insideSize = insideSize
)
summary(result_logitblp)

# MODEL 4: CournotBLP (Cournot with random coefficients)
result_cournotblp <- sim(prices, shares,
  supply = "cournot", demand = "BLP",
  demand.param = blp_params, ownerPre = ownerPre,
  ownerPost = ownerPost, insideSize = insideSize
)
summary(result_cournotblp)
}

Run the code above in your browser using DataLab