简体   繁体   中英

Create stock portfolio based on probabilities with rebalancing in R

I have used random forest in R to get probabilities for stocks being in a certain class. With those probabilities i would like to construct portfolios containing the 5 stocks with the highest probabilities on the first date of the dataset, and then rebalance this every 10 days with the stocks with the highest ranking at that time. The portfolio should be equal weighted.

Here is some example data that i think is representable of my data.

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

So the portfolio would contain stock F, A, B, E, and G for the first 10 days, and then rebalance it with the stocks of the highest percentage.

I am not very good at coding and R, and have tried looking at options as to how i can do this with PortfolioAnalytics, PerformanceAnalytics and tidyquant, but am not able to find a solution where i understand how to do this, as i am not interested in using any form of optimizing. I need a simple portfolio determined by my calculated percentages, with rebalancing.

If anyone has any suggestions as to how i can do this, i would highly appreciate it. And if this is the wrong forum for posting this question, i am sorry and will post it elsewhere.

Here would be an example how to do this with PMwR package. (Disclosure: I am the package maintainer.)

Let me start with an example dataset: 12 industry series from Ke.neth French's website. Note that I only use those data so that the functions run.

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))

The prices are stored in a data frame P . Each column holds the price of one asset; each row holds the prices at one date.

The main question for you is how to organise your signals. I will create random signals and organise them in a matrix of logicals. Each row holds the signals for one rebalancing date: TRUE if the asset is to be included, FALSE if not.

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

Once you have the prices and such a matrix of signals, the actual backtest does not require much code.

The key ingredient is the signal function. It is called at every rebalancing date (ie every 10 days) and looks up and returns the target portfolio.

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)

More details on using the package are in this tutorial .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM