This article covers how to compute relative strength or so-called relative price series. Here, I will use the relative prices and relative strength concepts interchangeably. I will also provide code in the Python programming language for calculations below.
How to Calculate Relative Strength?
First, take a stock price series, which is typically a closing price. Next, divide the stock’s closing prices by the benchmark’s closing prices. Then, multiply the result by the benchmark’s first price observation. This will allow you to plot and compare the relative and absolute time series for a stock.
Relative Strength of a Stock = (Absolute Stock Price Series ÷ Benchmark’s Price Series) × Benchmark’s First Price Observation
The benchmark can be another stock, industry index or a market index. Moreover, prices for a stock and its benchmark can be in different currencies. In this case, you need convert all prices to the same currency. This will allow you to control for currency fluctuations.
For instance, here is a chart showing the absolute and relative price series for Nvidia. It shows that the Nvidia stock showed strong outperformance in absolute and relative terms.

Why Relative Strength?
The question is why is it better to work with relative prices instead of absolute prices? The reason is this. Stocks tend to fluctuate with the market. When the market goes up, the tide lifts all boats. When the market goes down, stocks turn bearish.
Working with absolute prices will produce results that are correlated with the market. On the other hand, relative prices allow you to partially control for the correlation of a stock with the market. Doing so will let you better screen stocks that may show uncorrelated positive alpha.
Relative Strength in Python
Next, let’s see how to construct relative prices with the Python programming language. You can download the entire Python code, if you’d like. I will not go into many details for the code, as I assume you have some knowledge of Python.
I will use the “yfinance” Python module to fetch stock prices. The module is available for free by using the “pip3 install yfinance”.
Related:
This is the Python function that calculates the relative prices using Pandas DataFrames.
import pandas as pd
import numpy as np
import yfinance as yf
import matplotlib.pyplot as plt
def relative_prices(df, start, end, bm_df, bm_name, fx_df, fx_ticker=None, price='Close', rebase=False):
'''
df: stock dataframe with market prices (open, high, low, close)
bm_df, bm_name: benchmark's dataframe with prices, benchmark's name
fx_rate, fx_ticker: currency close price dataframe & Fx ticker name
start, end: string format of (YYYY-MM-DD) or datetime
price: price used to calculate relative series (Open, High, Low, Close)
rebase: rebase relative price by first stock price observation if True
'''
# Slice stock dataframe for period from start to end
df = df[start:end]
# Join stock, benchmark and currency df (only common dates remain)
df = df.join(bm_df[bm_name], how='inner')
if fx_ticker:
df = df.join(fx_df[fx_ticker], how='inner')
# Perform forex conversion, if applicable
df['bmadj'] = df[bm_name].mul(df[fx_ticker]).fillna(method='ffill')
df['bmadj'] = df['bmadj'].div(df['bmadj'][0])
df = df.drop([fx_ticker], axis=1)
# Calculate adjustment factor for relative strength
else:
df['bmadj'] = df[bm_name].div(df[bm_name][0])
# Divide absolute price by adjustment factor
df['r'+price] = df[price].div(df['bmadj'])
# Rebase to first stock price value
if rebase:
df['r'+price] = df['r'+price].div(df[price][0])
df = df.drop([bm_name, 'bmadj'], axis=1)
return df
The most important lines in this function are these.
df = df.join(bm_df[bm_name], how='inner')
if fx_ticker:
df = df.join(fx_df[fx_ticker], how='inner')
They join benchmark, forex and stock prices together preserving only common dates. As you may know, the forex market works 24/7, while the stock market follows federal holidays.
If you set “rebase” input to True, the function will rebase the entire relative price series further. It does that by dividing the obtained relative price by the first value of the closing stock price. Doing so normalizes everything relative to the value of 1. This will allow you to compare relative prices across stocks easily.
Relative Strength Case Studies
Nikon Corporation (7731.T)
Let’s consider the stock price of Nikon traded on the Tokyo stock exchange. I use Nasdaq as my benchmark and USD/JPY forex rates for conversion purposes. Here is the code.
''' Nikon Relative Price Computations '''
#Define tickers for stock/benchmark/fx and start/end dates
ticker = '7731.T'
bm_ticker = '^IXIC' #Nasdaq
bm_name = 'Nasdaq'
fx_ticker = 'USDJPY=X'
start = '2016-01-01'
end = None
#Initiate dataframes for data
df = pd.DataFrame()
bm_df = pd.DataFrame()
fx_df = pd.DataFrame()
#Download price data from Yahoo Finance
df = yf.download(tickers=ticker, start=start, end =end, interval= "1d", group_by = 'column', auto_adjust = True,
prepost = True, threads = True, proxy = None)
bm_df[bm_name] = yf.download(tickers=bm_ticker, start=start, end =end, interval = "1d",group_by = 'column',
auto_adjust = True, prepost = True, threads = True, proxy = None)['Close']
fx_df[fx_ticker] = yf.download(tickers=fx_ticker, start=start, end =end, interval= "1d", group_by = 'column', auto_adjust = True,
prepost = True, threads = True, proxy = None)['Close']
#Compute relative prices for a stock
df = relative_prices(df, start, end, bm_df, bm_name, fx_df=fx_df, fx_ticker=fx_ticker, price='Close', rebase=False)
df[['Close','rClose']].plot(figsize=(20,8), grid=True, title= 'Nikon Absolute (JPY) vs Relative to Nasdaq in USD Rebased')
plt.show()
As we can see from the graph below, relative price series factors out the forex effect and shows how Nikon performed relative to Nasdaq.

