Я пытаюсь создать функцию прокрутки. У меня есть событие, которое происходит один раз в год на release_Date
(которое я попытался наилучшим образом воспроизвести, используя данные о запасах ниже). Я измеряю это событие с помощью score
, обозначенного в столбце score
.
В конечном итоге я хочу перебалансировать портфели каждый месяц и вычислять доходность для каждого портфеля.
Каждый месяц я хочу применить функцию прокрутки, чтобы посмотреть на score
и назначить 1
, если он сверху ntile
или 2
, если внизу ntile
То естьЯ хочу использовать ntile
в некоторой степени следующим образом, но для каждого месяца df_monthly %>%
mutate(rank = ntile(score, 2))
.
Трудность, с которой я сталкиваюсь, заключается в том, что я хочу вычислить доходность портфеля для всех активов в rank = 1
идоходность портфеля для всех активов в rank = 2
каждого месяца. Оценка активов может упасть с rank = 1
до rank = 2
от одного месяца к следующему в зависимости от прихода новых score
в функцию.
То есть в месяце 1, GOOG
MSFT
и AMZN
могут быть в rank = 1
, а WAL
, MMM
и HOG
могут быть в rank = 2
. Во втором месяце рейтинг может измениться, потому что новые функции вошли в функцию, и rank = 1
теперь может выглядеть следующим образом: HOG
, GOOG
, MMM
.
Я хотел бы попытаться установить задержкупериод, т.е. вычислите ntiles
, используя последние 3 месяца score
- только с учетом компаний, которые столкнулись с событием за последние 3 месяца.
Любые указатели в правильном направлении были бы полезны,Если в каком-то месте мне неясно, дайте мне знать, и я перефразирую некоторые части.
Данные выглядят так:
# A tibble: 2,717 x 6
symbol year date monthly.returns release_date score
<chr> <dbl> <date> <dbl> <date> <dbl>
1 MKC 2010 2010-01-29 0 2010-02-28 0.741
2 MKC 2010 2010-02-26 0.0223 2010-02-28 0.741
3 MKC 2010 2010-03-31 0.0337 2010-02-28 0.741
4 MKC 2010 2010-04-30 0.0386 2010-02-28 0.741
5 MKC 2010 2010-05-28 -0.0253 2010-02-28 0.741
6 MKC 2010 2010-06-30 -0.0158 2010-02-28 0.741
7 MKC 2010 2010-07-30 0.0432 2010-02-28 0.741
8 MKC 2010 2010-08-31 0.0137 2010-02-28 0.741
9 MKC 2010 2010-09-30 0.0544 2010-02-28 0.741
10 MKC 2010 2010-10-29 0.0580 2010-02-28 0.741
# ... with 2,707 more rows
Я потратил некоторое время, чтобы попытаться повторитьнабор данных с использованием свободных данных:
library(tidyquant)
library(lubridate)
tickers <- c("GIS", "KR", "MKC", "SJM", "EL", "HRL", "HSY", "K",
"KMB", "MDLZ", "MNST", "PEP", "PG", "PM", "SYY", "TAP", "TSN", "WBA", "WMT",
"MMM", "ABMD", "ACN", "AMD", "AES", "AON", "ANTM", "APA", "CSCO", "CMS", "KO", "GRMN", "GPS",
"JEC", "SJM", "JPM", "JNPR", "KSU", "KEYS", "KIM", "NBL", "NEM", "NWL", "NFLX", "NEE", "NOC", "TMO", "TXN", "TWTR")
data <- tq_get(tickers,
get = "stock.prices", # Collect the stock price data from 2010 - 2015
from = "2010-01-01",
to = "2015-01-01") %>%
group_by(symbol) %>%
tq_transmute(select = adjusted, # Convert the data from daily prices to monthly prices
mutate_fun = periodReturn,
period = "monthly",
type = "arithmetic")
df_monthly <- data %>%
mutate(year = year(date)) %>%
group_by(symbol, year) %>% # I group_by and nest the data in order to create the event data which remains fixed over the monthly periods
nest() %>%
mutate( # Here I randomly create the dates
release_date = paste(year,
str_pad(ceiling(runif(row_number(), min = 1, max = 12)), 2, pad = "0"), # Create the months 1 - 12 months
str_pad(ceiling(runif(row_number(), min = 1, max = 27)), 2, pad = "0"), # Create the days - I choose 27 days in a month since later I set the days to the end of month day
sep = "-"),
score = runif(row_number(), min = 0, max = 1), # Randomly generate some scoring function
release_date = as.Date(release_date),
release_date = ceiling_date(release_date, "month") - days(1) # This gives the end of month date
) %>%
unnest() %>% # unnest to expand the yearly release_date and score to the monthly data
ungroup() %>%
mutate_if(is.integer, as.numeric) %>%
arrange(release_date)
РЕДАКТИРОВАТЬ:
Это дает мне среднюю доходность для каждого портфеля на основе рейтинга, но он не динамический, поскольку он учитывает только рейтинг year
.
df_monthly %>%
mutate(rank = ntile(score, 2)) %>%
group_by(year, rank) %>%
summarise(average_monthly_returns = mean(monthly.returns) * 100) %>%
arrange(rank, year)
Я изучаю функцию rolling_origin
из пакета rsample
, чтобы посмотреть, смогу ли я включить в эту функцию часть ранжирования и вычисления.