Skip to content
Real-Time-Stock-Quotes-in-Excel-using-Python

A Cotizaciones de Bolsa en Tiempo Real en Excel usando Python

Introducción

Tener acceso a información actualizada es una de las cosas más importantes que necesita cuando opera en los mercados financieros. Con la plantilla de calculadora de cotizaciones bursátiles en Excel de Someka podrá realizar un seguimiento de las cotizaciones bursátiles en tiempo real con las que ha operado y controlar el rendimiento de su cartera.

¿Y si quiere ir más allá?

Los operadores utilizan las cotizaciones bursátiles en tiempo real para elegir el momento adecuado para comprar y vender, y se puede acceder a esos datos en tiempo real directamente en Excel.

Trading-Journal-Template-Banner

En lugar de tener que pulsar un botón para actualizar las cotizaciones bursátiles, este blog le mostrará cómo con un poco de código Python puede transmitir datos en tiempo real directamente a Excel.

Python es un lenguaje de programación que ha ganado muchos adeptos en el sector financiero. Si está buscando una forma de hacer que sus propias decisiones de negociación estén más basadas en datos o en algoritmos, entonces le merecerá la pena invertir algo de su tiempo en aprender un poco de Python además de Excel.

Real-Time-Stock-Quotes-in-Excel-using-Python-03¿Python o Excel? ¡Utilice los dos juntos!

Mucha gente habla de utilizar Python en lugar de Excel. Python es un gran lenguaje de programación, ¡pero no sustituye a una hoja de cálculo! Excel es una herramienta extremadamente poderosa en prácticamente todas las industrias, y por una buena razón.

Para algunas tareas, en particular las que requieren algo más que cálculos sencillos, Python puede ser una opción mejor. Python cuenta con un inmenso ecosistema de paquetes para prácticamente cualquier tipo de cálculo que se le ocurra. Aunque podría ser posible hacerlo todo en Excel, una vez que haya aprendido un poco de Python, ¡descubrirá que algunas cosas son simplemente más fáciles en Python!

Afortunadamente, no hay necesidad de elegir entre uno u otro. Las funciones de Python se pueden llamar desde Excel utilizando PyXLL, el complemento de Python para Excel. Combinar Excel y Python utilizando Excel como front-end (o interfaz de usuario) con Python potenciando las tareas más complejas es una combinación perfecta.

Uso de Python para obtener cotizaciones bursátiles en tiempo real

Lo siguiente supone cierto conocimiento de Python. Si aún no está familiarizado con Python, no se preocupe si no lo entiende todo en este momento. Todavía puede seguir adelante, pero es posible que desee echar un vistazo a la sección de recursos para algunas páginas para ayudarle a empezar con Python también.

Para nuestra fuente de datos de precios de acciones, vamos a utilizar iextrading .com. IEX dispone de una API Socket.I O que utilizaremos para obtener actualizaciones en tiempo real. Socket.IO es una biblioteca para aplicaciones web en tiempo real, y podemos acceder a la API Socket.IO de IEX utilizando Python.

code

Lo primero que hay que hacer es instalar el paquete Socket.IO de Python para que podamos hablar con IEX. Lo instalamos utilizando el gestor de paquetes de Python, Pip, desde un símbolo del sistema:

pip install python-socketio

Ahora en un archivo Python podemos importar socketio y conectarnos al servidor IEX.

Para recibir las actualizaciones de la cotización de las acciones, necesitamos añadir algunas funciones callback que el cliente llamará en respuesta a determinados eventos.

importar socketio

endpoint = "https://ws-api.iextrading.com/1.0/tops"
símbolos = [
  "AAPL
  "MSFT"
    "SNAP"
]

@client.on("conectar", namespace=espacio de nombres)
async def on_connect():
  for símbolo in símbolos
      await client.emit("subscribe", symbol, namespace=espacio de nombres)
       print(f "Suscrito a '{símbolo}'")

En primer lugar, cuando el cliente se ha conectado al servidor, enviamos algunas órdenes para suscribirse a algunos símbolos bursátiles (a menudo llamados tickers).

Se llamará a la llamada de retorno on_connect una vez que el cliente se haya conectado. A medida que se suscribe cada símbolo, se imprime un mensaje en la salida de Python.

Otra llamada de retorno deberá recibir los datos cuando se actualice la cotización de una acción. Cada vez que algún dato esté listo, la API socket.io de IEX llamará a una llamada de retorno de mensaje con los datos codificados como una cadena JSON. Utilizamos el paquete json de Python para leer esa cadena JSON en un objeto diccionario de Python e imprimirla.

importar json

@client.on("mensaje", namespace=espacio_de_nombre)
def on_message(mensaje):
    data = json.loads(mensaje)
   print(datos)

