├── images ├── boxplot1.png ├── boxplot2.png ├── prices.png ├── 1_dataframe.png ├── 2_coinmarket.png ├── data_limpio.png └── data_original.png ├── .gitignore ├── __pycache__ └── functions.cpython-39.pyc ├── global_data.py ├── main.py ├── functions.py └── README.md /images/boxplot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pabloing93/Trading-Robot/HEAD/images/boxplot1.png -------------------------------------------------------------------------------- /images/boxplot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pabloing93/Trading-Robot/HEAD/images/boxplot2.png -------------------------------------------------------------------------------- /images/prices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pabloing93/Trading-Robot/HEAD/images/prices.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #Ingnoring local folder 2 | .ipynb_checkpoints/ 3 | __pycache__/ 4 | my_tests.py 5 | alquiler.csv -------------------------------------------------------------------------------- /images/1_dataframe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pabloing93/Trading-Robot/HEAD/images/1_dataframe.png -------------------------------------------------------------------------------- /images/2_coinmarket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pabloing93/Trading-Robot/HEAD/images/2_coinmarket.png -------------------------------------------------------------------------------- /images/data_limpio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pabloing93/Trading-Robot/HEAD/images/data_limpio.png -------------------------------------------------------------------------------- /images/data_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pabloing93/Trading-Robot/HEAD/images/data_original.png -------------------------------------------------------------------------------- /__pycache__/functions.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pabloing93/Trading-Robot/HEAD/__pycache__/functions.cpython-39.pyc -------------------------------------------------------------------------------- /global_data.py: -------------------------------------------------------------------------------- 1 | user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36" -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from functions import * 2 | from IPython.display import clear_output 3 | import time 4 | 5 | while(True): 6 | clear_output() 7 | df_bitcoin = importar_base_bitcoin() 8 | precio, tendencia = extraer_tendencias("BTC") 9 | media_bitcoin = limpieza_datos(df_bitcoin) 10 | decision = tomar_desiciones(precio, media_bitcoin, tendencia) 11 | visualizacion(df_bitcoin, precio, media_bitcoin, decision) 12 | time.sleep(300) -------------------------------------------------------------------------------- /functions.py: -------------------------------------------------------------------------------- 1 | import yfinance 2 | from bs4 import BeautifulSoup 3 | import requests 4 | from global_data import user_agent 5 | import pandas 6 | import matplotlib.pyplot as plt 7 | 8 | #Getting Yahoo! Finance Bitcoin History Data 9 | def importar_base_bitcoin(): 10 | bitcoin = yfinance.Ticker("BTC-USD") 11 | df_bitcoin = bitcoin.history(period="7d", interval="5m") 12 | return df_bitcoin 13 | 14 | #Getting tendencies from CoinMarket 15 | def extraer_tendencias(simbol: str) -> tuple: 16 | 17 | def get_tendencie(row: str) -> str: 18 | alta_icon = "icon-Caret-up" 19 | baja_icon = "icon-Caret-down" 20 | if(alta_icon in row): 21 | return "alta" 22 | else: 23 | return "baja" 24 | 25 | def str_to_float(price: str) -> float: 26 | return float(price.replace("$", "").replace(",", "")) 27 | 28 | def get_column_position(a_table: BeautifulSoup, column_name: str) -> int: 29 | for index, columna in enumerate(list(a_table.thead.tr.find_all("th"))): 30 | if(columna.find('p')): 31 | texto_p = columna.p.text.strip() 32 | if column_name == texto_p: 33 | return index 34 | 35 | def get_simbol_row(a_table: BeautifulSoup, a_simbol: str) -> list: 36 | for tr in a_table.tbody: 37 | p_tags = tr.find_all("p") 38 | for p in p_tags: 39 | if(p.string == a_simbol): 40 | return list(tr) 41 | 42 | #1) Obtengo el html de la web 43 | headers = { "User-Agent": user_agent } 44 | url = "https://coinmarketcap.com/" 45 | request = requests.get(url, headers) 46 | web_content = BeautifulSoup(request.content, features="lxml") 47 | html_table = web_content.find("table", class_="cmc-table") 48 | 49 | #2) obtengo la posicion de las columnas que me interesan 50 | tendencie_column_position = get_column_position(html_table, "1h %") 51 | price_column_position = get_column_position(html_table, "Price") 52 | 53 | #3) obtengo la fila de la moneda que me interesa 54 | simbol_row = get_simbol_row(html_table, simbol) 55 | 56 | #4) Accedo al contenido especifico que busco 57 | price_string = str(simbol_row[price_column_position].span.text) 58 | price = str_to_float(price_string) #limpio el dato 59 | tendencie_string = str(simbol_row[tendencie_column_position]) 60 | tendencie = get_tendencie(tendencie_string) #limpio el dato 61 | 62 | return ( price, tendencie ) 63 | 64 | def limpieza_datos(df_bitcoins: pandas.DataFrame) -> tuple: 65 | def draw_boxplot(title: str, dataframe: pandas): 66 | plt.figure(figsize=(8, 6)) 67 | plt.title(title) 68 | plt.boxplot(dataframe['Close'], vert=False) 69 | plt.show() 70 | # Hago una copia del dataframe original 71 | dataframe = df_bitcoins.copy() 72 | # Eliminar duplicados en el índice 73 | dataframe = dataframe[~dataframe.index.duplicated(keep='first')] 74 | # Buscar valores nulos en la columna "Close" y eliminarlos 75 | dataframe.dropna(subset=['Close'], inplace=True) 76 | # Verificar que todos los registros tengan un Volume de transacción mayor a 0 77 | dataframe = dataframe[dataframe['Volume'] > 0] 78 | # Identificar y eliminar outliers en la columna "Close" usando un boxplot 79 | #Obtengo los valores de Close que se encuentren entre Q1 y Q3 80 | Q1 = dataframe['Close'].quantile(0.25) 81 | Q3 = dataframe['Close'].quantile(0.75) 82 | dataframe = dataframe[(dataframe['Close'] >= Q1) & (dataframe['Close'] <= Q3)] 83 | # Calcular el precio promedio (Close) de esta selección 84 | media_bitcoin = dataframe['Close'].mean() 85 | return media_bitcoin 86 | 87 | def tomar_desiciones(current_price: int, mean_price: int, tendencie: str) -> str: 88 | #Defino los casos de decisiones 89 | case_1 = (current_price >= mean_price) & (tendencie == 'baja') 90 | case_2 = (current_price < mean_price) & (tendencie == 'alta') 91 | if (case_1): 92 | decision = 'Vender' 93 | elif (case_2): 94 | decision = 'Comprar' 95 | else: 96 | decision = 'Esperar' 97 | return decision 98 | 99 | def visualizacion(df_bitcoin: pandas.DataFrame, current_price: float, mean: float, decision: str): 100 | #Hago una copia del DF original 101 | dataframe = df_bitcoin.copy() 102 | #Creo una columna nueva y cargo el valor de la media 103 | dataframe['Promedio'] = mean 104 | #Configuro el tamaño del gráfico en 16x5 105 | plt.rc('figure', figsize = (16,5)) 106 | #Dibujo el gráfico (Volumen,Datetime) 107 | graph = dataframe['Close'].plot() 108 | #Dibujo la linea del promedio 109 | graph = dataframe['Promedio'].plot() 110 | #Seteo títulos al gráfico 111 | graph.set_title('Bitcoin BTC YFinance', {'fontsize': 22}) 112 | graph.set_ylabel('Precio de Cierre') 113 | graph.set_xlabel('Fecha') 114 | #Mostrar la decision con el metodo annotate() 115 | current_date = dataframe.index[-1] 116 | if (decision == 'Comprar'): 117 | plt.annotate( 118 | text = decision, 119 | horizontalalignment = 'center', 120 | xy=(current_date, current_price), 121 | arrowprops={'facecolor': 'green'}, 122 | xytext=(current_date, current_price+100) 123 | ) 124 | elif (decision == 'Vender'): 125 | plt.annotate( 126 | text = decision, 127 | horizontalalignment = 'center', 128 | xy=(current_date, current_price), 129 | arrowprops={'facecolor': 'red'}, 130 | xytext=(current_date, current_price+500) 131 | ) 132 | graph.legend( 133 | [f'Bitcoin Price: {round(current_price, 2)}', f'Mean: {round(mean, 2)}'], 134 | loc='upper left', 135 | title=f'Recomendacion: {decision}') 136 | plt.show() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Trading Robot 🤖 2 | 3 | ## Tecnologías utilizadas 📊 4 | 5 | ### Pandas 6 | Pandas es una biblioteca esencial para el análisis y manipulación de datos en Python. Muy utilizada en proyectos de Ciencia de Datos. 7 | 8 | ### BeautifulSoup (bs4) 9 | BeautifulSoup es una biblioteca utilizada para técnicas de webscraping. La utilizamos en nuestro proyecto para obtener datos de Coinmarket. 10 | 11 | ### Matplotlib Pyplot 12 | Una biblioteca de visualización de datos en Python. Nos facilita la creación de gráficos y mejor comprensión de la distribución de los datos a través de visualizaciones. 13 | 14 | ### Yfinance 15 | Yfinance es una herramienta open source que nos proporciona una API para acceder a datos financieros y del mercado en tiempo real. 16 | 17 | 18 | ## Etapas del algoritmo 19 | 20 | ## Configuración del ambiente 21 | > [!IMPORTANT] 22 | > Se requiere instalar las tecnologías necesarias para poder ejecutar el proyecto de manera local 23 | > ``` 24 | > pip install pandas, matplotlib, yfinance, beautifulsoup4 25 | > ``` 26 | 27 | ## Obtencion de datos 📁 28 | 29 | La función importar_base_bitcoin() utiliza la API de yfinance para obtener datos históricos de Bitcoin durante los últimos 7 días con intervalos de 5 minutos. 30 | Llamamos a la función y almacenamos su valor en una variable como se muestra a continuación: 31 | 32 | ![image](https://github.com/pabloing93/Trading-Robot/assets/32267303/039b9c9a-0315-4199-8a49-dc860e84e24c) 33 | 34 | 35 | 36 | [
 code link 
][KBD] 37 | 38 | [KBD]: f221f39a64f4846224f8496a8a094dc92aecfdac/functions.py#L9 39 | 40 | La función extraer_tendencias() recibe como parámetro "BTC" que es el símbolo de la moneda de la cuál extraeremos la información del precio y la tendencia. 41 | Llamamos a la función y almacenamos su valor en una variable como se muestra a continuación: 42 | 43 | ![image](https://github.com/pabloing93/Trading-Robot/assets/32267303/472c4f45-f544-4dc7-bcf2-ba72411739c3) 44 | ![image](https://github.com/pabloing93/Trading-Robot/assets/32267303/820ac7d5-4b1e-4e93-97b3-1bad6a5441f2) 45 | 46 | [
 code link 
][KBD] 47 | 48 | [KBD]: f221f39a64f4846224f8496a8a094dc92aecfdac/functions.py#L15 49 | 50 | Procedimiento: 51 | Utilizando el símbolo de la moneda aplicamos webscraping a la página web https://coinmarketcap.com/ 52 | Obtenemos el precio y la tendencia en 1h % 53 | visualizacion 54 | 55 | 56 | ## Depuración de los datos 🧹 57 | 58 | La depuración de los datos se realiza a través de la función limpieza_datos() 59 | 60 | ![image](https://github.com/pabloing93/Trading-Robot/assets/32267303/16156cd0-f087-4dfd-80b9-5f80e8a1c54e) 61 | 62 | Que se encuentra definida de la siguiente forma 63 | ![image](https://github.com/pabloing93/Trading-Robot/assets/32267303/8ab38bb2-aec3-4ad0-bffc-31bd84fd3af0) 64 | 65 | [
 code link 
][KBD] 66 | 67 | [KBD]: f221f39a64f4846224f8496a8a094dc92aecfdac/functions.py#L64 68 | 69 | 1. Hacemos una copia de ```df_bitcoin``` 70 | 2. Eliminamos los registros duplicados de la columna ```Datetime```. 71 | 3. Eliminamos los registros cuyo valor en la columna ```Close``` sea nulo o 0. 72 | 4. Nos quedamos con los registros cuyo valor en columna ```Volume``` sea mayor a 0. 73 | 5. Identifica y eliminanos los "outliers" del precio de cierre de Bitcoin. 74 | 75 | Gráfico Data Original 76 | 77 | 6. Agrupamos los datos que se encuentren entre el primer y el tercer Quartil ```Q3 > Close > Q1``` 78 | 7. Obtenemos el valor de la media desde los datos depurados 79 | 80 | Gráfico Data Limpio 81 | 82 | En resumen, este código se encarga de asegurarse de que los datos relacionados con el precio de Bitcoin sean precisos y útiles para futuros análisis. Esto implica eliminar datos duplicados, nulos e inusuales, y calcular el precio promedio después de realizar estas limpiezas. 83 | 84 | ## Toma de decisiones 🚀 85 | 86 | ![image](https://github.com/pabloing93/Trading-Robot/assets/32267303/abc8427a-5b2e-4e30-8e6d-8b92b909a36d) 87 | 88 | ![image](https://github.com/pabloing93/Trading-Robot/assets/32267303/6c754c05-3639-4ef7-b909-77b762413d09) 89 | 90 | [
 code link 
][KBD] 91 | 92 | [KBD]: f221f39a64f4846224f8496a8a094dc92aecfdac/functions.py#L87 93 | 94 | El algoritmo de toma de decisiones consiste en analizar el precio actual de la moneda, el precio promedio y la tendencia. 95 | - Caso 1: Si el precio actual es mayor o igual al precio promedio y la tendencia es "baja", entonces se recomienda "Vender". 96 | - Caso 2: Si el precio actual es menor que el precio promedio y la tendencia es "alta", entonces recomienda "Comprar". 97 | - Si ninguno de estos casos se cumple, se recomienda "Esperar". 98 | 99 | Finalmente, la función devuelve una decisión, que puede ser "Vender", "Comprar" o "Esperar" en función de los valores de entrada. 100 | 101 | ## Visualizacion 📈 102 | En éste procedimiento del algoritmo mostramos los resultados en un gráfico para facilitar su comprensión de los datos resultados y dar apoyo en la toma de decisiones. 103 | 104 | ![image](https://github.com/pabloing93/Trading-Robot/assets/32267303/29d31358-0d9f-4408-86c1-055dc03dc021) 105 | ![image](https://github.com/pabloing93/Trading-Robot/assets/32267303/311369ce-af57-4af3-ba1b-fc783e3eba18) 106 | [
 code link 
][KBD] 107 | 108 | [KBD]: f221f39a64f4846224f8496a8a094dc92aecfdac/functions.py#L99 109 | 110 | visualizacion 111 | 112 | ## Automatizacion 🧠 113 | 114 | Este proceso automatizado permite a los usuarios rastrear el precio de Bitcoin y tomar decisiones rápidas basadas en datos actualizados en tiempo real. 115 | 116 | ![image](https://github.com/pabloing93/Trading-Robot/assets/32267303/79c7c2d9-5b5d-47e6-a15f-a6db2f414068) 117 | 118 | --------------------------------------------------------------------------------