Оптимизируйте портфель с групповыми ограничениями - PullRequest
0 голосов
/ 04 апреля 2020

Моя цель состоит в том, чтобы оптимизировать портфель в , используя внутри add.constraint() аргумент type="group". В частности, группы создаются в соответствии с рыночной капитализацией как дискриминационная переменная.

library(tidyverse)
library(timetk)
library(quantmod)
library(stringr)
library(purrr)
library(PortfolioAnalytics)

Все начинается с двух фреймов данных, импортированных из csv, содержащих в своих столбцах временные ряды с 2010 по 2015 год цен акций и рыночных пределов, соответственно. Колонны - это названия компаний-эмитентов. На этом этапе я манипулирую информационным фреймом, содержащим рыночные ограничения, на и , чтобы получить следующее:

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

Как вы можете видеть содержит 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 кумулятивных вес - на каждый день.

1 Ответ

0 голосов
/ 22 апреля 2020

как я вижу, вы не использовали библиотеки Rglpk & quadprog до использования метода ROI. Попробуйте сначала установить, а затем импортировать эти пакеты.

...