Логарифмический возврат в pandas dataframe
Python pandas имеет функцию pct_change, которую я использую для расчета возвратов цен на акции в фрейме данных:
ndf['Return']= ndf['TypicalPrice'].pct_change()
Я использую следующий код для получения логарифмических возвратов, но он дает те же самые значения, что и функция pct.change():
ndf['retlog']=np.log(ndf['TypicalPrice'].astype('float64')/ndf['TypicalPrice'].astype('float64').shift(1))
#np is for numpy
Ответы
Ответ 1
Вот один из способов расчета возврата журнала с помощью .shift()
. И результат аналогичен, но не такой, как валовой доход, рассчитанный pct_change()
. Можете ли вы загрузить копию ваших образцов данных (ссылку на общий доступ к Dropbox), чтобы воспроизвести несогласованность, которую вы видели?
import pandas as pd
import numpy as np
np.random.seed(0)
df = pd.DataFrame(100 + np.random.randn(100).cumsum(), columns=['price'])
df['pct_change'] = df.price.pct_change()
df['log_ret'] = np.log(df.price) - np.log(df.price.shift(1))
Out[56]:
price pct_change log_ret
0 101.7641 NaN NaN
1 102.1642 0.0039 0.0039
2 103.1429 0.0096 0.0095
3 105.3838 0.0217 0.0215
4 107.2514 0.0177 0.0176
5 106.2741 -0.0091 -0.0092
6 107.2242 0.0089 0.0089
7 107.0729 -0.0014 -0.0014
.. ... ... ...
92 101.6160 0.0021 0.0021
93 102.5926 0.0096 0.0096
94 102.9490 0.0035 0.0035
95 103.6555 0.0069 0.0068
96 103.6660 0.0001 0.0001
97 105.4519 0.0172 0.0171
98 105.5788 0.0012 0.0012
99 105.9808 0.0038 0.0038
[100 rows x 3 columns]
Ответ 2
Возвраты журнала - это просто естественный логарифм 1 плюс арифметический возврат. Итак, как насчет этого?
df['pct_change'] = df.price.pct_change()
df['log_return'] = np.log(1 + df.pct_change)
Ответ 3
Одиночная строка и только вычисление журналов один раз.
Сначала преобразуйте в лог-пространство, затем возьмите 1-периодный diff.
np.log(df.price).diff()
Ответ 4
Результаты могут показаться похожими, но это происходит только из-за расширения Тейлора для логарифма. Так как log (1 + x) ~ x, результаты могут быть похожими.
Однако
Я использую следующий код для получения логарифмических возвратов, но он дает те же самые значения, что и функция pct.change().
не совсем корректно.
import pandas as pd
df = pd.DataFrame({'p': range(10)})
df['pct_change'] = df.pct_change()
df['log_stuff'] = \
np.log(df['p'].astype('float64')/df['p'].astype('float64').shift(1))
df[['pct_change', 'log_stuff']].plot();
![enter image description here]()
Ответ 5
@poulter7:
Я не могу комментировать другие ответы, поэтому я отправляю его как новый ответ: будьте осторожны с
np.log(df.price).diff()
так как это приведет к сбою для индексов, которые могут стать отрицательными, а также факторы риска, например. отрицательные процентные ставки. В этих случаях
np.log(df.price/df.price.shift(1)).dropna()
является предпочтительным и на основе моего опыта, как правило, более безопасного подхода. Он также оценивает логарифм только один раз.
Если вы используете +1 или -1, это зависит от порядка ваших временных рядов. Используйте -1 для нисходящего и +1 для восходящих дат - в обоих случаях сдвиг предоставляет предыдущее значение даты.