5 votos

Calcular el rendimiento anual / encontrar el primer punto de datos disponible de un año en python

Necesito calcular el rendimiento relativo acumulado del año hasta la fecha de un conjunto de datos dado. Normalmente calculo el rendimiento relativo acumulado con esta función simple:

def RelPerf(precio):
    RelPerf = (precio/precio[0])
    return RelPerf  

El problema es que necesito establecer en lugar de "precio[0]" el precio al inicio de cada año (primer punto de datos disponible del año). Dado que el conjunto de datos no contiene datos para cada día del año, no puedo simplemente utilizar algo como +365. Entonces la pregunta es, ¿cómo puedo obtener de manera dinámica la ubicación del primer punto de datos disponible en la fórmula?

Este es un breve ejemplo del dataframe utilizado:

              CLOSE_SPX    Close_iBoxx  A_Returns  B_Returns  A_Vola    B_Vola
2014-05-15    1870.85      234.3017    -0.009362   0.003412   0.170535  0.075468   
2014-05-16    1877.86      234.0216     0.003747  -0.001195   0.170153  0.075378
2014-05-19    1885.08      233.7717     0.003845  -0.001068   0.170059  0.075384   
2014-05-20    1872.83      234.2596    -0.006498   0.002087   0.170135  0.075410   
2014-05-21    1888.03      233.9101     0.008116  -0.001492   0.169560  0.075326   
2014-05-22    1892.49      233.5429     0.002362  -0.001570   0.169370  0.075341   
2014-05-23    1900.53      233.8605     0.004248   0.001360   0.168716  0.075333   
2014-05-27    1911.91      234.0368     0.005988   0.000754   0.168797  0.075294   
2014-05-28    1909.78      235.4454    -0.001114   0.006019   0.168805  0.075474   
2014-05-29    1920.03      235.1813     0.005367  -0.001122   0.168866  0.075451   
2014-05-30    1923.57      235.2161     0.001844   0.000148   0.168844  0.075430   
2014-06-02    1924.97      233.8868     0.000728  -0.005651   0.168528  0.075641   
2014-06-03    1924.24      232.9049    -0.000379  -0.004198   0.167852  0.075267

5voto

Skaughty Puntos 693

Necesitas usar un groupby, timegrouper y su opción anual, y tomar el primer valor en cada grupo.

Por ejemplo, si obtengo datos de yahoo:

import pandas as pd
import pandas.io.data as web

# Obtén datos del S&P 500 desde principios de 2011
SPY_Dat = web.DataReader('SPY', 'yahoo', datetime.date(2011,1,1), final)

# Convertir a datos anuales:
SPY_Ann_Dat = SPY_Dat.groupby(pd.TimeGrouper('A')).nth(0)

En este caso estamos utilizando el time grouper anual ('A'). También podríamos usar mensual (M), trimestral (Q) o semanal (W).

Curiosamente, nth también puede utilizar indexación negativa, así que si quisiéramos obtener el último día de cada año, podríamos cambiar la última línea a:

SPY_Last_Ann_Dat = SPY_Dat.groupby(pd.TimeGrouper('A')).nth(-1)

Así que, ahora si quisiéramos, como en tu ejemplo, calcular el retorno YTD, podemos ajustar las cosas un poco, para no solo obtener la primera fecha, sino aplicar una transformación usando los datos de la primera fecha en cada grupo:

import pandas as pd
import pandas.io.data as web

# Obtén datos del S&P 500 desde principios de 2011
SPY_Dat = web.DataReader('SPY', 'yahoo', datetime.date(2011,1,1))

# Agrupa los datos con el mismo TimeGrouper para agrupar las cosas por año
SPY_GroupedDat = SPY_Dat.groupby(pd.TimeGrouper('A'))

# Crea una nueva columna con datos YTD del cierre ajustado, utilizando una función lambda de transformación aplicada a nuestros datos de grupo.
SPY_Dat["YTD"] = SPY_GroupedDat['Adj Close'].transform(lambda x: x/x.iloc[0]-1.0)

Esto generará una columna en SPY_Dat que es un retorno YTD acumulado, reseteado en la primera fecha comercial de cada año.

0 votos

¡ok, ¡Gracias! Pero ¿cómo puedo hacer para que esto esté dentro de la función def RelPerf(), que se muestra en la pregunta?

0 votos

@hb.klein: Ok, agregué otro fragmento de código que hace lo que creo que estás buscando (en el contexto de datos obtenidos de Yahoo y calculando el rendimiento como precio_n/precio_0 - 1.0, puedes modificar fácilmente la función lambda para calcular el rendimiento de la manera que mejor te convenga.

1voto

anio Puntos 3254

El código se ve un poco anticuado, ya que grouper ahora requiere level y frequency.

Luego, pandas-datareader se atasca en Yahoo y Google.

El script a continuación funciona, utilizando quandl como fuente.

import pandas as pd
pd.core.common.is_list_like = pd.api.types.is_list_like # Resolviendo un problema de pandas-datareader v0.6.0
import pandas_datareader.data as web
from datetime import datetime

start = datetime(2011, 1, 1)
end = datetime(2018, 1, 1)

Obtener datos del S&P 500 desde principios de 2011 SPY_Dat = web.DataReader('AAPL.US', 'quandl', start, end)

Convertir a datos anuales:

SPY_Ann_Dat      = SPY_Dat.groupby(pd.Grouper(level='Date', freq='A')).nth(0)

Alternativamente:

SPY_Last_Ann_Dat = SPY_Dat.groupby(pd.Grouper(level='Date', freq='A')).nth(-1)

Agrupar los datos con el mismo TimeGrouper para agrupar las cosas por año

SPY_GroupedDat = SPY_Dat.groupby(pd.Grouper(level='Date', freq='A'))

Crear una nueva columna con datos YTD de cierre ajustado, utilizando una función lambda de transformación aplicada a nuestros datos agrupados.

SPY_Dat["YTD"] = SPY_GroupedDat['AdjClose'].transform(lambda x: x/x.iloc[0]-1.0)

0voto

Vagee Puntos 1

En caso de que falten datos de años, se genera un error.

Se puede corregir de la siguiente manera :

df["YTD"] = df1_GroupedDat['Adj Close'].transform(lambda x: 0 if x.empty else x/x.iloc[0]-1.0)

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X