OK, this is going to be a long post, but I think there may be something useful that comes out of it…
I think what we’re getting at is that it would be nice to have a data structure that does something like this:
If we start with:
# assetReturnsList <- table of returns organized as [Date, c(Asset 1, Asset 2, Asset 3…)]
#
# myPortfolio <- table of portfolio weights organized as [Date, c(Asset 1, Asset 2, Asset 3)]
Assuming the dates line up right, then the portfolio return stream is
# myPortfolioReturn <- rowsum( myPortfolio * assetReturnsList )
(note that this is element-by-element multiplication, not matrix multiplication here)
The equity levels are
# myEquityLevels <- startingEquity * exp( cumsum( log(myPortfolioReturn+1) ) )
(for space, I’ve left out the code that makes sure that the dates aren’t being multiplied along with the assets)
Now, let’s say you are comparing strategies. You have your trading system, and you want to compare it to a standard 60/40 allocation system. It would be nice to have portfolio generator functions that generate the portfolio weights for each time period just by sending in the returns and the relevant parameters.
# my6040portfolio <- generate6040portfolio( assetReturnsList );
## returns a portfolio history of portfolio weights that are 60% S&P and 40% Barclay’s Aggregate index, and 0% everything else. Pretty simple. In fact, all one needs the assetReturns list for is to know what columns to set to 60%, 40%, and 0%.
Now you have your trading system, which may take a lot more data to make its decisions:
# mySuperSystemPortfolio <- generateSuperSysWts( assetReturnsList, myBunchOfParams, otherDataEtc )
You want to be able to write different systems and compare them with each other, or may test different parameters for your system against each other, but you’d like all this data to be in one place and organized for comparability. This is what I meant about “being scattered all over the digital workspace”. I had an object for returns, and another for moving averages, and another for estimated volatilities, another for parameters, and another for portfolios and returns for each comparison strategy it was just starting to be a mess whenever I typed ls() to remember what I’d named things.
If your portfolios are in a three dimensional array, then you can organize them like this:
# portfolios[ c(“60/40”,”Strategy1”,”Strat2”), Date, c(Asset1, Asset2, Asset3)]
So you can work with just one big portfolio object that contains all your strategies together
Strategy1’s weights over time are given by: portfolio[“Strategy1”, T, T]
Strategy1’s weights today are: portfolio[“Strategy1”, Today(), T]
(btw, in R, I like to use the logical value T (true) as a placeholder for array indexes, rather than just leave it blank, the way most coders do)
It makes it helpful for passing to functions
# findSharpeRatio(portfolio[“Strategy1”,T,T], assetReturnsList)
# plotRiskReturnChart( portfolio[c(“Strategy1”,”60/40”,”SystemeDeJoey”),T,T], assetReturnsList)
this raises some design questions, which motivated my post: for example… should the portfolio object just contain the asset weights, which then get combined with the assetReturnsList to produce the portfolio returns and equity curves, or should it contain the portfolio return along with the weights. (I’m leaning toward including the portfolio return, because we may not know the composition of a comparison portfolio, and yet still know the returns).
With a 3d portfolio array, or you could interate through portfolios by strategy to do comparisons of Sharpe ratios, information ratios, drawdowns, etc., or compare each portfolio over just a specific number of start/end dates.
It would also be nice to be able to update the data quickly at the end of the day, week, or whenever new asset returns data comes in. You’d want to be able to generate new portfolio weights for each strategy without having to remember all of their names and typing them in by hand.
So maybe we have an array or list of functions, that look like this
# generator[[c(“60/40”,”Strategy1”,”Strat2”)]] <- an array of functions that generate portfolio weights
so that
# generator[[“60/40”]] <- function (returnsList) { 60% S&P, 40% Barclay’s Agg everywhere}
and
# generator[[“Strategy1”]] <- function(returnsList, params, etc) {code generating weights}
Then you can just have a list (vector) of strategies, and the update goes like this
# newReturnsList <- update(fromWhateverSourceYouHave)
# for (strat in strategiesList) {
# portfolio[strat,T,T] <- generator[[strat]](newReturnsList)
# }
The only part I’m concerned about is that the generator for different strategies may have different parameter lists and input data (say fundamental data like valuation, or things that can’t be determined by the returns stream alone. Parameters can be stored in the generator list by adding an extra index dimension for parameters, but extra data on the assets would be difficult.
I know this got intricate. Did anyone end up following that?