'Calculating Drawdown in Pandas
I have the following DataFrame:
Profit Cumulative
Date
1/6/2005 248.8500 248.85
1/12/2005 48.3500 297.20
1/13/2005 29.2900 326.49
1/13/2005 -500.0000 -173.51
1/13/2005 -250.9500 -424.46
1/14/2005 126.6600 -297.80
1/16/2005 58.7400 -239.06
1/19/2005 68.3500 -170.71
1/21/2005 140.0000 -30.71
1/23/2005 200.0000 169.29
1/26/2005 -250.6800 -81.39
1/27/2005 162.5000 81.11
1/27/2005 135.5100 216.62
1/27/2005 -650.0000 -433.38
1/28/2005 96.8800 -336.50
1/28/2005 -1000.0000 -1336.50
1/31/2005 140.0000 -1196.50
2/1/2005 140.0000 -1056.50
The first column are the dollar profits of my portfolio. I have calculated the second column with the following formula:
df['Cumulative'] = df.Profit.cumsum().round(2)
So, is there a formula where I can calculate the dollar (not %) drawdowns of my portfolio? The column should look like this:
Drawdown
0.00
0.00
0.00
-500.00
-750.95
-624.29
-565.55
-497.20
-357.20
-157.20
-407.88
-245.38
-109.87
-759.87
-662.99
-1,662.99
-1,522.99
-1,382.99
-1,382.99
Solution 1:[1]
df['Cumulative'] = df.Profit.cumsum().round(2)
df['HighValue'] = df['Cumulative'].cummax()
df['Drawdown'] = df['Cumulative'] - df['HighValue']
That is the simplest solution I can found.
Solution 2:[2]
From what I remember, a drawdown is the amount by which your portfolio profit is less than the high. (In the future, you should explicitly define your desired output and don't assume people know what you are asking.)
There may be better ways, but you can calculate this in pandas
using a itertuples()
:
import pandas as pd
from StringIO import StringIO
# read the data
df = pd.DataFrame.from_csv(StringIO("""Date Profit Cumulative
1/6/2005 248.8500 248.85
1/12/2005 48.3500 297.20
1/13/2005 29.2900 326.49
1/13/2005 -500.0000 -173.51
1/13/2005 -250.9500 -424.46
1/14/2005 126.6600 -297.80
1/16/2005 58.7400 -239.06
1/19/2005 68.3500 -170.71
1/21/2005 140.0000 -30.71
1/23/2005 200.0000 169.29
1/26/2005 -250.6800 -81.39
1/27/2005 162.5000 81.11
1/27/2005 135.5100 216.62
1/27/2005 -650.0000 -433.38
1/28/2005 96.8800 -336.50
1/28/2005 -1000.0000 -1336.50
1/31/2005 140.0000 -1196.50
2/1/2005 140.0000 -1056.50"""), sep="\s+").reset_index()
# calculate drawdown
prev_high = 0
for i, date, profit, cumulative in df.itertuples():
prev_high = max(prev_high, cumulative)
dd = cumulative - prev_high
df.loc[i, 'Drawdown'] = dd if dd < 0 else 0
The resultant dataframe:
>>> print(df)
Date Profit Cumulative Drawdown
0 2005-01-06 248.85 248.85 0.00
1 2005-01-12 48.35 297.20 0.00
2 2005-01-13 29.29 326.49 0.00
3 2005-01-13 -500.00 -173.51 -500.00
4 2005-01-13 -250.95 -424.46 -750.95
5 2005-01-14 126.66 -297.80 -624.29
6 2005-01-16 58.74 -239.06 -565.55
7 2005-01-19 68.35 -170.71 -497.20
8 2005-01-21 140.00 -30.71 -357.20
9 2005-01-23 200.00 169.29 -157.20
10 2005-01-26 -250.68 -81.39 -407.88
11 2005-01-27 162.50 81.11 -245.38
12 2005-01-27 135.51 216.62 -109.87
13 2005-01-27 -650.00 -433.38 -759.87
14 2005-01-28 96.88 -336.50 -662.99
15 2005-01-28 -1000.00 -1336.50 -1662.99
16 2005-01-31 140.00 -1196.50 -1522.99
17 2005-02-01 140.00 -1056.50 -1382.99
Investopedia definition of drawdown.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | nipy |
Solution 2 | Jim G. |