2015-02-05 6 views
9

Существует объект Pandas DataFrame с некоторыми данными запаса. SMA - скользящие средние, рассчитанные с предыдущих 45/15 дней.Python and Pandas - Скользящий средний кроссовер

Date  Price SMA_45  SMA_15 
20150127 102.75 113   106 
20150128 103.05 100   106 
20150129 105.10 112   105 
20150130 105.35 111   105 
20150202 107.15 111   105 
20150203 111.95 110   105 
20150204 111.90 110   106 

Я хочу найти все даты, когда SMA_15 и SMA_45 пересекаются.

Можно ли эффективно использовать Pandas или Numpy? Как?

РЕДАКТИРОВАТЬ:

Что я имею в виду 'пересечения':

строке данных, когда:

(45) Значение
  • длиной SMA была больше, чем короткий SMA (15) значение дольше, чем короткий период SMA (15), и он стал меньше.
  • Значения длинной SMA (45) были меньше короткого значения SMA (15) дольше, чем короткий период SMA (15), и он стал больше.
+2

Что это значит для SMA_15 и SMA_45 пересекаться на определенную дату? (В вашем примере SMA_45> SMA_15 везде, поэтому, похоже, нет хорошего кандидата.) – DSM

+0

Если «intersect» вы имеете в виду, где они одинаковы в одну и ту же дату, тогда просто использовать булевское индексирование , 'df [df.sma_15 == df.sma_45]'. –

+0

Это просто кусочек данных из случайного запаса. – chilliq

ответ

12

Я принимаю кроссовер означать, когда линии SMA - как функции времени - пересекаются, как показано на this investopedia page.

enter image description here

Поскольку СМА представляют собой непрерывные функции, есть пересечение, когда, для данной строки, (SMA_15 меньше SMA_45) и (предыдущий SMA_15 является больше, чем предыдущий SMA_45) - или наоборот.

В коде, который может быть выражен как

previous_15 = df['SMA_15'].shift(1) 
previous_45 = df['SMA_45'].shift(1) 
crossing = (((df['SMA_15'] <= df['SMA_45']) & (previous_15 >= previous_45)) 
      | ((df['SMA_15'] >= df['SMA_45']) & (previous_15 <= previous_45))) 

Если изменить свои данные

Date  Price SMA_45  SMA_15 
20150127 102.75 113   106 
20150128 103.05 100   106 
20150129 105.10 112   105 
20150130 105.35 111   105 
20150202 107.15 111   105 
20150203 111.95 110   105 
20150204 111.90 110   106 

так что есть переходы,

enter image description here

затем

import pandas as pd 

df = pd.read_table('data', sep='\s+') 
previous_15 = df['SMA_15'].shift(1) 
previous_45 = df['SMA_45'].shift(1) 
crossing = (((df['SMA_15'] <= df['SMA_45']) & (previous_15 >= previous_45)) 
      | ((df['SMA_15'] >= df['SMA_45']) & (previous_15 <= previous_45))) 
crossing_dates = df.loc[crossing, 'Date'] 
print(crossing_dates) 

дает

1 20150128 
2 20150129 
Name: Date, dtype: int64 
Смежные вопросы