What's good in the kitchen is good at the trade desk. We like choice as traders. We choose markets, trading styles and excuses for our sub-optimal performances. On those occasions when we need to crunch some numbers, we also like some choice. More than any other curve-fitting software, R is best suited for trading precisely because of its "quote" - diversity.
In fact, I'm sure this is on purpose. The Unix geniuses did a lot of thinking about software design and architecture when they designed their operating system. They even came up with a set of rules, one of which is the Rule of Diversity. This states that one must distrust all claims to one true way. Many commercial packages cannot do this of course, as they are confined to a monolithic vision of how things get done. R does this well.
This is a double-edged kitchen knife though and some care must be taken when choosing what tool you want to use for preparing your algorithm mis-en-place. Suppose you're interested in calculating price changes for your favorite, useless metal, silver. Price change or percentage change? Already with the choices. We are going to use percentage change over price change for our illustration of R's diversity.
We'll keep it simple and get the daily closing prices of the silver ETF known as SLV, managed by JP Morgan of course, and isn't that ironic? In any case, we'll avoid the crazy split that happened back in 2007 and just get the prices for the year 2010. I'm going to require three packages in this example, Jeff Ryan's quantmod, Joshua Ulrich's TTR and Brian Peterson's PerformanceAnalytics. TTR actually automatically loads with quantmod (as does xts and zoo) so you don't need to specify it. But I'm going to do it anyway. We'll illustrate diversity right from the get go.
Now we get the SLV prices into our environment. Two ways. I usually don't give the function's surname, but I will for now because it adds clarity later on.
Now to simplify our demonstration of returns, let's index out the closing price only, and look at prices for 2010.
SLV <- SLV[,4]
SLV <- SLV["2010"]
SLV <- SLV["2010"]
There are several permutations of that approach that are suitable, and probably some that aren't suitable but still work. Here is the head of data that we have as a result:
What?!? Silver was trading at $17? I could have gotten it that cheap and now it's trading what, north of $45? It's like Netflix, Amazon and Lulu. Combined. And I was going to get a gazillion sleeves from the Maple coin makers north of the border. Well, it's too late now. Isn't it. But I digress.
Now we set ourselves upon the task at hand. To calculate the percent change from one day to the next. I know everyone loathes to do it this way, and would much rather calculate the actual dollar and cents amount change, but percent returns are more tractable when we decide to get serious about our statistical pursuits. I'm going to use the default settings for four functions for the illustration. And each one will populate it's own epynomous column in our matrix.
SLV$Delt <- quantmod::Delt(Cl(SLV))
SLV$dailyReturn <- quantmod::dailyReturn(Cl(SLV))
SLV$ROC <- TTR::ROC(Cl(SLV))
SLV$CalculateReturns <- PerformanceAnalytics::CalculateReturns(Cl(SLV))
Now, the head of our data again:
SLV.Close Delt dailyReturn ROC CalculateReturns
2010-01-04 17.23 NA 0.000000000 NA NA
2010-01-05 17.51 0.016250725 0.016250725 0.016120096 0.016120096
Alright, well we certainly have diversity don't we? Let's take one line at a time. For January 4, 2010, only dailyReturn put a value in that row, and the others returned NA. And for January 5, 2010, we have Delt and dailyReturn with the same number, but different from the number that ROC and CalculateReturns share. Hmmm. As it turns out, there are two schools of though on this topic. Do you want simple returns, where you simply take yesterday's price minus today's price and divide it by yesterday's price, or do you want the log of that equation? Log, you're kidding right? No actually logarithms are no joking matter. There will be no laughter when logarithms come into the room to perform their magical tricks. Only awe.
Natural logarithms of returns are nice because you can add them up in their log-ness and then take the result and un-log it to get the correct result. That result being the total percent change from one date to the other. This comes in handy for calculating a monthly or annual return. Try it out yourself, it's quite cool actually. Don't forget to un-log though, by way of the exp(my_log_return) function.
You cannot add simple returns, but must multiply them. If your column has zeroes in it, well we have a problem that the add folk don't need to deal with. I like logs better, even though you have to put your returns into a spacesuit on a temporary basis.
Each function has a default on this issue and an option to change it to the other way of doing things. Here is a truncated parameter list for each function. Notice the diversity in how we define simple returns versus logarithmic returns.
Delt(x1,type = c("arithmetic", "log"))
periodReturn(x, type='arithmetic') # log would be "log"
ROC(x, type=c("continuous", "discrete"))
This adds up to more thinking on your part in the end, but you'll be fine. Make yourself a sandwich and begin contemplation at your leisure. Just don't cut yourself while doing it.