Macro en VBA para descargarse series históricas de Yahoo Finances

1 de diciembre Incluye: GOOG 0
Interesado en la ciencia en general y en la economía en particular. Escribo para poner mis ideas en orden. Futuro actuario, actualmente en... [+ info]
Interesado en la ciencia en general y en la economía en... [+ info]
34º en inB
34º en inB

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.

0fcc39109c002a095e490fa44c85357f27874edb.jpg

El problema radica en que este Excel viene con los datos de cada periodo temporal acumulados en filas:

08f13eb0cbbe359ce409210be70c8a2e670d01e9.jpg

Para solucionar esta pequeña molestia, a continuación voy a dejarles 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 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
        'Deseamos 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:

1c37d94b865d59d5c84a477d8c0ed53af2ba8726.jpg

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 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, introduciendo 
    '*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)
    'Separamos los datos y los escribimos
    For j = 0 To 6 
        Aux = Split(Columnas(j, 0), ",", -1, vbTextCompare)
        If j = 0 Then
            For i = 0 To UBound(Aux) - 2
                'Transformamos la primera columna en una fecha válida
                FechaCo = (Aux(i) + DateValue("1 enero, 1970")) / 86400
                FechaCo = DateAdd("yyyy", 70, FechaCo)
                FechaCo = DateAdd("d", 2, FechaCo)
                Cells(3 + i, j + 1) = FechaCo
            Next i
            'Escribimos el último dato de la columna fecha fuera del bucle, 
            'porque viene con unos caracteres que debemos eliminar
            Escri = Aux(i)
            Escri = Replace(Escri, "]", "")
            FechaCo = ((Escri + DateValue("1 enero, 1970")) / 86400)
            FechaCo = DateAdd("yyyy", 70, FechaCo)
            FechaCo = DateAdd("d", 2, FechaCo)
            Cells(UBound(Aux) + 2, j + 1) = FechaCo
       
     'Escribimos el resto de datos en las columnas adyacentes
        Else
            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), "]", "")
        End If
    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), "}}}", "")
    '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:

39c9e0ba1af296231124ef85c785778f6c1daff0.jpg

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. -Espero que esta macro les haya sido de utilidad.

Por mi parte nada más:

Un saludo, y hasta la próxima.

Usuarios a los que les gusta este artículo:

Este artículo no tiene comentarios
Escriba un nuevo comentario

Identifíquese ó regístrese para comentar el artículo.

Síguenos en:

Únete a inBestia para seguir a tus autores favoritos