Es una técnica utilizada para extraer datos de páginas web de forma automatizada. En esencia, se trata de un proceso mediante el cual un programa o script recorre y analiza el código HTML de una página web para extraer la información relevante y estructurada que se encuentra en ella.
Esta técnica es ampliamente utilizada en diversas áreas, desde el análisis de datos y la investigación hasta el desarrollo de aplicaciones y la monitorización de precios en comercio electrónico. El webscraping permite acceder a datos que de otro modo serían difíciles o tediosos de obtener manualmente, y puede ser utilizado para recopilar información como precios de productos, noticias, opiniones de usuarios, datos de contacto, entre otros.
El proceso de webscraping generalmente implica varias etapas. Primero, se identifican las fuentes de datos relevantes, es decir, las páginas web de las cuales se desea extraer la información. Luego, se desarrolla un script o programa que pueda acceder a estas páginas web, descargar su contenido HTML y analizarlo en busca de los datos específicos que se desean extraer. Este análisis puede implicar la búsqueda de patrones de texto, etiquetas HTML o incluso el uso de técnicas más avanzadas como el procesamiento de lenguaje natural.
Es importante tener en cuenta que el webscraping debe realizarse de manera ética y respetando los términos de servicio de los sitios web que se están raspando. Algunos sitios pueden tener políticas en contra del webscraping o pueden limitar el acceso a su contenido a través de medidas como el bloqueo de direcciones IP. Por lo tanto, es fundamental seguir las mejores prácticas y respetar las políticas de uso de los sitios web para evitar problemas legales o técnicos.
Si bien la gente suele tender a realizar webscraping directamente muchas veces puede ser mejor hacer un análisis previo del funcionamiento de la página web. Normalmente se darán 3 posibles casos:
En el primer caso, que es el que se verá hoy, se trabajará sobre el archivo HTML buscando los elementos que nos interesen. Cada vez es menos común este tipo de páginas puesto que obtener los datos es muy sencillo. En el caso de necesitar cargar el javascript habrá que ver dónde se encuentran los datos y extraerlos, un ejemplo sería Benzinga que almacena los datos en el elemento de tipo script con el id "__NEXT_DATA__". Su obtención es muy sencilla pero mucha gente se aproxima al problema con el primer método en mente y se queda bloqueada al ver que no carga el HTML en el código fuente. Por último, la posibilidad de replicar las llamadas al backend, mi método favorito. A menudo para evitar el webscraping las empresas no cargan sus datos de ninguna de las dos formas previamente mencionadas sino que a medida que el cliente usa la página cargan los datos por medio de llamadas al backend. Los parámetros de estás llamadas se pueden intentar replicar para poder realizarlas mediante un script. A menudo es bastante enrevesado o emplean métodos para no permitir la conexión por terceros, ya sea mediante cookies o tokens que hay que renovar cada cierto tiempo. Un ejemplo de este caso sería Yahoo Finance.
Finviz.com es un sitio web ampliamente utilizado por inversores y traders para obtener información financiera, realizar análisis de mercado y tomar decisiones de inversión. Su nombre proviene de "Financial Visualization" (Visualización Financiera). Ofrece una amplia gama de herramientas y recursos para el análisis de acciones, futuros, divisas y otros instrumentos financieros, si bien algunas herramientas son de pago.
Una de las características más destacadas de Finviz.com es su capacidad para proporcionar una visualización rápida y accesible de una gran cantidad de datos financieros. A través de su plataforma en línea, los usuarios pueden acceder a gráficos interactivos, tablas de rendimiento, datos fundamentales, noticias financieras y análisis técnico de miles de activos financieros de todo el mundo.
Entre las herramientas más populares que ofrece Finviz.com se encuentran:
Mapa de Mercado: Una visualización global que muestra el rendimiento de diferentes sectores y activos en tiempo real.
Escáner de Acciones: Permite a los usuarios filtrar acciones basándose en una amplia gama de criterios, como capitalización de mercado, relación precio-beneficio (P/E ratio), volumen de operaciones y patrones técnicos.
Heatmap (Mapa de Calor): Proporciona una representación visual de la fuerza relativa de las acciones dentro de un índice o sector.
Analizador de Portafolio: Permite a los usuarios rastrear y analizar el rendimiento de sus carteras de inversión, así como realizar comparaciones con índices de referencia.
Datos Fundamentales y Técnicos: Ofrece acceso a datos financieros fundamentales, como ingresos, ganancias y relación precio-valor contable (P/B ratio), así como indicadores técnicos como medias móviles, RSI (Relative Strength Index) y MACD (Moving Average Convergence Divergence).
En este artículo nos centraremos en obtener datos del screener solamente, si bien se pueden aplicar las mismas técnicas para obtener todos los detalles de un ticker o los sectores y las industrias.
El primer paso será ver si se pueden obtener los datos replicando las llamadas a la API, esto es preferible puesto que es más común modificar el aspecto de la página web (obligando a modificar el script de web scraping cuando esto ocurre) que la API. Para ello abriremos el panel de desarrollador de Chrome, ya sea pulsando FN + F12 o haciendo click derecho y pulsando en inspeccionar. Entre las opciones superiores se buscará la de pestaña de Red o Network, en esta se pueden ver las llamadas al backend y pinchando, se pueden filtrar dichas llamadas en función de su tipología, si bien a nosotros nos interesarán las de tipo Fetch/XHR soy partidario de no filtrarlas. En este caso se puede ver que la llamada que nos interesa es a "https://finviz.com/screener.ashx?v=111&o=-change" donde "o=-change" es simplemente el método empleado para ordenar la tabla.
Como, en este caso, el HTML obtenido de la url anterior es el mismo que se ve en la página (sin modificaciones por javascript, etc) se puede realizar una inspección directa sobre la página web sin tener que indegar en el HTML puro. Al buscar un poco apreciamos que la información que queremos se encuentra en una tabla que tiene una clase llamada "screener_table". Esta clase probablemente solo se aplique a la tabla que queremos extraer permitiéndonos identificarla facilmente, solo habrá que iterar sobre cada valor de cada fila para obtener sus datos.
Ahora bien, no se ven todos los datos en una sola tabla sino que a esta se le ha aplicación una paginación, concretamente en la imagen siguiente se puede ver que sin aplicar ningún filtro hay 476 páginas. Tedremos que obtener los datos de la tabla para cada una de las páginas, para ello deberemos seleccionar el número de páginas primero. Además cuando se va a la siguiente tabla se puede apreciar que cambia la url, incluyendo un parámetro "r" con un valor de 21 para la segunda página, 41 para la tercera, 61 para la cuarta, etc. Se puede identificar que el patrón es sumar 20 para cada aumento de página, debido a que hay 20 filas en cada página. Tras haber identificado esto se puede crear un script que itere sobre las páginas.
En caso de seleccionar algún filtro se añadirá el parámetro "f" a la url seguido de un listado con los ids de los distintos filtros seleccionados. Esto se tendrá que incluir en el script si lo que se pretende es poder filtrar los activos.
El primer paso será importar las librerías necesarias, que en nuestro caso serán certifi, urllib3, BeautifulSoup y pandas. Además se creará una función para gestionar las llamadas y devolver el HTML en un formato que se pueda utilizar. Esta función consta de dos partes principales, en la primera se realiza la llamada a la url y se obtiene una respuesta y en la segunda se transforma el contenido de la respuesta en un elemento de tipo BeautifulSoup sobre el que se podrá buscar el HTML deseado. Para evitar posibles problemas puede ser conveniente introducir medidas como un "user-agent" aleatorio en las cabeceras de las llamadas o esperar un tiempo aleatorio entre distintas llamadas.
import certifi
import pandas as pd
import urllib3
from bs4 import BeautifulSoup
def makeRequest(url:str) -> BeautifulSoup:
'''
Makes a request with the correct header and certifications.
Parameters
----------
url: str
String with the url from which to get the HTML.
Returns
-------
soup: bs4.BeautifulSoup
Contains the HTML of the url.
'''
headers: dict = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:28.0) Gecko/20100101 Firefox/28.0'}
content: urllib3.PoolManager = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where()).urlopen('GET',url, headers=headers)
soup: BeautifulSoup = BeautifulSoup(content.data,'html.parser')
return soup
La siguiente función que definiremos será la de obtener los datos de la tabla (getTable). En está función primero se tendrá que obtener la tabla buscando por el tag "table" y filtrando la tabla que tenga la clase "screener_table". Una vez tengamos la tabla se procederá a la identificación de las columnas iterando sobre los elementos con tag "th" y seleccionando el texto que tienen dentro, además se borrarán los carácteres innecesarios como los saltos de línea.
Una vez se disponga de la estructura de la tabla iteraremos sobre las filas de la tabla (ignorando la que contiene los nombres de las columnas) y sobre los elementos dentro de las distintas celdas de la fila para extraer el texto. Dado que dichas celdas contienen todas elemento de tipo "a" se filtrarán estos. Con los datos de las columnas y las filas se generará un DataFrame puesto que este formato es más fácil y eficiente de manipular que listas normales de Python.
La función se definiría como se ve a continuación, donde el único parámetro sería el HTML de la página y los bucles que se han explicado previamente se realizarán en una sola línea para mejorar en velocidad y eficiencia. En caso de no existir la tabla que se busca se devolverá un DataFrame vacío.
def getTable(soup:BeautifulSoup) -> pd.DataFrame:
'''
Extraction of screener table.
Parameters
----------
soup: bs4.BeautifulSoup
HTML of a webpage.
Returns
-------
table: pd.DataFrame
Contains the screener table.
'''
table = soup.find('table', {'class':'screener_table'})
if table:
cols: list = [col.get_text().replace('\n', '') for col in table.find_all('th')]
rows: list = [[a.get_text() for a in row.find_all('a')] for row in table.find_all('tr')[1:]]
return pd.DataFrame(data=rows, columns=cols)
else:
return pd.DataFrame()
El siguiente paso será crear la función que genere las urls e itere sobre estas para obtener el HTML de las distintas páginas. Como no se puede saber de antemano el número de páginas será necesario realizar siempre la primera llamada y obtenerlo de la misma. Esto resulta ser una tarea sencilla ya que los botones para cambiar de página se encuentran en un elemento de tipo "td" con id "screener_pagination". Dentro de dicho elemento se incluyen todos los enlaces y solo habrá que filtrar los que tengan un valor númerico y seleccionar el de mayor valor.
Además habrá que almacenar de alguna manera las tablas de cada página, para ello definiremos una lista llamada "complete_data" en la que iremos incluyendo los DataFrames y al final los concatenaremos todos para generar una sola tabla.
def getPages(filters:list=None) -> pd.DataFrame:
'''
Extraction of screener table.
Parameters
----------
filters: list
List of filters to apply. The filters must be the ids of
the ones from finviz.com.
Returns
-------
table: pd.DataFrame
Contains the screener table.
'''
filters: list = [] if filters == None else filters
complete_data: list = []
# Defining the url and connecting to obtain html
tempurl: str = f"https://finviz.com/screener.ashx?v=111&ft=4&o=-change&f={','.join(filters)}"
soup: BeautifulSoup = makeRequest(tempurl)
complete_data.append(getTable(soup))
page = max([int(a.get_text().replace('\n', '')) for a in soup.find('td', {'id': 'screener_pagination'}).find_all('a') if a.get_text().replace('\n', '') != ''])
if page:
n: int = page - 1
if n > 0:
for i in range(1, n):
tempurl: str = f"https://finviz.com/screener.ashx?v=111&ft=4&o=-change&f={','.join(filters)}&r={i*2}1"
soup: BeautifulSoup = makeRequest(tempurl)
complete_data.append(getTable(soup))
return pd.concat(complete_data)
El último paso será dar el formato deseado a las columnas de la tabla y para ello tendremos que crear una función que se use para cambiar los número en formato financiero a un formato que se pueda tratar con Python. Dado que la función es bastante sencilla no se explicará.
def _to_numeric(string:str) -> (int | float):
'''
Converts a string to a number of type float
or int.
Parameters
----------
string: str
String containing a number.
Returns
-------
number: int | float
Number in correct format.
'''
string: str = string.replace(',','')
float_cond: bool = '.' in string or string == 'nan'
number: (int | float)
if 'k' in string or 'K' in string:
number = float(string[:-1]) if float_cond else int(string[:-1])
number = number * 1000
elif 'm' in string or 'M' in string:
number = float(string[:-1]) if float_cond else int(string[:-1])
number = number * 1000000
elif 'b' in string or 'B' in string:
number = float(string[:-1]) if float_cond else int(string[:-1])
number = number * 1000000000
elif 't' in string or 'T' in string:
number = float(string[:-1]) if float_cond else int(string[:-1])
number = number * 1000000000000
elif '%' in string:
number = float(string[:-1]) if float_cond else int(string[:-1])
else:
number = float(string) if float_cond else int(string)
return number
Se aplicarán los formatos a las columnas concretas que se desee de la siguiente manera.
screener_df: pd.DataFrame = screener_df.drop_duplicates()
screener_df['Market Cap'] = screener_df['Market Cap'].apply(lambda x: _to_numeric(x))
screener_df['P/E'] = screener_df['P/E'].apply(lambda x: float('nan' if x == '-' else x))
screener_df['Price'] = screener_df['Price'].astype(float)
screener_df['Change'] = screener_df['Change'].apply(lambda x: float(x.replace('%', ''))/100)
screener_df['Volume'] = screener_df['Volume'].str.replace(',','').astype(float)
Cuando ejecutamos la función "getPages()" con algunos filtros obtenemos una tabla con datos como el símbolo, el nombre de la empresa, el sector, la industria, el país de origen, la capitalización de mercado, el precio y el volumen.
stock_filters: list = ['cap_largeunder', 'sh_avgvol_o1000', 'ta_highlow20d_b0to10h', 'ta_perf_4w30o', 'ta_sma20_pa10', 'ta_sma50_pa']
screener_df: pd.DataFrame = getPages(stock_filters)
No. | Ticker | Company | Sector | Industry | Country | Market Cap | P/E | Price | Change | Volume |
---|---|---|---|---|---|---|---|---|---|---|
1 | JAGX | Jaguar Health Inc | Healthcare | Biotechnology | USA | 8.784000e+07 | NaN | 0.32 | 0.0846 | 140586417.0 |
2 | CVNA | Carvana Co. | Consumer Cyclical | Auto & Truck Dealerships | USA | 1.415000e+10 | 49.01 | 121.67 | 0.0444 | 8515304.0 |
3 | JANX | Janux Therapeutics Inc | Healthcare | Biotechnology | USA | 3.360000e+09 | NaN | 64.78 | 0.0376 | 1044152.0 |
4 | PHG | Koninklijke Philips N.V. ADR | Healthcare | Medical Devices | Netherlands | 2.431000e+10 | NaN | 26.82 | 0.0098 | 1661489.0 |
5 | BILI | Bilibili Inc ADR | Communication Services | Electronic Gaming & Multimedia | China | 4.740000e+09 | NaN | 14.83 | 0.0075 | 7349068.0 |
6 | MTTR | Matterport Inc | Technology | Software - Application | USA | 1.430000e+09 | NaN | 4.54 | 0.0067 | 3069818.0 |
7 | CDMO | Avid Bioservices Inc | Healthcare | Biotechnology | USA | 5.237100e+08 | NaN | 8.25 | 0.0061 | 1300201.0 |
8 | HUMA | Humacyte Inc | Healthcare | Biotechnology | USA | 5.251400e+08 | NaN | 4.41 | 0.0023 | 802873.0 |
9 | DCPH | Deciphera Pharmaceuticals Inc | Healthcare | Drug Manufacturers - Specialty & Generic | USA | 2.090000e+09 | NaN | 25.38 | 0.0000 | 1851787.0 |
10 | SNAP | Snap Inc | Communication Services | Internet Content & Information | USA | 2.682000e+10 | NaN | 16.25 | -0.0031 | 23736909.0 |
11 | CUTR | Cutera Inc | Healthcare | Medical Devices | USA | 5.050000e+07 | NaN | 2.53 | -0.0156 | 454805.0 |
El webscraping del screener de Finviz emerge como una estrategia valiosa para los inversores y traders que desean optimizar su proceso de análisis y toma de decisiones en el mercado financiero. Esta técnica ofrece la ventaja de automatizar la recopilación de datos, lo que ahorra tiempo y esfuerzo a los inversores al evitar la necesidad de ingresar manualmente cada criterio de búsqueda en el screener de Finviz. Además, el webscraping permite una mayor flexibilidad en el manejo y análisis de los datos extraídos, lo que facilita la identificación de oportunidades de inversión, la realización de comparaciones detalladas y el seguimiento de tendencias del mercado en tiempo real. Sin embargo, es importante destacar que el webscraping debe realizarse de manera ética y legal, respetando los términos de servicio de Finviz y cualquier otro sitio web del que se extraigan datos.
En el mundo de las finanzas, las relaciones entre las diferentes economías globales son cruciales para entender y predecir movimientos en los mercados. Uno de los aspectos fundamentales que los inversores y analistas estudian es la diferencia de tipos de interés entre las distintas monedas fiat. Esta disparidad no solo refleja las políticas monetarias de los países, sino que también puede influir en el comportamiento de los inversores y en la dirección de los flujos de capital. En este artículo, exploraremos en detalle la importancia de la diferencia de tipos de interés en el contexto de las finanzas cuantitativas, y cómo esta relación puede afectar al mercado de divisas.
El mercado de divisas, también conocido como Forex (abreviatura de Foreign Exchange), es el mercado global descentralizado donde se negocian las distintas monedas del mundo. Su funcionamiento se basa en la compra y venta de divisas, con el objetivo de obtener ganancias mediante la especulación sobre las fluctuaciones en los tipos de cambio entre ellas o la obtención de una moneda concreta para poder realizar una transacción posterior.
En este mercado, participan una amplia variedad de actores, incluyendo bancos centrales, instituciones financieras, empresas multinacionales, inversores individuales y especuladores. Según un estudio trianual que el Banco de Pagos Internacionales realizó en 2022 el 46,1% de las transacciones eran exclusivamente entre bancos, el 48,2% fueron entre bancos y otro tipo de firma financiera y tan solo el 5,7% se realizaron entre un intermediario y una compañía no financiera. Dichas transacciones sumaron una media de 7,5 billones europeos al día, equivalente a 7,5 trillones americanos, a pesar de su extrema liquidez la variación de precios es mínima debido a que su valor se asocia con el de la economía que usa dicha moneda. Por ello se suele ofrecer un apalancamiento bastante alto para operar en el mercado llegando en ocasiones a ser de 500:1. Los pares más negociados el EUR/USD con un porcentaje de las transacciones del 22,7%, el USD/JPY con un 13,5% y el GBP/USD con un 9,5%.
La estructura de este mercado difiere de la típica como podría ser el Nasdaq, donde todas las transacciones están intermediadas por una entidad única. En el caso del mercado de divisas las transacciones se llevarán a cabo en distintas entidades en función del tamaño de dicha transacción pudiendo ser el bróker el que haga de contraparte (a estos brókers se les llama Market Makers), un banco u entidad financiera o incluso un banco central de algún país. Dichas entidades se encuentran en los países de todo el mundo, por lo que el mercado abre durante las 24 horas del día de lunes a viernes, cerrando solo los fines de semana.
La importancia del mercado de divisas radica principalmente en la facilitación del comercio internacional, permitiendo convertir el capital a monedas extranjeras para realizar transacciones comerciales de bienes o productos entre países. Debido a la flucutación del tipo de divisa 4las empresa se vieron en la necesidad de realizar también transacciones con objetivos de covertura para prevenir el riesgo de la depreciación de su moneda local o la apreciación de la moneda en la que se desea comerciar los productos extranjeros. Esto hace que el mercado de divisas sea de suma importancia para las entidades más grandes del mundo, reflejando también la diferencia en su naturaleza respecto a los mercados más tradicionales.
Un par de divisas en el mercado de Forex es la representación de dos monedas diferentes y su relación. La forma en que se expresan los pares de divisas es mediante la abreviatura de las dos monedas involucradas, siendo la primera la moneda base y la segunda la moneda cotizada. Por ejemplo, en el par EUR/USD, el euro (EUR) es la moneda base y el dólar estadounidense (USD) es la moneda cotizada.
La interpretación de un par de divisas implica comprender cómo se mueve el valor de una moneda en relación con la otra. Cuando observamos un par de divisas, el precio al que se cotiza indica cuántas unidades de la moneda cotizada se necesitan para comprar una unidad de la moneda base. Por ejemplo, si el par EUR/USD se cotiza a 1.20, significa que un euro equivale a 1.20 dólares estadounidenses. Técnicamente hablando todos los activos financieros se comercian en pares solo que la moneda cotizada no se suele especificar. Por ejemplo los activos comerciados en los mercados americanos en realidad cotizan respecto al dólar estadounidense. Si se toman las acciones de Apple su par sería el AAPL/USD, con un valor en el momento de escribir el artículo de 165$, esto querría decir que se requieren 165 unidades de la divisa cotizada (USD) para comprar una unidad del activo base (acciones de Apple). Como se explicó en el artículo Seguimiento de Tendencia Absoluta y Relativa en finanzas todo el relativo y todo activo se reflejará de forma relativa a otro. De esa necesidad nace el dinero, como punto de referencia para el intercambio de activos.
Cuando el precio de un par de divisas aumenta, indica que la moneda base está ganando fuerza en relación con la moneda cotizada, como cuando las acciones de una empresa aumentan de valor respecto a la moneda en la que se comercian, lo que se conoce como apreciación. Por otro lado, si el precio disminuye, significa que la moneda base está perdiendo valor en relación con la moneda cotizada, lo que se llama depreciación.
Los tipos de interés son uno de los conceptos fundamentales en el mundo de las finanzas y la economía. Básicamente, representan el coste del dinero, es decir, la cantidad que se paga o se recibe por el uso o préstamo de una determinada cantidad de capital durante un período de tiempo específico. Cuando una persona, empresa o gobierno toma prestado dinero, generalmente debe pagar un interés por ese préstamo. Del mismo modo, cuando alguien invierte o presta dinero, puede recibir intereses como recompensa por prestar ese capital. Los tipos de interés se expresan típicamente como un porcentaje y pueden ser fijos o variables.
Juegan un papel crucial en la economia puesto que el crédito depende de forma directa del tipo de interés. Los bancos centrales utilizan los tipos de interés como una herramienta para regular la oferta de dinero en la economía. Al aumentar o disminuir los tipos de interés de referencia, los bancos centrales pueden influir en la cantidad de dinero en circulación y controlar la inflación dado que se reducirán los préstamos, disminuyendo el gasto y por ende la demanda de productos y servicios. Por otro lado, una reducción en los tipos de interés puede incentivar el gasto y la inversión, impulsando así el crecimiento económico. Su impacto también se refleja en los mercados financieros. Por ejemplo, los bonos, cuyos rendimientos están inversamente relacionados con los tipos de interés, tienden a disminuir de valor cuando los tipos de interés aumentan, y viceversa. A su vez, pueden influir en los tipos de cambio entre las diferentes monedas, por lo general, las monedas con tasas de interés más altas tienden a apreciarse en relación con las monedas con tasas de interés más bajas, ya que ofrecen mayores rendimientos para los inversores. Además, los tipos de interés influyen en el coste de capital para las empresas, lo que puede afectar sus decisiones de inversión y financiamiento.
Para ver la relación se han seleccionado las divisas principales que componen la mayoría de los pares principales (mayors en inglés) y los cruces: EUR, GBP, USD, JPY, AUD, CAD, NZD y CHF. Cada uno representa una economía o conjunto de economías y se estudiarán los pares conformados por la combinación de las mismas.
class Currencies(enum.Enum):
EUR: str = 'zona-euro'
GBP: str = 'uk'
USD: str = 'usa'
JPY: str = 'japon'
AUD: str = 'australia'
CAD: str = 'canada'
NZD: str = 'nueva-zelanda'
CHF: str = 'suiza'
Los datos de precios de dichos pares se obtendrán de Yahoo Finance mediante la API yfinance, desarrollada por Ran Aroussi. Por otro lado los datos de los tipos de interés se obtendrán por webscraping de los datos de Expansión. Para todo ello se importarán las laibrerías siguientes:
import enum
import itertools
import datetime as dt
import matplotlib.pyplot as plt
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import yfinance as yf
Continuaremos por la definición de la función encargada de calcular la diferencia entre tipos de interés y la correlación entre la misma y el tipo de cambio. Para ello lo primero será dividir obtener las dos monedas del par de divisas para poder descargar los datos y calcular la difenrencia de tipos de forma correcta, posteriormente se calculará la correlación.
def getRelation(data:pd.DataFrame, pair:str, show_plot:bool=True) -> float:
curr1: str = pair[:3]
curr2: str = pair[3:]
if curr1 == curr2:
return 1
if curr1 not in df_tipos:
raise ValueError(f'{curr1} is not in the dataframe given')
if curr2 not in df_tipos:
raise ValueError(f'{curr2} is not in the dataframe given')
temp: pd.DataFrame = data[[curr1, curr2]].copy()
temp['Diff'] = df_tipos[curr1] - df_tipos[curr2]
temp['Price'] = yf.download(f'{pair}=X', start=temp.index.min(),
end=temp.index.max(), progress=False)['Close']
temp.dropna(inplace=True)
correlation: float = temp['Diff'].corr(temp['Price'])
if show_plot:
plot(temp, curr1, curr2, correlation)
return correlation
Finalmente se descargarán los datos de los tipos de interés e iteraremos sobre todas las combinaciones posibles entre las divisas que hemos seleccionado previamente.
exp: Expansion = Expansion()
df_tipos: pd.DataFrame = exp.interestRates(currencies=list(Currencies.__members__.values()))
pairs: list = list(itertools.product(*[Currencies.__members__.keys(),
Currencies.__members__.keys()]))
correlations: dict = {}
for pair in [f'{p[0]}{p[1]}' for p in pairs if p[0] != p[1]]:
correlations[pair] = getRelation(df_tipos, pair)
En la figura siguiente se pueden ver tanto el precio del par EUR/USD como la fluctuación de la diferencia entre los tipos de interés estodunidense y europeo. Se puede apreciar cierta relación entre ambos si bien son los tipos de interés los que tienden a reaccionar a la fluctuación del precio y no al revés. Esto se puede deber a que es la herramienta empleada por los bancos centrales para regular la economía. Además, con una correlación de casi 0,55 las tendencias suelen estar bastante sincronizadas.
En la siguiente tabla se puede ver la correlación para los pares conformados por las economías de las elegidas. En primer lugar, se observa que la mayoría de las correlaciones son positivas, siendo solo 5 valores negativos, lo que indica una asociación general entre la diferencia de tipos de interés y el tipo de cambio. Este hallazgo es coherente con la teoría de la paridad de los tipos de interés, que sugiere que los inversores tienden a mover su capital hacia las economías con tasas de interés más altas, lo que a su vez puede influir en la demanda de la moneda y, por lo tanto, en su valor relativo en el mercado de divisas. La mayor correlación sería la del par GBP/CAD, mientras que las más negativa se encuentra en el CHF/CAD. Esto se puede deber a factores económicos y políticos específicos que afectan a estas monedas. Se podría estudiar la posibilidad de realizar un filtro de mercado para una estrategia operativa basado en esta idea para ver si de verdad esta información aporta algún valor.
AUD | CAD | CHF | EUR | GBP | JPY | NZD | USD | |
---|---|---|---|---|---|---|---|---|
USD | 0.78 | 0.40 | 0.11 | 0.54 | 0.64 | 0.54 | 0.28 | 1 |
NZD | 0.63 | -0.39 | 0.46 | -0.19 | -0.43 | 0.26 | 1 | |
JPY | 0.25 | 0.06 | -0.06 | 0.05 | 0.07 | 1 | ||
GBP | 0.32 | 0.80 | 0.26 | 0.76 | 1 | |||
EUR | 0.20 | 0.14 | 0.04 | 1 | ||||
CHF | 0.74 | -0.52 | 1 | |||||
CAD | 0.19 | 1 | ||||||
AUD | 1 |
Tras analizar la correlación entre la diferencia de tipos de interés de dos economías y su tipo de cambio, se pueden extraer varias conclusiones significativas. La relación entre estos dos factores es de vital importancia en el mundo de las finanzas y la economía global, y comprenderla adecuadamente puede ser clave para tomar decisiones informadas en los mercados financieros.
En general, se observa una correlación positiva entre la diferencia de tipos de interés y el tipo de cambio. Esto significa que, cuando la diferencia entre los tipos de interés de dos economías aumenta, es probable que el tipo de cambio entre sus monedas también aumente y viceversa. Sin embargo, también se observan casos en los que la correlación entre la diferencia de tipos de interés y el tipo de cambio es negativa. Esto puede deberse a una variedad de factores, como expectativas sobre futuros cambios en la política monetaria, eventos económicos inesperados, o intervenciones de los bancos centrales. Estos casos subrayan la complejidad del mercado de divisas y la importancia de considerar una amplia gama de factores al analizar las relaciones entre los tipos de interés y los tipos de cambio.
Además, se observa que la fuerza y la dirección de la correlación pueden variar entre diferentes pares de divisas. Algunos pares pueden mostrar una correlación más fuerte y consistente entre la diferencia de tipos de interés y el tipo de cambio, mientras que en otros la relación puede ser menos pronunciada o incluso invertida. Esta variabilidad resalta la importancia de realizar un análisis detallado y específico para cada par de divisas antes de tomar decisiones de inversión.
Los sistemas de seguimiento de tendencia emergen como una solución popular y robusta para los traders e inversores, ofreciendo una metodología estructurada para identificar y aprovechar las tendencias del mercado. Aunque presentan ventajas notables, es importante tener en cuenta sus limitaciones y utilizarlos de manera complementaria con otras estrategias de análisis para tomar decisiones informadas en el complejo mundo de las inversiones.
El seguimiento de tendencias es un enfoque de inversión que se basa en la idea de que los activos financieros tienden a moverse en direcciones establecidas durante ciertos períodos de tiempo. Estos sistemas buscan identificar y seguir las tendencias alcistas o bajistas, aprovechando los movimientos del mercado en la misma dirección, en lugar de intentar predecir la dirección futura del mercad. Son muchos los inversores que han explotado este tipo de estrategias para generar retornos increibles. Un ejemplo notable es el legendario Paul Tudor Jones, conocido por utilizar una estrategia basada en el cruce de medias móviles para identificar tendencias a largo plazo en los mercados de futuros y divisas. Larry Hite, cofundador de Mint Investment Management Company, es conocido por utilizar el ADX como parte de su enfoque de seguimiento de tendencias. Otro ejemplo muy conocido es el experimento de las tortugas, llevado a cabo por Richard Dennis y William Eckhardt en la década de 1980, donde ser reclutó a un grupo aleatorio de personas para entrenarles y que aplicasen un sistema tendencial. Los resultados de las tortugas fueron impresionantes, con algunos miembros del grupo, como Jerry Parker y Curtis Faith, generando retornos significativos utilizando este sistema. Parker, por ejemplo, fundó Chesapeake Capital y ha tenido una exitosa carrera como gestor de fondos de cobertura. Son muchos los que usan este tipo de estrategias pero no es para cualquiera. Si se quiere aprender a diseñar una estrategia de este tipo se puede leer el siguiente artículo: Diseño de Estrategias de Seguimiento de Tendencias.
Simplicidad: Los sistemas de seguimiento de tendencia suelen basarse en reglas simples y fáciles de entender, lo que los hace accesibles incluso para traders novatos.
Identificación de Tendencias: Permiten identificar fácilmente las tendencias predominantes del mercado, lo que facilita la toma de decisiones de compra o venta.
Aprovechamiento de Movimientos Sostenidos: Al seguir las tendencias, estos sistemas permiten aprovechar los movimientos prolongados del mercado en una dirección específica, maximizando así el potencial de ganancias.
Reducción del Ruido del Mercado: Al centrarse en las tendencias a largo plazo, estos sistemas ayudan a filtrar el ruido del mercado y a evitar la toma de decisiones impulsivas basadas en fluctuaciones a corto plazo.
Retraso en la Identificación de Tendencias: Los sistemas de seguimiento de tendencia pueden tardar en confirmar una tendencia, lo que significa que los traders podrían perder parte de los movimientos iniciales del mercado.
Falsas Señales: En mercados volátiles o en transición, estos sistemas pueden generar señales falsas, lo que resulta en operaciones perdedoras.
Difícil en Mercados Laterales: En mercados sin una tendencia clara, los sistemas de seguimiento de tendencia pueden generar señales incorrectas o generar pérdidas debido a la falta de dirección definida del mercado.
Largos Periodos de Pérdidas: Una de las características principales y que hace más difícil el empleo de esta metodología son los largos periodos de pérdida. Hay inversores que llevan a cabo distintas estrategias para minimizar su efecto, como reducir el tamaño de posición durante estos periodos.
La principal diferencia entre una tendencia absoluta y una tendencia relativa es la forma en la que se consideran los precios. En el caso de la tendencia absoluta solo se tiene en cuenta el precio del activo mientras que en la tendencia relativa se considera la relación entre dos activos con el objetivo de ver cuál de los dos tiene un mejor rendimiento. La razón principal por la que decantarse por una metodología u otra es el tipo de gestión que se pretende realizar. La tendencia absoluta se suele emplear más en una gestión discreta donde se consideran operaciones puntuales en vez de tener siempre posiciones abiertas, mientras que la tendencia relativa se emplea más en el segundo caso, donde se quiere estar siempre en el mercado y mantener posiciones en los activos que mejor desempeño estén demostrando. Pero no tiene por qué utilizarse un sistema solo, se pueden emplear los dos en conjunto para encontrar oportunidades de inversión según la tendencia absoluta en activos que tengan buena tendencia relativa, usando así la tendencia relativa para filtrar solo los activos con mayor fortaleza. Curiosamente Kent Daniel dió una conferencia en la Universidad de Columbia en 2010 sobre este tipo de selección de activos y cómo seleccionar los de peor rendimiento relativo durante los periodos de crisis podía aumentar de forma significativa el retorno.
Cabe destacar que cuando se invierte en activos que cotizan en unidades monetarias distintas a la propia se debería tener en cuenta en el cálculo del precio del activo, convirtiéndolo así en un sistema de tendencias relativas. Esto se debe a que si se dispone de una cuenta en Euros y se pretende operar el mercado americano, en Dólares, suponiendo que el Euro está creciendo frente al Dólar el retorno final de la operación será menor debido a la devaluación del Dólar frente al Euro. Pudiendo llegar a ser más conveniente la inversión en algún activo europeo que muestre una tendencia absoluta ligeramente menor pero relativamente sea mayor. El mismo caso se podría dar a la inversa, donde el Dólar se aprecia frente al Euro y la inversión en el mercado estadounidense aproveche tanto la tendencia del activo como la de la divisa, este caso se verá más adelante.
Si seguimos este pensamiento, técnicamente hablando, todos tenemos abiertas posiciones en distintos activos permanentemente, pudiendo ser ese activo tu moneda local (dinero en la cuenta del banco), tu vehiculo, tu casa, etc. Cada posición se devaluará o se apreciará, estando tu patrimonio en constante fluctuación. Puede que compres una mesa a un precio y la vendas más cara, consiguiendo un rendimiento, o compres un coche y lo vendas al mismo precio pero debido a los costes de mantenimiento (cambios de neumáticos, aceite, filtros, etc) pase a ser una posición perdedora. Este planteamiento demuestra que la tendencia absoluta en realidad no existe sino que es simplemente un caso especial de la tendencia relativa en la que deliveradamente se ignora una variable o se considera constante.
El cálculo de este tipo de tendencias no es complejo y depende principalmente de la relación entre los activos. El principal problema es cuando se pretende usar para comparar, en tal caso se deberá realizar una estandarización previa para que la diferencia de escala no afecte a dicha comparación. Lo más normal es seleccionar un activo de referencia y dividir los precios de los activos que se estén estudiando entre los del activo de referencia. En el caso del cambio de moneda podrá variar en función del par que se esté tratando. Por poner un ejemplo, dado el precio de una acción A que vale 2€ y un tipo de cambio para el EUR/USD de 1,1. Si lo que se pretende es cambiar el precio a dólares habrá que tener en cuenta que el tipo de cambio se interpreta como que 1 Euro equivale a 1,1 Dólares, por lo que se deberá multiplicar (2 x 1,1 = 2,2), mientras que si la conversión es al revés se deberá dividir.
En el siguiente ejemplo vamos a comparar el rendimiento de AAPL, MSFT, GOOG, AMZN, TSLA, META, NVDA y BRK-A. Se ha elegido BRK-A en vez de BRK-B para poder apreciar el efecto de no aplicar la estandarización a las series temporales de forma más obvia. En los siguientes gráficos se empleará una escala logarítmica para que sea más fácil la comparación.
En este primer gráfico se puede apreciar los valores relativos de cada activo respecto al SPY sin estandarización previa. Como se puede ver BRK es la superior por bastante margen debido a que su precio es mucho mayor, por mucho que el retorno no haya superado el del activo de referencia. De manera opuesta TSLA está en la zona inferior, si bien su rendimiento ha sido considerablemente superior. Cuando se lleva a cabo la estadarización (gráfico inferior) BRK pasa a ser la inferior y TSLA la segunda mayor. Además se puede ver que en 2022 el rendimiento relativo de todos los activos decrecen en comparación con el del SPY, haciendo que la inversión en el SPY fuese la más recomendable, a excepción de BRK.
En este caso para estadarizar lo único que se ha hecho es calcular el retorno de las series temporales respecto a su primer valor, de tal forma que el valor relativo en realidad considera los retornos en vez del precio del activo. Además no se ha aplicado el cambio de divisa puesto que la relación entre los activos se mantendría igual debido a que todos cotizan en dólares. Aplicar el cambio de divisa tendría sentido al comparar inversiones con distinta unidad monetaria. A modo de ejemplo y para aclarar la explicación si se aplica dicho cambio de moneda a AAPL porque se está considerando una inversión en un activo europeo y la moneda que se usa por el inversor son Euros el precio al final del periodo es de 164€ en vez de 176$ y su retorno total sería de un 1300% en vez de 1100%, debido a que durante dicho periodo el Euro se ha devaluado respecto al Dólar. De esta manera si se compara con un activo que en euros ha logrado un rendimiento de 1200% durante ese mismo periodo, en caso de no haber aplicado el cambio de moneda parecería que el retorno del segundo activo es mayor cuando en realidad la inversión en AAPL habría ganado un 100% más que el activo europeo gracias a la exposición al USD.
En realidad habría que considerar más conceptos para poder comparar activos puesto que probablemente los costes de entrada y salida del mercado y los de mantenimiento de posiciones difieran, estos deberían estar reflejados para hacer una compararción más precisa.
Es muy importante considerar que todas las posesiones materiales son posiciones y algunas pueden ser más rentables que otras, desde la casa en la que vives o el coche que te compras hasta dónde tienes tu dinero. La principal ventaja de considerar tendencias absolutas es la menor necesidad de datos de mercado y la mayor simplicidad de los sistemas, permitiendo desarrollar estrategias de manera más sencilla. La principal desventaja es la exposición a riesgos que no se tienen en cuenta y el coste de oportunidad.
Las comisiones en el trading son un aspecto crítico que a menudo pasa desapercibido pero que puede tener un impacto significativo en la rentabilidad de una estrategia de inversión. Estas comisiones son los costes asociados con la ejecución de operaciones financieras en los mercados, y aunque pueden parecer pequeñas individualmente, su acumulación a lo largo del tiempo puede tener un efecto considerable en los resultados finales. Es importante entender que las comisiones no solo se limitan a las tarifas de corretaje que se cobran por comprar y vender activos, sino que también pueden incluir otros costes como spreads, cargos por financiamiento (apalancamiento), y comisiones de gestión en el caso de fondos de inversión. Por lo tanto, es crucial tener en cuenta todos estos factores al evaluar la rentabilidad de una estrategia de inversión.
Uno de los motivos fundamentales para prestar atención a las comisiones al probar una estrategia de inversión es que pueden reducir significativamente los rendimientos netos. Incluso una estrategia que parezca rentable en términos brutos puede volverse no rentable después de tener en cuenta las comisiones asociadas con la ejecución de las operaciones. Por lo tanto, es esencial calcular el impacto de las comisiones en los rendimientos esperados y asegurarse de que la estrategia sea lo suficientemente robusta como para generar ganancias netas después de tener en cuenta estos costos. Esto es más importante cuanto más frecuente sea la operativa de la estrategia dado que las comisiones totales aumentarán proporcionalmente a la cantidad de transacciones que se hagan. En las estrategias de más corto plazo, las comisiones pueden representar una parte significativa del capital invertido y pueden erosionar rápidamente cualquier beneficio potencial. Por lo tanto, es importante evaluar si una estrategia es factible dadas las tarifas de comisión y otros costos asociados.
Asimismo, las comisiones pueden influir en la elección de los instrumentos financieros en los que se invierte. Por ejemplo, las estrategias que involucran activos con spreads estrechos o sin comisiones o menor coste de apalancamiento pueden resultar más atractivas desde el punto de vista de la rentabilidad debido a los costos más bajos asociados con la ejecución de operaciones. Si bien es altamente probable que la elección de instrumentos financieros a operar se vea más afectada por el capital disponible y los márgenes requeridos.
Al realizar un backtest de una estrategia de inversión, es fundamental incluir una estimación realista de las comisiones asociadas con la ejecución de operaciones. Estas comisiones pueden variar según el tipo de activo, el broker utilizado y el volumen de operaciones, entre otros factores. Sin embargo, una estimación comúnmente aceptada para las comisiones de trading oscila entre el 0.1% y el 1% del valor total de la operación, si bien personalmente prefiero suponer un valor mayor.
Si se pretende hacer una buena aproximación lo primero será siempre tratar de reflejar las comisiones fijas como son las de corretaje, conexión a mercado, financiamiento o gestión. Este tipo de comisiones son las más fáciles de tener en cuenta ya que están definidas y solo habrá que consultarlas, a veces consultarlas resulta más complicado de lo que parece. El segundo paso será realizar una estimación de los parámetros que dependen del mercado, como son los spreads y el deslizamiento. En la mayor parte de los casos se puede desarrollar una ecuación relativamente sencilla basándose en la volatilidad y la liquidez del activo subyacente. Para evitar tener que realizar dicha estimación se pueden filtrar activos, es una práctica habitual es operar activos en los que el volumen de operación no supere el 5-10% de tal manera que el deslizamiento sea menos probable. Además también se pueden filtrar los activos por volatilidad, aumentando o disminuyendo la repercusión del spread.
La estrategia que se usará para el ejemplo operará un solo contrato y solo en largo el SPY. Se tomarán posiciones en función de la posición de la apertura de la vela actual relativa a la media del cierre del día anterior. En el gráfico superior se pueden apreciar los retornos brutos y netos de la estrategia en comparación con la estrategia DCA (Dollar Cost Average) sobre el mismo activo financiero. En la parte inferior se pueden apreciar los drawdowns de las tres trazas antes mencionadas.
Se puede observar como, si bien el rendimiento bruto es mayor y considerablemente más estable que la estrategia DCA, al considerar las comisiones se obtiene un retorno considerablemente menor. Esto se podría solventar con mayor apalancamiento dado que la volatilidad sigue siendo menor que para el DCA. Pero habría que plantearse si uno sería capaz de seguir esta estrategia teniendo en cuenta que se podrían repetir periodos como el que se aprecia entre 2015 y 2019 en el cual no obtuvo prácticamente rendimiento ninguno debido a la erosión por una operativa más frecuente.
Es importante incluir las comisiones al realizar un backtest de una estrategia porque reflejan los costes reales que se incurrirían al ejecutar las operaciones en un entorno de trading en vivo. Ignorar estos costes podría conducir a una sobreestimación de la rentabilidad de la estrategia y a expectativas poco realistas en cuanto a los rendimientos esperados.
Además, tener en cuenta las comisiones en el backtest permite evaluar la viabilidad de la estrategia. Si las comisiones representan una parte significativa de los rendimientos generados por la estrategia, esto podría indicar que la estrategia no es económicamente viable, especialmente si los rendimientos netos después de comisiones no son suficientes para justificar los costes asociados con la ejecución de las operaciones.
El seguimiento de tendencias es un enfoque de inversión que se basa en la idea de que los activos financieros tienden a moverse en direcciones establecidas durante ciertos períodos de tiempo. En otras palabras, esta estrategia busca capitalizar las tendencias del mercado, ya sea al alza o a la baja, en lugar de intentar predecir la dirección futura del mercado. Una vez que se identifica una tendencia, ya sea alcista o bajista, se suelen abrir posiciones en la dirección de la tendencia dominante y se mantienen esas posiciones hasta que la tendencia comienza a revertirse, momento en el cual se buscarán nuevas oportunidades. La estrategia de seguimiento de tendencias puede aplicarse a diversos mercados financieros, como acciones, divisas, materias primas y bonos, y puede adaptarse a diferentes horizontes temporales de inversión, desde operaciones intradía hasta inversiones a largo plazo. Sin embargo, es importante tener en cuenta que ninguna estrategia de inversión es infalible y que el seguimiento de tendencias puede tener sus puntos flacos, como la aparición de falsas señales.
El seguimiento de tendencias tiene sus orígenes en el análisis técnico, un enfoque que se remonta al menos al siglo XIX, cuando los operadores de mercado comenzaron a estudiar los patrones de precios y los movimientos del mercado para identificar oportunidades de inversión. Sin embargo, fue en el siglo XX cuando el seguimiento de tendencias empezó a tomar forma como una estrategia sistemática y cuantificable. Durante la década de 1970, experimentó un auge significativo, especialmente en los mercados de futuros y materias primas. Los inversores comenzaron a emplear estrategias basadas en reglas para aprovechar las tendencias a largo plazo en estos mercados, lo que llevó a la popularización de enfoques sistemáticos y cuantitativos para el seguimiento de tendencias. En la década de 1980, gracias al trabajo de varios gestores de fondos de cobertura y traders famosos que empleaban estrategias basadas en esta técnica, se popularizó aún más. Estos inversores obtuvieron retornos significativos utilizando este tipo de estrategias durante períodos de volatilidad del mercado, lo que atrajo la atención del público y contribuyó a la difusión de estas estrategias entre una amplia audiencia de inversores. Con el avance de la tecnología y la computación en las últimas décadas, el seguimiento de tendencias ha evolucionado aún más. Los inversores ahora utilizan algoritmos y modelos cuantitativos sofisticados para identificar y capitalizar tendencias en los mercados financieros. En la actualidad, las estrategias de seguimiento de tendencias son una parte integral del paisaje de inversión global y continúan siendo empleadas por una amplia variedad de inversores en diferentes mercados y clases de activos. Su historia de evolución y popularización refleja su importancia y su capacidad para generar retornos consistentes en diversos entornos de mercado.
Las principales características de este tipo de estrategias son una baja probabilidad de acierto y un alto ratio de beneficio entre riesgo. Esto se traduce en periodos de pérdida largos compensados por pocas operaciones con grandes beneficios. No todo el mundo es capaz de aguantar dichos periodos y habrá que tener mucha disciplina para no dejarse llevar por las emociones, este es el principal motivo por el que gran parte de los adeptos a este tipo de estrategias hayan optado por una operativa sistematizada.
Cabe destacar que existen dos tipos de estrategia, las discretas y las continuas. Las primeras constan de entradas y salidas únicas, gestionándose cada operación por separado. Este tipo de estrategias solo se encuentra expuesta al mercado durante periodos en los que hay señales. En las continuas para una única operación se pueden tener múltiples entradas y múltiples salidas, son estrategias que suelen estar la mayor parte del tiempo expuestas al mercado. La principal diferencia entre ellas es la generación de la señal. En la primera se busca una señal cuando sucede un acontecimiento, como podría ser la ruptura de una resistencia. Mientras que en la segunda se busca exponerse al mercado de forma proporcional a una señal, por ejemplo la diferencia entre el precio y su media móvil, de tal forma que cuanto mayor sea la distancia positiva mayor será la posición en largo y cuanto mayor sea la distancia negativa mayor será la posición en corto.
El primer paso es definir el momento en el que se empieza una tendencia. La práctica más habitual es definir un "breakout" (ruptura), esto se refiere a un evento en el que el precio de un activo financiero rompe o supera un nivel de resistencia importante o un nivel de soporte significativo en el gráfico de precios.
En este ejemplo usaremos una estrategia basada en el Canal de Donchian, este indicador calcula el máximo y el mínimo del precio durante los n últimos periodos. La regla de entrada será la ruptura del canal. Cuando el máximo de la vela supere o iguale (técnicamente no puede superar porque el canal se actualiza con los precios máximos) la línea superior del canal se entrará una posición en largo, mientras que si rompe a la baja la línea inferior del canal se entrará en una posición en corto. A menudo este segundo tipo de entrada se ignora, solo tomando posiciones en largo (alcistas).
Es importante destacar que las rupturas pueden ser falsas señales, especialmente en mercados lateralizados o durante períodos de baja liquidez. Por lo tanto, se suelen utilizar confirmaciones adicionales, como el volumen de negociación u otros indicadores técnicos, para validar una ruptura antes de tomar decisiones de trading basadas en ella.
Para este ejemplo se buscará que la tasa de cambio el precio de cierre esté entre dos valores. Esto se debe a que si el precio no cambia mucho puede ser que la variación no tenga la fuerza suficiente como para crear una tendencia y si por el contrario cambia muy rápidamente llamará la atención de los operadores de reversión que buscarán vender en corto.
Las estrategias tendenciales tienden a funcionar mejor en regímenes de mercado favorables, sobre todo cuando su horizonte temporal es más largo. Esto es debido a la mayor claridad de las tendencias, el menor ruido del mercado, la mayor participación del mercado, el seguimiento de la tendencia por parte de los inversores y la menor volatilidad, lo que crea un entorno propicio para la identificación y explotación de las tendencias del mercado. Si se aplica este tipo de estrategias sobre un universo de activos muy correlacionado es recomendable desarrollar un método para filtrar los regímenes de mercado que son poco favorables. Cuando el universo de activos está poco correlacionado es posible que haya distintos regímenes para distintos activos por lo que sería contraproducente filtrarlo.
Los seguidores de tendencias suelen intentar explotar las tendencias durante el mayor tiempo posible para exprimir al máximo la misma. A menudo en vez de definir precios de salida con beneficios prefieren definir un retroceso máximo del precio tras el cual se saldrán. El "Stop Loss" (SL) es el mecanismo usado para definir la pérdida máxima de una operación, se trata de una orden que, cuando es alcanzada por el precio, cierra la posición. El hecho de que sea dinámico hace referencia a que esta orden se irá moviendo con la fluctuación del precio. Hay distintas formas de moverlo, la más común es mover la orden proporcionalmente al precio solo cuando este se mueve en sentido favorable para la operación.
En el caso propuesto se empleará un Canal de Donchian con un periodo inferior al usado para las entradas. De tal forma que una posición en largo se cerrará cuando el precio alcance la línea inferior del canal y viceversa para las posiciones en corto.
Cuando se trata de operar múltiples activos habrá periodos de tiempo en los que se obtengan demasiadas señales y no se puedan aprovechar todas debido a restricciones de capital. Habrá que emplear un sistema para clasificar las señales en función de su calidad. En el caso de las estrategias continuas esto se hace de forma natural por cómo se calculan las posiciones pero en el caso de las discretas habrá que definir una forma concreta de clasificar las señales.
A medida que el capital disponible para operar aumenta aparecen nuevos riesgos para la operativa. Uno de ellos es operar activos que no constan de suficiente liquidez para poder entrar y salir con la fluidez deseada, este se ve agrabado cuanto menor sea el horizonte temporal de la estategia debido a la importancia del precio de entrada. A menudo se definen límites de volumen para evitar este problema, pero es una solución parcial. Por mucho que el volumen comerciado de un activo sea alto, si debido a que el precio es muy bajo el tamaño de la posición es también alto, se puede dar una situación en la que no se pueda salir o entrar al precio que se quiere. La solución correcta sería tener límites para el volumen monetario en función de la posición que se desea tener. Un ejemplo sería que la posición suponga solo un 1% de la media de volumen diario calculada durante el último mes multiplicada por el precio del activo. Esto no evita que se puedan dar situaciones de falta de liquidez pero si disminuye su probabilidad.
Después de haber definido todos los parámetros anteriores se deberá realizar un "backtest", el objetivo es ver si la estrategia habría sido rentable. Se realiza un backtest para no perder el tiempo ni el dinero al comprobar la rentabilidad de las estrategia, obviamente el rendimiento real será distinto al de dicho backtest pero uno se puede formar una idea a partir del mismo. Además es recomendable llevar a cabo una prueba de esfuerzo, en esta se modificarán los parámetros de la estrategia para ver si sigue siendo rentable o no. Si difiere mucho el resultado obtenido entre pruebas quiere decir que la estrategia es poco robusta, por lo que el backtest es menos fiable y habrá que tener más cuidado con su implementación en entorno real. La robestez a menudo puede ser motivo suficiente para desechar la estrategia.
En el ejemplo propuesto el backtest se hará sobre el Bitcoin. Además se hará la prueba de esfuerzo modificando los periodos de las líneas de los canales de Donchian y la distancia inicial del Stop Loss. Para cada prueba se definirán las siguientes métricas:
El resultado se puede ver en la tabla a continuación.
N. Trades | P. Media | G. Media | Fiabilidad | Frecuencia | Esperanza | Max. DD | Kelly | |||
---|---|---|---|---|---|---|---|---|---|---|
Margen SL | Indicador | Orden | ||||||||
1 | 50 50 20 20 | MARKET | 44 | -2.39% | 51.23% | 29.55% | 1.82% | 13.45% | 13.29% | 26.26% |
LIMIT | 40 | -3.72% | 36.80% | 32.50% | 1.66% | 9.45% | 23.10% | 25.67% | ||
STOP | 47 | -2.96% | 41.52% | 27.66% | 2.08% | 9.34% | 17.27% | 22.51% | ||
20 20 10 10 | MARKET | 44 | -2.39% | 51.23% | 29.55% | 1.82% | 13.45% | 13.29% | 26.26% | |
LIMIT | 40 | -3.72% | 36.80% | 32.50% | 1.66% | 9.45% | 23.10% | 25.67% | ||
STOP | 47 | -2.96% | 41.52% | 27.66% | 2.08% | 9.34% | 17.27% | 22.51% | ||
20 10 10 5 | MARKET | 44 | -2.39% | 51.23% | 29.55% | 1.82% | 13.45% | 13.29% | 26.26% | |
LIMIT | 40 | -3.72% | 36.80% | 32.50% | 1.66% | 9.45% | 23.10% | 25.67% | ||
STOP | 47 | -2.96% | 41.52% | 27.66% | 2.08% | 9.34% | 17.27% | 22.51% | ||
2 | 50 50 20 20 | MARKET | 46 | -2.40% | 47.68% | 28.26% | 1.91% | 11.76% | 15.60% | 24.65% |
LIMIT | 40 | -3.78% | 37.72% | 32.50% | 1.66% | 9.71% | 25.87% | 25.74% | ||
STOP | 51 | -2.83% | 41.36% | 25.49% | 2.26% | 8.43% | 25.02% | 20.39% | ||
20 20 10 10 | MARKET | 46 | -2.40% | 47.68% | 28.26% | 1.91% | 11.76% | 15.60% | 24.65% | |
LIMIT | 40 | -3.78% | 37.72% | 32.50% | 1.66% | 9.71% | 25.87% | 25.74% | ||
STOP | 51 | -2.83% | 41.36% | 25.49% | 2.26% | 8.43% | 25.02% | 20.39% | ||
20 10 10 5 | MARKET | 46 | -2.40% | 47.68% | 28.26% | 1.91% | 11.76% | 15.60% | 24.65% | |
LIMIT | 40 | -3.78% | 37.72% | 32.50% | 1.66% | 9.71% | 25.87% | 25.74% | ||
STOP | 51 | -2.83% | 41.36% | 25.49% | 2.26% | 8.43% | 25.02% | 20.39% | ||
4 | 50 50 20 20 | MARKET | 46 | -2.43% | 43.32% | 30.43% | 1.91% | 11.49% | 16.37% | 26.53% |
LIMIT | 40 | -3.85% | 37.98% | 32.50% | 1.66% | 9.74% | 28.14% | 25.65% | ||
STOP | 54 | -3.04% | 39.60% | 24.07% | 2.39% | 7.22% | 31.18% | 18.24% | ||
20 20 10 10 | MARKET | 46 | -2.43% | 43.32% | 30.43% | 1.91% | 11.49% | 16.37% | 26.53% | |
LIMIT | 40 | -3.85% | 37.98% | 32.50% | 1.66% | 9.74% | 28.14% | 25.65% | ||
STOP | 54 | -3.04% | 39.60% | 24.07% | 2.39% | 7.22% | 31.18% | 18.24% | ||
20 10 10 5 | MARKET | 46 | -2.43% | 43.32% | 30.43% | 1.91% | 11.49% | 16.37% | 26.53% | |
LIMIT | 40 | -3.85% | 37.98% | 32.50% | 1.66% | 9.74% | 28.14% | 25.65% | ||
STOP | 54 | -3.04% | 39.60% | 24.07% | 2.39% | 7.22% | 31.18% | 18.24% | ||
6 | 50 50 20 20 | MARKET | 46 | -2.42% | 43.09% | 30.43% | 1.91% | 11.43% | 16.64% | 26.53% |
LIMIT | 40 | -3.89% | 38.11% | 32.50% | 1.66% | 9.76% | 29.43% | 25.61% | ||
STOP | 54 | -3.13% | 42.88% | 22.22% | 2.39% | 7.09% | 28.26% | 16.54% | ||
20 20 10 10 | MARKET | 46 | -2.42% | 43.09% | 30.43% | 1.91% | 11.43% | 16.64% | 26.53% | |
LIMIT | 40 | -3.89% | 38.11% | 32.50% | 1.66% | 9.76% | 29.43% | 25.61% | ||
STOP | 54 | -3.13% | 42.88% | 22.22% | 2.39% | 7.09% | 28.26% | 16.54% | ||
20 10 10 5 | MARKET | 46 | -2.42% | 43.09% | 30.43% | 1.91% | 11.43% | 16.64% | 26.53% | |
LIMIT | 40 | -3.89% | 38.11% | 32.50% | 1.66% | 9.76% | 29.43% | 25.61% | ||
STOP | 54 | -3.13% | 42.88% | 22.22% | 2.39% | 7.09% | 28.26% | 16.54% |
Como se puede observar el tipo de orden utilizada para abrir la posición influye bastante, probablemente por emplear niveles diarios para la colocación de las órdenes limitadas o stop. Además se puede apreciar un aumento del drawdown máximo y una disminución de la esperanza matemática a medida que se amplía el margen al Stop Loss. Esto se debe a que el tamaño de posición será menor y las ganancias no podrán compensar con tanta holgura las pérdidas incurridas en los drawdowns. Se ve reflejado también en el decremento de las ganancias medias y el incremento de las pérdidas medias. Si bien al haber más margen para posible movimiento del precio debido al ruido la fiabilidad es algo mayor si bien en general es muy baja, como es normal en este tipo de estrategias. En la siguiente gráfica se puede apreciar una curva de balance obtenida durante el backtest, aplicando unas comisiones que se traducirían en un 15% del retorno bruto de las operaciones de media. Dicho balance está calculado de forma diaria, por lo que el drawdown máximo asciende a un 54%. Esto se debe a que el precio puede hascender mucho más rápido que el Stop Loss dinámico y realizar un retroceso bastante grande para finalmente recuperar gran parte de ese retroceso y cerrar la operación. El drawdown calculado de esta forma estaría teniendo en cuenta las ganancias no realizadas mientras que los que se ven en la tabla anterior son sobre ganancias realizadas. En la gráfica se aprecian los pocos periodos en los que hay grandes retornos y las falsas señales entre medias.
Las estrategias de seguimiento de tendencias son difíciles de operar de forma discrecional pero pueden ser muy rentables si se hace con cabeza. Este ejemplo no es representativo ya que el Bitcoin es un activo con un retorno bastante atípico, además se ha considerado un universo de un solo activo cuando este tipo de estrategias se benefician enormemente de universos mayores y descorrelacionados. Si se quiere aprender más sobre este tipo de estrategias leer los blogs de Nick Radge (The Chartist - Share Trading Strategies & Technical Analysis) y Robert Carver (This Blog is Systematic (qoppac.blogspot.com)). Ambos son gestores especializados en seguimiento de tendencias que siguen en activo y crean contenido educativo, el primero se decanta más por estrategias discrecionales y el segundo por estrategias continuas.
La media móvil es uno de los indicadores técnicos más utilizados para el análisis de tendencias en series temporales. Pero muchas personas la utilizan sin entender cómo funciona. En este artículo aprenderás a calcular varios tipos de medias móviles para comprender su comportamiento, fortalezas y debilidades.
Una media móvil es simplemente el cálculo de una media aritmética sobre una muestra de los datos que evoluciona con el tiempo. Esto significa que para el punto de tiempo t y un período de la media móvil n debes sumar los valores de una muestra que incluya los últimos n valores hasta t y luego dividir el total por el número de valores en la muestra (n). De esta manera la ecuación queda como a continuación:
media = sum(muestra[t-n:t])/n
Al aplicar este cálculo a una muestra de datos de más de n valores se empezará usando una muestra que contenga los primeros n valores. Pero, para la próxima iteración se reemplazará el primer valor de la muestra con el siguiente valor de la serie temporal (n+1) y se iterará este proceso sobre toda la serie temporal. A esto se le llama Media Móvil. Cabe destacar que no se puede obtener la media para los primeros n-1 valores a menos que se haga la media con un periodo más corto.
Esta es la más simple de todas y da el mismo peso a todos los valores, este es el cálculo de la media aritmética de la fórmula anterior. A partir de aquí, se utilizará el módulo pandas
para la manipulación de datos; se pueden realizar todos los cálculos sin usarlo, pero será menos eficiente. El siguiente código muestra cómo calcular un promedio móvil simple con pandas
:
import pandas as pd
data = pd.DataFrame({'a':[1, 2, 3, 4, 5, 6, 7, 8, 9],
'b':[9, 8, 7, 6, 5, 4, 3, 2, 1]})
data['c'] = data['a'].rolling(3).mean()
El pandas.DataFrame
está compuesto por las columnas a y b, en este caso en la última línea de código se aplica la media móvil a la columna a y se almacenará en la columna c. Para calcular el indicador se usarán dos funciones: rolling
y mean
. La primera es para iterar sobre muestras de 3 valores, en este caso, y la segunda para calcular la media aritmética. En el siguiente cuadro se puede apreciar el resultado del cálculo y se puede observar lo que se comentó antes. Los dos primeros valores no se han podido calcular puesto que no se puede formar una muestra lo suficientemente grande para cumplir con el periodo de la media.
0 NaN
1 NaN
2 2.0
3 3.0
4 4.0
5 5.0
6 6.0
7 7.0
8 8.0
Name: c, dtype: float64
La media móvil exponencial otorga pesos exponenciales, siguiendo la siguiente fórmula.
media[t] = muestra[t]*(1+n) + media[t-1]*(1-(1+n))
Para iterar la media mientras se aplica el nuevo método de ponderación se usará la función ewm
en lugar de rolling
, con algunos parámetros adicionales. Se utilizará el mismo pandas.DataFrame
que en el ejemplo anterior para los datos de base.
data['c'] = data['a'].ewm(span=3, adjust=False, min_periods=3).mean()
El resultado difererirá ligeramente de los obtenidos con la SMA pero son muy parecidos.
0 NaN
1 NaN
2 2.250000
3 3.125000
4 4.062500
5 5.031250
6 6.015625
7 7.007812
8 8.003906
Name: c, dtype: float64
La media móvil de ponderación lineal, también llamada media móvil de ponderado acumulativo, aplica la siguiente fórmula.
media[t] = (muestra[t]*n + muestra[t-1]*(n-1) + ... + muestra[t-n]*(1))/(1 + 2 + ... + n)
O, lo que es lo mismo.
pesos = [i+1 for i in range(n)]
media[t] = sum([valor*(i+1)/sum(pesos) for i, valor in enumerate(muestra[t-n:t])])
El último precio es el que tiene el mayor peso, que será n/n!
y el peso del último precio será 1/n!
donde n!
es el número combinatorio, por si alguien no lo conoce. El siguiente código muestra cómo aplicar la fórmula a un pandas.DataFrame
, pero, en este caso, se necesitará una nueva librería: numpy
.
import numpy as np
pesos= np.arange(1,3+1)
data['c'] = data['a'].rolling(3).apply(
lambda valores: np.dot(valores, pesos)/pesos.sum(),
raw=True)
El código anterior aplicado a los datos del primer ejemplo devuelve lo siguiente:
0 NaN
1 NaN
2 2.333333
3 3.333333
4 4.333333
5 5.333333
6 6.333333
7 7.333333
8 8.333333
Name: c, dtype: float64
Cuando comparamos todos los métodos de cálculo de la media móvil que hemos visto, está claro que la EMA es la media móvil más rápida en reaccionar a los giros de series temporales y la SMA es la más lenta. Cuál usar dependerá de la serie temporal y las preferencias de cada uno.
Las medias móviles son uno de los indicadores de tendencia más simples y más utilizados. Dependiendo de sobre qué se calculen, se pueden usar de diferentes maneras. Por ejemplo, cuando se aplican al trading, se pueden usar para la clasificación de tendencias o como soporte y resistencia.