My strategy is designed to buy and sell all assets of a universe and rebalance periodically. It goes either long or short. To limit risk exposure to a single currency I would like the assets in the universe to have low relashionship and low price correlation between them (positive or even negative as it can go short).

For example, if the universe has 3 currency pairs A, B and C, my objective is to have price correlation c1 (between A and B), c2 (between B and C) and c3 (between A and C) as low as possible. Let's say c0 is the average of c1, c2, and c3, it will give information on the "global" correlation between pairs A, B and C.

Now imagine we have 26 currency pairs (from A to Z) to consider for creating a small universe of 5 of them (3 was for the example).

The method I apply is to create every possible combination of groups of 5 currency pairs and then it calculates c0 correl$corr of every single group. I also calculate standard deviation of c1, c2 and c3 correl$stddev as it will filter out groups with low c0 and high c1, c2 and c3. Finally I sum the global correlation and the stddev in order to rank groups with a single value correl$"corr+stddev.

In this example 16 pairs are candidates.

My dataset is an xts object with historical prices of the 16 currency pairs. I could extend it to ~50 to improve the selection as I guess bigger is the pool and better it must be.

This is how I proceed to achieve this :

# Put all symbols name in a list 
pairs <- names(mydata)
# Create groups of 5 currency pairs with no duplication
group <- combn( pairs , 5 )
# Calculate number of groups
nb_group <- ncol(group)
# Create empty object to store my result
result <- NULL
# For every groups
for (i in 1:nb_group) {

  # Calculate the mean correlation for the group
  correl <- round(mean(cor(mydata[, group[,i]])),3)
  # Transform as data frame and give a name
  correl <- as.data.frame(correl)
  colnames(correl) <- "cor"
  rownames(correl) <- toString(group[,i])
  # Calculate stddev and the sum of correlation and stddev
  correl$stddev <- round(sd(cor(mydata[, group[,i]])),3)
      correl$"cor+sddev" <- correl$cor + correl$stddev
  # export data
  result <- rbind(correl, result)

# Basket of currency pairs with the lowest correlation and stddev

This return something like :

> head(result[order(result[,3]),])
                                          cor stddev      cor+sddev
GBPUSD, USDCAD, USDRUB, USDTRY, NZDUSD  0.032  0.583          0.615
GBPUSD, USDCHF, USDCAD, USDRUB, USDTRY  0.048  0.569          0.617
GBPUSD, USDJPY, USDRUB, USDTRY, NZDUSD  0.052  0.576          0.628
GBPUSD, USDCAD, EURCHF, USDRUB, USDTRY  0.048  0.582          0.630
GBPUSD, USDCAD, USDRUB, USDMXN, NZDUSD  0.065  0.566          0.631
GBPUSD, USDCHF, USDCAD, USDRUB, USDMXN  0.097  0.536          0.633

Result is same when I average correlation and stddev (instead of the sum)

Do you think R could help to achieve this and is there a more efficient approach to create such basket of currency pairs ?

I've checked portfolio optimization packages like tawny, PortfolioAnalytics and fPortfolio but unfortunatly I'm not familiar with financial formulas and I got lost.

Thank you, Florent

  • $\begingroup$ Can you please be more precise? What is your exact objective? " create a basket of currency pairs that have low correlation between them" is only one of them. What do you exactly try to achieve? And I do not follow your correlation tables: What does 0.07 for USDJPY exactly describe? Which correlations of which data points are you calculating? I highly recommend you are solid on what you want to get to and have a solid grasp at which statistical techniques get you there before using R. $\endgroup$
    – Matt
    May 22 '15 at 4:20
  • $\begingroup$ Hello, sorry for not being clear. I reformulate my objective in a different way. Regards $\endgroup$
    – Florent
    May 22 '15 at 8:33
  • $\begingroup$ I actually run the script over 46 currency pairs and it gives me 1.370.754 possible groups with no duplication (duplication could be one group A,B,C and another B,A,C). With daily data back to 2015-01-01 it is now more than 12 hours now and yet not finished. $\endgroup$
    – Florent
    May 22 '15 at 9:12

If I understand your problem correctly you are trying to search for the optimal basket of 5 pairs (without worrying about weighting).

The problem is computationally there are too many combinations to sort through.

So I will propose a simple algorithm:

Calculate correlation matrix, grab the pair that has the least avg correlation as a seed for your basket, then iterate through the correlations with the rest of pairs searching for the next pair that is the least correlated with the current basket and iteratively adding them until you have enough items required.

If you want to add correlation and stddev I suggest you come up with a preference function or utility function to model the tradeoff between them.

##simple example on edhec test data

cormat = cor(edhec)

###Seed the basket
inital_asset = which.min(colMeans(cormat))
names_in_basket = labels(inital_asset)

###Grab the one least avg correlated with existing basket
  names_in_basket=c(names_in_basket, labels(which.min(cormat[,names_in_basket[1]])))
    names_in_basket=c(names_in_basket, labels(which.min(rowMeans(cormat[!rownames(cormat)%in%names_in_basket,names_in_basket]))))



###Sanity Check

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.