Habrá notado que el código anterior utiliza las palabras clave async y await de Python. Python 3.5 las contiene y puede utilizarlas comúnmente para la programación asíncrona. Aquí es donde no queremos que todo el programa tenga que esperar a que una operación se complete, como esperar a que una solicitud a un servidor web remoto regrese. En su lugar, Python utiliza un bucle de eventos para programar cada función, y cuando una función tiene que esperar, Python suspende esa función y continúa con cualquier otra que esté lista para continuar.

Para completar este código debemos obtener el bucle de eventos asyncio de Python, programar la tarea para crear el cliente creado anteriormente, e iniciar el bucle de eventos.

importar asyncio

bucle = asyncio.get_event_loop()
loop.create_task(task)
loop.run_forever()

Cuando ejecutamos este código, la salida producida tiene el aspecto que se muestra a continuación. Se va actualizando a medida que cambian los precios de las acciones en tiempo real.

Suscrito a 'AAPL
Suscrito a 'MSFT
Suscrito a 'SNAP'
{'symbol': 'AAPL', 'sector': 'technologyhardwareequipment', 'securityType': 'commonstock', 'bidPrice': 181,1, 'bidSize': 100, 'askPrice': 182.03, 'askSize': 100, 'lastUpdated': 1552491513626, 'lastSalePrice': 182,04, 'lastSaleSize': 100, 'lastSaleTime': 1552491513046, 'volume': 355975, 'marketPercent': 0.02927, 'seq': 84605}

Transmisión de datos de Python a Excel

En la sección anterior aprendimos a obtener cotizaciones bursátiles en tiempo real de IEX utilizando la API Socket.IO. En esta sección veremos cómo utilizar eso para hacer una hoja de cálculo que se actualice en tiempo real.

Para llamar a nuestro código Python desde Excel utilizamos el complemento PyXLL. Puede descargar una versión de prueba gratuita del complemento PyXLL en https://www.pyxll.com/download.html.

  1. Una vez descargado el complemento PyXLL, siga las instrucciones para instalarlo. En el archivo de configuración, pyxll.cfg, verá que hay una opción que dice pythonpath y otra que dice modules. El pythonpath es una lista de carpetas donde Python buscará cuando cargue los módulos Python listados. Un módulo Python es simplemente un archivo de texto que contiene código Python con un nombre de archivo que termina en «.py».
  2. Comience creando un nuevo módulo Python (un archivo de texto terminado en «.py») y guárdelo en algún lugar (por ejemplo, C:/Proyectos/ExcelStockPrices/iex.py). Añada la carpeta donde guardó el archivo a la lista pythonpath del archivo pyxll.cfg (por ejemplo, C:/Proyectos/ExcelStockPrices) y añada el nombre del módulo a la lista de módulos (por ejemplo, iex). Tenga en cuenta que el nombre del módulo no incluye la extensión de archivo «.py».
  3. Cuando se inicie Excel, o se vuelva a cargar el complemento PyXLL, se cargará ese nuevo módulo «iex».
  4. A continuación escribiremos una función en Python que podrá llamar desde Excel. Esto se hace utilizando el decorador @xl_func de PyXLL. Dado que nuestra función devolverá datos en tiempo real, y no un único valor, devolveremos un tipo especial de objeto llamado objeto RTD. En Python, crearemos una nueva clase que derive de la clase RTD de PyXLL.
from pyxll import xl_func, RTD


clase IEXClient(RTD):
   def __init__(self, symbols):
       super().__init__(self, value=None)
       self.symbols = symbols


@xl_func("str[] símbolos: rtd<objeto>")
def iex(símbolos):
   return IEXClient(símbolos)

La función iex toma una lista de cadenas y devuelve un objeto RTD. La cadena pasada a @xl_func más arriba es la firma de la función. PyXLL utiliza esto para determinar cómo convertir los valores pasados de Excel a Python, así como la forma de convertir el valor de retorno de Python a Excel. Esta firma está diciendo que symbols es una lista de cadenas, y la función devolverá un objeto RTD cuyo valor es un objeto Python. El valor del objeto IDT es lo que aparecerá en Excel.

Cuando se llama a la función iex con una lista de símbolos, el resultado en Excel es un manejador del objeto Python «Ninguno». Si hubiéramos especificado otro tipo para el tipo de retorno de la función (por ejemplo, «rtd») entonces podríamos devolver otros tipos a Excel en lugar de un manejador a un objeto Python.

Real-Time-Stock-Quotes-in-Excel-using-Python-06

Los objetos RTD tienen dos métodos, conectar y desconectar. Éstos se llaman cuando Excel está listo para empezar a recibir valores y cuando Excel ya no los necesita respectivamente. Por ejemplo, conectar se llamaría cuando un usuario introduce la fórmula, y desconectar se llamaría si el usuario borrara la fórmula.

