Python 使用多索引移位
我一直在尝试制作一个简单的股票组合跟踪器。我从10万美元开始,根据权重投资两支股票。每个月,我都想卖出这只股票,然后设定新的起始美元(上期买入的股票*当前价格),然后根据这个月的权重再次投资这两只股票 由于之前的一些帮助,我知道了如何计算每个时期购买的股票,但我很难更新每个日期的起始余额。我认为,由于操作顺序的原因,它需要作为一个循环来完成,但是很难让轮班工作 开始我的代码:Python 使用多索引移位,python,python-2.7,pandas,Python,Python 2.7,Pandas,我一直在尝试制作一个简单的股票组合跟踪器。我从10万美元开始,根据权重投资两支股票。每个月,我都想卖出这只股票,然后设定新的起始美元(上期买入的股票*当前价格),然后根据这个月的权重再次投资这两只股票 由于之前的一些帮助,我知道了如何计算每个时期购买的股票,但我很难更新每个日期的起始余额。我认为,由于操作顺序的原因,它需要作为一个循环来完成,但是很难让轮班工作 开始我的代码: import pandas as pd from datetime import datetime df = pd.D
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
考虑以这种方式组织您的数据(我已经省略了2017-03-01,因为您没有显示该日期的价格,这使示例更加简洁): 以上,返回为(收盘价/开盘价) 现在乘以每只股票:
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(轴=1),Cum WgtRet类似于cumprod(Sum WgtRet)
现在,只需将您的起始资本乘以Cum WgtRet即可得到月末余额:
Date End Balance
2017-01-01 127320
2017-02-01 103520
上面的每个操作都很容易以矢量化的形式完成,没有循环。您可以在开始时将库存列从行标签“轴心”到列标签
如果要添加“购买的股份”列,只需移动(1)结束余额以创建开始余额列,然后乘以权重。这是计算美元的一种方法
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
非常感谢。这看起来很有希望,但远高于我的技能水平。什么是获得数据的最佳方法,甚至可以像您的第一个数据帧那样设置数据?我的想法是使用类似于
df.groupby(['Stock'])['Price'].shift(-1)/df.groupby(['Stock'])['Price']
的东西,但是在创建数据帧之后,我遇到了错误,请执行df.set_index(['Date',Stock'],inplace=True)
然后df.Weight.unstack()
获取每只股票的权重,px=df.Price.unstack()
获取价格,然后px/px.shift()
获取返回值。将每个新列添加到索引仅为Date的单个数据框中。谢谢。我做错了什么?我只看到前两行。@user2242044-ummm。前两排是什么意思?对不起,没关系。当我尝试你的代码时,我把df缩短到了两个月。只是我很傻:)@user2242044啊哈,编码很开心
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