Вычисление возвратов из фрейма данных с финансовыми данными

У меня есть дата-фрейм с ежемесячными финансовыми данными:

In [89]: vfiax_monthly.head()
Out[89]: 
            year  month  day       d   open  close   high    low  volume  aclose
2003-01-31  2003      1   31  731246  64.95  64.95  64.95  64.95       0   64.95
2003-02-28  2003      2   28  731274  63.98  63.98  63.98  63.98       0   63.98
2003-03-31  2003      3   31  731305  64.59  64.59  64.59  64.59       0   64.59
2003-04-30  2003      4   30  731335  69.93  69.93  69.93  69.93       0   69.93
2003-05-30  2003      5   30  731365  73.61  73.61  73.61  73.61       0   73.61

Я пытаюсь рассчитать доходность так:

In [90]: returns = (vfiax_monthly.open[1:] - vfiax_monthly.open[:-1])/vfiax_monthly.open[1:]

Но я'м получаю только нули:

In [91]: returns.head()
Out[91]: 
2003-01-31   NaN
2003-02-28     0
2003-03-31     0
2003-04-30     0
2003-05-30     0
Freq: BM, Name: open

Я думаю что's, потому что арифметические операции выровнены по индексу, и это делает[1:] а также[:-1] бесполезный.

Мой обходной путь:

In [103]: returns = (vfiax_monthly.open[1:].values - vfiax_monthly.open[:-1].values)/vfiax_monthly.open[1:].values

In [104]: returns = pd.Series(returns, index=vfiax_monthly.index[1:])

In [105]: returns.head()
Out[105]: 
2003-02-28   -0.015161
2003-03-31    0.009444
2003-04-30    0.076362
2003-05-30    0.049993
2003-06-30    0.012477
Freq: BM

Есть ли лучший способ рассчитать прибыль? Я неТ как преобразование в массив, а затем обратно в серию.

Ответы на вопрос(4)

Можно также использовать смесьdiff а такжеshift методы серии панд:

retrun = vfiax_monthly.open.diff()/vfiax_monthly.open.shift(1)

вероятности предвзятости - использовать встроенную функциюpd.DataFrame.pct_change(), В вашем случае все, что вам нужно использовать, это эта функция, так как у вас есть ежемесячные данные, и вы ищете ежемесячный доход.

Если, к примеру, вы хотите посмотреть на возвращение 6 месяцев, вы просто установите параметрdf.pct_change(periods = 6) и это даст вам 6-месячный процент возврата.

Поскольку у вас сравнительно небольшой набор данных, самый простой способ - это выполнить повторную выборку параметров, по которым необходимо рассчитать данные, а затем использоватьpct_change() функционировать снова.

Однако из-за хороших свойствlog Обычно используется формула для расчета доходности (если вы планируете делать статистику по серии возвращаемых данных):

Что бы вы реализовали как таковое:

log_return = np.log(vfiax_monthly.open / vfiax_monthly.open.shift())

 Henry Henrinson23 апр. 2018 г., 23:26
само собой" лол..
Решение Вопроса

Вместо нарезки используйте.shift для перемещения позиции индекса значений в DataFrame / Series. Например:

returns = (vfiax_monthly.open - vfiax_monthly.open.shift(1))/vfiax_monthly.open.shift(1)

Это то, чтоpct_change делает под капотом. Вы также можете использовать его для других функций, например:

(3*vfiax_monthly.open + 2*vfiax_monthly.open.shift(1))/5

Вы также можете посмотреть впрокатка а такжеокно функции для других видов анализа финансовых данных.

 Daniel Velkov15 нояб. 2012 г., 03:21
Тот'это то, что я искал!
 DonCristobal07 июл. 2015 г., 00:55
Я думаю, что первая строка должна выглядеть следующим образом: Return = (vfiax_monthly.open - vfiax_monthly.open.shift (1)) / vfiax_monthly.open.shift (1)

ange ().

