Type: | Package |
Title: | Synthetic Matching Method for Returns |
Version: | 1.0.0 |
Description: | Implements the revised Synthetic Matching Algorithm of Kreitmeir, Lane, and Raschky (2025) <doi:10.2139/ssrn.3751162>, building on the original approach of Acemoglu, Johnson, Kermani, Kwak, and Mitton (2016) <doi:10.1016/j.jfineco.2015.10.001>, to estimate the cumulative treatment effect of an event on treated firms’ stock returns. |
License: | MIT + file LICENSE |
Encoding: | UTF-8 |
URL: | https://github.com/davidkreitmeir/synthReturn |
BugReports: | https://github.com/davidkreitmeir/synthReturn/issues |
RoxygenNote: | 7.3.2 |
Imports: | base (≥ 4.0.0), stats, utils, corpcor (≥ 1.6.10), data.table, quadprog (≥ 1.5), parallel, mirai |
Depends: | R (≥ 4.0) |
LazyData: | true |
Suggests: | knitr, rmarkdown, testthat (≥ 3.0.0) |
Config/testthat/edition: | 3 |
NeedsCompilation: | no |
Packaged: | 2025-09-02 01:30:27 UTC; david |
Author: | David H Kreitmeir [aut, cre], Christian Düben [ctb] |
Maintainer: | David H Kreitmeir <david.kreitmeir1@monash.edu> |
Repository: | CRAN |
Date/Publication: | 2025-09-08 18:40:02 UTC |
Simulated timeseries of stock returns
Description
ret_two_evdates
presents a simulated timeseries of stock returns for 20
treated firms and a set of 60 potential control firms. The simulated data allows for a max
estimation window of 100 trading days (in event time: -100 to -1) and a max event window
of 6 trading days (in event time: 0 to +5).
Usage
ret_two_evdates
Format
ret_two_evdates
has 14,000 rows and 5 variables:
- eventdate
Calendar date when the event happened (
<Date>
).- date
Calendar date (
<Date>
).- ret
Raw stock return (
<num>
).- treat
Binary treatment indicator (
<lgcl>
).- unit
Unique identifier for each treated, respectively control firm (
<int>
).
Simulated timeseries of stock returns
Description
ret_two_evdates_num
presents a simulated timeseries of stock returns for 20
treated firms and a set of 60 potential control firms. The simulated data allows for a max
estimation window of 100 trading days (in event time: -100 to -1) and a max event window
of 6 trading days (in event time: 0 to +5).
Usage
ret_two_evdates_num
Format
ret_two_evdates_num
has 14,000 rows and 5 variables:
- eventdate
Numeric date when the event happened (
<int>
).- date
Numeric date (
<int>
).- ret
Raw stock return (
<num>
).- treat
Binary treatment indicator (
<lgcl>
).- unit
Unique identifier for each treated, respectively control firm (
<int>
).
Compute synthetic returns
Description
synthReturn
implements the revised Synthetic Matching Algorithm of
Kreitmeir et al. (2025), building on the original approach of Acemoglu et al. (2016), to estimate
the cumulative treatment effect of an event on treated firms’ stock returns.
Usage
synthReturn(
data,
unitname,
treatname,
dname,
rname,
edname,
estwind,
eventwind,
estobs_min = 1,
eventobs_min = 1,
inference = c("none", "permutation", "bootstrap"),
correction = FALSE,
ncontrol_min = 10,
ndraws = 25,
ncores = NULL,
static_scheduling = TRUE
)
Arguments
data |
The name of the data frame that contains the data. |
unitname |
The name of the column containing IDs of treated and control units. |
treatname |
The name of the indicator column set to |
dname |
The name of the column containing the date variable. The column must either be of type |
rname |
The name of the column containing the stock returns. |
edname |
The name of the column containing the (treatment unit-specific) event date. All event dates must also exist in |
estwind |
Argument to set estimation window period in relative time to event, i.e. |
eventwind |
Argument to set event window period in relative time to event, i.e. |
estobs_min |
Argument to define minimum number of trading days during the estimation window.
Can be an integer or a proportion (i.e. between 0 and 1). Default is |
eventobs_min |
Argument to define minimum number of trading days during the event window. Can be an
integer or a proportion (i.e. between 0 and 1). Default is |
inference |
Argument to define which inference method is to be used. Both permutation and bootstrap inference are implemented. Default is |
correction |
Logical defining if "corrected" synthetic matching results are used for inference. If |
ncontrol_min |
Minimum number of control firms required to create synthetic match. Default is |
ndraws |
Number of randomly drawn placebo treatment groups if |
ncores |
Number of CPU cores to use. |
static_scheduling |
Logical setting the parallel scheduling type. |
Details
The data's dname
and edname
columns refer to dates. dname
is the date that a row refers to. edname
is the date when a unit was treated.
I.e., edname
is constant across all rows per unit. And it is ignored for never treated units.
The package does not care what interval a time period refers to. It evaluates units' sequences of distinct Date
or numerical values in dname
and
edname
, irrespective of whether they denote days, hours, etc.
estwind
and eventwind
describe sections in these sequences. 0 is the treatment time. Hence, c(-1, -100)
is a unit's 100 observations before
treatment. When dname
and edname
are in days and a specific unit is observed on 2 days per week, c(-1, -100)
covers 50 weeks before treatment in
the case of that unit. In the case of financial data, that would be a company's 100 trading days before treatment.
Value
An S3 object containing the following components:
n_treat_pre |
Number of treatment units in the data. |
n_treat_res |
Number of treatment units in the data that fulfill the minimum requirements and are used in the calculation of
the average treatment effect |
ate |
Data.table containing the relative time period |
ar |
Data.table reporting the estimated abnormal returns, the "goodness" of the synthetic match estimate |
ate_bootstrap |
Data.table containing the average treatment effect estimates |
n_bootstrap |
Number of bootstrap iterations that returned a valid result. |
ate_placebo |
Data.table containing the average treatment effect estimates |
n_placebo |
Number of placebo draws that returned a valid result. |
call |
List with arguments used in the call. |
Examples
# Load data in that comes in the synthReturn package
data(ret_two_evdates)
# -----------------------------------------------
# Example with Permutation Inference
# -----------------------------------------------
set.seed(123) # set random seed
# Run synthReturn
res.placebo <- synthReturn(
data = ret_two_evdates,
unitname = "unit",
treatname = "treat",
dname = "date",
rname = "ret",
edname = "eventdate",
estwind = c(-100,-1),
eventwind = c(0,5),
estobs_min = 1,
eventobs_min = 1,
inference = "permutation",
correction = FALSE,
ncontrol_min = 10,
ndraws = 10,
ncores = 1
)
# -----------------------------------------------
# Example with Nonparametric Bootstrap
# -----------------------------------------------
set.seed(123) # set random seed
# Run synthReturn
res.boot <- synthReturn(
data = ret_two_evdates,
unitname = "unit",
treatname = "treat",
dname = "date",
rname = "ret",
edname = "eventdate",
estwind = c(-100,-1),
eventwind = c(0,5),
estobs_min = 1,
eventobs_min = 1,
inference = "bootstrap",
correction = FALSE,
ncontrol_min = 10,
ndraws = 25,
ncores = 1
)
# -----------------------------------------------
# Example with Missing Returns
# -----------------------------------------------
set.seed(123) # set random seed
# Randomly introduce 2% of missing return values
ret_two_evdates[sample.int(nrow(ret_two_evdates), floor(0.02*nrow(ret_two_evdates))), ret := NA]
# Run synthReturn
res.boot <- synthReturn(
data = ret_two_evdates,
unitname = "unit",
treatname = "treat",
dname = "date",
rname = "ret",
edname = "eventdate",
estwind = c(-100,-1),
eventwind = c(0,5),
estobs_min = 0.9, # require 90% of trading days during estimation window w/ non-missing returns
eventobs_min = 0.9, # require 90% of trading days during event window w/ non-missing returns
inference = "bootstrap",
correction = FALSE,
ncontrol_min = 10,
ndraws = 25,
ncores = 1
)