функция прокрутки для обновления столбца на основе рейтинга / оценки - PullRequest
0 голосов
/ 11 октября 2019

Я пытаюсь создать функцию прокрутки. У меня есть событие, которое происходит один раз в год на 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, GOOGMSFT и 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, чтобы посмотреть, смогу ли я включить в эту функцию часть ранжирования и вычисления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...