Plotting Financial Data With Python: Comparing Returns

Programming |

Updated on

It’s hard to compare the returns on the given securities just by looking at their price history in absolute terms so we need to find a better way of comparing historical returns. One of the possible solutions is to adjust the whole data series in such a way that the first data point would be equal to some predefined number. We are going to adjust the price history of both stocks so they will always start with the same value, let’s say 100. This method allows us to see what would happen with $100 invested in 2 given stocks on the date D.

Thumbnail

Contents

This is the third part of the “Plotting Financial Data With Python” series and it’s better if you read it in chronological order:

  1. Part 1 - History
  2. Part 2 - Variance
  3. Part 3 - Comparing Returns (you are here)
  4. Part 4 - Efficient Frontier (2 Assets)
  5. Part 5 - Efficient Frontier (N Assets)

Source Code

You can get the full source code here: https://github.com/bubelov/market-plots

Data

You should already have a function for retrieving stock price history, if you don’t have it - go to the first post and implement it. It should return all of the data we need but it has 2 major issues:

  1. The values can have different date ranges, we need to use the same range for both datasets
  2. The values are in absolute terms so we need to adjust them to start with the same value but keep the original proportions

Adjusting The Range

The most obvious way to solve the range mismatch is to cut out all of the dates that are not present in both data sets. Here is the possible solution:

1
2
3
4
5
stock_data = alpha_vantage.get_stock_price_history(stock_symbol, interval, adjusted=True)
benchmark_data = alpha_vantage.get_stock_price_history(benchmark_symbol, interval, adjusted=True)

stock_data = { k:v for (k,v) in stock_data.items() if k in benchmark_data.keys() }
benchmark_data = { k:v for (k,v) in benchmark_data.items() if k in stock_data.keys() }

We just filter each dataset and keep only the dates that are present in the other dataset. Now we can be sure that we’re comparing the same date range.

Adjusting The Values

Different stocks can have different prices at any given time and if some stock is selling for $1000 per share it does not mean that it’s better than the stock trading for $1 per share. It’s all relative so we have to scale the data before we compare it.

Here’s how we can do that:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def adjust_values(data, start=100.0):
    scale_factor = None

    for k, v in sorted(data.items()):
        if scale_factor == None:
            scale_factor = v / start

        data[k] = v / scale_factor

    return data

Plotting The Data

Let’s create a new file and name it compare.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import sys
import pathlib
import numpy as np
import matplotlib.pyplot as plt

import alpha_vantage


def compare(stock_symbol, benchmark_symbol, interval='MONTHLY', adjusted=True):
    stock_data = alpha_vantage.get_stock_price_history(
        stock_symbol, interval, adjusted)

    benchmark_data = alpha_vantage.get_stock_price_history(
        benchmark_symbol, interval, adjusted)

    stock_data = {k: v for (k, v) in stock_data.items()
                  if k in benchmark_data.keys()}

    benchmark_data = {
        k: v for (k, v) in benchmark_data.items() if k in stock_data.keys()}

    stock_data = adjust_values(stock_data)
    benchmark_data = adjust_values(benchmark_data)

    plt.plot(list(benchmark_data.keys()), list(benchmark_data.values()), label=benchmark_symbol)
    plt.plot(list(stock_data.keys()), list(stock_data.values()), label=stock_symbol)

    plt.title(f'{stock_symbol} vs {benchmark_symbol} (adjusted)')
    plt.legend()

    pathlib.Path('img/compare').mkdir(parents=True, exist_ok=True)
    plt.savefig(f'img/compare/{stock_symbol}-{benchmark_symbol}.png')
    plt.close()


def adjust_values(data, start=100.0):
    scale_factor = None

    for k, v in sorted(data.items()):
        if scale_factor == None:
            scale_factor = v / start

        data[k] = v / scale_factor

    return data


compare(sys.argv[1], sys.argv[2])

This code combines the previous steps and also draws the resulting datasets on the screen.

Testing

Let’s test this module by comparing the Tesla Inc cumulative returns using the S&P 500 index as a benchmark:

python compare.py TSLA SPX

You should see the chart similar to this one:

SPX vs TSLA

It seems like the TSLA stock made much more money for it’s shareholders than the SPX index but it also looks more volatile and jittery.

Conclusion

Now we have a tool for comparing stock performance and it also gives us a hint about the stock volatility. We can use the script from the Part 2 - Variance to measure the volatility more accurately.

In the next post we’ll create a tool for measuring the “compatibility” of 2 given stocks. Expected returns might be a good hint on what to buy but it’s also important to understand the relationship between different stocks in a portfolio.

This site doesn't have ads and the reasons are simple:

  • Most people don't want to see ads, that's not what they look for when they open web pages.
  • Ad scripts can track visitors, exposing private data to third parties.

If you found this post valuable and you wish to leave a tip, you can do it with Bitcoin:

34CXtg7c4Vbw8DZjAwFQVsrbu9eDEbTzbA