{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "

# Andrey Varkentin. Risk management with Python.

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this tutorial we are going to learn some basic risk management instruments, that could be used not only in trading, but also in daily operations of every organisation, which strive to manage its own risks. However, now it is broadly used in financial organisations due to specifics of risks, these organisations are facing." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This tutorial is devoted to VaR and Monte-Carlo simulation and is organized as follows: first, we will introduce theoretical foundations of VaR, then apply basic VaR and Monte-Carlo simulation on Tesla equity prices, finally, look at Bocconi University Student Investment Club example realization of 4 types of VaR." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Theory" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The Value-at-risk (VaR) has been used for decades to assess market risk. In a nutshell, the VaR is a statistical technique used to measure the level of risk of a portfolio given a certain confidence interval and within a fixed timeframe.[[1]](https://medium.com/@Francesco_AI/big-data-and-risk-management-in-financial-markets-part-i-eed4e245f3db)\n", "\n", "The VaR can be computed through:\n", "\n", "- Historical method - we organise histrical returns in descending order and choose a threshold to define possible losses;\n", "- Delta-Normal method - first step to modelling: we evaluate mean and standard deviation and model the distribution of returns, after that taking the required threshold;\n", "- Monte Carlo simulation - we model returns trajectories, and then run a multitude of simulated trials, which result in distribution of returns.\n", "\n", "We will try to implement them in our first part of Tesla equity analysis.\n", "\n", "Of course, this is not the complete list of methods. In BSIC approach there are 4 methods of VaR as follows [[2]](http://www.bsic.it/wp-content/uploads/2017/03/VaR-with-Python.pdf):\n", "- Parametric VaR -to build it, the only variables needed are the mean and the standard deviation of a portfolio/security. The problem is that it works under two restrictive assumptions, namely normal distribution and independence of returns. This leads to myopically equating all returns in terms of importance, overlooking big shocks that should be carried over and should be given more power to impact the actual VaR.\n", "- EWMA (Exponentially weighted moving average) tries to solve the problem of slow reaction to new information and the equal importance of returns. Using a decay factor the EWMA formula is able to weight different information as it comes in, giving more importance to recent returns and less importance to data far in the past by slowly decaying their contribution to the VaR. Through this, the measure limits the ‘echo effect’, occurring when a large shock of the past becomes too old to be considered and leaves the estimation, causing a big change in the VaR which is not due to a change in the markets.\n", "- Historical Simulation(HS) VaR is instead efficient when the risk manager cannot, or doesn’t intend to, make assumptions on the underlying distribution of returns as it is calculated by the simple picking of the chosen percentile loss in a given period of time. This method is even simpler than the parametric one and that is precisely its weakness. \n", "- Filtered Historical Simulation VaR can be described as being a mixture of the historical simulation and EWMA methods. Returns are first standardized, with volatility estimation weighted as in EWMA VaR, before a historical percentile is applied to the standardized return as in the historical model. From the graphs it is easy to spot that this model looks very much like EWMA, as returns are standardised and weighted by the same decay factor. The main difference lies in the fact that this model is generally more conservative because it looks at the worst past losses and adjust its VaR value according to it.\n", "\n", "We will look at them in our second part of Tesla equity analysis.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's go deep into formal definition of VaR. More information about this, portfolio optimisation technics and etc. can be found [here [3]](http://www.quantatrisk.com/2013/03/08/var-expected-shortfall-black-swan/).\n", "\n", "More formally, given a daily (or, weekly, monthly, etc.) distribution of returns (of, for example, a single stock, a portfolio of assets, etc.), we are interested in finding the value of VaRα of, say, α=0.05 (five percent) which would say to as that there is 5% of chances that the value of VaR 0.05 would be exceeded in trading on the next day. This value is located in the left tail of the distribution and, by convention, it is given as positive number. Therefore, we define VaRα as:\n", "$$P[X\\leq VaR\\alpha]=1-\\alpha$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Okay then, having VaRα calculated we know how far the loss could reach at the 1−α confidence level. The next super important question in risk management every risk manager should ask or at least be interested in reporting is: if VaRα event occurs on the next day, what is the expected loss we might expect to suffer (say, in dollars)? VaRα is the threshold. Now we are interested in the expected value of loss given the exceedance. It is the definition of expected shortfall and is based on the concept of conditional probability as follows:\n", "\n", "$$E[X | X \\gt VaR\\alpha] = ES$$ . \n", "\n", "In general, if our daily distribution of returns can be described by a function f(x) which would represent a power density function (pdf), then:\n", "\n", "$$ES = 1 / \\alpha \\int_{-\\infty}^{VaR\\alpha}xf(x)dx.$$ " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "VaRα and ES can be, in fact, calculated by the method is based on the empirical distribution, i.e. using data as given:\n", "\n", "$$VaR\\alpha=h^{VaR}_{i}$$ for $$\\sum _{i=1}^{M-1}H_{i}(h_{i+1}-h_{i}) \\leq \\alpha ,$$\n", "\n", "where H represents the normalized histogram of returns (i.e., its integral is equal 1) and M is the number of histograms bins. Similarly for ES, we get:\n", "\n", "$$ES = \\sum_{i=1}^{h^{VaR}_{i}} h_{i}H_{i}(h_{i+1}-h_{i}).$$ " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Practice. Tesla equities from 2010." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's try to implement all theoretical constructions on history of Tesla equity prices from 29/06/2010" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# install package for downloading equity prices\n", "# !pip install pandas-datareader" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CAGR = 37.82%\n", "Annual Volatility = 51.6%\n" ] } ], "source": [ "import math\n", "\n", "import matplotlib.pyplot as plt\n", "# necessary packages\n", "import numpy as np\n", "from pandas_datareader import data\n", "from scipy.stats import norm\n", "\n", "# download tesla price data into DataFrame\n", "tesla = data.DataReader(\"TSLA\", \"yahoo\", start=\"29/06/2010\")\n", "\n", "# calculate the compound annual growth rate (CAGR) which\n", "# will give us our mean return input (mu)\n", "days = (tesla.index[-1] - tesla.index[0]).days\n", "cagr = ((((tesla[\"Adj Close\"][-1]) / tesla[\"Adj Close\"][1])) ** (365.0 / days)) - 1\n", "print(\"CAGR =\", str(round(cagr, 4) * 100) + \"%\")\n", "mu = cagr\n", "\n", "# create a series of percentage returns and calculate\n", "# the annual volatility of returns\n", "tesla[\"Returns\"] = tesla[\"Adj Close\"].pct_change()\n", "vol = tesla[\"Returns\"].std() * math.sqrt(252) # 252 - number of trading days\n", "print(\"Annual Volatility =\", str(round(vol, 4) * 100) + \"%\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Uhm, high growth rates and volatility, situation typical for startups." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's plot charts for Tesla with Seaborn and Bokeh to see the whole dynamics." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "