Я создал эту тему, потому что в настоящее время нет ни одной темы, посвященной портфолио-календарю в исследовании событий. Хотя этот подход используется в финансах, этот вопрос относится к коду, используемому на первом этапе использования этого подхода; расчет средней доходности всех сделок за период.
Я хочу создать доходность портфеля (равновзвешенную) по набору предварительно заданных сделок (n =~100000) за период выборки (в этом примере: с 01-01-2000 по 01-01-2010), уже имея фактическая доходность этих сделок в день. Поскольку это исследование событий, для каждой сделки учитываются только первые x дней (в этом примере 21 день, где t=0 — начальный день периода, а t=20 — последний день сделки).
Данные структурированы таким образом:
Для каждой транзакции идентификатор уникален, и для каждой транзакции известна фактическая доходность за день после события. Например, Ret.t0 — это возврат, сделанный в день, когда произошло событие (которое находится в столбце «Дата», например, 2000-01-01), Ret.t1 — это возврат, сделанный через 1 день после дня, когда произошло событие. событие имело место (например, 2000-01-02).
Создание образца, воспроизводимого в коде r:
size = 1e5
df <- data.frame(
ID = seq.int(size),
FirmID = sample(1:1000),
Date = sample(seq(
as.Date('2000/01/01'), as.Date('2010/01/01'), by = "day"
), size, replace = TRUE),
Ret.t0 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t1 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t2 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t3 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t4 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t5 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t6 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t7 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t8 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t9 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t10 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t11 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t12 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t13 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t14 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t15 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t16 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t17 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t18 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t19 = sample(-2000:2000, size, replace = TRUE)/100000,
Ret.t20 = sample(-2000:2000, size, replace = TRUE)/100000)
Основная проблема заключается в том, что, например, сделка, совершенная 01-01-2000, имеет доход в день t=6, который необходимо сопоставить со сделкой, заключенной 01-07-2000, доходность которой соответствует дню t= 0. Каждая сделка, которая имеет доход, должна быть учтена в средней доходности, которая является доходностью портфеля. Однако количество сделок в любой момент времени также не фиксировано.
Вывод доходности портфеля должен выглядеть следующим образом:
Date Return
2000-01-01 0.01205
2000-01-02 0.0089
2000-01-03 0.0012
….
2010-01-21 0.0302
как это?
library(dplyr)
library(tidyr)
df %>%
## ID not needed:
select(-ID) %>%
## stack return timepoints per FirmID and Date
pivot_longer(cols = starts_with('Ret'),
names_to = 'return_code',
values_to = 'return') %>%
arrange(FirmID, Date) %>%
rename('start_date' = 'Date') %>%
## extract timepoint t = 0, 1, ... from return code Ret.t0 ...
## and cast it to integer to add it to start date:
mutate(t = gsub('.*t', '', return_code) %>% as.integer,
date = start_date + t) %>%
## group by actual date and summarise:
group_by(date) %>%
summarise(avg_return = mean(return, na.rm = TRUE))
Благодарю вас! Ваш код также очень эффективен.