Para enviar un nuevo valor a Excel desde el objeto IDT todo lo que tiene que hacer es establecer la propiedad value en el objeto IDT.

Podemos tomar el código escrito en la sección anterior y añadirlo a la clase IEXClient. Lo añadiremos al método connect para que nos conectemos al servidor IEX utilizando un cliente Socket.IO cuando Excel se conecte a nuestro objeto RTD.

En lugar de simplemente imprimir los datos, los almacenaremos en un diccionario Python para poder recuperarlos más tarde.

clase IEXClient(RTD):

    endpoint = "https://ws-api.iextrading.com/1.0/tops"
    namespace = "/1.0/tops"

    def __init__(self, symbols):
        super().__init__(valor={})
       self.symbols = symbols
       self.cliente = socketio.AsyncClient()
       self.datos = {}

   async def connect(self):
        """Conectar AsyncClient y suscribirse a las actualizaciones."""
       @self.client.on("conectar", namespace=self.namespace)
       async def on_connect():
           for símbolo en self.símbolos
               await self.client.emit("suscribir",
                                       símbolo,
                                      namespace=self.namespace)

       @self.client.on("mensaje", namespace=self.namespace)
        def on_message(mensaje):
            latest = json.loads(mensaje)
            símbolo = latest["símbolo"]

            anterior = self.data.setdefault(símbolo, {})
            previous.update(latest)

            # Notificar a Excel que ha habido una actualización
            auto.valor = auto.datos

        await self.client.connect(self.endpoint,
                                 namespaces=[self.namespace])

   async def disconnect(self):
       await self.client.disconnect()

Observe que los métodos connect y disconnect están marcados como async. PyXLL entiende los métodos async y los programará en el bucle de eventos de Python por nosotros.

Ahora cuando recargamos el complemento PyXLL y la función es llamada de nuevo el resultado es un handle a un diccionario Python. A medida que entran los precios, se actualiza el diccionario y se actualiza el valor mostrado en Excel.

Real-Time-Stock-Quotes-in-Excel-using-Python-07

Por sí solo, esto no es demasiado útil. Necesitamos una forma de sacar los valores del diccionario de Python y pasarlos a nuestra hoja. Esto es tan sencillo como escribir otra función que tome el diccionario, el símbolo y la clave y devuelva el valor. La firma para esta función dice que el primer parámetro es un objeto Python, seguido del símbolo y la clave como cadenas, y devuelve un valor de un tipo variable (es decir, podría ser una cadena, un número u otro tipo).

@xl_func("objeto datos, cadena símbolos, cadena clave: var")
def iex_unpack(datos, símbolo, clave):
    # obtener los valores del símbolo
    valores = datos.get(símbolo, Ninguno)
   si no valores
       return "#SinDatos"

    # devuelve el valor para la clave especificada
   return valores.get(clave, "#SinDatos")

Esta función iex_unpack se llama con el manejador del diccionario como primer argumento, y el símbolo y la clave y devuelve el valor del diccionario. A medida que entran nuevos valores y se actualiza el diccionario, estos valores se actualizan.

Real-Time-Stock-Quotes-in-Excel-using-Python-08

Cálculos de cartera con cotizaciones bursátiles en tiempo real

¡Ahora tenemos todo lo que necesitamos para añadir cotizaciones en tiempo real a la Calculadora de Cartera Someka! Puede crear su propia hoja utilizando la plantilla. Si sólo actualiza la hoja como yo lo he hecho a continuación, cuando pulse el botón «Calcular » se sobrescribirán las celdas modificadas.

Real-Time-Stock-Quotes-in-Excel-using-Python-09

Puede obtener otros datos no incluidos en la cotización de las acciones en tiempo real de la API REST de IEX. El código siguiente muestra cómo obtener un único valor utilizando el paquete Python aiohttp.

from pyxll import xl_func
import aiohttp

endpoint = "https://api.iextrading.com/1.0/"

@xl_func
async def iex_fetch(símbolo, clave):
   """devuelve un valor para un símbolo de iextrading.com"""
    url = endpoint + f "stock/{symbol}/batch?types=quote"
   async con aiohttp.ClientSession() como session:
       async with sesión.get(url) as respuesta:
            assert respuesta.estado == 200
            datos = await respuesta.leer()

    datos = json.loads(datos)["cita"]
    return datos.get(clave, "#SinDatos")

La función anterior es una función asíncrona. Esto significa que puede llamarla varias veces y cada solicitud al punto final REST de IEX puede ejecutarse de forma concurrente, lo que mejora enormemente la capacidad de respuesta de la hoja de cálculo.

Para obtener el precio de apertura de una acción, llamaría a la función anterior en Excel de la siguiente manera

=iex_fetch("AAPL", "open")

Encontrará más información sobre la API IEX en su página web https://iextrading.com/developer/docs/.

Buscar