首页 > 解决方案 > 使用 .expanding() Python 计算投资组合回撤

问题描述

我正在尝试使用以下代码计算投资组合随时间推移的投资组合回撤。我尝试使用 .expanding() 函数,但似乎无法获得所需的输出。如果有人能让我知道我哪里出错了,我将不胜感激。

def drawdown_2(arr):
    tot_return = arr.add(1).cumprod()
    max_return = tot_return.add(1).cummax()
    return (tot_return / max_return) - 1

df['Drawdown'] = df.groupby(df.portfolio)['performance'].expanding().apply(drawdown_2)

输入数据格式如下

portfolio   period  performance
port1   201501  0.003718
port1   201502  -0.004890
port1   201503  -0.004171
port1   201504  -0.006922
port1   201505  0.003545
port1   201506  0.003545
port1   201507  0.006901
port1   201508  0.000101
port1   201509  0.009081
port1   201510  0.003062
port1   201511  -0.008425
port1   201512  0.002580
port2   201501  0.009135
port2   201502  0.009149
port2   201503  -0.004252
port2   201504  -0.008788
port2   201505  -0.006210
port2   201506  0.006020
port2   201507  0.002983
port2   201508  0.008498
port2   201509  0.008080
port2   201510  0.000138
port2   201511  -0.008425
port2   201512  0.002580

所需的输出是一个数组,它是投资组合先前最大值与投资组合当前值之间的差值。上述输入的回撤数字以所需格式如下:

portfolio   period  performance Drawdown
port1   201501  0.003718    0.00000
port1   201502  -0.004890   -0.00490
port1   201503  -0.004171   -0.00900
port1   201504  -0.006922   -0.01590
port1   201505  0.003545    -0.01240
port1   201506  0.003545    -0.00890
port1   201507  0.006901    -0.00210
port1   201508  0.000101    -0.00200
port1   201509  0.009081    0.00000
port1   201510  0.003062    0.00000
port1   201511  -0.008425   -0.00842
port1   201512  0.002580    -0.00587
port2   201501  0.009135    0.00000
port2   201502  0.009149    0.00000
port2   201503  -0.004252   -0.00430
port2   201504  -0.008788   -0.01300
port2   201505  -0.006210   -0.01910
port2   201506  0.006020    -0.01320
port2   201507  0.002983    -0.01030
port2   201508  0.008498    -0.00190
port2   201509  0.008080    0.00000
port2   201510  0.000138    0.00000
port2   201511  -0.008425   -0.00860
port2   201512  0.002580    -0.00605

提前感谢一百万的帮助。

标签: pythonfinance

解决方案


我正在使用来自 yfinance 的数据:

import yfnance as yf

df = yf.download('aapl', start='2020-01-01')[['Close']]
df['Chg'] = df['Close'].pct_change()

    Close
Date    
2019-12-31  73.412498
2020-01-02  75.087502
2020-01-03  74.357498
2020-01-06  74.949997
2020-01-07  74.597504
... ...
2020-09-03  120.879997
2020-09-04  120.959999
2020-09-08  112.820000
2020-09-09  117.320000
2020-09-10  118.930000

计算累积回报、滚动最大峰值和从尾随峰值的回撤为:

df['Cum_ret'] = (1+ df['Chg']).cumprod()  # cumulative return
df['Peaks'] = df['Cum_ret'].cummax()      # cumulative peaks
df['Drawdown'] = (df['Cum_ret'] - df['Peaks']) / df['Peaks']  # drawdown from trailing peak

累积回报和峰值: 在此处输入图像描述

亏损: 在此处输入图像描述

编辑:刚刚注意到您正在处理 2 个投资组合回报,所以这并没有真正回答您的问题......

我认为这会做你想要的:

df['Drawdown'] = df.groupby('portfolio')['performance'].apply(drawdown_2)

    portfolio   period  performance Drawdown
0   port1   201501  0.003718    0.000000
1   port1   201502  -0.004890   -0.004890
2   port1   201503  -0.004171   -0.009041
3   port1   201504  -0.006922   -0.015900
4   port1   201505  0.003545    -0.012411
5   port1   201506  0.003545    -0.008910
6   port1   201507  0.006901    -0.002071
7   port1   201508  0.000101    -0.001970
8   port1   201509  0.009081    0.000000
9   port1   201510  0.003062    0.000000
10  port1   201511  -0.008425   -0.008425
11  port1   201512  0.002580    -0.005867
12  port2   201501  0.009135    0.000000
13  port2   201502  0.009149    0.000000
14  port2   201503  -0.004252   -0.004252
15  port2   201504  -0.008788   -0.013003
16  port2   201505  -0.006210   -0.019132
17  port2   201506  0.006020    -0.013227
18  port2   201507  0.002983    -0.010284
19  port2   201508  0.008498    -0.001873
20  port2   201509  0.008080    0.000000
21  port2   201510  0.000138    0.000000
22  port2   201511  -0.008425   -0.008425
23  port2   201512  0.002580    -0.005867

推荐阅读