Моя цель состоит в том, чтобы оптимизировать портфель в portfolioanalytics , используя внутри add.constraint()
аргумент type="group"
. В частности, группы создаются в соответствии с рыночной капитализацией как дискриминационная переменная.
library(tidyverse)
library(timetk)
library(quantmod)
library(stringr)
library(purrr)
library(PortfolioAnalytics)
Все начинается с двух фреймов данных, импортированных из csv, содержащих в своих столбцах временные ряды с 2010 по 2015 год цен акций и рыночных пределов, соответственно. Колонны - это названия компаний-эмитентов. На этом этапе я манипулирую информационным фреймом, содержащим рыночные ограничения, на xts и dplyr , чтобы получить следующее:
structure(list(date = structure(c(14638, 14666, 14699, 14729,
14760, 14790), class = "Date"), asset = c("X3M.cap", "X3M.cap",
"X3M.cap", "X3M.cap", "X3M.cap", "X3M.cap"), mktcap = c(56983.51,
57045.4, 59591.06, 63227.7, 56553.39, 56330.44), ptf = c(TRUE,
TRUE, TRUE, TRUE, TRUE, TRUE)), class = c("grouped_df", "tbl_df",
"tbl", "data.frame"), row.names = c(NA, -6L), groups = structure(list(
date = structure(c(14638, 14666, 14699, 14729, 14760, 14790
), class = "Date"), .rows = list(1L, 2L, 3L, 4L, 5L, 6L)), row.names = c(NA,
-6L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE))
Как вы можете видеть tibble содержит 4 столбца с датой, активами (названиями акций), mktcap (дискриминационная переменная) и Ptf
. Ptf
в этом случае содержит логические значения, показывающие TRUE
, когда переменная mktcap
этого наблюдения попадает в первый квинтиль из mktcap
с всех asset
с в течение определенного c дня. Это FALSE
, когда он попадает в последний квинтиль, и NA
в противном случае.
Оттуда я извлекаю для каждого date
asset
s, значения которых TRUE
и false, используя следующий код:
long_components_size <- data_SIZE %>% filter(ptf==TRUE) %>%
select(asset,date) %>% group_by(date)
long_comps_size <- group_split(long_components_size, keep=FALSE)
names(long_comps_size) <- unique(long_components_size$date) #long
Тот же самый код реплицируется для ptf==FALSE
. Таким образом, я получил два списка, содержащие для каждой даты тиббл с asset
s как chr
.
list(`2010-01-29` = structure(list(asset = c("X3M.cap", "ABBOTT.LABORATORIES.cap",
"ACCENTURE.CLASS.A.cap", "ALPHABET.A.cap", "ALTRIA.GROUP.cap",
"AMAZON.COM.cap", "AMERICAN.EXPRESS.cap", "AMGEN.cap", "ANTHEM.cap",
"APACHE.cap", "APPLE.cap", "AT.T.cap", "BANK.OF.AMERICA.cap",
...
"UNION.PACIFIC.cap", "UNITED.PARCEL.SER..B..cap", "UNITED.TECHNOLOGIES.cap",
"UNITEDHEALTH.GROUP.cap", "US.BANCORP.cap", "VERIZON.COMMUNICATIONS.cap",
"VISA..A..cap", "WALGREENS.BOOTS.ALLIANCE.cap", "WALMART.cap",
"WALT.DISNEY.cap", "WELLS.FARGO...CO.cap")), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -91L)))
Я не уверен, но, вероятно, эти списки содержат сами списки, где эти chr
затем хранятся. Название тиббла / списка внутри каждого списка совпадает со днем, когда stock
попадают в ту или иную категорию.
Моя цель - создать портфель и, следовательно, получить подходящие веса из optimize.portfolio
, передав в add.constraint
аргумент type="groups"
, который позволяет выбрать вес каждой группы.
Я попытался сделать это следующим образом:
stocks <- read.csv("prova_price.csv",sep=";")
stocks_xts <- as.xts(data[,-1], order.by=as.Date(data$Index,
format="%d/%m/%Y"))
port_size <- portfolio.spec(assets=stocks_xts)
port_size <- add.constraint(port_size,type="dollar neutral")
port_size <- add.constraint(port_size, type="group",
groups=list(groupA=long_comps_size$`2010-01-29`$asset,
groupB=short_comps_size$`2010-01-29`$asset),
group_min=c(+1,-1),
group_max=c(+1,-1))
port_size <- add.objective(port_size, type="risk",name="sd")
optimize.portfolio(R=stocks_xts, portfolio=port_size,
optimize_method="ROI", trace=FALSE)
, где stocks_xts
содержит временные ряды цен в своих столбцах и содержит те же символы data_SIZE$asset
, что и названия столбцов.
> str(stocks_xts)
An ‘xts’ object on 2010-01-01/2015-12-31 containing:
Data: num [1:1565, 1:505] 58527 58775 58407 59235 59277 ...
- attr(*, "dimnames")=List of 2
..$ : NULL
..$ : chr [1:505] "X3M...MARKET.VALUE" "ABBOTT.LABORATORIES...MARKET.VALUE" "ABBVIE...MARKET.VALUE" "ABIOMED...MARKET.VALUE" ...
Indexed by objects of class: [Date] TZ: UTC
xts Attributes:
NULL
Я попытался установить веса двух групп, заданных в качестве аргументов ранее полученных списков, и присвоить им веса -1 и +1, потому что я хочу получить портфель dollar-neutral
.
Я думаю, что проблема заключается в структуре списков long_comps_size
и short_comps_size
, которые должны быть не просто символами, а чем-то большим. Моя конечная цель состоит в том, чтобы придумать временные ряды доходности портфеля, портфеля, построенного путем отрицательного взвешивания акций, которые привели к FALSE
в data_SIZE
, и положительного взвешивания тех, у кого TRUE
- так, чтобы иметь 0 кумулятивных вес - на каждый день.