Skip to content

Introduction

How did the tech giants managed to cope with the new technological revolution ?

Context : In this analysis, we sought to learn about the stock market behavior of tech giants for more than a decade. Indeed, in recent years a technological revolution has emerged in society with: the democratization of digital services, the use of electric cars with integrated systems, quantum supercomputers and ordinates, as well as AI and the entire semis conductors industry.

To do this, we decided to take the companies components the "Magnificient 7" that are: Apple, Amazon, Alphabet, Meta, Nvidia and Tesla. These companies are at the heart of the global technology sector and represent this industry. Our time scale of analysis begins in the year 2010 and ends with the last data available.

Methodology

To make our analysis, we took several reference metrics on these 7 companies. We first sought to have the price chart of these companies from 2010 until today. The next step was to calculate the log returns of these companies using the formula:

Once we have these log returns, we take the mean of them multiply by the number of trading days in order to have our annualized log returns.

The second step of our analysis was to calculate the VAR and CVAR for each company. For this we took a confidence level of 95%, that is to say, in the 5% of the worst trading days of the company, how much will be my daily return. To calculate the kurtosis and the skewness of the 7 companies, we used these formulas:

1. Selecting Stocks and Importing Data

The first step is introducing the data from online sources (Yahoo Finance):

  1. Imports Necessary Libraries: The script imports pandas for data manipulation, yfinance for fetching financial data, numpy for numerical operations, and matplotlib.pyplot for data visualization.

  2. Defines Ticker Symbols: A dictionary named tickers is created to map stock ticker symbols to their respective company names. The tickers included are for Apple (AAPL), Microsoft (MSFT), Alphabet (GOOGL), Amazon (AMZN), Tesla (TSLA), Nvidia (NVDA), and Meta (META).

  3. Fetches Stock Data: The script uses the yfinance library to download historical stock data for each ticker symbol. It specifically extracts the 'Close' price for each stock.

  4. Combines Data into a DataFrame: The closing prices for all the stocks are combined into a single pandas DataFrame named stocks.

  5. Filters Data by Date: The DataFrame is filtered to include only the data from January 1, 2010, onwards.

  6. Exports Data to CSV: Finally, the filtered DataFrame is saved to a CSV file named Stocks.csv.

This script is useful for financial analysis and research, as it automates the process of collecting and organizing historical stock price data for multiple companies. The resulting CSV file can be used for further analysis, such as calculating returns, volatility, or other financial metrics.

# Attention: This part might not work bacause of different Python environments. If it happened, please delete this box and use the code in the next box to read data.

import pandas as pd
import yfinance as yf
import numpy as np
import matplotlib.pyplot as plt

# Define the ticker symbols for the stocks and index
tickers = {
    'AAPL': 'Apple',
    'MSFT': 'Microsoft',
    'GOOGL': 'Alphabet',
    'AMZN': 'Amazon',
    'TSLA': 'Tesla',
    'NVDA': 'Nvidia',
    'META': 'Meta',
}

# Fetch the data from Yahoo Finance and keep only the close price for each index
close_prices = {name: yf.download(ticker)['Close'] for ticker, name in tickers.items()}

# Combine all close prices into a single dataframe
stocks = pd.DataFrame(close_prices)

# Keep only the data after the year 2010
stocks = stocks[stocks.index >= '2010-01-01']

stocks.to_csv('Stocks.csv')
# Alternative: When the previous session report error, try to read data from csv-file manually
# In this case, please delete the previous box and read data directly by the code below

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

stocks = pd.read_csv('Stocks.csv', index_col=[0], parse_dates=True)
stocks

2. Visualizing the Stock Prices

This code block plots the closing prices of multiple stocks over time, adds a dashed grid along the y-axis for better readability.

Conclusion: We note that companies like Tesla and Nvidia have higher annualised log returns than the other main ones, due to their recent presence and attractiveness in financial markets. The other 5 companies are in a 17-23% return range, benefiting from a fundamentally solid image and not momentum.

stocks.plot()
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.tight_layout()
plt.show()

3. Log Returns Calculation and Annualization

In this section of the notebook, we performed several key steps to calculate and annualize the log returns of selected stocks. Below is a detailed explanation of each step:

Step 1: Calculate the Log Returns

Log returns are calculated using the natural logarithm of the ratio of consecutive closing prices. This is done for each stock in the stocks DataFrame. The shift(1) function shifts the data by one period, allowing us to compute the ratio of the current price to the previous day's price.

Step 2: Check the Log Returns

