Skip to content

Linear and logarithmic returns

Course exercise 117 · Part II

Problem

From a series of ten prices, compute linear and logarithmic returns, once with vectorised operations and once with a loop.

Method

\[ R^{lin}_t = \frac{P_t - P_{t-1}}{P_{t-1}}, \qquad R^{log}_t = \ln P_t - \ln P_{t-1} = \ln\!\left(1 + R^{lin}_t\right) \]

Code

clear all, clc

%% 1

P = [10 10.3 10.7 12 14.2 14.9 19 10.4 16 8.5]

R_lin = diff(P) ./ P(1 : end-1)

R_log = diff(log(P))

%% 2

t = length(P);

R_lin_ = NaN(1, t-1);

for k = 2 : t;
    R_lin_(k-1) = (P(k) - P(k-1)) ./ (P(k-1));
end

R_lin_

R_log_ = NaN(1, t-1);

for k = 2 : t;
    R_log_(k-1) = log(P(k) ./ P(k-1));
end

R_log_
import numpy as np

# %% 1
P = np.array([10, 10.3, 10.7, 12, 14.2, 14.9, 19, 10.4, 16, 8.5])

R_lin = np.diff(P) / P[:-1]             # MATLAB: diff(P) ./ P(1:end-1)   (P[:-1] = all but the last)
print("R_lin =", R_lin)

R_log = np.diff(np.log(P))
print("R_log =", R_log)

# %% 2
t = len(P)

R_lin_ = np.zeros(t - 1)
for k in range(1, t):                   # MATLAB: for k = 2 : t
    R_lin_[k-1] = (P[k] - P[k-1]) / P[k-1]
print("R_lin_ =", R_lin_)

R_log_ = np.zeros(t - 1)
for k in range(1, t):
    R_log_[k-1] = np.log(P[k] / P[k-1])
print("R_log_ =", R_log_)

Results

Price 10.3 10.7 12.0 14.2 14.9 19.0 10.4 16.0 8.5
Linear 3.00% 3.88% 12.15% 18.33% 4.93% 27.52% −45.26% 53.85% −46.88%
Log 2.96% 3.81% 11.47% 16.83% 4.81% 24.31% −60.26% 43.08% −63.25%

The loop and the vectorised version give identical results.

Takeaways

  • For small moves the two returns are almost equal; for large ones they diverge, and the log return is always the smaller of the two.
  • Log returns add up over time (\(\sum R^{log}_t = \ln P_T / P_0\)); linear returns add up across assets in a portfolio. Each has its use.
  • diff(P) ./ P(1:end-1) replaces the whole loop, and there is one return fewer than prices.