使用 cumprod() 计算 Python 中的净值曲线
Using cumprod() to calculate equity curve in Python
我在使用 cumprod() 计算复合 return 时遇到困难。它从一开始就开始复合,但我只希望它在 'Final_Order' 等于买入时开始,在 'Final_Order 等于卖出时停止,然后在下一个买入订单时再次重置。请看下面的例子。
下面的示例数据显示了我希望看到的第 'Backtest' 列的输出。
Time Adj_Price Final_Order Backtest
0 7 nan 1000
1 6 nan 1000
2 5 Buy 1000
3 7 Buy 1400
4 8 Sell 1600
5 6 Sell 1600
6 4 Buy 1600
7 5 Buy 2000
8 7 Buy 2800
9 9 Sell 3600
10 7 Sell 3600
11 7 Sell 3600
12 6 Sell 3600
以下是 'Backtest'.
的计算结果
- 时间 1 =IF(Final_Order ="Buy(t0)",(6/7)*1000, 否则 1000) = 1000
- 时间 2 =IF(Final_Order ="Buy(t1)",(5/6)*1000, 否则 1000) = 1000
- 时间 3 =IF(Final_Order ="Buy(t2)",(7/5)*1000, 否则 1000) = 1400
- 时间 4 =IF(Final_Order ="Buy(t3)",(8/7)*1400, 否则 1400) = 1600
- 时间 5 =IF(Final_Order ="Buy(t4)",(6/8)*1600, 否则 1600) = 1600
- 时间 6 =IF(Final_Order ="Buy(t5)",(4/6)*1600, 否则 1600) = 1600
- 时间 7 =IF(Final_Order ="Buy(t6)",(5/4)*1600, 否则 1600) = 2000
- 时间 8 =IF(Final_Order ="Buy(t7)",(7/5)*2000, 否则 2000) = 2800
- 时间 9 =IF(Final_Order ="Buy(t8)",(9/7)*2800, 否则 2800) = 3600
- 时间 10 =IF(Final_Order ="Buy(t9)",(7/9)*3600,否则 3600) = 3600
下面是我正在使用的代码。
data['Backtest'] = np.where(data['Final_Order'] == 'Buy',
((1 + data['Adj
Close'].pct_change(1)).cumprod())*1000,
data['Backtest'].ffill())
创建一个列表,其初始值为 1000,具有比率和最终顺序:
b = [1000]+list(zip(df.Adj_Price.shift(-1)/df.Adj_Price,df.Final_Order))
df['BACK']=list(itertools.accumulate(b,lambda x,y: round(y[0]*x) if y[1]=="Buy" else x))[:-1]
df
Time Adj_Price Final_Order Backtest BACK
0 0 7 NaN 1000 1000
1 1 6 NaN 1000 1000
2 2 5 Buy 1000 1000
3 3 7 Buy 1400 1400
4 4 8 Sell 1600 1600
5 5 6 Sell 1600 1600
6 6 4 Buy 1600 1600
7 7 5 Buy 2000 2000
8 8 7 Buy 2800 2800
9 9 9 Sell 3600 3600
10 10 7 Sell 3600 3600
11 11 7 Sell 3600 3600
12 12 6 Sell 3600 3600
将创建的列与已经存在的列进行比较,它们是相同的
我在使用 cumprod() 计算复合 return 时遇到困难。它从一开始就开始复合,但我只希望它在 'Final_Order' 等于买入时开始,在 'Final_Order 等于卖出时停止,然后在下一个买入订单时再次重置。请看下面的例子。
下面的示例数据显示了我希望看到的第 'Backtest' 列的输出。
Time Adj_Price Final_Order Backtest
0 7 nan 1000
1 6 nan 1000
2 5 Buy 1000
3 7 Buy 1400
4 8 Sell 1600
5 6 Sell 1600
6 4 Buy 1600
7 5 Buy 2000
8 7 Buy 2800
9 9 Sell 3600
10 7 Sell 3600
11 7 Sell 3600
12 6 Sell 3600
以下是 'Backtest'.
的计算结果- 时间 1 =IF(Final_Order ="Buy(t0)",(6/7)*1000, 否则 1000) = 1000
- 时间 2 =IF(Final_Order ="Buy(t1)",(5/6)*1000, 否则 1000) = 1000
- 时间 3 =IF(Final_Order ="Buy(t2)",(7/5)*1000, 否则 1000) = 1400
- 时间 4 =IF(Final_Order ="Buy(t3)",(8/7)*1400, 否则 1400) = 1600
- 时间 5 =IF(Final_Order ="Buy(t4)",(6/8)*1600, 否则 1600) = 1600
- 时间 6 =IF(Final_Order ="Buy(t5)",(4/6)*1600, 否则 1600) = 1600
- 时间 7 =IF(Final_Order ="Buy(t6)",(5/4)*1600, 否则 1600) = 2000
- 时间 8 =IF(Final_Order ="Buy(t7)",(7/5)*2000, 否则 2000) = 2800
- 时间 9 =IF(Final_Order ="Buy(t8)",(9/7)*2800, 否则 2800) = 3600
- 时间 10 =IF(Final_Order ="Buy(t9)",(7/9)*3600,否则 3600) = 3600
下面是我正在使用的代码。
data['Backtest'] = np.where(data['Final_Order'] == 'Buy',
((1 + data['Adj
Close'].pct_change(1)).cumprod())*1000,
data['Backtest'].ffill())
创建一个列表,其初始值为 1000,具有比率和最终顺序:
b = [1000]+list(zip(df.Adj_Price.shift(-1)/df.Adj_Price,df.Final_Order))
df['BACK']=list(itertools.accumulate(b,lambda x,y: round(y[0]*x) if y[1]=="Buy" else x))[:-1]
df
Time Adj_Price Final_Order Backtest BACK
0 0 7 NaN 1000 1000
1 1 6 NaN 1000 1000
2 2 5 Buy 1000 1000
3 3 7 Buy 1400 1400
4 4 8 Sell 1600 1600
5 5 6 Sell 1600 1600
6 6 4 Buy 1600 1600
7 7 5 Buy 2000 2000
8 8 7 Buy 2800 2800
9 9 9 Sell 3600 3600
10 10 7 Sell 3600 3600
11 11 7 Sell 3600 3600
12 12 6 Sell 3600 3600
将创建的列与已经存在的列进行比较,它们是相同的