Вот быстрый пример

In[1]: aapl = get_data_yahoo('aapl', start='11/1/2012', end='11/13/2012')

In[2]: appl
Out[2]: 
          Open    High     Low   Close    Volume  Adj Close
Date                                                           
2012-11-01  598.22  603.00  594.17  596.54  12903500     593.83
2012-11-02  595.89  596.95  574.75  576.80  21406200     574.18
2012-11-05  583.52  587.77  577.60  584.62  18897700     581.96
2012-11-06  590.23  590.74  580.09  582.85  13389900     580.20
2012-11-07  573.84  574.54  555.75  558.00  28344600     558.00
2012-11-08  560.63  562.23  535.29  537.75  37719500     537.75
2012-11-09  540.42  554.88  533.72  547.06  33211200     547.06
2012-11-12  554.15  554.50  538.65  542.83  18421500     542.83
2012-11-13  538.91  550.48  536.36  542.90  19033900     542.90

In[3]: aapl.pct_change()
Out[3]:
                Open      High       Low     Close    Volume  Adj Close
Date                                                                   
2012-11-01       NaN       NaN       NaN       NaN       NaN        NaN
2012-11-02 -0.003895 -0.010033 -0.032684 -0.033091  0.658945  -0.033090
2012-11-05 -0.020759 -0.015378  0.004959  0.013558 -0.117186   0.013550
2012-11-06  0.011499  0.005053  0.004311 -0.003028 -0.291453  -0.003024
2012-11-07 -0.027769 -0.027423 -0.041959 -0.042635  1.116864  -0.038263
2012-11-08 -0.023020 -0.021426 -0.036815 -0.036290  0.330747  -0.036290
2012-11-09 -0.036049 -0.013073 -0.002933  0.017313 -0.119522   0.017313
2012-11-12  0.025406 -0.000685  0.009237 -0.007732 -0.445323  -0.007732
2012-11-13 -0.027502 -0.007250 -0.004251  0.000129  0.033244   0.000129
 Daniel Velkov14 нояб. 2012 г., 22:08
Мне нравится это решение. Но это'специфичен для моего варианта использования. Что, если я хочу вычислить среднее значение между каждой парой месяцев (или чем-то сложным, у которого нет встроенной функции панд):(vfiax_monthly.open[1:] - vfiax_monthly.open[:-1])/2
 Matti John15 нояб. 2012 г., 01:53
(vfiax_monthly.open [1:] - vfiax_monthly.open [: - 1]) / vfiax_monthly.open [1:] - это не процентное изменение, а возврат инвестиций. Процентное изменение - это текущая строка, разделенная на предыдущую, что будет эквивалентно vfiax_monthly.open [1:] / vfiax_monthly.open [: - 1] -1, поэтому в любом случае pct_change () будет неправильным.
 spencerlyon214 нояб. 2012 г., 22:49
Не могли бы вы добавить примерчто-то сложное на оригинальный пост? Предполагая, что у вас былDateTimeIndex с регулярной частотой вы всегда можете использоватьdf.resample агрегировать данные с другой регулярной частотой (как каждые два месяца), а затем использоватьdf.pct_change() чтобы получить прибыль. Также есть различные вариантыpct_change()  [увидеть ,periodsfreq], которые позволяют указать, сколько точек данных следует использовать для вычисления результатов (periods по умолчанию равен 1, поэтому решение дало тот же ответ, что и ваша функция).
 Daniel Velkov15 нояб. 2012 г., 00:28
(vfiax_monthly.open[1:] + vfiax_monthly.open[:-1])/2 был пример, хотя, может быть, естькакая-то оконная функция. Но давайскажи мне нужно:(3*vfiax_monthly.open[1:] + 2*vfiax_monthly.open[:-1])/5, Сейчас я'м, понимая, что выбор индекса результата является произвольным, так что, возможно, магическая функция, которую яищу не существует.

Ваш ответ на вопрос