Nikon staged a rally from January to July of 2023. The cumulative capital appreciation was about 70% in Japanese yen.
But, the relative performance was less impressive at about 15%-20% appreciation. Why? Because Nasdaq showed strong performance too with around 30%-40% appreciation. Also, the Japanese yen depreciated by about 10% for the same period. These factors made the 70% gain less impressive on relative and currency-adjusted basis.
Walt Disney (DIS)
Next, let’s take a look at Walt Disney relative price series. Here is a quick code that will compute relative performance.
''' Walt Disney Relative Price Computations '''
ticker = 'DIS'
benchmark = '^GSPC'
tickers_list = [benchmark] + [ticker]
data = round(yf.download(tickers= tickers_list,start= '2016-01-01', end = None,
interval = "1d",group_by = 'column',auto_adjust = True,
prepost = True, treads = True, proxy = None)['Close'],2)
data['relative price'] = round(data[ticker].div(data[benchmark])*data[benchmark][0] ,2)
data.rename(columns={ticker:'absolute price'}, inplace=True)
data[['absolute price','relative price']].plot(figsize=(20,8),grid=True, title= str.upper(ticker)+ ' Absolute and Relative Stock Prices Comparison')
plt.show()
We see that from March of 2020 to March of 2021, Disney staged a rally. But, this appreciation was weak relative to S&P500. Disney’s absolute stock price peaked in March of 2021. But, the relative price series barely show any new highs in comparison to the relative price peak in December of 2019.

From March of 2021, everything went downhill for Disney. Around November of 2021, Disney broke through its relative price floor range of $70-$80 achieved in 2020. From there, the stock depreciated by about 40% due to various fundamental factors. One can view this exercise as a one-stock study case. But, it shows that using relative prices in a right way can signal opportunity. And, this is before absolute prices take notice.
Apple (AAPL), Nvidia (NVDA) and Qualcomm (QCOM)
Finally, let’s take a look at the relative performance of Apple, Nvidia and Qualcomm. We can rebase relative prices further by dividing them by the first relative price in the series for each stock. This action normalizes relative prices to 1 and makes it easy to compare stocks. Here is code that does this.
''' Apple, Nvidia, Qualcomm Relative Price Computations '''
tickers_list = ['AAPL','NVDA','QCOM']
rel_ticker_list = ['rAAPL','rNVDA','rQCOM']
# Dataframes instantiation
tech = pd.DataFrame()
start = '2016-01-01'
benchmark = yf.download(tickers= '^IXIC',start= start, end = None, interval = "1d", group_by = 'column', auto_adjust = True, prepost = True, threads = True, proxy = None)['Close']
for ticker in tickers_list:
tech[ticker] = yf.download(tickers= ticker,start= start, end = None, interval = "1d", group_by = 'column', auto_adjust = True, prepost = True, threads = True, proxy = None)['Close']
tech['r'+ticker] = tech[ticker].div(benchmark*tech[ticker][0])*benchmark[0]
tech = tech[rel_ticker_list]
tech.plot(figsize= (20,8),grid=True, style=['r','b','g'], title= 'AAPL, NVDA, QCOM Relative Price Series' )
plt.show()

Comparing relative prices for these three stocks, we see that Qualcomm was an utter laggard. Apple showed strong performance. But, Nvidia smoked them all!
Concluding Remarks
This will be it for this tutorial. You can download a Python file with the complete code here. Feel free to ask questions or contact me if you need clarifications through my contact page.