我一直在靠墙试图找出这个问题的最佳方法。我在Excel中有一个SLOW backtester,我正在尝试移植到pandas。我以为我能够利用python的强大功能,而不仅仅是在python中重新创建Excel函数,但我被卡住了!
关键的挑战在于随着时间的推移,对多个和动态变化的仪器进行投资组合P& L计算。例如,根据标准,我想在前N个时期购买工具A和C.然后我想在接下来的N个时期使用B和C.等等。我想根据当前股权购买每种工具的比例金额(而不是每次购买100股股票)。
Excel,基于行的功能首先根据初始权益计算股票,然后根据“前一行”中可用的权益计算股票。类似于: IF(RebalancePeriod = TRUE,EquityFromPrevRow / CurrentSharePrice,PreviousRowShares)
尝试熊猫吃它。以下是示例输入:
import datetime as dt
import pandas as pd
from pandas import *
dates = date_range('1/1/2000', periods=6)
index=dates
data = {'A': pd.Series([20, 30, 10, 0, 0, 0], index=index)
, 'B': pd.Series([0, 0, 0, 50, 51, 52], index=index)
, 'C': pd.Series([11, 12, 20, 18, 17, 19], index=index)}
initial_capital = 5000.0
prices = pd.DataFrame(data, index=dates)
这不会让你走得太远,但这里是所需的输出。在这个例子中,我想通过在第4行(2000-01-04)从A到B交换来重新平衡工具,其中A = 0。
Prices
A B C
2000-01-01 20 0 11
2000-01-02 30 0 12
2000-01-03 10 0 20
2000-01-04 0 50 18
2000-01-05 0 51 17
2000-01-06 0 52 19
Shares (initial or current equity / price)
A B C
2000-01-01 250.0 0.0 454.5
2000-01-02 250.0 0.0 454.5
2000-01-03 250.0 0.0 454.5
2000-01-04 0.0 115.9 322.0
2000-01-05 0.0 115.9 322.0
2000-01-06 0.0 115.9 322.0
Equity (shares * price)
A B C Total
2000-01-01 5,000.0 0.0 5,000.0 10,000.0
2000-01-02 7,500.0 0.0 5,454.5 12,954.5
2000-01-03 2,500.0 0.0 9,090.9 11,590.9
2000-01-04 0.0 5,795.5 5,795.5 11,590.9
2000-01-05 0.0 5,911.4 5,473.5 11,384.8
2000-01-06 0.0 6,027.3 6,117.4 12,144.7
我意识到这一点有很多。我感谢任何帮助。谢谢。
答案 0 :(得分:1)
只需遵循您在Excel
中所做的相同想法,唯一的区别是应用于每一行的excel function
现在表示为循环:
In [113]:
print prices
A B C
2000-01-01 20 0 11
2000-01-02 30 0 12
2000-01-03 10 0 20
2000-01-04 0 50 18
2000-01-05 0 51 17
2000-01-06 0 52 19
In [114]:
swap=pd.Series([False,]*len(dates),index=dates, name='sawp')
swap[3]=True
total=pd.DataFrame({'A':0, 'B':0, 'C':0},index=dates)
total.ix[0]=[5000,5000,5000]
shares=total/prices
shares['swap']=swap
In [115]:
#the loop
for idx in range(1, len(shares)):
if shares.ix[idx, 'swap']:
shares.ix[idx, ['A','B','C']]=(shares.ix[idx-1, ['A','B','C']]*prices.ix[idx-1]).sum()/2/prices.ix[idx]
else:
shares.ix[idx, ['A','B','C']]=shares.ix[idx-1, ['A','B','C']]
In [116]:
#Get rid of the infinite numbers
shares[shares==np.inf]=0
In [117]:
print shares
A B C swap
2000-01-01 250 0.000000 454.545455 False
2000-01-02 250 0.000000 454.545455 False
2000-01-03 250 0.000000 454.545455 False
2000-01-04 0 115.909091 321.969697 True
2000-01-05 0 115.909091 321.969697 False
2000-01-06 0 115.909091 321.969697 False
In [118]:
print shares*prices
A B C swap
2000-01-01 5000 0.000000 5000.000000 NaN
2000-01-02 7500 0.000000 5454.545455 NaN
2000-01-03 2500 0.000000 9090.909091 NaN
2000-01-04 0 5795.454545 5795.454545 NaN
2000-01-05 0 5911.363636 5473.484848 NaN
2000-01-06 0 6027.272727 6117.424242 NaN
In [119]:
#Total asserts
print (shares*prices).sum(1)
2000-01-01 10000.000000
2000-01-02 12954.545455
2000-01-03 11590.909091
2000-01-04 11590.909091
2000-01-05 11384.848485
2000-01-06 12144.696970
Freq: D, dtype: float64