Calculating the maximum drawdown of a set of returns I wrote a simple function that calculates and returns the maximum drawdown of a set of returns. I am trying to squeeze as much efficiency for speed out of the code as possible. I've got it down to about as fast as I can go. Does anyone have suggestions on how to write this function more efficiently, perhaps through list comprehensions etc.?

import numpy as np

def max_drawdown(returns):

    draw_series = np.array(np.ones(np.size(returns)))
    max_return = 0; max_draw = 1; draw = 1
    returns = returns + 1

    for r in range(returns.count()-1, 0, -1):

        if returns[r] &gt; max_return:
            max_return = returns[r]

        else:
            draw = returns[r] / max_return
            if draw &lt; max_draw:
                max_draw = draw

        draw_series[r-1] = -(1 - max_draw)

    return draw_series
You are correct to point out that your implementation is terribly inefficient compared to most built-in Numpy operations of similar complexity.  100X speedup would be reasonable for large arrays once you eliminate the python loop.  It would be trivial to replace your python loop with some Numpy indexing or broadcasting if it weren't for the pesky draw_series[r-1] = -(1 - max_draw) line which operates on the next-to-be-computed item in the array.  This is analogous to Numpy's accumulate but obviously there's no implementation of it for your particular algorithm.  You have three options as I see it:


Study your problem hard and see if you decompose it into numpy-only
accumulate and regular operations. 
See if your algorithm can be expressed as a compiled numexpr
expression. 
Compile this function using Cython, f2py or ctypes


One minor improvement is to replace returns = returns + 1 with returns += 1 which will operate in-place and avoid re-allocating the returns array.

Hope this helps.  good luck.