Calculating Drawdowns from Returns in R
Summary
The document explains how to calculate a drawdown series and maximum drawdown from periodic returns. Its method first compounds the returns into an implied wealth or price series, then compares each value with the running peak. The gap from that peak, expressed as a proportion, gives the drawdown; the largest decline is the maximum drawdown. The example also notes that a drawdown library function can perform the calculation.
The answer says an implied price series is a straightforward intermediate step and shows the equivalent calculations in R. It does not present a direct formula on raw returns that avoids compounding, nor does it discuss complications such as missing observations, nonstandard return definitions, or how to treat the initial value. The example is a computational explanation rather than a comparison of methods or empirical evidence.
Key ideas
- Compounding periodic returns creates the wealth series used to measure drawdowns.
- Compare each wealth value with its running maximum to obtain the drawdown.
- The maximum drawdown is the greatest decline from a prior running peak.
- An R package or basic cumulative operations can calculate the result.
Tags
Full text
# Reproduce findDrawdowns and maxDrawdown functions in R given return series
# Reproduce findDrawdowns and maxDrawdown functions in R given return series
Is there any formula to calculate all drawdowns (and maximum drawdown) directly from return series? Or is it always necessary to convert the returns into implied "prices" first and then proceed with finding drawdowns?
Here is an example (done in Excel):
```
Date Returns 100,00 Drawdown
01.02.2000 0,30 100,30 -
01.03.2000 2,60 102,91 -
01.04.2000 1,10 104,04 -
01.05.2000 -1,00 103,00 -1,00
01.06.2000 1,50 104,54 -
01.07.2000 2,50 107,16 -
01.08.2000 1,60 108,87 -
01.09.2000 6,70 116,17 -
01.10.2000 -1,40 114,54 -1,40
01.11.2000 4,00 119,12 -
01.12.2000 -0,50 118,53 -0,50
01.01.2001 8,10 128,13 -
01.02.2001 4,00 133,25 -
01.03.2001 -3,70 128,32 -3,70
01.04.2001 -6,10 120,49 -9,57
01.05.2001 1,70 122,54 -8,04
01.06.2001 -4,90 116,54 -12,54
01.07.2001 -2,20 113,97 -14,47
01.08.2001 7,00 121,95 -8,48
01.09.2001 5,80 129,03 -3,17
01.10.2001 -6,50 120,64 -9,47
01.11.2001 2,40 123,53 -7,29
01.12.2001 -0,50 122,92 -7,76
01.01.2002 -0,90 121,81 -8,59
```
I am taking the current "price", then subtracting from this "price" the maximum "price" between the inititation date and the current date, then dividing this difference by that max "price". And finally, the drawdown is the minimum between this result and 0:
```
=MIN((C11-MAX($C$3:C11))/MAX($C$3:C11);0)*100
```
Max drawdown would be the minimum among the drawdowns.
I would like to do this in R. Preferably without creating the "price" table. Any ideas?
## Answer by Enrico Schumann (score 2, accepted)
https://quant.stackexchange.com/a/31372
I don't think you can do it without prices. But creating such a "price" series is very easy in R.
```
r <- rnorm(10, sd = 0.01) ## returns
cumprod(1 + r) ## => 'prices'
```
You can then easily compute the maximum drawdown:
```
require("NMOF")
drawdown(cumprod(1 + r))
```
In fact, you may not even need a package for computing drawdowns, since it is also very easy in R.
```
v <- cumprod(1 + r)
1 - v/cummax(v) ## drawdown
max(1 - v/cummax(v)) ## max. drawdown
```Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.