使用Pandas转换为多索引

时间:2018-01-13 02:15:51

标签: python python-2.7 pandas

我正在尝试制作一个简单的股票投资组合跟踪器。我从10万美元开始,并根据两只股票的权重进行投资。每个月,我想出售股票,然后设定新的起始美元(上期购买的股票*当前价格),并根据这个月的权重再次投资两只股票。

我想出了如何计算每个时期购买的股票,这要归功于之前的一些SO帮助,但我很难更新每个日期的起始余额。我认为由于操作的顺序,它需要作为循环完成,但无法让转变工作。

开始我的代码:

import pandas as pd
from datetime import datetime

df = pd.DataFrame(data=[[datetime(year=2017, day=01, month=01), 100000, 'AAPL', 0.6, 1000],
                        [datetime(year=2017, day=01, month=01), 100000, 'GOOG', 0.4, 1200],
                        [datetime(year=2017, day=01, month=02), 100000, 'AAPL', 0.7, 1400],
                        [datetime(year=2017, day=01, month=02), 100000, 'GOOG', 0.3, 1300],
                        [datetime(year=2017, day=01, month=03), 100000, 'AAPL', 0.8, 980],
                        [datetime(year=2017, day=01, month=03), 100000, 'GOOG', 0.2, 1400]
                        ],
                  columns=['Date', 'Dollars Available', 'Stock', 'Weight', 'Price'])

df = df.set_index(['Date', 'Dollars Available', 'Stock'])
df['Shares Bought'] = (df.index.get_level_values('Dollars Available') * df['Weight']).values / df['Price'].values

到目前为止,我已经到了这里。如您所见,每个日期的起始余额都相同。

                                    Weight  Price  Shares Bought
Date       Dollars Available Stock                              
2017-01-01 100000            AAPL      0.6   1000      60.000000
                             GOOG      0.4   1200      33.333333
2017-02-01 100000            AAPL      0.7   1400      50.000000
                             GOOG      0.3   1300      23.076923
2017-03-01 100000            AAPL      0.8    980      81.632653
                             GOOG      0.2   1400      14.285714

期望的输出:

                                        Weight  Price  Shares Bought
Date       Dollars Available Stock                              
2017-01-01 10000.00          AAPL      0.6   1000          60.00
                             GOOG      0.4   1200          33.33
2017-02-01 127333.33         AAPL      0.7   1400          63.66
                             GOOG      0.3   1300          29.38
2017-03-01 103531.79         AAPL      0.8    980          73.95
                             GOOG      0.2   1400          22.19

2 个答案:

答案 0 :(得分:1)

考虑以这种方式组织您的数据(我已经离开了2017-03-01,因为您没有显示该日期的价格,这使得示例更简洁):

Date        AAPL Return  GOOG Return  AAPL Weight  GOOG Weight
2017-01-01          1.4        1.083          0.6          0.4
2017-02-01          0.7        1.077          0.7          0.3

以上,回报是(收盘价/开盘价)。

现在每个股票相乘:

Date        AAPL WgtRet  GOOG WgtRet  Sum WgtRet  Cum WgtRet
2017-01-01         0.84       0.4332      1.2732      1.2732
2017-02-01         0.49       0.3231      0.8131      1.0352

在上面,Sum WgtRet就像sum(axis = 1),而Cum WgtRet就像cumprod(Sum WgtRet)。

现在,只需拿起你的起始资本并乘以Cum WgtRet即可获得月末余额:

Date        End Balance
2017-01-01  127320
2017-02-01  103520

上述每个操作都很容易以矢量化形式完成,没有循环。你可以" pivot"从行标签到开头的列标签的库存列。

如果你想添加"买入的股票"列,只需移动(1)结束余额以生成开始余额列,然后乘以权重。

答案 1 :(得分:0)

这是一种计算美元的方法

df['New1']=((1+df.groupby('Stock').Price.pct_change())).shift(-2)*df.Weight

df.groupby('Date').New1.sum().cumprod().mul(100000).shift().fillna(100000)
Out[288]: 
Date
2017-01-01    100000.000000
2017-02-01    127333.333333
2017-03-01    103531.794872
Name: New1, dtype: float64