En el dinámico mundo de las inversiones, la capacidad de tomar decisiones informadas y estratégicas es fundamental para el éxito de cualquier empresa de compra de acciones. En este contexto, Global Securities Colombia se ha propuesto llevar a cabo un proyecto integral de analítica descriptiva y predictiva con el objetivo de potenciar su capacidad de análisis y mejorar sus decisiones de inversión. Global Securities Colombia conoce a profundidad el funcionamiento de los productos de inversión y sus beneficios, sin embargo la llegada de un nuevo canal 100% digital para potenciar de manera inteligente la capacidad de comprar acciones por parte del inversionista, pone la empresa frente a la inevitable transformación de todos los productos financieros.
Este informe final presenta los hallazgos y resultados obtenidos durante el desarrollo del proyecto, el cual se divide en dos partes fundamentales: analítica descriptiva (EDA) y analítica predictiva (modelado).
En la primera parte, se llevó a cabo un exhaustivo análisis exploratorio de datos con el fin de extraer insights significativos del conjunto inicial de datos. Este análisis no solo permitió identificar tendencias clave en el mercado de acciones, sino también proporcionó una visión profunda de los factores que influyen en el rendimiento de las empresas. Similar a un Business Intelligence (BI), este enfoque permitió a Global Securities Colombia obtener una comprensión más completa y contextualizada del entorno en el que opera, facilitando así la toma de decisiones fundamentadas.
En la segunda parte del proyecto, nos adentramos en el campo de la analítica predictiva, donde se quiere implementar un modelo predictivo para estimar la clasificación de si una empresa es favorable o no para comprar acciones. A través de técnicas avanzadas de aprendizaje automático y modelado predictivo, se propone construir un modelo robusto capaz de evaluar una amplia gama de variables independientes y generar predicciones precisas y confiables. Este modelo no solo proporciona a Global Securities Colombia una herramienta invaluable para evaluar el potencial de inversión de diferentes empresas, sino que también allana el camino para una toma de decisiones más ágil y eficaz.
Realizar un análisis exploratorio de datos exhaustivo con el fin de identificar tendencias, patrones y relaciones significativas en el mercado de acciones, así como en los factores que influyen en el rendimiento de las empresas. Este análisis descriptivo permitirá extraer insights relevantes para la toma de decisiones informadas y estratégicas por parte de Global Securities Colombia
Implementar técnicas de Machine Learning para desarrollar un modelo de clasificación para determinar si cierta firma con determinadas variables financieras es favorable para comprar acciones en ella o no con el fin de minimizar pérdidas e impulsar la toma de deciones basada en datos para añadir valor al negocio
Los datos usados en este caso de estudio provienen de un proyecto de aprendizaje de IA llamado “AI Learn to invest” del libro SaturdaysAI - Euskadi 1st edition. Se recopilaron más de 900 inversiones aleatorias con los datos de los últimos 10 años del mercado NYSE (The New York Stock Exchange). Los ratios financieros y la volatilidad fueron calculadas y agregaron al conjunto de datos de inversiones aleatorias.
Biblioteca de datos: En su totalidad, el conjunto de datos utilizados
contiene estas características
| Columna | Descripción |
|---|---|
| company | Acrónimo de la compañía |
| sector | Sector de la compañía |
| horizon (days) | Números de dias desde que se compra hasta que se vende |
| amount | Número de dólares invertidos |
| date_BUY_fix | Fecha de compra |
| date_SELL_fix | Fecha de venta |
| price_BUY | Precio de compra de la acción |
| price_SELL | Precio de venta de la acción |
| Volatility_Buy | Volatilidad al comprar |
| Volatility_sell | Volatilidad al vender |
| Sharpe Ratio | Sharpe Ratio |
| expected_return (yearly) | Retorno anual esperado en dólares |
| inflation | Inflación durante la variable horizon (days) |
| nominal_return | Retorno nominal |
| ESG_ranking | ESG_ranking |
| PE_ratio | PE_ratio |
| EPS_ratio | EPS_ratio |
| PS_ratio | PS_ratio |
| PB_ratio | PB_ratio |
| NetProfitMargin_ratio | Utilidad neta anual |
| current_ratio | Reporte de utilidad más reciente de la firma |
| roa_ratio | roa_ratio |
| roe_ratio | roe_ratio |
| investment | Categoría si es buena (1) inversión o mala (0) |
El objetivo en esta sección es hacer un análisis exploratorio de
datos, en el cual se busca indagar sobre nuestros datos, es decir: ver
cómo son sus distribuciones, que relación tienen las variables con
respecto a la variable objetivo, revisar correlaciones, datos nulos,
repetidos y por ultimo pero no menos importante mirar insight
importantes sobre nuestros datos hasta donde la analitica descriptiva
nos permita ver.
De la misma manera, se busca ver las relaciones de
ciertas variables sobre la varaible que nos interesa para este caso de
estudio, la cual es investment.
| company | sector | horizon (days) | amount | date_BUY_fix | date_SELL_fix | price_BUY | price_SELL | Volatility_Buy | Volatility_sell | Sharpe Ratio | expected_return (yearly) | inflation | nominal_return | ESG_ranking | PE_ratio | EPS_ratio | PS_ratio | PB_ratio | NetProfitMargin_ratio | current_ratio | roa_ratio | roe_ratio | investment |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| BBY | RETAIL | 2 | 100 | 2017-05-25 | 2017-05-26 | 55.5518035888672 | 53.4839134216309 | 0.383665561445214 | 0.385748037581804 | 0.383665561445214 | 0.00143725177373282 | 1.96 | -0.0372245369842635 | 12 | 12.58 | 3.73 | 0.38 | 3.19 | 3.01 | 1.49 | 8.69 | 26.69 | BAD |
| BAC | BANK | 330 | 15000 | 2016-11-22 | 2017-10-18 | 18.6167488098145 | 24.6544723510742 | 0.32280914735273 | 0.236349982241439 | 0.32280914735273 | 0.170969089074298 | -0.2 | 0.324316753851068 | 26.3 | 11.39 | 1.26 | 1.71 | 0.54 | 15.7 | 0.92 | 0.67 | 5.54 | GOOD |
| AXP | BANK | 7 | 3000 | 2016-09-27 | 2016-10-04 | 59.8622970581055 | 59.5177268981934 | 0.238641964426928 | 0.23549052448518 | 0.238641964426928 | 0.00282362508670049 | -0.2 | -0.00575604640726786 | 19.8 | 10.58 | 5.64 | 1.67 | 2.6 | 15.68 | 1.91 | 3.39 | 25.78 | BAD |
| KSS | RETAIL | 5 | 20000 | 2016-10-11 | 2016-10-17 | 38.216724395752 | 35.9853286743164 | 0.428559475465407 | 0.42933966287501 | 0.428559475465407 | 9.38982975912348e-05 | -0.2 | -0.058387937655996 | 12.9 | 11.09 | 3.27 | 0.36 | 1.25 | 3.17 | 1.6 | 4.41 | 11.35 | BAD |
| JPM | BANK | 360 | 15000 | 2015-03-12 | 2016-03-07 | 51.8693351745605 | 52.047966003418 | 0.194611787041076 | 0.254011465927661 | 0.194611787041076 | 0.149978680823231 | -0.5 | 0.00344386193222372 | 27.9 | 9.38 | 5.46 | 1.87 | 0.81 | 19.91 | 0.99 | 0.81 | 8.91 | GOOD |
Primeramente, con el fin de ver el comportamiento de las ventas
de las acciones, realizamos un hsitograma de la columna
price_SELL. Como vemos, la distribución de precios de venta
de acciones está altamente concentrada en el rango más bajo, lo que
indica que la mayoría de las empresas tienen valores de mercado
relativamente bajos, esto tambien puede sugerir que muchas de las
empresas en tu dataset son de pequeña o mediana capitalización, en lugar
de empresas más grandes. Podemos decir que si bien no se puede
determinar solo con el histograma, un sesgo hacia la izquierda podría
indicar que las empresas en el dataset podrían ser más volátiles en
términos de precios de acciones, ya que los valores más bajos pueden
experimentar cambios más significativos en porcentaje. Luego, se podria
inferir que hay una posible exclusión de empresas grandes, es posible
que las empresas más grandes con precios de acciones más altos se
excluyan de este conjunto de datos, lo que podría sesgar la distribución
hacia la izquierda. Algo positivo, es que hubo potencial de
oportunidades de inversión, es decir, si para este periodo de tiempo se
estuviesen buscando oportunidades de inversión, un sesgo hacia la
izquierda podría indicar que hay un gran número de empresas con precios
de acciones relativamente bajos, lo que podría presentar oportunidades
para invertir en empresas con potencial de crecimiento.
ggplot(df, aes(x = price_SELL)) +
geom_histogram(binwidth = 0.5, fill = "skyblue", color = "black") +
labs(title = "Distribucion de Precio de venta de la accion", x = "Valores", y = "Frecuencia")
Ahora, dado que es un problema de clasificacion, queremos ver
como se comportan las clases, para esto veremos como se comportan las
categorias desde diferentes angulos, donde 0 se cataloga como mala
inversion para esa firma y 1 como buena
ggplot(df, aes(x = investment)) +
geom_bar(fill = "skyblue") +
labs(title = "Conteo de inversiones", x = "Inversión", y = "Conteo")+
scale_y_continuous(labels = scales::comma)
Notamos que existe un pequeño desbalance entre las dos
clases (35/65) (malas inversiones y buenas inversiones) en tu dataset.
Este desbalance podría tener implicaciones en el modelado y análisis
subsiguientes, ya que podría resultar en un sesgo hacia la clase
dominante. Será importante realizar un análisis más detallado de las
características de las empresas clasificadas como malas inversiones para
identificar posibles patrones, factores subyacentes y áreas de mejora.
Esto puede ayudar a los inversores y analistas a comprender mejor las
razones detrás de estas clasificaciones y tomar decisiones más
informadas en el futuro.
F3 <- df2 %>%
group_by(sector, investment) %>%
summarise(count = n()) %>%
ungroup() %>%
tidyr::pivot_wider(names_from = investment, values_from = count, values_fill = 0)
## `summarise()` has grouped output by 'sector'. You can override using the
## `.groups` argument.
# Calcular el porcentaje
F3 <- F3 %>%
mutate(porcentaje = GOOD/ (GOOD + BAD))
kable(F3, format = "markdown", align = c("l", "r", "r", "r"),
caption = "Tabla agrupada por Sector", row.names = FALSE)
| sector | BAD | GOOD | porcentaje |
|---|---|---|---|
| AUTO | 57273 | 22563 | 0.2826169 |
| BANK | 59592 | 25165 | 0.2969076 |
| FMCG | 32239 | 19756 | 0.3799596 |
| RETAIL | 63896 | 32373 | 0.3362765 |
| TECH | 51440 | 40961 | 0.4432961 |
Podemos ver varias tendencias remarcables en la tabla
agrupada, por ejemplo en el sector de bienes de consumo masivo (FMCG)
hay una proporción relativamente alta de empresas clasificadas como
“BAD” en comparación con las clasificadas como “GOOD”, mientras que en
el sector tecnológico (TECH) sucede lo contrario. Tambien evidenciamos
oportunidades de inversión como es el sector tecnológico (TECH) parece
tener un rendimiento particularmente bueno en términos de inversiones.
Un análisis de correlación de Spearman se utiliza para
evaluar la relación entre dos variables, especialmente cuando estas
variables no siguen una relacion no lineal. En este contexto, donde hay
información financiera y datos sobre si una empresa es una buena o mala
inversión, un análisis de correlación de Spearman podría ser útil para
comprender cómo diferentes indicadores financieros se relacionan con la
calidad de la inversión (buena o mala), del mismo modo, La correlación
de Spearman es menos sensible a los valores atípicos que la correlación
de Pearson, por lo que puede proporcionar una medida más robusta de la
relación entre las variables incluso en presencia de valores atípicos en
el conjunto de datos.
datos_numericos <- df[sapply(df, is.numeric)]
# Calcular la matriz de correlación
matriz_correlacion <- cor(datos_numericos, method = "spearman")
# Establecer el tamaño del gráfico
options(repr.plot.width = 8, repr.plot.height = 8) # Cambia estos valores según tu preferencia
# Visualizar la matriz de correlación como un mapa de calor
corrplot(matriz_correlacion, method = "color",
addCoef.col = "black", # color de los coeficientes
tl.col = "black", # color del texto de las etiquetas
tl.srt = 45, # ángulo de las etiquetas
diag = FALSE, # no mostrar los coeficientes en la diagonal principal
tl.cex = 0.7, # tamaño del texto de las etiquetas
mar = c(0,0,1,0), # margen alrededor del gráfico
number.cex = 0.5
)
Elegimos El top 5 de variables con mayor correlacion tanto positiva
como negativa sobre la variable respuesta investment,
serian: nominal_return, inflation,
NetProfitMargin_ratio,
roa_ratio``,price_SELL`
¿Cómo se comportan las variables respecto a la variable target? - Boxplots
ggplot(df2, aes(y = investment, x = nominal_return)) +
geom_boxplot(color = "cadetblue") +
labs( y = "investment")
ggplot(df2, aes(y = investment, x = inflation)) +
geom_boxplot(color = "cadetblue") +
labs( y = "investment")
ggplot(df2, aes(y = investment, x = NetProfitMargin_ratio)) +
geom_boxplot(color = "cadetblue") +
labs( y = "investment")
ggplot(df2, aes(y = investment, x = roa_ratio)) +
geom_boxplot(color = "cadetblue") +
labs( y = "investment")
ggplot(df2, aes(y = investment, x = price_SELL)) +
geom_boxplot(color = "cadetblue") +
labs( y = "investment")
Como podemos evidenciar, para la variable de
nominal_return, esta tiene muchisimos datos atipicos por
mayor del rango intercuartilico, esto se puede deber a que mucha
empresas catalogadas como “GOOD” tienen esta variable mucho mas alta,
aunque se puede indagar mas profundamente ya que en la categoria de
“BAD” tambien hay.
Algo que causa curiosidad es en el box-plot de
price_SELL, ya que como vimos previamente en el histograma,
los datos estan mayormente sesgados a la izquierda, son muy pocas las
empresas que de verdad logran vender sus acciones a mucho mejor precio
que las demas y esto se ve reflejado en el diagrama de cajas y bigotes
En este diagrama evolutivo del precio de venta podemos notar que sugiere una tendencia alcista en el mercado de acciones dentro de este periodo de tiempo. Esto puede indicar que las empresas en tu dataset están experimentando un crecimiento en su valor de mercado a medida que pasa el tiempo. Tambien se podria inferir que esto nos da una confianza del mercado, ya que un aumento en el precio de las acciones también puede indicar una mayor confianza del mercado en las perspectivas futuras de las empresas. Los inversores podrían estar comprando acciones en anticipación de un rendimiento positivo continuo en el futuro.
ggplot(df, aes(x = date_SELL_fix, y = price_SELL)) +
geom_line(color = "blue") +
scale_x_date(labels = function(x) format(x, "%Y\n%b")) +
labs(title = "Evolución del precio de venta a lo largo del tiempo",
x = "Tiempo",
y = "Valor")