This line of code outputs the calculated log returns. It is a DataFrame where each column represents the log returns of a specific stock, and each row corresponds to a trading day.

Step 3: Annualize the Log Returns

To annualize the log returns, we first determine the average daily log return for each stock using the mean() function. We then multiply this average by the number of trading days in a year (typically 252) to get the annualized log returns. This gives us a sense of the expected yearly return based on the daily log returns.

Step 4: Display the Annualized Log Returns

Finally, this line of code outputs the annualized log returns. It provides a summary of the expected annual performance of each stock based on historical data.

By following these steps, we have successfully calculated and annualized the log returns for the selected stocks, providing valuable insights into their historical performance.

# Calculate the daily and log return of each index
log_returns = np.log(stocks/stocks.shift(1))
daily_returns = stocks.pct_change()

# check the log returns
log_returns
# Annualize the log returns
trading_days = 252
annualized_log_returns = log_returns.mean() * trading_days

# Display the annualized log returns
annualized_log_returns

4. Visualizing Log-Returns of Each Stock

# Plot the annualized log returns with more descriptive details
plt.figure(figsize=(6,5))
annualized_log_returns.plot(kind='bar', color='blue')
plt.title('Annualized Log Returns of Selected Stocks (2010-Present)')
plt.xlabel('Stocks')
plt.ylabel('Annualized Log Return')
plt.xticks(rotation=45)
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.tight_layout()
plt.show()
# Calculate the 95% Value at Risk (VaR) for each fund
VaR_95 = log_returns.quantile(0.05).round(4)*(-1)

# Calculate the 95% Conditional Value at Risk (CVaR) for each fund
CVaR_95 = log_returns[log_returns<=-VaR_95].mean()

5. VaR and CVaR Analysis

In this step, we perform the following steps to calculate and visualize the 95% Value at Risk (VaR) and Conditional Value at Risk (CVaR) for each fund:

  1. Value at Risk (VaR):

    • Definition: VaR is a statistical measure that quantifies the potential loss in value of a portfolio over a defined period for a given confidence interval. For example, a 95% VaR indicates that there is a 95% chance that the portfolio will not lose more than this amount over the specified period.
    • Calculation: We use the quantile(0.05) method on the daily_returns DataFrame to compute the 5th percentile of daily returns for each fund. This value represents the maximum loss expected with 95% confidence.
    • Conversion: We multiply the result by -1 to convert it into a positive value, as VaR is typically expressed as a positive number.
  2. Conditional Value at Risk (CVaR):

    • Definition: CVaR, also known as Expected Shortfall, is a risk assessment measure that provides the average loss given that the loss is beyond the VaR threshold. It offers a more comprehensive view of tail risk compared to VaR.
    • Calculation: We filter the daily_returns DataFrame to include only the returns that are less than or equal to the negative VaR value.
    • Mean Calculation: We then calculate the mean of these filtered returns to obtain the CVaR, which represents the average loss given that the loss is beyond the VaR threshold.
  3. Visualize the Results:

    • We set up a subplot figure with 3 rows and 2 columns to accommodate the KDE plots for each fund.
    • We iterate over each column in the daily_returns DataFrame and plot the KDE of daily returns.
    • For each plot, we add vertical red lines to indicate the 95% VaR (dashed line) and 95% CVaR (solid line).
    • We set the title and labels for each subplot and add a legend to distinguish between the distribution, VaR, and CVaR lines.
    • Finally, we adjust the layout and display the plot with a main title "VaR and CVaR".

Observation and Conclusion: We saw that Tesla and Nvidia have a slightly higher VaR and CVaR than the other companies, again due to their momentum aspect and high volatility.

# Import seaborn for kde plots
import seaborn as sns

# Set up the subplot figure
fig, ax_kde = plt.subplots(4, 2, figsize=(12, 14))

# Flatten the axes array for iteration
ax_kde = ax_kde.flatten()

# Plot KDE for each column in daily_returns
for i, column in enumerate(log_returns.columns):
    sns.kdeplot(data=log_returns, x=column, ax=ax_kde[i], color='b', label='Distribution of Daily Return')
    ax_kde[i].axvline(x=-VaR_95[i], color='r', linestyle='-', label='95% VaR')
    ax_kde[i].axvline(x=CVaR_95[i], color='r', linestyle='--', label='95% CVaR')
    ax_kde[i].set_title(f'{column}')
    ax_kde[i].set_xlabel('daily return')
    ax_kde[i].legend()

# Adjust layout
plt.suptitle('VaR and CVaR', size=30)
plt.tight_layout()
plt.show()