Open amazinginging opened 7 months ago
Hello, I've made a few changes in both functions because I was studying new combinations of Copulas and portfolio restrictions. Although, I kept the old version on the files. Please, try to use them instead of the new ones. Furthermore, if you provide me the error messages I can check what is going on and give you a better answer.
This repository was build for my conclusion project. You can access the whole paper here: https://lume.ufrgs.br/handle/10183/26434/browse?type=author&value=Jungblut%2C+Jo%C3%A3o+Ramos
Thank you very much for your reply, your code is very excellent, but the following problems have occurred during my operation, and I have also made some modifications, but I don't know whether these modifications are correct. I can't find the old code under the current codebase, so I just run the R file main.R. Hope to get in touch with you in this way. My email address is 2105564065@qq.com. If it is convenient for you, we can also contact you by email.I have four questions as followings:
purrr::map()
at portfolio_analysis.R:101:2:
ℹ In index: 1.
Caused by error in association_measure_with_error_handling()
:
! object 'association_measure' not found
Run rlang::last_trace()
to see where the error occurred.
Warning message:
In value[3L] :
An error occurred while computing the association measure: An error occurred evaluating the 'table' parameter while selecting a method for the '%in%' function: argument "combination" is missing, with no default
I tried to modify 48 lines of code in the portfolio.analysis.R file, The original code is: association_measure <- OptMixtureCopulas(unif_dist = unif_dist, K = K), I modify it as follows: association_measure <- OptMixtureCopulas(unif_dist = unif_dist, K = K,combination = c("Clayton","Gumbel","t"))solnp-->The linearized problem has no feasible solnp-->solution. The problem may not be feasible.
Iter: 1 fn: -1490.7666 Pars: 1.18545 1.00000 1.59273 1.00000 0.52227 10.10246 1.00000
solnp--> Solution not reliable....Problem Inverting Hessian.
Error in purrr::map()
at portfolio_analysis.R:101:2:
ℹ In index: 1.
Caused by error in CVaROptimization()
:
! unused argument (Turnover = 3e-04)
Run rlang::last_trace()
to see where the error occurred.
There were 36 warnings (use warnings() to see them),
Therefore, I deleted the first CVaROptimization function and the third one, and only saved the following CVaROptimization function code: CVaROptimization <- function(returns,
Alpha = 0.975,
TargetReturn = 0,
Turnover = 0.0003,
NumAssets = 8) {
cvar_objective <- function(r_mat, alpha, probs = NULL) { x.names <- colnames(r_mat) N <- NCOL(r_mat) S <- NROW(r_mat) mu <- colMeans(r_mat) if (is.null(probs)) probs <- rep(1/S, S) if (alpha < 0.5) alpha <- 1 - alpha
Amat <- cbind(as.matrix(r_mat), diag(S), 1)
var.names <- c(x.names, paste0("z_cvar_aux", seq_len(S)), "gamma")
bnds <- ROI::V_bound(li = c(N + S + 1), lb = c( -Inf),
ui = c(N + S + 1), ub = c( Inf))
constraint <- L_constraint(L = Amat, dir = rep(">=", S),
rhs = rep(0, S),
names = var.names)
objective <- L_objective(c(rep(0, N), probs/(1 - alpha), 1))
list(objective = objective, constraint = constraint, bounds = bnds)
}
budget_constraint <- function(r_mat, dir = "==", rhs = 1) { x.names <- colnames(r_mat) L_constraint(L = rep(1, NCOL(r_mat)), dir = dir, rhs = rhs, names = x.names) }
reward_constraint <- function(r_mat, dir = ">=", rhs = TargetReturn) {
x.names <- colnames(r_mat)
L_constraint(L = colMeans(r_mat), dir = dir,
rhs = rhs, names = x.names)
}
turnover_constraint <- function(r_mat, x0 = NULL, dir = "<=", rhs = Turnover) {
x.names <- colnames(r_mat)
N <- NCOL(r_mat)
S <- NROW(r_mat)
if (is.null(x0)) x0 <- rep(1/N, N)
Amat <- cbind(diag(N), - diag(N), diag(N))
var.names <- c(x.names,
paste0("y_plus_aux", seq_len(N)),
paste0("y_minus_aux", seq_len(N)))
rbind(L_constraint(L = Amat, dir = rep("==", N), rhs = x0,
names = var.names),
L_constraint(c(rep(0, N), rep(1, N), rep(1, N) ),
dir = dir, rhs = rhs, names = var.names))
}
cardinality_constraint <- function(r_mat, dir = "<=", rhs = NumAssets) { x.names <- colnames(r_mat) N <- NCOL(r_mat) Amat <- cbind(diag(N), -diag(N)) var.names <- c(x.names, paste0("z_card_aux", seq_len(N))) cat("Variable types for z_card_aux must be set to binary.\n") rbind(L_constraint(L = Amat, dir = rep("<=", N), rhs = rep(0, N), names = var.names), L_constraint(L = c(rep(0, N), rep(1, N)), dir = dir, rhs = rhs, names = var.names)) }
tmp <- cvar_objective(returns, 0.975) lp <- OP()
constraints(lp) <- rbind( tmp$constraint, budget_constraint(returns), reward_constraint(returns),
cardinality_constraint(returns, dir = "<=", rhs = NumAssets),
use.names = TRUE
)
obj <- c((tmp$objective)$L) objective(lp) <- c(obj, double(NCOL(constraints(lp)) - length(obj))) types(lp) <- rep("C", NCOL(constraints(lp))) types(lp)[grep("z_card_aux", constraints(lp)$names)] <- "B" (sol <- ROI_solve(lp, solver = "glpk")) weights <- round(solution(sol)[1:ncol(returns)], 4)[1:ncol(returns)]
return(weights) }
solnp-->The linearized problem has no feasible solnp-->solution. The problem may not be feasible.
Iter: 1 fn: -1490.7666 Pars: 1.18545 1.00000 1.59273 1.00000 0.52227 10.10246 1.00000 solnp--> Solution not reliable....Problem Inverting Hessian. Variable types for z_card_aux must be set to binary. For this problem, I tried to modify 123 lines of copula_estimate.R. The original code is: if(is.null(pi) == TRUE){ pi = c(Clayton = 1, Gumbel = 1, t = 1, Normal = 1, Frank = 1, Joe = 1) }, I modify it as follows: if(is.null(pi) == TRUE){ pi = c(Clayton = 1/6, Gumbel = 1/6, t =1/6, Normal = 1/6, Frank =1/6 1, Joe = 1/6) } After the modification, Its results are as follows: 1 of 8
Iter: 1 fn: -1349.3177 Pars: 1.185451489 0.000000078 1.884782512 0.054868385 0.517355370 9.338307771 0.945131537 Iter: 2 fn: -1349.3177 Pars: 1.1854514890 0.0000000183 1.8848063293 0.0548664868 0.5173557482 9.3384527559 0.9451334949 Iter: 3 fn: -1349.3177 Pars: 1.18545148897 0.00000001068 1.88476221200 0.05486982385 0.51735509669 9.33816085686 0.94513016548 solnp--> Completed in 3 iterations Variable types for z_card_aux must be set to binary. At this point, the result I ran was different from your portfolio_return data in excel in the result folder. 4.After making the above changes, I try to run your code with my own data set, and sometimes the following two problems occur: 1: In .local(copula, tau, ...) : For the Gumbel copula, tau must be >= 0. Replacing negative values by 0.
When I have time to test the code again, I'll come back with a solution for your doubts.
Okay,thank you very much. And I also have a question,do these files contain the old version?I cannot find the old version.I'm a little worried.
I checked the files again and found that I had removed the old version of the OptMixtureCopulas function. If you try to run main.R, you'll encounter an error because it was designed for my conclusion project. Instead, please run test.R, which has been updated with new functionalities.
Thanks for your answer, I re-downloaded your codebase, I ran test.R, but something went wrong, I was running 63 lines of test.R: MarketComposition <- read_excel("data_directory/MarketComposition.xlsx") %>% mutate(date = as.Date(Data), # convert to date format m = month(date, label = TRUE)) %>% # convert to numeric format dplyr::filter(m == "dez") %>% # update factors select(date, everything(),-c(Data, m)) %>% # select date, month and tickers gather("Ticker", "Composition", -date, na.rm=TRUE) %>% # adjust to panel data group_by(date) %>% # Select tickers by last date of the month reframe(Tickers = Ticker) MarketComposition The resulting MarketComposition is empty, 0 obs. of 2 variables. I don't know how to solve this problem. In addition, I would like to ask you about the problems that occur when running the main.R file. Can you show me the latest portfolio_optimization.R and portfolio_analysis.R files that I need to run the main.R file. In view of the problems caused by running main.R, I made some code modifications last time, and I also told you my modification scheme, but I am not sure whether the modification method is correct.
It's all good with MarketComposition; it might be a misidentification of a function. Try declaring the library first in all tidyverse functions as in "dplyr::filter()".
MarketComposition <- read_excel("data_directory/MarketComposition.xlsx") %>%
- mutate(date = as.Date(Data), # convert to date format
- m = month(date, label = TRUE)) %>% # convert to numeric format
- dplyr::filter(m == "dez") %>% # update factors
- select(date, everything(), -c(Data, m)) %>% # select date, month, and tickers
- gather("Ticker", "Composition", -date, na.rm=TRUE) %>% # adjust to panel data
- group_by(date) %>% # Select tickers by last date of the month
- reframe(Tickers = Ticker) MarketComposition
A tibble: 1,557 × 2
date Tickers
1 1997-12-31 ITUB4 2 1997-12-31 PETR4 3 1997-12-31 BBDC4 4 1997-12-31 ELET3 5 1997-12-31 BBAS3 6 1997-12-31 ITSA4 7 1997-12-31 CMIG4 8 1997-12-31 VIVT3 9 1997-12-31 ELET6 10 1997-12-31 CSNA3 # ℹ 1,547 more rows # ℹ Use `print(n = ...)` to see more rows
On the other hand, I will reorganize this repository and include the old version.
Thanks for your patient answer. I tried the method you suggested again, but the result of MarketComposition is still MarketComposition
Now I guess there is a problem with MarketComposition.xlsx. The first column of my MarketComposition.xlsx file is Data, and the data format is "1997/12/31". MarketComposition.xlsx has 301 rows and 214 columns, but some columns are all NA Also, thank you very much for reorganizing your code base and uploading code files containing older versions.
Hello, thank you for uploading the old version of the code. There's nothing wrong with him But I have also been running your new version of the code recently and have a new question to ask you. When the mean-CVAR model is used to calculate portfolio weights, if the turnover limit is applied in addition, the code is expressed as follows:
CVaROptimization_turnover <- function(returns, Alpha = 0.95, TargetReturn = 0, Turnover = 0.2, NumAssets = 8) {
cvar_objective <- function(r_mat, alpha, probs = NULL) { x.names <- colnames(r_mat) N <- NCOL(r_mat) S <- NROW(r_mat) mu <- colMeans(r_mat) if (is.null(probs)) probs <- rep(1/S, S) if (alpha < 0.5) alpha= 1 - alpha
Amat <- cbind(as.matrix(r_mat), diag(S), 1)
var.names <- c(x.names, paste0("z_cvar_aux", seq_len(S)), "gamma")
## set bounds for gamma (-Inf, Inf)
bnds <- ROI::V_bound(li = c(N + S + 1), lb = c( -Inf),
ui = c(N + S + 1), ub = c( Inf))
constraint <- L_constraint(L = Amat, dir = rep(">=", S),
rhs = rep(0, S),
names = var.names)
objective <- L_objective(c(rep(0, N), probs/(1 - alpha), 1))
list(objective = objective, constraint = constraint, bounds = bnds)
}
budget_constraint <- function(r_mat, dir = "==", rhs = 1) { x.names <- colnames(r_mat) L_constraint(L = rep(1, NCOL(r_mat)), dir = dir, rhs = rhs, names = x.names) }
reward_constraint <- function(r_mat, dir = ">=", rhs = TargetReturn) { x.names <- colnames(r_mat) L_constraint(L = colMeans(r_mat), dir = dir, rhs = rhs, names = x.names) }
turnover_constraint <- function(r_mat, x0 = NULL, dir = "<=", rhs = Turnover) { x.names <- colnames(r_mat) N <- NCOL(r_mat) S <- NROW(r_mat) if (is.null(x0)) x0 <- rep(1/N, N) Amat <- cbind(diag(N), - diag(N), diag(N)) var.names <- c(x.names, paste0("y_plus_aux", seq_len(N)), paste0("y_minus_aux", seq_len(N)))
rbind(L_constraint(L = Amat, dir = rep("==", N), rhs = x0,
names = var.names),
L_constraint(c(rep(0, N), rep(1, N), rep(1, N) ),
dir = dir, rhs = rhs, names = var.names))
}
#
tmp <- cvar_objective(returns, 0.95)
lp <- ROI::OP()
constraints(lp) <- rbind( tmp$constraint, budget_constraint(returns), reward_constraint(returns,dir = ">=", rhs = TargetReturn), turnover_constraint(returns),
use.names = TRUE
)
obj <- c((tmp$objective)$L) objective(lp) <- c(obj, double(NCOL(constraints(lp)) - length(obj)))
types(lp) <- rep("C", NCOL(constraints(lp)))
types(lp)[grep("z_card_aux", constraints(lp)$names)] <- "B"
(sol <- ROI_solve(lp, solver = "glpk"))
weights <- round(solution(sol)[1:ncol(returns)], 4)[1:ncol(returns)] print(weights)
return(weights) }
If the copula type does not use the mixture type, and only a single copula model, such as GUASS, or t, is used to calculate, the resulting weight will sometimes yield NA: 85 of 171 [1] NA NA NA NA NA NA NA NA NA NA
Hello, recently I was running your code package to # Construct portfolio and benchmarks mixture_portfolio_1y <- RollingWindowEstimation(returns = returns, We = 252, Wt = nrow(returns), K = 1000, When Mixture = TRUE) here, you'll get an error, I changed line 48 of portfolio.analysis.R to association_measure < -OptMixtureCopulas (unif_dist = unif_dist, K = K,combination = c("Clayton", "Gumbel", "t", "Normal", "Frank", "Joe")) but I still get an error and I find 75 lines zsim < -ComputeZSim (copula_mixture = association_measure, garch_coef = fit_garch$garch_coef) The zsim generated here contains a lot of NA but here I don't know how to modify it