2016-10-24 1 views
1

Massive Bearbeitung:Iterating Through Zeitserien an einem Tag

Ok, so habe ich eine Zeitreihe Datenrahmen auf der Minute Ebene. Zum Beispiel ist dieser Datenrahmen ein Jahr lang Daten. Ich versuche ein analytisches Modell zu erstellen, das diese Daten Tag für Tag durchläuft.

Die Funktion wird: 1) Schneiden Sie einen Tag Daten aus dem Datenrahmen. 2) Erstellen Sie eine 30-minütige Teilscheibe des Tagesschnitts (der ersten 30 Minuten des Tages). 3) Übergeben Sie die Daten aus beiden Schichten durch den analytischen Teil der Funktion. 4) An neuen Datenrahmen anhängen. 5) Iterationen bis zum Abschluss fortsetzen.

Der Datenrahmen ist in folgendem Format:

      open_price high low close_price volume  price 
2015-01-06 14:31:00+00:00 46.3800 46.440 46.29 46.380 560221.0 46.380 
2015-01-06 14:32:00+00:00 46.3800 46.400 46.30 46.390 52959.0  46.390 
2015-01-06 14:33:00+00:00 46.3900 46.495 46.36 46.470 100100.0 46.470 
2015-01-06 14:34:00+00:00 46.4751 46.580 46.41 46.575 85615.0  46.575 
2015-01-06 14:35:00+00:00 46.5800 46.610 46.53 46.537 78175.0  46.537 

Es scheint mir, dass datetimeindex Funktionalitäten sind der beste Weg, Pandas zu dieser Aufgabe zu gehen, aber ich habe keine Ahnung, wo ich anfangen soll.

(1) Scheint so, als könnte ich die .Rollforward-Funktionalität verwenden, beginnend mit dem df-Startdatum/-zeit, und einen Tag vorwärts durch jede Iteration rollen.

(2) Verwenden Sie eine df.loc [Maske], um den Subslice zu erstellen.

Ich bin ziemlich sicher, dass ich es nach (2) herausfinden kann, aber wieder bin ich nicht sehr vertraut mit Zeitreihenanalyse oder pandas datetimeindex Funktionalitäten.

Finale Datenrahmen:

   high  low retrace time 
2015-01-06 46.440 46.29 True  47 
2015-01-07 46.400 46.30 True  138 
2015-01-08 46.495 46.36 False NaN 
2015-01-09 46.580 46.41 True  95 
2015-01-10 46.610 46.53 False NaN 

High = Hoch von ersten 30 Minuten des Tages

Low = Tiefsttemperatur ersten 30 Minuten des Tages

Retrace = Boolean, zurückgegeben, wenn der Preis in dem offenen Preis zu einem bestimmten Zeitpunkt während des Tages nach den ersten 30 Minuten.

Zeit = Die Zeit (Minuten), die zum Zurückverfolgen benötigt wurde.

Hier ist mein Code, der scheint zu funktionieren (bedankt sich bei allen für Ihre Hilfe!):

sample = msft_prices.ix[s_date:e_date] 
sample = sample.resample('D').mean() 
sample = sample.dropna() 
sample = sample.index.strftime('%Y-%m-%d') 
ORTDF = pd.DataFrame() 
ORDF = pd.DataFrame() 
list1 = [] 
list2 = [] 
def hi_lo(prices): 

     for i in sample: 
      list1 = [] 
      if i in prices.index: 

       ORTDF = prices[i+' 14:30':i+' 15:00'] 
       ORH = max(ORTDF['high']) #integer value 
       ORHK = ORTDF['high'].idxmax() 
       ORL = min(ORTDF['low']) #integer value 
       ORLK = ORTDF['low'].idxmin() 
       list1.append(ORH) 
       list1.append(ORL) 



       if ORHK < ORLK: 
        dailydf = prices[i+' 14:30':i+' 21:00'] 
        if max(dailydf['high']) > ORH: 
         ORDH = max(dailydf['high']) 
         ORDHK = dailydf['high'].idxmax() 
         touched = 1 
         time_to_touch = ORDHK - ORHK 
         time_to_touch = time_to_touch.total_seconds()/60 
         list1.append(touched) 
         list1.append(time_to_touch) 
         list2.append(list1) 
        else: 
         touched = 0 
         list1.append(touched) 
         list1.append('NaN') 
         list2.append(list1) 
       elif ORHK > ORLK: 
        dailydf = prices[i+' 14:30':i+' 21:00'] 
        if min(dailydf['low']) < ORL: 
         ORDL = min(dailydf['low']) 
         ORDLK = dailydf['low'].idxmin() 
         touched = 1 
         time_to_touch = ORDLK - ORLK 
         time_to_touch = time_to_touch.total_seconds()/60 
         list1.append(touched) 
         list1.append(time_to_touch) 
         list2.append(list1) 
        else: 
         touched = 0 
         list1.append(touched) 
         list1.append('NaN') 
         list2.append(list1) 


      else: 
       pass 


     ORDF = pd.DataFrame(list2, columns=['High', 'Low', 'Retraced', 'Time']).set_index([sample]) 
     return ORDF 

