Создайте портфель акций на основе вероятностей с перебалансировкой в ​​R

Я использовал случайный лес в R, чтобы получить вероятности того, что акции принадлежат определенному классу. С этими вероятностями я хотел бы построить портфели, содержащие 5 акций с наивысшими вероятностями на первую дату набора данных, а затем перебалансировать его каждые 10 дней с акциями с наивысшим рейтингом в то время. Портфель должен быть равновзвешенным.

Вот несколько примеров данных, которые, как мне кажется, могут быть представлены моими данными.

Date <- rep(seq(as.Date("2009/01/01"), by = "day", length.out = 100), 10)
Name <- c(rep("Stock A", 100), rep("Stock B",100), rep("Stock C", 100), rep("Stock D", 100), rep("Stock E",100), rep("Stock F",100), rep("Stock G",100), rep("Stock H",100), rep("Stock I", 100), rep("Stock J", 100))
Return <- rnorm(1000)
Prob <- runif(1000)           

DF <- data.frame(Date, Name, Return, Prob)
DF <- DF %>% arrange(Date, desc(Prob))
> head(DF)
        Date    Name      Return      Prob
1 2009-01-01 Stock F  0.52259644 0.8084277
2 2009-01-01 Stock A  0.57720376 0.7617348
3 2009-01-01 Stock B -0.09864981 0.7256358
4 2009-01-01 Stock E -1.26136381 0.6200346
5 2009-01-01 Stock G -1.37360527 0.5680765
6 2009-01-01 Stock D -0.04794049 0.4793370

Таким образом, портфель будет содержать акции F, A, B, E и G в течение первых 10 дней, а затем сбалансировать его с акциями с наивысшим процентом.

Я не очень хорошо разбираюсь в кодировании и R и пробовал искать варианты того, как я могу сделать это с помощью PortfolioAnalytics, PerformanceAnalytics и tidyquant, но я не могу найти решение, в котором я понимаю, как это сделать, поскольку я не заинтересованы в использовании любых форм оптимизации. Мне нужен простой портфель, определяемый моими расчетными процентами, с ребалансировкой.

Если у кого-то есть предложения, как я могу это сделать, я был бы очень признателен. И если это неправильный форум для размещения этого вопроса, я прошу прощения и отправлю его где-нибудь еще.


person signe    schedule 15.04.2020    source источник


Ответы (1)


Вот пример того, как это сделать с помощью пакета PMwR. (Раскрытие информации: я сопровождаю пакет.)

Позвольте мне начать с примера набора данных: 12 отраслевых серий с веб-сайта Кеннета Френча. Обратите внимание, что я использую эти данные только для выполнения функций.

library("NMOF")
library("PMwR")

P <- French(dest.dir = "~/Downloads/French",
            "12_Industry_Portfolios_daily_CSV.zip",
            price.series = TRUE, na.rm = TRUE)
timestamp <- as.Date(row.names(P))

Цены хранятся в фрейме данных P. В каждом столбце указана цена одного актива; каждая строка содержит цены на одну дату.

Главный вопрос для вас - как организовать свои сигналы. Я буду создавать случайные сигналы и организовывать их в логическую матрицу. Каждая строка содержит сигналы для одной даты ребалансировки: ИСТИНА, если актив должен быть включен, ЛОЖЬ, если нет.

reb.dates <- timestamp[seq(from = 5, to = length(timestamp), by = 10)]
best.stocks <- t(replicate(length(reb.dates),
                           sample(c(rep(TRUE, 5), rep(FALSE, 7)))))

colnames(best.stocks) <- colnames(P)
head(data.frame(reb.dates, best.stocks))
##    reb.dates NoDur Durbl Manuf Enrgy ....  Hlth Money Other
## 1 1926-07-07  TRUE FALSE  TRUE  TRUE .... FALSE FALSE FALSE
## 2 1926-07-19 FALSE FALSE  TRUE  TRUE .... FALSE  TRUE FALSE
## 3 1926-07-30 FALSE  TRUE  TRUE FALSE .... FALSE FALSE FALSE
## 4 1926-08-11  TRUE  TRUE FALSE FALSE .... FALSE FALSE  TRUE
## 5 1926-08-23 FALSE FALSE  TRUE FALSE ....  TRUE  TRUE FALSE
## 6 1926-09-03 FALSE FALSE  TRUE  TRUE ....  TRUE FALSE FALSE

Если у вас есть цены и такая матрица сигналов, фактическое тестирование на истории не требует большого количества кода.

Ключевой ингредиент - это функция signal. Он вызывается при каждой дате ребалансировки (т.е. каждые 10 дней), ищет и возвращает целевой портфель.

signal <- function(best.stocks, reb.dates) {
    w <- numeric(ncol(Close()))    
    w[best.stocks[Timestamp(0) == reb.dates]]  <- 1
    w <- w/sum(w)
    w
}

bt <- btest(prices = list(as.matrix(P)),
            timestamp = timestamp,
            signal = signal,
            do.signal = reb.dates,
            initial.cash = 100,
            convert.weights = TRUE,
            best.stocks = best.stocks,
            reb.dates = reb.dates)

## see a performance summary 
summary(as.NAVseries(bt))

## see the trades
journal(bt)

Более подробную информацию об использовании пакета можно найти в этом руководстве.

person Enrico Schumann    schedule 15.04.2020