2

I am trying to learn the DEoptim library in R but I think I am misunderstanding the library documentation from

https://www.rdocumentation.org/packages/DEoptim/versions/2.2-4/topics/DEoptim

I am getting the error argument "returns_covar" is missing, with no default when I try the code below

The function I am trying to optimize (minimize) is:

calculate_portfolio_variance <- function(allocations, returns_covar)
{
  # Name: calculate_portfolio_variance
  # Purpose: Computes expected portfolio variance, to be used as the minimization objective function
  # Input: allocations = vector of allocations to be adjusted for optimality; returns_covar = covariance matrix of stock returns
  # Output: Expected portfolio variance

  portfolio_variance <- allocations%*%returns_covar%*%t(allocations)
  return(portfolio_variance)
}

filter_and_sort_symbols <- function(symbols)
{
  # Name: filter_and_sort_symbols
  # Purpose: Convert to uppercase if not
  # and remove any non valid symbols
  # Input: symbols = vector of stock tickers
  # Output: filtered_symbols = filtered symbols

  # convert symbols to uppercase
  symbols <- toupper(symbols)

  # Validate the symbol names
  valid <- regexpr("^[A-Z]{2,4}$", symbols)

  # Return only the valid ones
  return(sort(symbols[valid == 1]))
}

# Create the list of stock tickers and check that they are valid symbols
tickers <- filter_and_sort_symbols(c("XLE", "XLB", "XLI", "XLY", "XLP", "XLV", "XLK", "XLU", "SHY", "TLT"))
# Set the start and end dates
start_date <- "2013-01-01"
end_date <- "2014-01-01"

# Gather the stock data using quantmod library
getSymbols(Symbols=tickers, from=start_date, to=end_date, auto.assign = TRUE)

# Create a matrix of only the adj. prices
price_matrix <- NULL
for(ticker in tickers){price_matrix <- cbind(price_matrix, get(ticker)[,6])}
# Set the column names for the price matrix
colnames(price_matrix) <- tickers

# Compute log returns
returns_matrix <- apply(price_matrix, 2, function(x) diff(log(x)))
returns_covar <- cov(returns_matrix)

# Specify lower and upper bounds for the allocation percentages
lower <- rep(0, ncol(returns_matrix))
upper <- rep(1, ncol(returns_matrix))

# Calculate the optimum allocation; THIS CAUSES AN ERROR
set.seed(1234)
optim_result <- DEoptim(calculate_portfolio_variance, lower, upper, control = list(NP=100, itermax=300, F=0.8, CR=0.9, allocations, returns_covar))

Again, the error from the last line is that the returns_covar argument is missing, but I try passing it into the DEoptim() function.

I think the above has a parenthesis error, so I've tried the following

optim_result <- DEoptim(calculate_portfolio_variance, lower, upper, control = list(NP=100, itermax=300, F=0.8, CR=0.9), returns_covar)

This results in the following error:

Error in allocations %*% returns_covar %*% t(allocations) : non-conformable arguments

When I check the dimensionality of the matrices, everything seems ok

> dim(allocations)
[1]  1 10
> dim(returns_covar)
[1] 10 10

Adding a dimensionality check within the calculate_portfolio_variance() function

  print(dim(allocations))
  print(dim(returns_covar))

shows that the allocation vector becomes NULL on the second iteration. I'm not sure why or how to address it.

[1]  1 10
[1] 10 10
NULL
[1] 10 10
Error in allocations %*% returns_covar %*% t(allocations) : non-conformable arguments
0

1 Answer 1

2

Not clear if this is what you intend, but if you change calculate_portfolio_variance to

  portfolio_variance <- t(allocations)%*%returns_covar%*%allocations

It works for me. I think it's an issue with your matrix math.

EDIT full working reproducible example:

library(quantmod)
library(DEoptim)


calculate_portfolio_variance <- function(allocations, returns_covar)
{
  # Name: calculate_portfolio_variance
  # Purpose: Computes expected portfolio variance, to be used as the minimization objective function
  # Input: allocations = vector of allocations to be adjusted for optimality; returns_covar = covariance matrix of stock returns
  # Output: Expected portfolio variance

  ### I CHANGED THIS LINE
  #portfolio_variance <- allocations%*%returns_covar%*%t(allocations)
  portfolio_variance <- t(allocations)%*%returns_covar%*%allocations
  return(portfolio_variance)
}

filter_and_sort_symbols <- function(symbols)
{
  # Name: filter_and_sort_symbols
  # Purpose: Convert to uppercase if not
  # and remove any non valid symbols
  # Input: symbols = vector of stock tickers
  # Output: filtered_symbols = filtered symbols

  # convert symbols to uppercase
  symbols <- toupper(symbols)

  # Validate the symbol names
  valid <- regexpr("^[A-Z]{2,4}$", symbols)

  # Return only the valid ones
  return(sort(symbols[valid == 1]))
}

# Create the list of stock tickers and check that they are valid symbols
tickers <- filter_and_sort_symbols(c("XLE", "XLB", "XLI", "XLY", "XLP", "XLV", "XLK", "XLU", "SHY", "TLT"))
# Set the start and end dates
start_date <- "2013-01-01"
end_date <- "2014-01-01"

# Gather the stock data using quantmod library
getSymbols(Symbols=tickers, from=start_date, to=end_date, auto.assign = TRUE)

# Create a matrix of only the adj. prices
price_matrix <- NULL
for(ticker in tickers){price_matrix <- cbind(price_matrix, get(ticker)[,6])}
# Set the column names for the price matrix
colnames(price_matrix) <- tickers

# Compute log returns
returns_matrix <- apply(price_matrix, 2, function(x) diff(log(x)))
returns_covar <- cov(returns_matrix)

# Specify lower and upper bounds for the allocation percentages
lower <- rep(0, ncol(returns_matrix))
upper <- rep(1, ncol(returns_matrix))

# Calculate the optimum allocation
set.seed(1234)
### USING YOUR CORRECTED CALL
optim_result <- DEoptim(calculate_portfolio_variance, lower, upper, control = list(NP=100, itermax=300, F=0.8, CR=0.9), returns_covar)
Sign up to request clarification or add additional context in comments.

5 Comments

Do you mean to just modify the line within calculate_portfolio_variance()? I replaced it with what you suggested but still get the same non-conformable arguments error. I agree, there seems to be an issue with the matrix math, but I haven't pinned down where it is yet. When I use str(lower) it displays a vector of correct length, using dim(lower) displays NULL.
For what it's worth, when I execute portfolio_variance <- allocations%*%returns_covar%*%t(allocations) in the console, it calculates correctly. But when I execute portfolio_variance <- t(allocations)%*%returns_covar%*%allocations in the console, I get a non-conformable arguments error
@coolhand I updated my answer to include a working reproducible example.
It's working for me, thanks! Do you know if the issue was an order of operations issue?
@coolhand sort of, in that because allocations is a vector you need to be careful about where you transpose. See ?matmult for more info. It appears that %*% will automatically try to transpose vectors to make the multiplication work, but you explicitly transposed allocations on the right. Interestingly, omitting the transpose and just doing allocations%*%returns_covar%*%allocations works as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.