如何使用 Python 中的 Returns 计算最大回撤
How to calculate MaximumDrawdown using Returns in Python
我有 DataFrame final
和我的投资组合 returns。我正在尝试使用 returns 计算 MaxDrawdown。我试过下面的代码,确实看到了很多 stackexchange 问题。但无法解决这个问题。有什么方法可以使用投资组合的 returns 来计算最大回撤。
Returns
1/2/2009 0.030483579
1/5/2009 0.002872092
1/6/2009 0.01461333
1/7/2009 -0.032431836
1/8/2009 0.0055774
1/9/2009 -0.019844336
1/12/2009 -0.019705618
1/13/2009 0.001093185
1/14/2009 -0.032726765
1/15/2009 0.013635182
1/16/2009 0.009807648
1/20/2009 -0.044440252
1/21/2009 0.035156229
1/22/2009 -0.01460641
1/23/2009 0.007399468
1/26/2009 0.007910521
1/27/2009 0.007848472
1/28/2009 0.028944903
1/29/2009 -0.023816962
1/30/2009 -0.02550717
2/2/2009 -0.000292223
2/3/2009 0.020191091
2/4/2009 -7.93651E-06
2/5/2009 0.020070065
2/6/2009 0.026235957
2/9/2009 -0.001606124
2/10/2009 -0.03629415
2/11/2009 0.00248416
2/12/2009 0.001925152
2/13/2009 -0.00441840
代码:
cum_returns = (1 + final).cumprod()
drawdown = 1 - final.div(final.cummax())
谁能帮我解决这个问题。谢谢!
IIUC 在 cumprod
添加 diff
之后,min 是最大回撤
(df.Returns+1).cumprod().diff().min()
Out[316]: -0.043177386133390616
基于 MDD definition
s=(df.Returns+1).cumprod()
np.ptp(s)/s.max()
Out[319]: 0.11457761692384323
您可以使用 pandas.expanding()
(doc) 获得截至日期的最大回撤数据框,然后将 max
应用于 window.
pandas.expanding
将以 pandas.rolling does, but with a window that starts at the beginning of the dataframe and expands up to the current row (more info about the Window Functions here and pandas.expanding):
的方式应用函数
>> cum_returns = (1 + final).cumprod()
>> drawdown = 1 - final.div(final.cummax())
>> drawdown.expanding().max()
Returns
1/2/2009 0.000000
1/5/2009 0.000000
1/6/2009 0.000000
1/7/2009 0.032432
1/8/2009 0.032432
1/9/2009 0.046343
1/12/2009 0.065136
1/13/2009 0.065136
1/14/2009 0.094742
1/15/2009 0.094742
1/16/2009 0.094742
1/20/2009 0.114578
1/21/2009 0.114578
1/22/2009 0.114578
1/23/2009 0.114578
1/26/2009 0.114578
1/27/2009 0.114578
1/28/2009 0.114578
1/29/2009 0.114578
1/30/2009 0.114578
2/2/2009 0.114578
2/3/2009 0.114578
2/4/2009 0.114578
2/5/2009 0.114578
2/6/2009 0.114578
2/9/2009 0.114578
2/10/2009 0.114578
2/11/2009 0.114578
2/12/2009 0.114578
2/13/2009 0.114578
将回撤和最大回撤 (MDD) 放在一个数据框中,这样您就可以比较结果:
>> df_dd = pd.concat([drawdown, drawdown.expanding().max()], axis=1)
>> df_dd.columns = ['drawdown', 'MDD']
>> df_dd
drawdown MDD
1/2/2009 0.000000 0.000000
1/5/2009 0.000000 0.000000
1/6/2009 0.000000 0.000000
1/7/2009 0.032432 0.032432
1/8/2009 0.027035 0.032432
1/9/2009 0.046343 0.046343
1/12/2009 0.065136 0.065136
1/13/2009 0.064114 0.065136
1/14/2009 0.094742 0.094742
1/15/2009 0.082399 0.094742
1/16/2009 0.073399 0.094742
1/20/2009 0.114578 0.114578
1/21/2009 0.083450 0.114578
1/22/2009 0.096837 0.114578
1/23/2009 0.090154 0.114578
1/26/2009 0.082957 0.114578
1/27/2009 0.075759 0.114578
1/28/2009 0.049007 0.114578
1/29/2009 0.071657 0.114578
1/30/2009 0.095336 0.114578
2/2/2009 0.095601 0.114578
2/3/2009 0.077340 0.114578
2/4/2009 0.077347 0.114578
2/5/2009 0.058830 0.114578
2/6/2009 0.034137 0.114578
2/9/2009 0.035688 0.114578
2/10/2009 0.070687 0.114578
2/11/2009 0.068379 0.114578
2/12/2009 0.066585 0.114578
2/13/2009 0.070709 0.114578
假设您已经有一个包含累积 return 的列,这非常简单:您想要获得任何给定点的最大值并将其与实际累积 return 进行比较仅在该点之后出现的行。
然后,如果取最低值,则得到数组的最大回撤。
import pandas as import pd
import numpy as np
def max_drawdown(arr: pd.Series) -> int:
return np.min(arr / arr.expanding().max()) - 1
如果您需要先计算累计值 return,使用 log 会非常简单:
import numpy as np
final['log_return'] = np.log(1 + final['Returns'])
final['log_cum_return'] = np.cumsum(final['log_return'])
final['cumulative_returns'] = np.expm1(final['log_cum_return'])
我有 DataFrame final
和我的投资组合 returns。我正在尝试使用 returns 计算 MaxDrawdown。我试过下面的代码,确实看到了很多 stackexchange 问题。但无法解决这个问题。有什么方法可以使用投资组合的 returns 来计算最大回撤。
Returns
1/2/2009 0.030483579
1/5/2009 0.002872092
1/6/2009 0.01461333
1/7/2009 -0.032431836
1/8/2009 0.0055774
1/9/2009 -0.019844336
1/12/2009 -0.019705618
1/13/2009 0.001093185
1/14/2009 -0.032726765
1/15/2009 0.013635182
1/16/2009 0.009807648
1/20/2009 -0.044440252
1/21/2009 0.035156229
1/22/2009 -0.01460641
1/23/2009 0.007399468
1/26/2009 0.007910521
1/27/2009 0.007848472
1/28/2009 0.028944903
1/29/2009 -0.023816962
1/30/2009 -0.02550717
2/2/2009 -0.000292223
2/3/2009 0.020191091
2/4/2009 -7.93651E-06
2/5/2009 0.020070065
2/6/2009 0.026235957
2/9/2009 -0.001606124
2/10/2009 -0.03629415
2/11/2009 0.00248416
2/12/2009 0.001925152
2/13/2009 -0.00441840
代码:
cum_returns = (1 + final).cumprod()
drawdown = 1 - final.div(final.cummax())
谁能帮我解决这个问题。谢谢!
IIUC 在 cumprod
添加 diff
之后,min 是最大回撤
(df.Returns+1).cumprod().diff().min()
Out[316]: -0.043177386133390616
基于 MDD definition
s=(df.Returns+1).cumprod()
np.ptp(s)/s.max()
Out[319]: 0.11457761692384323
您可以使用 pandas.expanding()
(doc) 获得截至日期的最大回撤数据框,然后将 max
应用于 window.
pandas.expanding
将以 pandas.rolling does, but with a window that starts at the beginning of the dataframe and expands up to the current row (more info about the Window Functions here and pandas.expanding):
>> cum_returns = (1 + final).cumprod()
>> drawdown = 1 - final.div(final.cummax())
>> drawdown.expanding().max()
Returns
1/2/2009 0.000000
1/5/2009 0.000000
1/6/2009 0.000000
1/7/2009 0.032432
1/8/2009 0.032432
1/9/2009 0.046343
1/12/2009 0.065136
1/13/2009 0.065136
1/14/2009 0.094742
1/15/2009 0.094742
1/16/2009 0.094742
1/20/2009 0.114578
1/21/2009 0.114578
1/22/2009 0.114578
1/23/2009 0.114578
1/26/2009 0.114578
1/27/2009 0.114578
1/28/2009 0.114578
1/29/2009 0.114578
1/30/2009 0.114578
2/2/2009 0.114578
2/3/2009 0.114578
2/4/2009 0.114578
2/5/2009 0.114578
2/6/2009 0.114578
2/9/2009 0.114578
2/10/2009 0.114578
2/11/2009 0.114578
2/12/2009 0.114578
2/13/2009 0.114578
将回撤和最大回撤 (MDD) 放在一个数据框中,这样您就可以比较结果:
>> df_dd = pd.concat([drawdown, drawdown.expanding().max()], axis=1)
>> df_dd.columns = ['drawdown', 'MDD']
>> df_dd
drawdown MDD
1/2/2009 0.000000 0.000000
1/5/2009 0.000000 0.000000
1/6/2009 0.000000 0.000000
1/7/2009 0.032432 0.032432
1/8/2009 0.027035 0.032432
1/9/2009 0.046343 0.046343
1/12/2009 0.065136 0.065136
1/13/2009 0.064114 0.065136
1/14/2009 0.094742 0.094742
1/15/2009 0.082399 0.094742
1/16/2009 0.073399 0.094742
1/20/2009 0.114578 0.114578
1/21/2009 0.083450 0.114578
1/22/2009 0.096837 0.114578
1/23/2009 0.090154 0.114578
1/26/2009 0.082957 0.114578
1/27/2009 0.075759 0.114578
1/28/2009 0.049007 0.114578
1/29/2009 0.071657 0.114578
1/30/2009 0.095336 0.114578
2/2/2009 0.095601 0.114578
2/3/2009 0.077340 0.114578
2/4/2009 0.077347 0.114578
2/5/2009 0.058830 0.114578
2/6/2009 0.034137 0.114578
2/9/2009 0.035688 0.114578
2/10/2009 0.070687 0.114578
2/11/2009 0.068379 0.114578
2/12/2009 0.066585 0.114578
2/13/2009 0.070709 0.114578
假设您已经有一个包含累积 return 的列,这非常简单:您想要获得任何给定点的最大值并将其与实际累积 return 进行比较仅在该点之后出现的行。
然后,如果取最低值,则得到数组的最大回撤。
import pandas as import pd
import numpy as np
def max_drawdown(arr: pd.Series) -> int:
return np.min(arr / arr.expanding().max()) - 1
如果您需要先计算累计值 return,使用 log 会非常简单:
import numpy as np
final['log_return'] = np.log(1 + final['Returns'])
final['log_cum_return'] = np.cumsum(final['log_return'])
final['cumulative_returns'] = np.expm1(final['log_cum_return'])