2016-05-25 16 views
4

Ich habe tägliche Renditen von drei Märkten (GLD, SPY und USO). Mein Ziel ist es, die durchschnittliche paarweise Korrelation aus einer Korrelationsmatrix auf rollierender Basis von 130 Tagen zu berechnen.Rollierende durchschnittliche paarweise Korrelation in Python

Mein Ausgangspunkt war:

import numpy as np 
import pandas as pd 
import os as os 
import pandas.io.data as web 
import datetime as datetime 
from pandas.io.data import DataReader 

stocks = ['spy', 'gld', 'uso'] 
start = datetime.datetime(2010,1,1) 
end = datetime.datetime(2016,1,1) 

df = web.DataReader(stocks, 'yahoo', start, end) 
adj_close_df = df['Adj Close'] 

returns = adj_close_df.pct_change(1).dropna() 
returns = returns.dropna() 

rollingcor = returns.rolling(130).corr() 

Diese eine Gruppe von Korrelationsmatrizen erzeugt. Das Extrahieren der unteren (oder oberen) Dreiecke, das Entfernen der Diagonalen und dann das Berechnen des Durchschnitts für jede Beobachtung ist jedoch, wo ich eine Leerstelle gezeichnet habe. Idealerweise möchte ich, dass die Ausgabe für jedes Datum in einer Serie ist, in der ich sie dann nach den Daten indizieren kann.

Vielleicht habe ich von der falschen Stelle gestartet, aber jede Hilfe wäre willkommen.

+0

Mit durchschnittlicher Korrelation meinen Sie einen Durchschnitt von 3 Werten in diesem Fall für jedes Datum? (alle paarweisen Kombinationen) – aldanor

+0

Ja der Durchschnitt der 3 Werte. – Joe

Antwort

3

Um die durchschnittliche paarweise Korrelation zu erhalten, können Sie die Summe der Korrelationsmatrix finden, subtrahieren n (Einsen auf der Diagonalen), dividieren durch 2 (Symmetrie) und schließlich dividieren durch n (Durchschnitt). Ich denke, das sollte es tun:

>>> n = len(stocks) 
>>> ((rollingcor.sum(skipna=0).sum(skipna=0) - n)/2)/n 
Date 
2010-01-05   NaN 
2010-01-06   NaN 
2010-01-07   NaN 
       ... 
2015-12-29 0.164356 
2015-12-30 0.168102 
2015-12-31 0.166462 
dtype: float64 
+0

Ausgezeichnet! Lief wie am Schnürchen. Vielen Dank! – Joe

1

Sie numpy ‚s nutzen könnten tril das untere Dreieck des Datenrahmen zuzugreifen.

def tril_sum(df): 
    # -1 ensures we skip the diagonal 
    return np.tril(df.unstack().values, -1).sum() 

Berechnet die Summe des unteren Dreiecks der Matrix. Beachten Sie die unstack() in der Mitte davon. Ich erwarte eine Multiindex-Serie, die ich in einen Datenrahmen pivotieren muss.

dann gilt es zu Ihrem Panel

n = len(stock) 
avg_cor = rollingcor.dropna().to_frame().apply(tril_sum)/((n ** 2 - n)/2) 

Sieht aus wie:

print avg_cor.head() 

Date 
2010-07-12 0.398973 
2010-07-13 0.403664 
2010-07-14 0.402483 
2010-07-15 0.403252 
2010-07-16 0.407769 
dtype: float64 

Diese Antwort, die die Diagonalen überspringt.

+0

Danke! Funktioniert auch für mich. Vielen Dank. – Joe