En este articulo, vamos a extraer informacion de nuestro data bundle fuera de la pipeline, para poder realizar nuestro analisis, out of pipeline o independientemente de la plataforma, pero asegurandonos, que estamos utilizando exactamente la misma informacion que esta utilizando el modelo.
Esto es muy util a la hora de trabajar con universos, por que muchas veces, los intentos de replicar una composicion de un universo no proporciona unos resultados satisfactorios, y para evitar mucho lio a futuro, me parece fundamental entender toda este proceso desde el primer momento que se toca codigo.
Data Source
Toda la data que estoy utilizando, ha sido obtenida de datalake, para construir un datalake como el que yo utilizo, pasate por aqui, o si deseas solo un sample de los datos, puedes pedirmelo directamente aqui.
Sinceramente, recomiendo a todos que se creen su DataLake, por que un datalake de 1TB de informacion, cuesta exactamente 7.95$ mensuales. Y facilitando las labores de research en todos los sentidos.
Zipline Bundle en profundidad
Zipline trabaja los datos de una forma muy particular. Los agrupa en conjuntos llamados Bundles. Los Data Bundles, mediante un proceso de ingest, se cargan los datos necesarios, y el motor de zipline los procesa para dejarlos listos para cualquier proceso.
Si necesitas aprender mas sobre data bundles, y data asset management. Crear un datalake nosql, que es una estructura apta para el big data, en la nube de un proveedor de calidad, de una forma sencilla y entendible, sobre una infraestructura soportada economicamente por Bloomberg, Pasate por aqui.
En este caso, yo voy a utilizar el bundle:
- QA Bundle : etf_model
- Composicion: ETFs sectoriales de SPDR del mercado de renta variable americana.(11 Tickers)
He utilizado este bundle, por que es el primero que publicare sobre su creacion, y automatizaremos un proceso, para que la gente puede descargar un pequeño sample, y realizar sus pruebas en su entorno . Pero usualmente, en cualquier labor de research o modelizacion, se utilizan universos dinamicos en funcion a condiciones, o universsos extremadamente amplios, de una magnitud estilo, todas las acciones tecnologicas mundiales, o top 5000 empresas mas captilizadas en estados unidos. Todo esto lo debatiremos mas adelante, como punto de introduccion solo es necesario puntualizar que es un universo extremadamente pequeño, pero puede considerarse como representativo.
El primer Analisis con Python y Zipline
Para nuestro primer analisis, el objetivo principal sera, crear un conjuntos de funciones auxiliares, que nos permitan acceder a la informacion del data bundle, y poder manger la informacion en un formatico pythonico como son los dataframes.
Una vez que tengamos posesion de toda la informacion que compone el data bundle, realizaremos una serie de plots descriptivos, que nos serviran como prueba de concpeto visual sobre las posibilidades existentes , una vez descargado el bundle de datos a pd.DataFrame().
Cargar Librerias
El primer paso, es cargar las librerias necesarias. Primero vamos cargar la libreria de ArcticDB, y posteriormente las 3 funciones que nos permiten transformar la informacion necesitata a un formato pandas dataframe, dandonos un amplio abanico de posibilidades para extraer valor de los datos.
from zipline.data.bundles import load
from zipline.data.bundles.core import BundleData
from zipline.data.data_portal import DataPortal
Introducimos una fecha de inicio, y una fecha final, al mismo tiempo asignamos un trading calendar. En este caso el bundle, contiene los etfs sectoriales de SPDR unicamente, por consecuencia, con un calendario sera suficiente para todo el abanico de activos.
start_date = '2000-01-01'
end_date = '2023-09-30'
trading_calendar = get_calendar('NYSE')
Ahora vamos a cargar el bundle, y vamos a realizar tres consultas:
- Consultamos todos los assets en el bundle : Esto nos devuelve una lista, que nos dejara puntear a los activos dentro del pipeline en el futuro
- Consultamos, en un formato de lista pythonica, los symbolos dentro del bundle. Los devuelve en un formato human readable.
- Consultamos la metadata del exchange, por si existe la necesidad de verificarlo en algun punto.
bundle = load('etf_model')
assets = bundle.asset_finder.retrieve_all(bundle.asset_finder.sids)
symbols = [asset.symbol for asset in assets]
exchange = bundle.asset_finder.exchange_info
La variable assets, contiene los punteros a los activos,se pueden utilizar para consultar posiones, estados, puntear a la hora de ejecutar ordenes etc…

La variable symbols, ha storeado en una lista, los nombres de los activos en formato readable. Estos activos han sido importados de nuestro datalake siguiendo LOS PROCESOS QUE EXPLICAMOS AQUI

Y como ultimo paso, tenemos la informacion sobre la metadata del exchange, informacion que ha sido generada en nuestra pipeline de data ingest (la forma de proporcionar datos actualizados a zipline), y por ello fijamos valores personalizados.

