Measuring Portfolio risk using Monte Carlo simulation in python — Part 1

Abdalla A. Mahgoub, MSc / CISI
CodeX
Published in
9 min readNov 13, 2022

Introduction

One of my strengths as a data scientist is that I always use the simplest methods and techniques to explain complicated and yet intensive data and Artificial intelligence related concepts.

Hence , I will try my best to explain the concept of Monte Carlo simulation and why is it an important method for portfolio risk management and an important method used by major players in the financial field.

As data scientists, we always have the task to deal with uncertainties and be prepared for unexpected situations, by simply predicting the risk associated with every event we try to pursue , or achieve.

Imagine, you are managing a list of stocks or a portfolio where your investment mandate is simply to achieve capital growth and mitigating your risk at the same time.

Monte Carlo Simulation method is used to account for risk in quantitative analysis and decision making. To sum it up , this method is used by professionals in fields of finance, , energy , project management , oil &gas , transportation , ESG and in many more sectors.

What is Monte Carlo simulation?

Monte Carlo simulation performs risk analysis by building models of possible results, by simply substituting a range of values — called a probability distribution — for any factor that has inherent uncertainty. In simple terms, Monte Carlo model is used to predict the probability of different outcomes or in our case portfolio value based on different volatilities results from all stocks in question. The outcome of this model will explain the impact of risk and uncertainty in prediction and forecasting models. These risks will be presented in form of cVar and Var values.

I will explain what are cVar and Var in Part-2 of this paper, but for now you need to understand these simple explanation.

How Monte Carlo method works

Basically , Monte Carlo model builds models of possible results by substituting a range of values presented in the model in a form of probability distribution , for any factor that has inherent uncertainty. Then, it calculated and run these results over and over again, where each time using different set of random values from the probability function.

Based on the number of uncertainties in question, the model could involve hundreds or thousands of recalculation before its complete.

What using probability distribution and why is it important for a Monte Carlo Simulation model

Well to answer these question , you have to keep in mind one thing , Monte Carlo is a normal or a bell curve probability distribution and the bell curve is Monte Carlo method .

Coding part 1 — Monte Carlo Simulation model

Before we start this , I would like to be clear that due to my experience in the financial field , I’ve decided to develop this method in relation to the stock market , in another word the capital market.

You can always implement this method to any other sub field of the economy to measure your overall risk. As long as you have a historical data .

Now that we got a good grasp on what is the Monte Carlo simulation is and why big players are using this method , let’s look into putting all that into motion by coding a Monte Carlo simulation method in Python.

You need the following

First let’s call the right libraries to perform the Monte Carlo Simulation (MCS) model

I assume some of you would know the function of calling these libraries , in case if you don’t , here is a brief description of these libraries ( Source : Wikipedia and other web channels)

Code

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import datetime as dt
from pandas_datareader import data as pdr

· Pandas : It is a software library that is used for data manipulation and analysis, it offers data structures and operations for manipulating numerical tables and time series.

· pandas_datareader : Here is an extension or a package of pandas library where it helps us to extract data from a wide range of Internet sources into a pandas DataFrame.

· Numpy : It is a software library that is used for adding support for large, multi-dimensional arrays and matrices, along with a large collection of high-level mathematical functions to operate on these arrays.

· Matplotlib : This python library is used to create 2D graphs and plots by using python scripts. It has a module named pyplot which makes things easy for plotting by providing feature to control line styles, font properties, formatting axes etc.

Importing and extracting Data

Code

# import data
def get_data(stocks, start, end):
stockData = pdr.get_data_yahoo(stocks, start, end)
stockData = stockData['Close']
returns = stockData.pct_change()
meanReturns = returns.mean()
covMatrix = returns.cov()
return meanReturns, covMatrix

Here we define a function in python and we call it get_data(), simply with the help of our pandas_data reader library , we can extract financial related data from Yahoo Finance .

On this function, we extract the following , close prices of the designated stocks , daily price change , the average price performance or the mean and the covariance of returns, by returns I mean the price percentage change for the stock.

Tip : Calculating covariance of two randomly variables or returns is a major component for the monte carlo simulation method . Covariance evaluates how the mean values of two random stocks move together. If stock A’s return moves higher whenever stock B’s return moves higher and the same relationship is found when each stock’s return decreases, then these stocks are said to have positive covariance.

Why are we using Covariance as a measure of risk in our Monte Carlo method, because simply in modern portfolio theory we use covariances to statistically reduce the overall risk of a portfolio by protecting against volatility through covariance-informed diversification.

Here is a list of relevant formulas of the get_data() function :

Mean formula :

Where :

Xn = All daily returns or price percentage change of the stock.

n = total number of returns or price percentage change or sample size.

Price percentage change:

To calculate a percentage price change, first work out the difference (increase or decrease) between the two numbers you are comparing

If it’s a price increase we start with

Increase = New Number — Original Number

And If it’s a price decrease we start with

Decrease=Original Number−New Number

Hence the price percentage (%) change is calculated as following

For example , if you own some shares in pepsi at cost price of $ 178/share and the stock started trading at $189/share , following up with the above calculations your

Increase = 189–178 = $ 11 (this is the difference between the cost and current market prices, in theory you are making unrealized gain of $11/share )

Hence your price percentage change is :

% change = (11/178) * 100 = 6.179%

Covariance:

As for the covariance the following is the covariance formula , assuming we need to measure the directional relationship between two stocks , Stock A and Stock B.

Where

Return : is the price change of the stock

Average : is simply the mean or average price of the stock

