Fastest algorithm for calculating retrospective maximum drawdown

Simple question - what would be the fastest algorithm for calculating retrospective maximum drawdown ?

I've found some interesting talks but I was wondering what people thought of this question here.

-

1
Your question is not clear to me. Do you mean the easiest technique to code, or code that is CPU efficient? – montyhall Dec 30 '12 at 6:28
A vectorized approach (since inception) is very fast. – pat Dec 30 '12 at 9:18
You should probably clarify your question. Most readers are assuming you are asking about retrospective maximum drawdown, whereas I infer from the PDF you want to compute an expectation of it. – Brian B Dec 30 '12 at 15:13
Sorry for the confusion, I indeed meant algorithm/code that is CPU efficient for calculating retrospective maximum drawdown. – speciman Dec 30 '12 at 15:24

3 Answers

I won't give you the answer delivered on a silver platter but hopefully the following will get your started:

a) you need to define exactly over which look-back period you aim to derive the maximum drawdown.

b) you need to keep track of the max price while you iterate the look-back window.

c) you need to keep track of the min price SUBSEQUENT to any NEW max, thus each time you make a new max you need to reset the max low to zero (relatively speaking as a divergence from the max value)

this should get you pretty easily to where you want to get without having to iterate the time series more than once. I disagree that a vectorized approach will solve this problem (@Pat, please provide an answer if you disagree I would be curious how you would approach this in a vectorized manner because the algorithm here is path-dependent).

-
There is only 1 path from inception (and only 1 iteration required with vectorized dd result of that path). What you are describing above is a rolling dd (*Note I specified since inception). If you have a time series and can show an example of your algorithm and time, I will reproduce using a vectorized approach and compare times. – pat Dec 30 '12 at 23:15

1
@pat, "rolling dd", well, that is pretty much industry practice. Nobody cares about the maximum draw down over a ten year window, at least I do not know of too many investors with such long term memory. Please go ahead and show your vectorized version (even the one where you define maximum dd from inception), it would add a lot of value to other users. What holds you back? – Freddy Dec 31 '12 at 8:25

Zipline, the opensource python backtester, has a batch and iterative implementation for max drawdown.

Here is the batch: https://github.com/quantopian/zipline/blob/master/zipline/finance/risk.py#L284

Here is the iterative: https://github.com/quantopian/zipline/blob/master/zipline/finance/risk.py#L578

disclosure: I'm one of the zipline maintainers

-

(After the clarification, this answer is no longer relevant)

Expected maximum drawdown is going to be highly sensitive to your choice of SDE, and to your calibration of it. Therefore you should play with a variety of parameterizations to estimate your model error.

So far as efficient computation goes, we can regard this as a payoff very similar to a lookback option (much as in the PDF you linked). As with lookback options, the first instinct is to price them using Monte Carlo techniques, but one can actually do so much more quickly using a multi-level PDE solver, at least for sufficiently simple SDEs.

The way a 2-level PDE solver works for a payoff like this is that, rather than having a grid of $(S,t)$ values on which you run your difference equations and boundary conditions, you have a grid of $( \{M,S\}, t )$ values, where $M$ represents the maximum achieved so far. Obviously there are some new boundary conditions that go with it, for example that $\frac{\partial M}{\partial S}=1$ at and above the line $S=M$.

Differencing and updating on this grid, you ultimately end up with a value $V_{0,0}$ corresponding to today's maximum $M_0$ and stock price $S_0$.

See section 5.3.2 of this pdf for how it works with lookbacks. Max drawdowns will be very similar.

-
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 8, "mathjax_display_tex": 0, "mathjax_asciimath": 0, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0}, "config": {"markdown_headings": false, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "github"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "english_confidence": 0.9258064031600952, "perplexity_flag": "middle"}