2015-02-05 9 views
9

C'è un oggetto DataFrame di Pandas con alcuni dati di magazzino. Le SMA sono medie mobili calcolate dai precedenti 45/15 giorni.Python and Pandas - Moving Average Crossover

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 

Voglio trovare tutte le date, quando SMA_15 e SMA_45 si intersecano.

Può essere fatto in modo efficiente con Pandas o Numpy? Come?

EDIT:

Cosa intendo per 'intersezione':

La riga di dati, quando:

  • lungo SMA (45) valore era più grande di breve SMA (15) valore per un periodo SMA più lungo di quello breve (15) e si è ridotto.
  • Il valore SMA lungo (45) era inferiore al valore SMA breve (15) per un periodo SMA più lungo del breve (15) ed è diventato più grande.
+2

Cosa significa per SMA_15 e SMA_45 ad intersecano in una certa data? (Nel tuo esempio SMA_45> SMA_15 ovunque, quindi non sembra essere un buon candidato.) – DSM

+0

Se per "intersecare" vuoi dire dove sono gli stessi nella stessa data, allora è una semplice questione di usare l'indicizzazione booleana come in questo modo , 'df [df.sma_15 == df.sma_45]'. –

+0

È solo un pezzo di dati da magazzino casuale. – chilliq

risposta

12

mi sto prendendo un crossover per indicare quando le linee SMA - in funzione del tempo - si intersecano, come raffigurato sulla this investopedia page.

enter image description here

Poiché le SMA rappresentano funzioni continue, c'è un incrocio quando, per una determinata riga, (SMA_15 è inferiore SMA_45) e (il precedente SMA_15 è maggiore del precedente SMA_45) - o vice versa.

In codice, che potrebbe essere espresso come

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))) 

Se cambiamo i vostri dati per

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 

modo che non ci sono incroci,

enter image description here

poi

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) 

cede

1 20150128 
2 20150129 
Name: Date, dtype: int64