Muchas veces deseamos descargar en un Excel una determinada serie histórica. Siempre podemos acceder a una web como la de Yahoo Finances y copiar los datos manualmente, o descargar un archivo que el propio Yahoo pone a nuestra disposición.
El problema radica en que este Excel viene con los datos de cada periodo temporal acumulados en filas:
Para solucionar esta pequeña molestia, a continuación voy a presentarles una macro programada en Excel, la cual lo hará automáticamente. Esta macro nos permitirá descargar los datos del periodo seleccionado, y además organizarlos por celdas. Aunque por supuesto, esto mismo también se puede realizar fácilmente en Excel de forma manual. (Si desea saber cómo, lo explica muy bien Óscar Carchano —profesor de la Universidad de Valencia— en el siguiente enlace: click aquí).
La ventaja que presentaría mi macro, es que con ligeros cambios, puede reutilizarse el código para descargar de forma sencilla datos procedentes de cualquier página web.
Primer paso: Programar una función que nos descargue en formato texto los datos de una página web
La función en cuestión será la siguiente:
'Función para descargar toda la info. en formato texto de una pág. web.
'Como parámetro de entrada, la fun. recibirá una dirección web en formato texto.
Function ObtenerLink(Link As String) As String
Dim A, Aux As String
Dim HTTP As Object
'Creamos un objeto
Set HTTP = CreateObject("MSXML2.XMLHTTP")
'Con dicho Objeto
With HTTP
'Abrimos el link
.Open "GET", Link, False
.send
'Descargamos el texto de la web como respuesta,
'y lo introducimos en una variable creada para tal efecto.
Aux = .responseText
End With
'Nos interesan nada más que los datos que hay a partir de "]},"; así pues lo dividimos con "split"
A = Split(Aux, "]},", -1, vbTextCompare)
'La función nos va a devolver sólo la 2ª parte, que es la que deseamos
ObtenerLink = A(1)
End Function
Segundo Paso: Generar el enlace con la serie selecionada
Una vez programada la función con la que nos descargaremos la información, a continuación deberemos programar otra que nos genere el enlace que necesitamos:
'Función para obtener una url. La función recibirá como entrada el nombre de la compañía,
'una fecha de inicio y una fecha final:
Function YahooHistorico(Empresa As String, FechaI As Date, FechaF As Date) As String
Dim periodo1, periodo2, DataValue As Date
Dim Link As String
' Según queramos el intervalo de la información [ Minutos: 1m, 2m, 5m, 15m, 30m, 60m, 90m,
' Horas 1h, días (es el que tenemos puesto) 1d, 5d, Semanas: 1wk, Meses: 1mo, 3mo].
' Esto se modifica en el link tras: "&interval="
'La fecha introducida, la transformamos en el formato que Yahoo Finances reconoce:
periodo1 = (FechaI - DateValue("1 enero, 1970")) * 86400
periodo2 = (FechaF - DateValue("1 enero, 1970")) * 86400
'Generamos el link que necesitamos, poniendo donde corresponde el nombre de la compañía,
'la fecha inicial y la final:
Link = "https://query1.finance.yahoo.com/v8/finance/chart/" & Empresa & "?symbol=" & Empresa & "&period1=" & periodo1 & "&period2=" & periodo2 & "&interval=1d&includePrePost=true&events=div%2Csplit"
'Lo mandamos a la otra función que hemos programado anteriormente:
YahooHistorico = ObtenerLink(Link)
End Function
Para obtener el nombre de la compañía, lo tomamos de la web de Yahoo Finances:
En este caso, para el ejemplo con el que nosotros vamos a trabajar, el nombre de nuestra empresa será "GOOG" (Google).
Tercer Paso: Programar nuestra macro
Para finalizar, a continuación programaremos nuestra macro. Con ella, tras introducir el nombre de la empresa, la fecha inicio y la final, se nos descargará toda la serie histórica de la compañía en nuestro Excel, tal y como deseamos:
'Macro extraer datos históricos de Yahoo Finances
Sub YhFDescargaSerieH()
'Antes de comenzar, congelamos la actualización de la página de nuestro Excel
Application.ScreenUpdating = False
'Declaramos las variables que vamos a necesitar
Dim i, j, DatFinal As Integer
Dim FechaCo As Date
Dim Respuesta, Aux, Datos, Columnas(6, 0), Escri As String
'Aquí llamamos a la función que nos va a generar el enlace:
'introducimos *entre comillas* el nombre de la empresa,
'la fecha de inicio de la serie que deseamos descargar y la final.
Respuesta = YahooHistorico("GOOG", "01/12/2018", "01/11/2019")
'Comenzamos a trocear los datos: Cuando encuentre la apertura de corchete,
'insertará un salto de línea
Datos = Split(Respuesta, "[", -1, vbTextCompare)
'Introducimos los distintos datos en una matriz:
Columnas(0, 0) = Datos(1)
Columnas(1, 0) = Datos(4)
Columnas(2, 0) = Datos(7)
Columnas(3, 0) = Datos(5)
Columnas(4, 0) = Datos(3)
Columnas(5, 0) = Datos(9)
Columnas(6, 0) = Datos(6)
For j = 1 To 6
'Separamos los datos
Aux = Split(Columnas(j, 0), ",", -1, vbTextCompare)
'Escribimos las columnas con los valores (Las fechas las dejamos para el final).
'Atención: Salvo la columna de las fechas (que siempre es la primera),
'Yahoo cambia el orden de todas las demás.
For i = 0 To UBound(Aux) - 2
Cells(3 + i, j + 1) = Aux(i)
Next i
Cells(UBound(Aux) + 2, j + 1) = Replace(Aux(i), "]", "")
Next j
'Quitamos los corchetes que aparecen en los datos de la última fila
Cells(UBound(Aux) + 2, 3) = Replace(Cells(UBound(Aux) + 2, 3), "}", "")
Cells(UBound(Aux) + 2, 6) = Replace(Cells(UBound(Aux) + 2, 6), "}}}", "")
'Escribimos los datos almacenados en la primera columna, que como indiqué más arriba, siempre son las fechas.
j = 0
'Necesitamos una variable que nos señale cuál es la última fila porque a veces hay más datos acumulados al final de la columna de las fechas.
'Por ello, indicaremos que el bucle termine en "DatFinal" en vez de en "UBound(Aux)-2" como en los anteriores.
DatFinal = i
Aux = Split(Columnas(0, 0), ",", -1, vbTextCompare)
For i = 0 To DatFinal
'Transformamos la primera columna en una fecha válida
Escri = Aux(i)
Escri = Replace(Escri, "]", "")
FechaCo = (Escri + DateValue("1 enero, 1970")) / 86400
'La ajustamos añadiendo días, años... según nos convenga.
FechaCo = DateAdd("yyyy", 70, FechaCo)
FechaCo = DateAdd("d", 2, FechaCo)
Cells(3 + i, j + 1) = FechaCo
Next i
'Descongelamos nuestra hoja
Application.ScreenUpdating = True
End Sub
Y con esto estaría ya todo listo: ejecutando nuestra macro, ya disponemos de los datos que deseamos bien organizados en nuestro Excel:
Ustedes podrán añadir y editar lo que deseen del código para hacerlo más completo o mejorarlo, pero la idea general pienso que se ve clara en el presente artículo. Así que esto ha sido todo, espero que las funciones y la macro presentadas en este post les sean de utilidad.
Por mi parte nada más:
Un saludo, y hasta la próxima.