# Calculating log-returns across multiple securities and time

I've been getting very confused on the topic of calculating returns. To get cumulative returns in time, log-returns are used, but apparently log-returns aren't used across different securities at a fixed time?

I would like to get cumulative returns as a function of time over my portfolio.

I have two securities, A and B. I buy one share of both A and B when the market opens and sell when it closes.

Suppose these are the prices for a specific day:

    open    close
A   9       10
B   10      8


My overall return for that day is (10+8)/(10+9) - 1 = -5.2%. I store that -5.2% for that day. I repeat this for many days. How do I then calculate my cumulative sum? If it helps, I'm doing this in python.

Side note: I can use a cumsum() function very easily in python, but that assumes log-returns. I have no issue working with log-returns, but I'm not sure how to go about doing that.

I will add that I always purchase 1 share of whatever security is in my portfolio for that day. The securities in my portfolio change over the course of time.

In Python, simple geometric returns:

    import numpy as np
import pandas as pd
simple_ret = sp500.pct_change()
(1+simple_ret).cumprod()[-1] -1

0.74751768460019963


Log-returns:

    log_ret = np.log(1+simple_ret)
np.exp(log_ret.cumsum()[-1]) -1

0.74751768460020074


In Quantitative Finance, doing your math in log-returns considered good manners, however for many practical applications (backtesting trading strategies e.g.), simple geometric returns suffice.

• Those pieces of code are great -- thank you for that. I can very clearly see how to go back-and-forth between simple geometric returns and log-returns Oct 8, 2015 at 14:32

When doing series like this in Python, I usually just add 1 to each return, then multiply across these sums for cumulative returns. Such as, if my returns over three days were -5.2%, 2.1% & 4.8%, then the values I would store would be:

1 + (-0.052) = 0.948

1 + (0.021) = 1.021

1 + (0.048) = 1.048

Then, to calculate my cumulative returns, I would just multiply (0.948)(1.021)(1.048) - 1 = 0.0144 or 1.44%.

This works especially well with arrays in Python, where you can store each return as an array in a larger array, allowing you to date index each part of the series then slice it however you want. Happy to work through the code for this if you provide me more detail on your data set.

• Awesome, thank you. Just a follow up on your question. The cumulative return for 3 days is 1.44%. If I wanted cumulative return for 2 days, it would be (0.948)(1.021) - 1 = -3.2%. So when I'm running my cumprod() function over my entire DataFrame, I shouldn't include the minus one in my previous calculations, only at the end. In this sense, I can run cumprod() over the DataFrame and then applymap() to subtract 1 from every element -- is that correct? Oct 7, 2015 at 14:58
• So you're pulling the entire return series straight into a Dataframe and then calculating returns from there I'm assuming? Is it just one column of returns, or do you have a date index as well? Oct 7, 2015 at 15:04
• I have a DataFrame where columns are dates and rows are users. For each user I calculate a return for that day. Each user has a different portfolio over time. According to your answer, I will then applymap() to add 1 to each return, and then make a new DataFrame from that which will calculate cumprod(). Oct 7, 2015 at 15:08
• You're correct- .applymap() will do the trick for the return series. You don't necessarily have to make a new Dataframe if you're series is large and you're trying to save memory, too; just overwrite the values when using .applymap(). Then, like you said, .cumprod() - 1 at the end should do it for you. Oct 7, 2015 at 15:20