Dies ist wahrscheinlich nicht die eleganteste Weg zu gehen darüber, aber hey, es funktioniert!

+2

Tipp: Verwenden Sie keinen Jargon!Die meisten Menschen hier werden finanzielle Terminologie nicht verstehen. Es ist nicht wirklich klar, was dein Problem ist. –

+3

Sie würden viel besser durch ein minimales, vollständiges und verifiziertes Beispiel versorgt werden. http://stackoverflow.com/help/mcve – piRSquared

+0

Hmm ... sollte ich von vorne anfangen? – supernoob

Antwort

1

lesen the docs für allgemeine Referenz

Setup (das nächste Mal diese bitte geben, sich in der Frage!):

dates = pd.to_datetime(['19 November 2010 9:01', '19 November 2010 9:02', '19 November 2010 9:03', 
         '20 November 2010 9:05', '20 November 2010 9:06', '20 November 2010 9:07']) 
df = pd.DataFrame({'low_price': [1.2, 1.8, 1.21, 2., 4., 1.201], 
        'high_price': [3., 1.8, 1.21, 4., 4.01, 1.201]}, index=dates) 
df 

        high_price low_price 
2010-11-19 09:01:00  3.000 1.200 
2010-11-19 09:02:00  1.800 1.800 
2010-11-19 09:03:00  1.210 1.210 
2010-11-20 09:05:00  4.000 2.000 
2010-11-20 09:06:00  4.010 4.000 
2010-11-20 09:07:00  1.201 1.201 

Ich werde Gruppe von Tag und dann für jeden Tag eine Funktion anwenden, berechnet ob es einen Rückfall gab und die Zeit, als es passierte. Ihre Frage war nicht klar, auf welche Spalte arbeiten oder was ist das Toleranzniveau zu sagen: „Preise sind die gleichen“, so habe ich sie als Optionen

def retrace_per_day(day, col='high_price', epsilon=0.5): 
    """take day data and returns whether there was a retrace. 
    If yes, return 1 and the minute in which it did. 
    Otherwise return 0 and np.nan""" 
    cond = (np.abs(day[col] - day[col][0]) < epsilon) 
    cond_index = cond[cond].index 
    if len(cond_index) > 1: 
     retrace, period = 1, cond_index[1] 
    else: 
     retrace, period = 0, np.nan 
    return pd.Series({'retrace': retrace, 'period' : period}) 

df.groupby(pd.TimeGrouper('1D')).apply(retrace_per_day) 

      period retrace 
2010-11-19 NaN  0.0 
2010-11-20 2010-11-20 09:06:00  1.0 

Anschließend können Sie diese verwenden, wieder in Ihre ursprüngliche zu fusionieren Datenrahmen bei Bedarf.

+0

Ihr Beispiel ist großartig, aber ich muss Werte zurückgeben, leider kein Datenrahmen (wenn mein Ansatz richtig ist). Um ganz genau zu sein, muss ich innerhalb der ersten 30 Minuten die Höhe und den Tiefstwert finden, in der Reihenfolge, in der es aufgetreten ist, und dann herausfinden, ob der Preis vom Beginn des Tages an zurückverfolgt wurde. So würde die Funktion so aussehen: Identifizieren Sie High & Low innerhalb der ersten 30 Minuten des Tages, beide an list1 anfügen. Identifizieren Sie die Reihenfolge, wenn der Preis zurückgeliefert wird, geben Sie "an" oder "falsch" an und fügen Sie an list1 an. Finde das Zeitdelta zwischen dem Beginn des Tages und dem Retracement. An Liste1 anhängen. Hängen Sie list1 an list2 an. Neue Iteration beginnen – supernoob

+0

@supenoob: Ich habe keine Ahnung was "retracen" in diesem Zusammenhang bedeutet. Können Sie bitte die (vereinfachte) erwartete Ausgabe zu Ihrer Frage machen? Wir müssen nicht alle Schritte verstehen, nur welche Teile Sie kombinieren müssen. Sie müssen wahrscheinlich nicht tun dies anhängen und trennen in Listen .. Es scheint mir, Sie müssen nur eine neue Variable namens: "Retracement", dass wird eine, sagen wir, auf der Minute jeden Tag, wenn der Preis begann "zurückzuverfolgen" (was auch immer das bedeutet!) und sonst Null. Ist es das? Dies ist durch eine 'groupby'-'Apply'-Kombination möglich. – cd98

+0

Wenn alle Iterationen abgeschlossen sind, erstellen Sie den Datenrahmen aus list2. – supernoob