Расчет Собственного Капитала На Основе Динамических Строк Pandas



Я бился головой о стену, пытаясь найти наилучший подход к этому вопросу. У меня медленный тестирования в Excel, который я пытаюсь порт для панд. Я думал, что смогу использовать мощь python, а не просто воссоздавать функции Excel в python, но я застрял!



Ключевая проблема заключается в расчете портфеля P&L для нескольких и динамически изменяющихся инструментов с течением времени. Например, основываясь на критериях, я хочу купить инструмент A и C для первые N периодов. Затем я хочу использовать B и C для следующих N периодов. И так далее. Я хочу покупать пропорциональные суммы каждого инструмента на основе текущего капитала (в отличие от покупки 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)


Это не приведет вас очень далеко, но вот желаемые результаты. В этом примере я хочу перебалансировать инструменты, поменяв их местами с A на B в 4-м ряду, 2000-01-04, где 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


Я понимаю, что в этом много чего есть. Я ценю любую помощь. Спасибо.

456   1  

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

Comments

    Ничего не найдено.