Skip to content
All library documents

Simple and Log Returns in Quantmod

Article Quant Q&A · Author: Zach

Summary

The document explains why several R functions for calculating price returns can produce different results. The key distinction is between arithmetic (simple) returns, calculated as the price change relative to the previous price, and logarithmic returns, calculated as the difference between log prices. Quantmod’s close-to-close calculation uses arithmetic returns by default, while TTR’s rate-of-change function defaults to log returns; setting its type to discrete aligns it with the arithmetic calculation. Other return functions also have their own defaults, so users should check the selected method rather than assume the outputs are interchangeable.

The choice depends on how returns will be used. Simple returns compound by multiplying gross returns across periods, whereas log returns aggregate by addition and can be convenient for time-series analysis. The document notes that zero-valued signals may behave differently across calculation methods and that log returns must be converted back before interpreting them as simple returns. Its examples illustrate the differences, but do not establish one universally correct choice.

Key ideas

  • Quantmod’s close-to-close return is arithmetic by default, while TTR’s rate-of-change function defaults to log returns.
  • Choosing the discrete option makes the rate-of-change result align with the arithmetic close-to-close return.
  • Simple returns compound through multiplication, while log returns add across periods.
  • Return function defaults vary, so the method should be selected explicitly for the intended use.

Tags

Full text
# Quantmod: what's the difference between ROC(Cl(SPY)) and ClCl(SPY)


# Quantmod: what's the difference between ROC(Cl(SPY)) and ClCl(SPY)












I feel like I'm missing something fundamental here, but I can't shake the feeling that these two series should be equivalent.

/edit: there is also dailyReturn(Cl(SPY)). I've seen all 3 of these methods used to calculate stock returns on various blogs, and I'm wondering which is 'correct.' They all give slightly different results...

/edit2: and there is also Delt(Cl(SPY)), which seems to be equivalent to ClCl(SPY)

## Answer by Joshua Ulrich (score 3, accepted)

https://quant.stackexchange.com/a/1080

`TTR::ROC` calculates log returns by default. `quantmod::ClCl` uses `quantmod::Delt`, which calculates arithmetic returns by default.

`ROC(Cl(SPY), type="discrete")` should match `ClCl(SPY)`. Which is 'correct' depends on your purpose.

## Answer by Milktrader (score 6)

https://quant.stackexchange.com/a/1082

To expand on what Joshua has already stated, here is a truncated parameter list of similar functions, along with the package to which they belong.

```
quantmod::Delt(x1,type = c("arithmetic", "log"))
quantmod::periodReturn(x, type='arithmetic') # log would be "log"
TTR::ROC(x, type=c("continuous", "discrete"))
PerformanceAnalytics::CalculateReturns(prices, method=c("compound","simple"))
```

Your choice are simple returns, which are `(today's_close - yesterday's_close) / yesterday's_close`, or log returns, which are `log(today's_close) - log(yesterday's_close)`, or, equivalently, `log(today's_close / yesterday's_close)`. If you decide on simple returns, you must multiply returns to get the total return at the end of a period. With log returns you get to add them. This is preferred when your vector may have zeroes in it for obvious reasons. If you have a simple 1 or -1 signal, then you're only going to have a zero in the beginning, or an NA depending on which function you choose. But once you have a system that goes flat, or signals a 0, then you will have some trouble with simple returns.

Simple returns are referred to as arithmetic, discrete or simple in the above functions. The log returns are alternately referred to as log, continuous or compound.

The `Delt` function is sort of an artifact and has been updated with the `dailyReturn` function. Here is a snapshot of what each function generates on the first two lines of a trading system. Notice also that some have their defaults set to simple returns and others have default set to log returns. Each function allows you to change the default.

```
            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
```

Remember that once you convert your returns to a log return, you need to un-convert it to get simple returns again, and this is accomplished by simply applying `exp(log_return)`.

My recent blog post about this topic may be of interest to you. http://www.milktrader.net/2011/04/chop-slice-and-dice-your-returns-in-r.html

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.