What is mmr?

The Measuring Market Risk (mmr) package takes the Matlab code that accompanies Kevin Dowd's Measuring Market Risk textbook and rewrites it in R in a functional style using the purrr package. Dowd's book is an outstanding introduction to market risk analysis, for students and practioners. The combination of text and code makes for a powerful learning experience, however there are drawbacks in his choice of Matlab. First and foremost, Matlab is a proprietary language which is prohibitively expensive for most students. This instantly prevents many from using a very good book. On top of that by endorsing Matlab, students/practioners are drawn into a closed ecosystem where "toolboxes" providing even the most basic functionality are costly. Secondly, Matlab is not a functional language. This makes turning simple and elegant mathematical ideas into simple and elegant code difficult.

R is a functional open source language with a booming package ecosystem; solving both problems. mmr is not a direct port from Dowd's Matlab to R. All important functionality is included along with some functions Dowd included in his text but left out of the accompanying code. Dowd's book can be bought on Amazon or PDF versions are floating around the internet.

What is mmr for?

mmr is for learning the basics of risk measurement - it is not for production risk management systems. Each function is small and simple so they can be understood easily. This vignette will provide examples to illustrate how these the functions in mmr can be chained together to do meaningful analysis and produce some pretty plots.

Packages Required

For this walkthrough you will need to install and load the following packages:

# devtools::install_github("dandermotj/mmr")
packages <- c("quantmod", "ggplot2", "tibble", "purrr")
invisible(lapply(packages, library, character.only = TRUE))

Loading Financial Data

To get financial data we will use the quantmod package. The getSymbolsfunction can fetch data from a range of APIs (Yahoo finance, FRED, ...). Unfortunately, getSymbols loads data silently by default (this will change in version 0.5), so for clarity and reproducibility we'll explicitly assign the data: getSymbols(..., auto.assign = FALSE). The getSymbols function is quite complicated so make sure to read the docs (?getSymbols).

# Prevent getSymbols from big warning print
options("getSymbols.warning4.0"=FALSE)
  ```


The ticker we will use as an example is Tableau (`NYSE: DATA`). Tableau is interesting from a market risk standpoint because in early 2016, between February 3rd and February 8th its stock price halved unexpectedly. 

```r
tab <- getSymbols("DATA", source = "yahoo", auto.assign = FALSE)
str(tab)

By defualt a xts time series object. To make life easier we will convert this to a tibble (a data frame like object following the tidy data philosophy). Tibbles are nearly identical to data frames, but have much nicer print methods. The variable names of tab are annoying always being prefixed by DATA, so we'll rename the columns and remove this prefix.

(We could put it in a tidy format with broom::tidy(tab) but let's keep it this way for the moment.) By "tidying" the data we preserve the dates in the index column, all the variables are collected into the series variable and their corresponding prices are in the value column. This long form of data makes working with other packages such as dplyr simpler.

tab <- as_tibble(tab) %>% add_column(Date = index(tab))
names(tab) <- c("Open", "High", "Close", "Low", "Volume", "Adjusted", "Date")
tab

Let's quickly plot the adjusted closing price with ggplot so we have an idea of the history of Tableau's price.

ggplot(data = tab, aes(x = Date, y = Adjusted)) +
  geom_line() +
  labs(title = "Tableau Stock Price")

Tableau's dramatic price crash is obvious in the plot.

From now on, we're going to concentrate on the dailty adjusted price of Tableau, so we'll copy it into its own variable price for readability.

price <- tab$Adjusted

The final data processing step before we begin is turning price into profit and loss data. When analysing risk, we look at Profit/Loss (P/L) figures, not price. Some people prefer to think of Loss/Profit (L/P) instead because we are focusing on the potential losses not potential returns, but this is just a preference. There are a few different P/L calculations, some which include borrowing and reinvestment but we'll go with the most basic, simply the differenced series.

$$ P/L = P_t - P_{t - 1} $$

By computing the P/L the length of the output will be one less than the length of the price vector. This makes it awkward dealing with data frames or tibbles, because they are rectangular data structures requiring each column to contain the same number of rows. mmr provides a simple helper profit_loss function to compute P/L data that preserves length by appending NA to the last row.

profit_loss <- function(price){
  c(diff(price), NA)
}

# We only want to compute the P/L for the prices of the stock
# this basic function won't work for dates appropriately, and
# we want to keep the volume column the same
price_cols <- c(1:4, 6)

tab_pl <- tab %>% dmap_at(price_cols, profit_loss) 
tab_pl %>% 
  ggplot(aes(x = Date, y = Adjusted)) +
  geom_line() +
  labs(title = "P/L Tableau")

tab_pl %>% ggplot(aes(x = Adjusted)) +
  geom_histogram()

To make things very clear, mmr functions always expects P/L data. One is just the negative of the other: $P/L = -L/P$ To get P/L from prices.

To compute returns we have a price_to_rets function.

price_to_rets <- function(price) {
  diff(price)/price[-length(price)]
}
price <- price_to_rets()

Basic Risk Measures

Value at Risk & Expected Shortfall

Non Parametric Models

Historical Simulation

Parametric Models

Weighting Returns

Rolling Risk Measures

Backtesting



dandermotj/mmr documentation built on June 4, 2019, 9:26 p.m.