пользовательская функция groupby Rolling agg для бета-версии портфолио - PullRequest
1 голос
/ 26 мая 2020

Спасибо за чтение и заранее за любые ответы.

Бета - это мера систематического c риска инвестиционного портфеля. Он рассчитывается путем взятия ковариации доходности этого портфеля ios по сравнению с эталоном / рынком и деления ее на дисперсию рынка. Я хотел бы вычислить c это на постоянной основе для многих портфелей ios.

У меня есть df следующим образом

PERIOD,PORT1,PORT2,BM
201504,-0.004,-0.001,-0.013
201505,0.017,0.019,0.022
201506,-0.027,-0.037,-0.039
201507,0.026,0.033,0.017
201508,-0.045,-0.054,-0.081
201509,-0.033,-0.026,-0.032
201510,0.053,0.07,0.09
201511,0.03,0.032,0.038
201512,-0.05,-0.034,-0.044
201601,-0.016,-0.043,-0.057
201602,-0.007,-0.007,-0.011
201603,0.014,0.014,0.026
201604,0.003,0.001,0.01
201605,0.046,0.038,0.031

За исключением многих других столбцов, таких как port1 и порт2.

Я хотел бы создать набор данных с скользящей бета-версией по столбцу BM.

Я создал аналогичный набор данных скользящей корреляции с

df.rolling(3).corr(df['BM'])

..., который взял каждый столбец в моем большом наборе и рассчитал корреляцию с моим столбцом BM.

Я попытался создать специальную функцию для бета-версии, но из-за того, что она требует двух аргументов, я борюсь. Ниже представлена ​​моя пользовательская функция и то, как я заставил ее работать, скармлив ей два столбца возвратов.

    def beta(arr1,arr2):
    #ddof = 0 gives population covar. the 0 and 1 coordinates take the arr1 vs arr2 covar from the matrix
    return (np.cov(arr1,arr2,ddof=0)[0][1])/np.var(arr2)

    beta_test = beta(df['PORT1'],df['BM'])

Таким образом, это помогает мне найти бета-версию между двумя столбцами, которые я использую ... Вопрос в том, как это сделать для моих данных выше и данных с большим количеством столбцов / портфелей ios? И как тогда делать это постоянно? Из того, что я видел выше с корреляцией, должно быть возможно следующее: запускать каждый трехмесячный набор данных в каждом столбце по сравнению с одним указанным столбцом.

beta_data = df.rolling(3).agg(beta(df['BM']))

Любой указатель в правильном направлении приветствуется

Ответы [ 2 ]

1 голос
/ 26 мая 2020

IIU C, вы можете set_index столбцы PERIOD и BM, filter столбец с PORT в нем (в случае, если у вас есть другие столбцы, которые вы не хотите применять функцию beta), затем используйте rolling.apply например:

print (df.set_index(['PERIOD','BM']).filter(like='PORT')
         .rolling(3).apply(lambda x: beta(x, x.index.get_level_values(1)))
         .reset_index())
    PERIOD     BM     PORT1     PORT2
0   201504 -0.013       NaN       NaN
1   201505  0.022       NaN       NaN
2   201506 -0.039  0.714514  0.898613
3   201507  0.017  0.814734  1.055798
4   201508 -0.081  0.736486  0.907336
5   201509 -0.032  0.724490  0.887755
6   201510  0.090  0.598332  0.736964
7   201511  0.038  0.715848  0.789221
8   201512 -0.044  0.787248  0.778703
9   201601 -0.057  0.658877  0.794949
10  201602 -0.011  0.412270  0.789567
11  201603  0.026  0.354829  0.690573
12  201604  0.010  0.562924  0.558083
13  201605  0.031  1.716066  1.530471
0 голосов
/ 26 мая 2020
def getbetas(df, market, window = 45):
    """ given an unstacked pandas dataframe (columns instruments, rows
    dates), compute the rolling betas vs the market.
    """
    nmarket = market/market.rolling(window).var()
    thebetas = df.rolling(window).cov(other=nmarket)
    return thebetas
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...