using EventStudies, TSFrames, DataFrames, Dates, MarketData
using CairoMakieStock splits
First, we'll load the stock split data from eventstudies.R.
stock_returns = EventStudies.load_data("StockPriceReturns.rda")
split_dates_df = EventStudies.load_data("SplitDates.rda")
other_returns = EventStudies.load_data("OtherReturns.rda")720×4 TSFrame with Dates.Date Index
Index NiftyIndex CallMoneyRate SP500 USDINR
Date Float64? Float64? Float64? Float64?
────────────────────────────────────────────────────────────────────────────
2010-07-01 -1.15678 missing missing 0.300978
2010-07-02 -0.27268 missing -1.34102 0.0
2010-07-05 -0.0229161 missing missing 0.407027
2010-07-06 1.00999 missing missing -0.01069
2010-07-07 -0.910725 missing 0.0671392 0.533107
2010-07-08 1.05809 missing 3.08501 -0.347263
2010-07-09 1.04421 missing 0.936867 -0.410599
2010-07-12 0.569144 missing missing 0.0428709
⋮ ⋮ ⋮ ⋮ ⋮
2013-03-20 missing 0.00810168 missing -0.312433
2013-03-21 missing 0.00811214 missing 0.220647
2013-03-22 missing 0.00793053 missing -0.183842
2013-03-25 missing 0.00813298 missing -0.0920387
2013-03-26 missing 0.00818972 missing 0.330962
2013-03-27 missing missing missing -0.0918373
2013-03-28 missing 0.00841387 missing -0.266753
705 rows omittedNo model
Let's try a regular event study, with no model:
eventtime_ts, event_return_codes = eventstudy(
stock_returns, # returns TSFrame
Symbol.(split_dates_df.name) .=> split_dates_df.when, # [:colname => event_time, ...]
-6:7 # window - asymmetric to completely mimic R
) # note that we haven't provided a model, so it defaults to `nothing` (no-op).(14×5 TSFrame with Int64 Index
Index HDFC.Bank HDFC ONGC Tata.Motors Tata.Power
Int64 Float64? Float64? Float64? Float64? Float64?
─────────────────────────────────────────────────────────────────
-6 0.182875 -1.39424 3.62834 1.79053 2.65584
-5 0.778869 -2.42392 -0.118961 -0.165678 0.142118
-4 -0.26351 -0.300476 0.562961 1.57929 1.14979
-3 -1.37165 0.237117 0.942451 0.416966 0.220375
-2 -1.73087 -0.800433 -0.312044 2.5547 -2.32828
-1 1.42525 1.25307 0.298643 -3.26589 1.36306
0 0.549044 3.0914 -5.74383 -4.22636 -1.81471
1 0.6109 3.62009 -2.5154 -4.72033 3.83498
2 1.05532 -0.685468 -0.364565 2.02027 -0.396826
3 -0.702305 -1.74247 1.36032 5.85999 1.67574
4 -1.56862 -0.558304 0.735891 6.78009 -2.5744
5 -1.31113 -0.907892 1.12031 -0.216685 -2.69394
6 1.02236 1.29106 -1.19187 2.90141 -0.206292
7 0.735224 -0.832071 -0.610305 -0.846438 1.38428, EventStudies.EventStatus[EventStudies.DataMissing(), EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.Success(), EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.Success(), EventStudies.WrongSpan() … EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.Success(), EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.DataMissing(), EventStudies.Success(), EventStudies.Success()])Now, let's perform bootstrap inference:
t0, lower, upper = EventStudies.inference(BootstrapInference(), eventtime_ts |> EventStudies.remap_cumsum)([0.0, -0.3575148629418301, 0.1880957720707066, 0.27714742452122465, -0.24623724107390998, -0.03141143177055383, -1.660301978084302, -1.4942548850162929, -1.1685092865325686, 0.12174605270397265, 0.6846773161436914, -0.11718994326018972, 0.6461452838188286, 0.6122837568587869], [0.0, -1.506726002073397, -1.4427668290151807, -1.3863363773538318, -2.513148050657854, -1.3437587464359702, -3.612493387761333, -6.586713817372562, -5.07775529240563, -3.5130756688838893, -3.081870439362042, -3.0708410583829426, -3.738197403769643, -3.4077241990091345], [0.0, 0.4673977740634405, 1.2096207008857363, 1.678093652093331, 2.6828472511659918, 1.2078518093625057, 0.2579500612082697, 3.3663073907141263, 2.9709845951455223, 2.8878453741074317, 4.6923199716414565, 4.067936147179984, 5.81225247120455, 5.554618864263193])and plot the results!
scatterlines(index(eventtime_ts), t0; label = "Mean")
lines!(index(eventtime_ts), upper; color = Makie.wong_colors(0.5)[1], linestyle = :dash, label = "95% CI")
lines!(index(eventtime_ts), lower; color = Makie.wong_colors(0.5)[1], linestyle = :dash)
# spruce up the figure
axislegend(Makie.current_axis(); position = :lt)
Makie.current_axis().xlabel = "Event time (days)"
Makie.current_axis().ylabel = "Return (%)"
Makie.current_axis().title = "Event study of stock splits"
Makie.current_axis().titlealign = :left
Makie.current_axis().subtitle = "In the Indian market, with no market model applied"
translate!(Makie.current_axis().scene.plots[1], 0, 0, 1)
Makie.current_figure()Market model (NIFTY)
eventtime_ts, event_return_codes = eventstudy(
stock_returns, # same as before
Symbol.(split_dates_df.name) .=> split_dates_df.when, # same as before
-6:7, # same as before
MarketModel(other_returns[:, [:NiftyIndex]]) # ooh, what's this?
)(14×5 TSFrame with Int64 Index
Index HDFC.Bank HDFC ONGC Tata.Motors Tata.Power
Int64 Float64 Float64 Float64 Float64 Float64
────────────────────────────────────────────────────────────────────
-6 0.225854 -0.80165 3.81861 0.690046 2.62294
-5 -1.16383 -1.45301 1.05671 0.420064 0.863938
-4 0.885413 -0.24794 0.501271 0.262824 -0.113561
-3 -0.641317 -0.729052 -0.0692522 -1.2425 0.378054
-2 -0.157188 0.0103284 1.36897 1.75614 0.361421
-1 0.255605 1.30565 0.411895 -0.783726 2.15257
0 0.20872 1.37799 -4.6109 -1.17577 -1.32339
1 0.875184 2.02536 -1.67066 -4.59387 2.16844
2 1.23528 -0.499531 0.0971726 0.0125441 -0.00315845
3 -1.631 -2.11913 0.433975 4.10823 0.871909
4 -0.795657 0.354297 -0.917114 6.51367 -1.59143
5 -0.920316 0.122166 0.938381 1.16485 -1.41924
6 -0.746065 0.84182 -1.08392 -0.0517011 0.875767
7 -0.180709 0.88173 -1.26 -0.696715 1.73189, EventStudies.EventStatus[EventStudies.ModelDataMissing(), EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.Success(), EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.Success(), EventStudies.WrongSpan() … EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.Success(), EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.WrongSpan(), EventStudies.ModelDataMissing(), EventStudies.Success(), EventStudies.Success()])Now for the inference:
t0, lower, upper = EventStudies.inference(BootstrapInference(), eventtime_ts |> EventStudies.remap_cumsum)([0.0, -0.05522637387771654, 0.20237504247193847, -0.2584376133455678, 0.40949695842266987, 1.0778949505152826, -0.0267745490975587, -0.26588460454727886, -0.09742413797151475, 0.23537286450527545, 0.9481255949593376, 0.9252929048053623, 0.8924728201203213, 0.9877120842924988], [0.0, -0.9627249142940759, -0.9396767129442709, -1.7183160990485633, -1.4278826779182983, -0.750118744459108, -1.049822782053468, -3.8276028982670427, -3.886589043346444, -1.7623287311970084, -2.2195231643581796, -1.9382108356031056, -2.4473268749472705, -3.063124807094376], [0.0, 0.9293814669388158, 1.2214418180167814, 1.007002165595523, 2.19323258084696, 2.847367322890443, 1.321690490307419, 3.202860512841476, 3.3481142600205573, 3.1604723372510106, 3.924512763642318, 3.9747765928190466, 4.636071272056952, 4.78119919485043])and the plots!
scatterlines(index(eventtime_ts), t0; label = "Mean")
lines!(index(eventtime_ts), upper; color = Makie.wong_colors(0.5)[1], linestyle = :dash, label = "95% CI")
lines!(index(eventtime_ts), lower; color = Makie.wong_colors(0.5)[1], linestyle = :dash)
# spruce up the figure
axislegend(Makie.current_axis(); position = :lt)
Makie.current_axis().xlabel = "Event time (days)"
Makie.current_axis().ylabel = "Return (%)"
Makie.current_axis().title = "Event study of stock splits"
Makie.current_axis().titlealign = :left
Makie.current_axis().subtitle = "In the Indian market, with the NIFTY index applied as a market model"
translate!(Makie.current_axis().scene.plots[1], 0, 0, 1)
Makie.current_figure()Note how this looks subtly different than the first plot, just because of the market model!
Intraday data
aggregate_returns = EventStudies.load_data("AggregateReturns.rda")
rate_cuts_df = EventStudies.load_data("RateCuts.rda")
index_returns = EventStudies.load_data("IndexReturns.rda")
intraday_eventtime_ts, event_return_codes = eventstudy(
aggregate_returns,
Symbol.(rate_cuts_df.name) .=> rate_cuts_df.when,
-34:35,
MarketModel(index_returns[:, [:x_1]])
)
intraday_eventtime_ts.coredata[1, :] .= 0
t0, lower, upper = EventStudies.inference(BootstrapInference(), intraday_eventtime_ts |> EventStudies.remap_cumsum)
lines(t0)
lines!(lower)
line!(upper)
Makie.current_figure()Something else
This page was generated using Literate.jl.