Data Portal
Un data portal, es un objeto de zipline, que su funcion principal es ser una interconexion, entre los data bundles de zipline, y el usuario final via python dataframes. La forma de definirlo suele ser siempre la mista, por lo cual el siguiente fragmento, podrian considerarlo como un snippet para crear un data portal.
data_portal = DataPortal(bundle.asset_finder,
trading_calendar=bundle.equity_daily_bar_reader.trading_calendar,
first_trading_day=bundle.equity_daily_bar_reader.first_trading_day,
equity_daily_reader=bundle.equity_daily_bar_reader,
adjustment_reader=bundle.adjustment_reader)
Descargar los Precios utilizando Data Portal del Bundle de Zipline.
Para ello , vamos a definir una funcion, que desde una rango de fechas, pueda hacer una llamada al data portal y consultar para descargar los datos solicitados. Vamos a realizar esta funcion utilizando la estructura minima funcional, y que cada cual la adapte a sus preferencias.
def get_pricing(data_portal, trading_calendar, assets, start_date, end_date, field='close'):
end_dt = pd.Timestamp(end_date)
start_dt = pd.Timestamp(start_date)
end_loc = trading_calendar.closes.index.get_loc(end_dt)
start_loc = trading_calendar.closes.index.get_loc(start_dt)
return data_portal.get_history_window(assets=assets, end_dt=end_dt, bar_count=end_loc - start_loc,
frequency='1d',
field=field,
data_frequency='daily')
Mediante esta funcion, basicamente lo que hacemos es:
- Convertir los inputs a formato datetime
- elegir un inicio y un final, donde concuerde con la estructura del calendario
- y una vez tiene las imputs estandarizadas(transformadas a un formato correcto para su posterior llamada)
Una vez que la funcion tiene los imputs estandarizados y con un formato compatible con el data portal, vamos a solicitar una ventana rolante de N dias, tantos como tenga nuestro rango, que disponga de los datos de nuestro rango, y ademas añadimos, el tipo de frecuencia que utilizarmeos, y que tipo field utilizaremos como referencia, dejando por defecto el close, y dejando la posibilidad de modificarlo en caso de que fuera necesario.
Llamando a la funcion
Ahora vamos a llamar a la funcion, y vamos a storear la informacion en una variable.
historical_data = get_pricing(data_portal, trading_calendar, assets,
start_date=start_date, end_date=end_date)

Tras llamar a la funcion, ,lo que obtenemos es un clasico dataframe, con un indice en formato datetime, donde disponemos los datos de los activos requeridos en el periodo fijado. Listos para pasar por cualquier otro proceso de research. Esto garantiza que la data de research y backtest sea la misma, a nivel de intervalos, tickers, actualizaciones etc… Facilitando aun mas la labor del big data management.
Trabajando con los datos.
Una vez que hemos descargado los datos, vamos a hacer un ejemplo sobre como extraer informacion de los mismos. Este es un campo que trataremos mas en profundidad, ahora vamos a visualizar la correlacion de los retornos diarios de todos los activos contra todos los activos, y ademas los vamos a visualizar de una forma ordenada, y con un alto indice de interpretabilidad. Para ello, vamos a utilizar la libreria de pandas para calcular las correlaciones, y la libreria de seaborn para los plots.
correlation_matrix = historical_data.pct_change().corr(method='kendall')
plt.figure(figsize=(12, 9))
sns.heatmap(correlation_matrix, annot=True, fmt=".2f", cmap='coolwarm')
plt.title('Mapa de calor de la correlación (método Kendall)')
plt.show()
Este ejemplo es muy sencillo, una vez que hemos descargado el historical data, unicamente hay que crear un nuevo dataframe,que contenga la matriz de correlacion de la corrrelacion con los cambios en la matriz de correlacion. Una vez que tenemos la matriz (que en el ejemplo esta nombrada como correlacion matrix), el siguiente paso es directamente plotearlo de una forma habiutal mediante seaborn.

Otro ejemplo relevante, seria plotear el precio de los activos obtenidos desde los ziplines data bundles. Para ello es unicamente calcular los cambios porcentuales y sumarlos, dando como resultado una curva que acumula sus resultados porcentuales.
pct_data = historical_data.pct_change()
pct_data.cumsum().plot(figsize=(20, 9),legend=True,)
plt.title('Porcentuales')
plt.legend(loc='lower left')
plt.show()

Conclusiones
En esta segunda entrega, hemos avanzado hasta poder obtener datos de un data bundle, y trabajar con ellos como si fueran datos de cualquier otra fuente. El entender este articulo, te posibilita, a utilizar una de las bases de datos mas potentes que hubieron, desarolladas y mantenidas por la comunidad de quantopian hasta 2018 para acciones y 2020 para futuros. las miticas quandl-bundle. Al cargarlos, mediante dataportal, hay data de gran calidad desde 1980, hastsa 2018, con todos los sesgos eliminados.
Aunque recomendamos crear nuestro datalake, o entender los procesos de data ingesting AQUI. La posibilidad de poder utilizar todo tipo de datos, sobre todo tipo de activos y todo tipo de estrategias, aumenta hasta casi el infinito las posibilidades de research que hay de tras de estas ampliaciones de la capacidad y la ruputura de barreras entre las tecnicas profesionales y las utilizadas por el trader retail medio.
Otras entradas de esta misma coleccion:
Zipline, Backtesting en Python 1: Quantopian y Pipelines
Zipline, Backtesting en Python 2: Mi primear Pipeline
Zipline, Backtesting en Python 3: Mi primer BacktestZipline, Backtesting en Python 2 : Mi primer Data Research
Zipline, Backtesting en Python 4: Mi primear Pipeline
Zipline, Backtesting en Python 5: Mi primer Backtest
Zipline, Backtesting en Python 6: Mi primer Portfolio Report