All articles
Article8 min read

Stop Using Simple Returns

Simple returns are not symmetric, they don't add up over time, and their average flatters volatile assets. Why log returns and log charts are the natural tools to study prices, with BTC as the example.

For a long time, I plotted my charts on a linear scale and computed simple returns. Then I discovered log charts and log returns, and it changed the way I look at markets.

On a log chart, I can compare today's prices with prices from ten years ago on the same picture. And log returns are symmetric around zero: +20% then −20% in log returns brings me back exactly to my starting price, while +20% then −20% in simple returns leaves me 4% down.

In this article, we'll look at the limits of simple returns, and at why prices tend to grow exponentially rather than linearly.

Definitions

Let StS_t be the price of an asset at time tt.

Simple returns compound: to get the performance of an asset over several days, you have to multiply the daily returns together.

Log returns add up: the performance over several days is just the sum of the daily log returns.

This additive property is huge, and it makes your DataFrame code much simpler: a cumsum() gives the cumulative performance, a rolling sum gives the return over a window, and going from daily to monthly returns is just a sum.

Simple returns aren't symmetric

Take a very common example: you gain 50%, then lose 50%. Intuitively, you are back to breakeven. You are not:

R=(1+r1)(1+r2)−1=1.5×0.5−1=−25%R = (1 + r_1)(1 + r_2) - 1 = 1.5 \times 0.5 - 1 = -25\%

You end up 25% down. Simple returns have no symmetry.

Now take log returns, with r1log⁡=+50%r^{\log}_1 = +50\% and r2log⁡=−50%r^{\log}_2 = -50\%:

Rlog⁡=r1log⁡+r2log⁡=50%−50%=0%R^{\log} = r^{\log}_1 + r^{\log}_2 = 50\% - 50\% = 0\%

This time you are back to breakeven: log returns are symmetric.

Be careful though: log returns don't magically fix the +50% / −50% sequence of simple returns. They just describe it differently. A log return of +50% is a simple return of +64.9% (e0.5−1e^{0.5} - 1), and a log return of −50% is a simple return of −39.3% (e−0.5−1e^{-0.5} - 1).

Why symmetry matters: the mean of simple returns lies

Most models fitted on returns rely on averages: the mean return, a regression minimizing the errors around the mean, and so on. And the mean of simple returns is biased.

Take a price that alternates +50% and −50% every day. The mean simple return is 0%, so your model thinks the asset is flat. In reality, you lose 25% every two days.

With log returns, ln⁡(1.5)=+40.5%\ln(1.5) = +40.5\% and ln⁡(0.5)=−69.3%\ln(0.5) = -69.3\%, so the mean is −14.4% per day: the model sees that you are losing money, and projecting that mean forward lands exactly on the real price.

A model built on the mean simple return projects a flat price. The mean log return lands on the real one.

With simple returns, your model is biased upward, and the more volatile the asset, the more it overestimates the performance. This gap is called the volatility drag.

When simple and log returns are close

For small moves, simple and log returns are almost the same. Since S1/S0=1+rS_1 / S_0 = 1 + r, the log return is just ln⁡(1+r)\ln(1 + r), and the Taylor expansion of ln⁡(1+r)\ln(1 + r) when r→0r \to 0 gives:

rlog⁡=ln⁡(1+r)=r−r22+o(r2)r^{\log} = \ln(1 + r) = r - \frac{r^2}{2} + o(r^2)

To first order, rlog⁡≈rr^{\log} \approx r: this is why daily returns are often used interchangeably. Equivalently, er≈1+r=S1/S0e^{r} \approx 1 + r = S_1 / S_0.

The second-order term tells us more: the log return is always a bit smaller than the simple return, and the gap grows with the square of the return.

Simple returnLog return
1%0.995%
10%9.53%
50%40.5%

This −r22-\frac{r^2}{2} term is where the volatility drag comes from. Averaging it over many periods, with μ\mu the mean simple return and σ\sigma its volatility:

E[rlog⁡]≈μ−σ22\mathbb{E}\left[r^{\log}\right] \approx \mu - \frac{\sigma^2}{2}

The bigger the volatility, the further the real (log) growth rate falls below the average simple return.

Why prices grow exponentially

Returns are proportional to the price: +1% on a price of 100 is +1, on a price of 200 it is +2. Each gain is computed on the new price, so gains compound. If a price grows by gg each period:

St=S0(1+g)t=S0 etln⁡(1+g)S_t = S_0 (1 + g)^t = S_0 \, e^{t \ln(1 + g)}

This is an exponential. Take the log, and it becomes a straight line:

ln⁡(St)=ln⁡(S0)+tln⁡(1+g)\ln(S_t) = \ln(S_0) + t \ln(1 + g)

That's why log returns and log charts are the natural tools to study prices.

Use a log chart, not a linear one

Since prices are exponential, a linear chart doesn't let you compare moves across time.

When BTC was around $100, a 1% move was $1. When BTC was at $100,000, the same 1% was a $1,000 move. Comparing price changes in dollars makes no sense, but comparing changes in log price, i.e. log returns, does:

ln⁡(100)−ln⁡(99)=0.01005ln⁡(100 000)−ln⁡(99 000)=0.01005\begin{aligned} \ln(100) - \ln(99) &= 0.01005 \\ \ln(100\,000) - \ln(99\,000) &= 0.01005 \end{aligned}

You don't have to plot the log price itself: switching the price axis to a log scale does the same job, and keeps the axis readable in dollars. The chart below shows how much easier it is to read past years on a log scale.

Same data, two scales. On a log scale, the height of a move is its percentage.

Look at the two crashes. On the linear chart, the 2025 crash (−28%) looks bigger than the 2018 one (−84%), because it lost more dollars: $29,888 versus $16,177. On the log chart, the height of a move is its percentage, and the 2025 crash is nothing compared to 2018. In 2018 you lost 84% of your money, in 2025 "only" 28%. That is the information that matters when you compare two moves, and the linear chart hides it.

Conclusion

Simple returns are what your broker shows you, and they are the right tool to combine assets in a portfolio. But to study a price over time, log returns are better on every count: they add up, they are symmetric, their mean doesn't flatter volatile assets, and they turn exponential growth into a straight line.

Want to try it on real data?

Angolin serves the full BTC history at 1d, 1h and 1m granularity.

More articles