n : is the size or total number of the size .

Extracting Financial data

stockList = ['BNS.TO', 'GOOGL', 'XOM', 'NIO', 'KO', 'PEP','ARCC','IBM','AGNC','LCID']
stocks = [stock for stock in stockList]
endDate = dt.datetime.now()
startDate = endDate - dt.timedelta(days=300)

meanReturns, covMatrix = get_data(stocks, startDate, endDate)

weights = np.random.random(len(meanReturns))
weights /= np.sum(weights)

Here, I’ve selected around 10 stocks of which 9 of them are listed in the US and 1 in Canada, these stocks represent our portfolio. A well-established and constructed portfolio usually consists of a collection of stocks, bonds, commodities, futures, and derivatives. The allocation of values or investments for these asset classes is determined by a fund manager who must follow a strict investment mandate based on the company’s investment objection that he or she works for.

Some fund managers prefer investing in stocks and bonds only with an asset allocation of 70% stocks to 20% bonds and the remaining are being reserved as cash. Others have a different investment agenda and so on.

Anyhow, we can always talk about asset allocation techniques in another article and I think I should.

Back to our case, we will measure our portfolio risk based on the based 300 days performance of all these stocks. By using all the data we’ve gathered from our pre-function of Covariance, mean, and stock price change.

As for the weights of the portfolio or the stocks, I defined them randomly, of course as you know all weights for the portfolio should be added to 1, representing 100% weighting, or a weight matrix equals 1 as I mentioned earlier.

Now we are ready to move to perform the Monte Carlo simulation methodology

Monte Carlo Simulation analysis

# Monte Carlo simulation
mc_sims = 100 # number of simulations
T = 100 #timeframe in days

meanM = np.full(shape=(T, len(weights)), fill_value=meanReturns)
meanM = meanM.T

portfolio_sims = np.full(shape=(T, mc_sims), fill_value=0.0)

initialPortfolio = 47000

for m in range(0, mc_sims):
Z = np.random.normal(size=(T, len(weights)))#uncorrelated RV's
L = np.linalg.cholesky(covMatrix) #Cholesky decomposition to Lower Triangular Matrix
dailyReturns = meanM + np.inner(L, Z) #Correlated daily returns for individual stocks
portfolio_sims[:,m] = np.cumprod(np.inner(weights, dailyReturns.T)+1)*initialPortfolio

font = {'family': 'serif',
'color': 'white',
'weight': 'normal',
'size': 25,
}
plt.figure(figsize=(20, 10))
plt.plot(portfolio_sims)
plt.ylabel('Portfolio Value ($)', fontdict=font)
plt.xlabel('Days', fontdict=font)
plt.title('Monte carlo simulation of a stock portfolio', fontdict=font)
plt.show()

The beauty of using python to run such a simulation is that you can run as many tests and simulations for hundreds of portfolios and get these results in a matter of seconds if not minutes.

For our portfolio, we will run 100 simulations at a timeframe of 100 days of the 300 defined days.

With defining meanM and portfolio_sims we basically create an empty array and fill it up with the mean return of our defined stocks along with their weightings.

Then we create a loop of events or tests to determine a possible portfolio given the acquired data concerning covariance and the mean returns of these stocks.

We will be assuming daily returns are distributed by a u multivariate Normal Distribution, where we will figure out the Z variable which are samples from a normal distribution, then we use the Cholesky decomposition to determine the Lower Triangular matrix.

Tip: Cholesky decomposition is a decomposition of a Hermitian, positive-definite matrix into the product of a lower triangular matrix and its conjugate transpose, which is useful for efficient numerical solutions (Source Wikipedia : https://en.wikipedia.org/wiki/Cholesky_decomposition )

Simply, we will turn uncorrelated hundreds of stocks, into a relatively correlated group, by doing so we can visualize the results in a range of 100 portfolios.

Now what we need to do is to record all these portfolio simulations into the daily return and accumulate them into days, and then save them as per simulation, we will use this line of code to do that portfolio_sims[:,m] = np.cumprod(np.inner(weights, dailyReturns.T)+1)*initialPortfolio. ( Please refer to the code snippet above).

Here, I’ve decided to have an initial portfolio amount of USD 47,000 , then we simply plot our method by using matplotlib library as indicated in the code above.

Figure — 1 Monte Carlo simulation results

Looking at the figure above, We can see 100 different portfolio simulations, what does the line chart mean at this point, We can closely see the initial portfolio amounts are at the USD 47,000 mark. Hence, in the next 100 days, the portfolio should be valued at over USD 63k or shouldn’t drop below USD 30k.

To determine the worst-case scenario for your portfolio, we need to dig even deeper in our code and figure out the VAR and cVar value, which will tell us how much we might lose in case the market or the portfolio tanked or dropped to a certain level.

Basically, Var and cVar are concepts that are used in the field of financial risk measurement to evaluate the market risk or credit risk of a portfolio.

We shall touch base on this concept in the next part of this paper — Monte Carlo simulation in python — Part 2

In part 2, you will be able to quantify possible losses in case the market moved against your position by adopting Var and cVar. If any of you saw the movie “Margin Call”, you will understand these kinds of strategies came in handy to capture the worst-case scenario and act on it before it happened.

Please don’t hesitate to reach out to me if you ever need any help concerning this paper.

--

--

Abdalla A. Mahgoub, MSc / CISI
CodeX
Writer for

Master's in Data Science. Technology Entrepreneur ,Data Scientist, Ops Analyst (ICT),Strategic Business developer, Speaker ,Writer, Full Stack developer