1. Descarga Gratuita de Históricos vía APIs.
[acceso al notebook](ejemplo con Estrategia_bolinger_bands )
Para tu comodidad y para evitar la tediosa tarea de repetir descargas y enfrentarte a peticiones de datos innecesarias en webs gratuitas, ofrecemos los siguientes scripts. Con ellos, podrás guardar los históricos directamente en archivos .csv en la carpeta que prefieras. Así, importar estos datos a nuestros scripts de estrategias será mucho más sencillo y rápido.
1.1.- APIs: Histórico de Acciones, Índices, Divisas y Cripto:
Lista de APIs gratuitas que te permitirán acceder a una amplia variedad de datos financieros y realizar tus propios análisis. Todas ofrecen también suscripciones de pago con licencias específicas.
Además de los datos históricos, muchas de estas APIs te permiten calcular indicadores técnicos como:
Media móvil simple (SMA)
Media móvil exponencial (EMA)
Índice de fuerza relativa (RSI)
Convergencia/Divergencia de medias móviles (MACD) Y muchos otros
Es importante entender que los datos descargados de estas Web's, son para uso personal, prohibiéndose su redistribución o venta. Se recomienda encarecidamente revisar los términos de uso de para asegurar su cumplimiento. En el contexto de un uso sin ánimo de lucro, se considera generalmente aceptable siempre que se respeten estas directrices y se eviten peticiones de datos excesivas o abusivas.
yfinance: Es la más popular con una API sencilla de 'Yahoo Finanace'. yfinance es una biblioteca de Python que proporciona una interfaz para acceder a los datos de Yahoo Finance, licenciada bajo la Apache License 2.0. Su uso está estrictamente limitado a fines de investigación, educativos y para uso personal, prohibiéndose su redistribución o venta.
Alpha Vantage: Ofrece una amplia gama de datos y es fácil de usar. Su uso está regido por sus Términos de Servicio. La versión gratuita es para uso personal y no comercial, con límites en la frecuencia de las consultas. Es imprescindible revisar sus Términos de Servicio actualizados para asegurar el cumplimiento de sus condiciones. Requiere una clave de API y tiene diferentes planes. get free API key
Marketstack: Se centra en proporcionar datos históricos precisos y detallados de múltiples mercados a nivel mundial, lo cual es crucial para estrategias conservadoras que a menudo se basan en el análisis de tendencias a largo plazo. Su plan gratuito puede ser suficiente para empezar y probar la facilidad de importación para un número limitado de llamadas y datos. Los planes de pago ofrecen mayor capacidad. Requiere una clave de API y tiene diferentes planes
EOD Historical Data: Está muy enfocada en proporcionar datos históricos de alta calidad para una amplia gama de activos (acciones, ETFs, divisas, criptomonedas. Ofrece diferentes tipos de datos históricos y ajustes por dividendos y splits, lo cual es importante para un análisis preciso a largo plazo. Requiere una clave de API y tiene diferentes planes
Tiingo: Proporciona una API REST para datos de precios de acciones (EOD e intradía), noticias y datos fundamentales. Requiere una clave de API y tiene diferentes planes, incluyendo una opción gratuita con restricciones. Su API es conocida por ser robusta y bien documentada. Aunque cubren otros mercados, su enfoque principal parece estar en los datos estadounidenses.
IEX Cloud: Es un poco más complejo para una importación directa y sencilla de largas series históricas en el plan gratuito. Sin embargo, para datos más recientes o específicos, es una buena opción.
Finnhub: Similar a Tiingo, ofrece ambos tipos de datos. Su API es bastante completa y permite acceder a una variedad de datos, incluyendo fundamentales y noticias. Requiere una clave de API y tiene diferentes planes. Asegúrate de que la profundidad de sus datos históricos cumpla con los requisitos de tu estrategia conservadora.
Te sugiero registrarte en las versiones de prueba o los planes gratuitos de estas plataformas para experimentar directamente con sus APIs y evaluar cuál se adapta mejor a tus necesidades de importación y a la cobertura de los activos que te interesan.
APIs destacadas para el cálculo de indicadores técnicos:
Alpha Vantage: Amplia gama de indicadores precalculados.
IEX Cloud: Personalización de indicadores a través de su API.
Quandl: Cálculo de indicadores utilizando su lenguaje de consulta.
Polygon.io: Indicadores técnicos y API flexible.
Intrinio: Amplia variedad de indicadores técnicos.
Marketstack: Cálculo de indicadores personalizados.
Tiingo: Cálculo de indicadores técnicos.
Finnhub: Cálculo de indicadores técnicos y datos en tiempo real.
Importante: Recuerda revisar los términos de servicio y las limitaciones de cada API antes de utilizarla, suelen variar de un proveedor a otro. Las opciones gratuitas suelen tener restricciones en cuanto a la cantidad de datos y la frecuencia de las solicitudes.
1.2.- Símbolos para identificar instrumentos financieros.
Encontrar los símbolos correctos para los instrumentos financieros que deseas analizar es crucial. Aquí tienes algunos recursos útiles:
Stock Screener de Nasdaq: Puedes buscar el ticker en Stock Screener
Yahoo Finances: Tambien puedes buscar el ticker en esta Web.
Discusión en Stack Overflow sobre cómo listar todos los tickers: acceso - Explora diferentes enfoques y limitaciones para obtener listados de tickers.
Listas de símbolos en GitHub: acceso - Este repositorio ofrece listas precompiladas de símbolos que pueden ser de gran utilidad.
Discusión en Stack Overflow sobre cómo obtener tickers europeos: acceso - Aprende cómo abordar la obtención de datos para mercados europeos.
1.3.- Instrucciones generales
Antes de ejecutar los scripts, es recomendable establecer un directorio donde se almacenarán los archivos descargados. Un ejemplo sería:
OUTPUT_DIRECTORY = '/mi ruta de acceso/Ficheros_yfinance'
Si estás trabajando en un entorno de Google Colaboratory y deseas guardar los archivos en la carpeta predeterminada de tu sesión, puedes usar la siguiente ruta:
[acceso al notebook](ejemplo con Estrategia_bolinger_bands )
Para tu comodidad y para evitar la tediosa tarea de repetir descargas y enfrentarte a peticiones de datos innecesarias en webs gratuitas, ofrecemos los siguientes scripts. Con ellos, podrás guardar los históricos directamente en archivos .csv en la carpeta que prefieras. Así, importar estos datos a nuestros scripts de estrategias será mucho más sencillo y rápido.
1.1.- APIs: Histórico de Acciones, Índices, Divisas y Cripto:
Lista de APIs gratuitas que te permitirán acceder a una amplia variedad de datos financieros y realizar tus propios análisis. Todas ofrecen también suscripciones de pago con licencias específicas.
Además de los datos históricos, muchas de estas APIs te permiten calcular indicadores técnicos como:
Media móvil simple (SMA)
Media móvil exponencial (EMA)
Índice de fuerza relativa (RSI)
Convergencia/Divergencia de medias móviles (MACD) Y muchos otros
Es importante entender que los datos descargados de estas Web's, son para uso personal, prohibiéndose su redistribución o venta. Se recomienda encarecidamente revisar los términos de uso de para asegurar su cumplimiento. En el contexto de un uso sin ánimo de lucro, se considera generalmente aceptable siempre que se respeten estas directrices y se eviten peticiones de datos excesivas o abusivas.
yfinance: Es la más popular con una API sencilla de 'Yahoo Finanace'. yfinance es una biblioteca de Python que proporciona una interfaz para acceder a los datos de Yahoo Finance, licenciada bajo la Apache License 2.0. Su uso está estrictamente limitado a fines de investigación, educativos y para uso personal, prohibiéndose su redistribución o venta.
Alpha Vantage: Ofrece una amplia gama de datos y es fácil de usar. Su uso está regido por sus Términos de Servicio. La versión gratuita es para uso personal y no comercial, con límites en la frecuencia de las consultas. Es imprescindible revisar sus Términos de Servicio actualizados para asegurar el cumplimiento de sus condiciones. Requiere una clave de API y tiene diferentes planes. get free API key
Marketstack: Se centra en proporcionar datos históricos precisos y detallados de múltiples mercados a nivel mundial, lo cual es crucial para estrategias conservadoras que a menudo se basan en el análisis de tendencias a largo plazo. Su plan gratuito puede ser suficiente para empezar y probar la facilidad de importación para un número limitado de llamadas y datos. Los planes de pago ofrecen mayor capacidad. Requiere una clave de API y tiene diferentes planes
EOD Historical Data: Está muy enfocada en proporcionar datos históricos de alta calidad para una amplia gama de activos (acciones, ETFs, divisas, criptomonedas. Ofrece diferentes tipos de datos históricos y ajustes por dividendos y splits, lo cual es importante para un análisis preciso a largo plazo. Requiere una clave de API y tiene diferentes planes
Tiingo: Proporciona una API REST para datos de precios de acciones (EOD e intradía), noticias y datos fundamentales. Requiere una clave de API y tiene diferentes planes, incluyendo una opción gratuita con restricciones. Su API es conocida por ser robusta y bien documentada. Aunque cubren otros mercados, su enfoque principal parece estar en los datos estadounidenses.
IEX Cloud: Es un poco más complejo para una importación directa y sencilla de largas series históricas en el plan gratuito. Sin embargo, para datos más recientes o específicos, es una buena opción.
Finnhub: Similar a Tiingo, ofrece ambos tipos de datos. Su API es bastante completa y permite acceder a una variedad de datos, incluyendo fundamentales y noticias. Requiere una clave de API y tiene diferentes planes. Asegúrate de que la profundidad de sus datos históricos cumpla con los requisitos de tu estrategia conservadora.
Te sugiero registrarte en las versiones de prueba o los planes gratuitos de estas plataformas para experimentar directamente con sus APIs y evaluar cuál se adapta mejor a tus necesidades de importación y a la cobertura de los activos que te interesan.
APIs destacadas para el cálculo de indicadores técnicos:
Alpha Vantage: Amplia gama de indicadores precalculados.
IEX Cloud: Personalización de indicadores a través de su API.
Quandl: Cálculo de indicadores utilizando su lenguaje de consulta.
Polygon.io: Indicadores técnicos y API flexible.
Intrinio: Amplia variedad de indicadores técnicos.
Marketstack: Cálculo de indicadores personalizados.
Tiingo: Cálculo de indicadores técnicos.
Finnhub: Cálculo de indicadores técnicos y datos en tiempo real.
Importante: Recuerda revisar los términos de servicio y las limitaciones de cada API antes de utilizarla, suelen variar de un proveedor a otro. Las opciones gratuitas suelen tener restricciones en cuanto a la cantidad de datos y la frecuencia de las solicitudes.
1.2.- Símbolos para identificar instrumentos financieros.
Encontrar los símbolos correctos para los instrumentos financieros que deseas analizar es crucial. Aquí tienes algunos recursos útiles:
Stock Screener de Nasdaq: Puedes buscar el ticker en Stock Screener
Yahoo Finances: Tambien puedes buscar el ticker en esta Web.
Discusión en Stack Overflow sobre cómo listar todos los tickers: acceso - Explora diferentes enfoques y limitaciones para obtener listados de tickers.
Listas de símbolos en GitHub: acceso - Este repositorio ofrece listas precompiladas de símbolos que pueden ser de gran utilidad.
Discusión en Stack Overflow sobre cómo obtener tickers europeos: acceso - Aprende cómo abordar la obtención de datos para mercados europeos.
1.3.- Instrucciones generales
Antes de ejecutar los scripts, es recomendable establecer un directorio donde se almacenarán los archivos descargados. Un ejemplo sería:
OUTPUT_DIRECTORY = '/mi ruta de acceso/Ficheros_yfinance'
Si estás trabajando en un entorno de Google Colaboratory y deseas guardar los archivos en la carpeta predeterminada de tu sesión, puedes usar la siguiente ruta:
OUTPUT_DIRECTORY = '/content'
Asimismo, define el periodo de tiempo de las cotizaciones que deseas analizar, especificando las fechas de inicio y fin:
DATE_START = '2010-01-04'
DATE_END = 'today' # 'today' es un valor válido para yfinance
introduce en el diccionario 'stocks_to_download', el ticker y el nombre (por este orden), de los valores cuyas cotizaciones quieres descargar. Obseva que todas las línes finalizan con una com, excepto la última.
stocks_to_download = {
"IBE.MC": "Iberdrola.csv",
"TEF.MC": "Telefonica.csv",
"R4.MC": "Renta4.csv",
"^IBEX": "Ibex35.csv",
"^GSPC": "Sp500.csv"
}
Más adelante, detallaremos el proceso para leer e integrar estos ficheros en los scripts de estrategias de este blog.
Obtén una clave de API (por ejemplo, API_KEY_MARKETSTACK = 'xxxxxx') si la API que vas a utilizar lo requiere.
Copia el script de importación correspondiente a la API de descarga seleccionada, en una celda de un nuevo cuaderno de Colaboratory , y ejecuta el script.
2.- Opciones de descarga.
2.1.- Yahoo
yf.download es una función específica de la biblioteca yfinance que se utiliza para descargar datos de Yahoo Finance.
ticker.history es una función más general que pertenece a la biblioteca pandas_datareader y permite acceder a datos financieros de diversas fuentes, , incluyendo Yahoo Finance, Google Finance, Alpha Vantage, entre otros. Ambas funciones pueden ser útiles dependiendo de nuestras necesidades y preferencias.
Al utilizar ticker.history(), necesitarás especificar la fuente de datos, como 'yahoo' para Yahoo Finance, y otros parámetros como el rango de fechas y la frecuencia de los datos.
2.1.1 Yahoo Utilizando la API.
Script:
import yfinance as yf
import pandas as pd
import os
from datetime import datetime
# Definir el directorio de destino
OUTPUT_DIRECTORY = '/content'
DATE_START = '2010-01-04'
DATE_END = datetime.today().strftime('%Y-%m-%d') # Obtener la fecha actual en el formato correcto
# Diccionario de símbolos y nombres de archivo
stocks_to_download = {
"IBE.MC": "Iberdrola.csv",
"TEF.MC": "Telefonica.csv",
"R4.MC": "Renta4.csv",
"^IBEX": "Ibex35.csv",
"^GSPC": "Sp500.csv"
}
if __name__ == '__main__':
# Crear el directorio si no existe
if not os.path.exists(OUTPUT_DIRECTORY):
os.makedirs(OUTPUT_DIRECTORY)
all_value_closures_list = [] # Lista para almacenar los DataFrames
for stock_symbol, filename in stocks_to_download.items():
stock_name_for_print = filename.replace(".csv", "")
print(f"\nDescargando datos para: {stock_name_for_print} ({stock_symbol}) desde yfinance")
try:
df = yf.download(stock_symbol, start=DATE_START, end=DATE_END, progress=False, auto_adjust= False)
if df is not None and not df.empty:
# Ya no formateamos el índice aquí, dejamos que yfinance lo maneje
# df.index = pd.to_datetime(df.index).strftime('%Y-%m-%d' )
# df.index = pd.to_datetime(df.index)
df.index.name = 'Date'
print(f"\nDataFrame descargado para {stock_name_for_print} (yfinance):")
#print(df.head())
all_value_closures = df[['Close']].copy()
all_value_closures.columns = [stock_symbol]
all_value_closures_list.append(all_value_closures)
#print(f"\nDataFrame 'all_value_closures' para {stock_name_for_print} (yfinance):")
#print(all_value_closures.head())
filepath = os.path.join(OUTPUT_DIRECTORY, filename)
# Guardar el DataFrame
all_value_closures.to_csv(filepath)
print(f"Datos de {stock_name_for_print} guardados en '{filepath}'")
else:
print(f"No se encontraron datos para {stock_name_for_print} ({stock_symbol}) en el rango especificado.")
except Exception as e:
print(f"Error al descargar los datos para {stock_name_for_print} ({stock_symbol}) desde yfinance: {e}")
print("\nProceso de descarga y guardado completado (yfinance).")
# La variable all_value_closures_list contiene ahora los DataFrames de cada acción
2.1.2.- Utilizando 'download'.
Script:
import yfinance as yf
import pandas as pd
# IBEX 35
ticker = '^IBEX'
start = '2010-01-04'
end = '2024-12-30'
df = yf.download(ticker, start, end, progress=False, auto_adjust= False)
df.index = pd.to_datetime(df.index).strftime('%Y-%m-%d' )
df.index = pd.to_datetime(df.index)
df.index.name = 'Date'
all_value_closes = df.xs(ticker, level=1, axis=1)
all_value_closes[:3]
2.2.- Alpha Vantage.
Repositorio oficial en GitHub: [Alpha_Vantage] Aquí encontrarás la documentación oficial y el código fuente de la librería.
Para acceder a los datos de Alpha Vantage, necesitas una clave de acceso 'API_KEY = "xxxxxxxxxx"'. Puedes obtener una gratuita registrándote en su sitio web:
Enlace para obtener la clave API: [get free API key]]
Es importante tener en cuenta que la API gratuita de Alpha Vantage tiene las siguientes limitaciones de uso:
- Límite diario: 25 solicitudes por día.
- Límite por minuto: 5 solicitudes por minuto.
Para un uso más intensivo, considera explorar los planes de pago que ofrecen mayores cuotas de solicitude
2.2.1.- Alphavantage Utilizando la API.
Script.
import requests
import pandas as pd
import time
import os # Importar la librería para trabajar con directorios
# Reemplaza 'TU_CLAVE_DE_API' con tu clave de API real de Alpha Vantage
#API_KEY = 'TU_CLAVE_DE_API'
OUTPUT_SIZE = 'full' # 'compact' para los últimos 100 puntos de datos
OUTPUT_DIRECTORY = '/content'
Ficheros_investing' # Directorio de destino
DATE_START = '2010-01-04'
DATE_END = pd.to_datetime('today').strftime('%Y-%m-%d')
# Diccionario de símbolos y nombres de archivo
stocks_to_download = {
'Apple': 'AAPL',
'Microsoft': 'MSFT',
'Google': 'GOOGL',
'S&P 500': '^GSPC'
}
# Función para descargar datos de series de tiempo diarias
def get_daily_data(symbol, api_key, outputsize='compact'):
base_url = 'https://www.alphavantage.co/query'
params = {
'function': 'TIME_SERIES_DAILY',
'symbol': symbol,
'outputsize': outputsize,
'apikey': api_key
}
response = requests.get(base_url, params=params)
data = response.json()
return data
if __name__ == '__main__':
# Crear el directorio si no existe
if not os.path.exists(OUTPUT_DIRECTORY):
os.makedirs(OUTPUT_DIRECTORY)
for stock_name, symbol in stocks_to_download.items():
print(f"\nDescargando datos para: {stock_name} ({symbol})")
raw_data = get_daily_data(symbol, API_KEY, OUTPUT_SIZE)
print("Respuesta JSON sin procesar de la API (como DataFrame):")
print(pd.Series(raw_data)) # Imprime la respuesta JSON como una Serie de Pandas
if 'Time Series (Daily)' in raw_data:
# Procesar los datos
time_series = raw_data['Time Series (Daily)']
df = pd.DataFrame.from_dict(time_series, orient='index')
df.index = pd.to_datetime(df.index)
df = df.sort_index(ascending=True)
# Renombrar el índice a 'Date'
df.index.name = 'Date'
# Renombrar las columnas para mayor claridad
df = df.rename(columns={
'1. open': 'Open',
'2. high': 'High',
'3. low': 'Low',
'4. close': 'Close',
'5. volume': 'Volume'
})
# Filtrar por rango de fechas
all_value_closures = df[(df.index >= DATE_START) & (df.index <= DATE_END)]
print(f"\nDataFrame 'all_value_closures' para {stock_name}:")
print(all_value_closures) # Imprime el DataFrame resultante
# Definir el nombre del archivo basado en el nombre de la acción
filename = f'{stock_name.lower()}.csv'
filepath = os.path.join(OUTPUT_DIRECTORY, filename)
# Guardar el DataFrame filtrado
all_value_closures.to_csv(filepath)
print(f"Datos de {stock_name} guardados en '{filepath}'")
elif 'Error Message' in raw_data:
print(f"Error al descargar los datos para {stock_name} ({symbol}): {raw_data['Error Message']}")
else:
print(f"Respuesta inesperada de la API para {stock_name} ({symbol}).")
# Ser respetuoso con la tasa de llamadas de la API
time.sleep(15)
print("\nProceso de descarga y guardado completado.")
2.4.- Marketstack Utilizando la API.
Ofrece una potente API para acceder a información histórica y actual de una amplia gama de instrumentos financieros.
Características principales:
Amplia cobertura: Explora datos de más de 70 bolsas de valores en todo el mundo.
Datos históricos: Accede a información histórica de hasta 1 año, ideal para análisis y estrategias a largo plazo.
Datos de fin de día: Obtén datos esenciales de cierre de jornada para tus análisis.
Seguridad: La conexión HTTPS garantiza la protección de tus datos.
Puedes probar la API de Marketstack de forma gratuita y realizar hasta 100 solicitudes al mes.
Para empezar.
Obtén tu clave de API: [API KEY]
Encuentra los tickers que necesitas: [ marketstack ]
Integración en Python: Explora la librería en Market Stack API - Python [Market Stack API - Python] .
Con Marketstack, tendrás las herramientas necesarias para potenciar tus análisis bursátiles y tomar decisiones informadas.
Script.
import requests
import pandas as pd
import time
import os # Importar la librería para trabajar con directorios
# Reemplaza 'TU_CLAVE_DE_API_MARKETSTACK' con tu clave de API real de Marketstack
#API_KEY_MARKETSTACK = 'TU_CLAVE_DE_API_MARKETSTACK'
OUTPUT_DIRECTORY = '/content'
Ficheros_Marketstack' # Directorio de destino
DATE_START = '2024-01-04'
DATE_END = pd.to_datetime('today').strftime('%Y-%m-%d')
# Diccionario de símbolos y nombres de archivo
stocks_to_download = {
'Apple': 'AAPL',
'Microsoft': 'MSFT',
'Google': 'GOOGL',
'S&P 500': '^GSPC'
}
# Función para descargar datos históricos diarios desde Marketstack
def get_marketstack_daily_data(symbol, api_key, start_date, end_date):
base_url = 'http://api.marketstack.com/v1/eod'
params = {
'access_key': api_key,
'symbols': symbol,
'date_from': start_date,
'date_to': end_date,
'limit': 1000 # Puedes ajustar el límite si es necesario
}
response = requests.get(base_url, params=params)
data = response.json()
return data
if __name__ == '__main__':
# Crear el directorio si no existe
if not os.path.exists(OUTPUT_DIRECTORY):
os.makedirs(OUTPUT_DIRECTORY)
all_value_closures_list = [] # Lista para almacenar los DataFrames
for stock_name, symbol in stocks_to_download.items():
#print(f"\nDescargando datos para: {stock_name} ({symbol}) desde Marketstack")
raw_data = get_marketstack_daily_data(symbol, API_KEY_MARKETSTACK, DATE_START, DATE_END)
#print("Respuesta JSON sin procesar de la API (Marketstack):")
#print(pd.Series(raw_data)) # Imprime la respuesta JSON como una Serie de Pandas
if 'data' in raw_data:
stock_data = raw_data['data']
if stock_data:
df = pd.DataFrame(stock_data)
df['Date'] = pd.to_datetime(df['date']).dt.date
df = df.set_index('Date')
df = df.sort_index(ascending=True)
# Renombrar las columnas para mayor claridad (adaptado a Marketstack)
df = df.rename(columns={
'open': 'Open',
'high': 'High',
'low': 'Low',
'close': 'Close',
'volume': 'Volume'
})
all_value_closures = df
all_value_closures_list.append(all_value_closures) # Añadir a la lista
#print(f"\nDataFrame 'all_value_closures' para {stock_name} (Marketstack):")
#print(all_value_closures) # Imprime el DataFrame resultante
# Definir el nombre del archivo basado en el nombre de la acción
filename = f'{stock_name.lower()}.csv'
filepath = os.path.join(OUTPUT_DIRECTORY, filename)
# Guardar el DataFrame filtrado
all_value_closures.to_csv(filepath)
print(f"Datos de {stock_name} guardados en '{filepath}'")
else:
print(f"No se encontraron datos para {stock_name} ({symbol}) en el rango especificado.")
elif 'error' in raw_data:
print(f"Error al descargar los datos para {stock_name} ({symbol}) desde Marketstack: {raw_data['error']['message']}")
else:
print(f"Respuesta inesperada de la API para {stock_name} ({symbol}) desde Marketstack.")
# Ser respetuoso con la tasa de llamadas de la API (Marketstack tiene sus propios límites)
time.sleep(15)
print("\nProceso de descarga y guardado completado (Marketstack).")
# La variable all_value_closures_list contiene ahora los DataFrames de cada acción
2.4.- EOD Historical Data Utilizando la API.
EOD Historical Data: Ofrecen una API RESTful con varios planes, incluyendo uno gratuito con limitaciones. Puedes acceder a datos históricos de acciones, ETFs, divisas y más. La documentación de su API es bastante completa.
Sign Up for EOD Historical Data: If you haven't already, create an account on the EOD Historical Data website
Obtain Your API Token: Once you have an account, navigate to your account settings or API documentation section to find your API token. This token is a unique string of characters that identifies your account.
get API-token: API TOKEN = "api_token=" xxxxxxxxx"
python-eodhistoricaldata
El plan gratuito de EOD Historical Data a menudo solo da acceso a 1 año de datos históricos EOD.
Script:
import requests
import pandas as pd
import time
import os # Importar la librería para trabajar con directorios
# Reemplaza 'TU_CLAVE_DE_API_EODHD' con tu clave de API real de EOD Historical Data
#API_KEY_EODHD = 'TU_CLAVE_DE_API_EODHD'
OUTPUT_DIRECTORY = '/content'
# Directorio de destino
DATE_START = '2010-01-04'
DATE_END = pd.to_datetime('today').strftime('%Y-%m-%d')
# Diccionario de símbolos y nombres de archivo
stocks_to_download = {
'Apple': 'AAPL.US', # EODHD requiere el símbolo con el código de mercado (ej: .US para acciones de EE.UU.)
'Microsoft': 'MSFT.US',
'Google': 'GOOGL.US' # Ajusta los símbolos según el mercado
}
# Función para descargar datos históricos diarios desde EOD Historical Data
def get_eodhd_daily_data(symbol, api_key, start_date, end_date):
base_url = f'https://eodhistoricaldata.com/api/eod/{symbol}'
params = {
'api_token': api_key,
'from': start_date,
'to': end_date,
'fmt': 'json'
}
response = requests.get(base_url, params=params)
data = response.json()
return data
if __name__ == '__main__':
# Crear el directorio si no existe
if not os.path.exists(OUTPUT_DIRECTORY):
os.makedirs(OUTPUT_DIRECTORY)
all_value_closures_list = [] # Lista para almacenar los DataFrames
for stock_name, symbol_eodhd in stocks_to_download.items():
#(f"\nDescargando datos para: {stock_name} ({symbol_eodhd}) desde EOD Historical Data")
raw_data = get_eodhd_daily_data(symbol_eodhd, API_KEY_EODHD, DATE_START, DATE_END)
#print("Respuesta JSON sin procesar de la API (EOD Historical Data):")
#print(pd.Series(raw_data)) # Imprime la respuesta JSON como una Serie de Pandas
if isinstance(raw_data, list): # Los datos se devuelven como una lista de diccionarios
if raw_data:
df = pd.DataFrame(raw_data)
df['Date'] = pd.to_datetime(df['date']).dt.date
df = df.set_index('Date')
df = df.sort_index(ascending=True)
df = df.drop(columns=['date'])
# Renombrar las columnas para mayor claridad (adaptado a EODHD)
df = df.rename(columns={
'open': 'Open',
'high': 'High',
'low': 'Low',
'close': 'Close',
'volume': 'Volume'
})
all_value_closures = df
all_value_closures_list.append(all_value_closures) # Añadir a la lista
#print(f"\nDataFrame 'all_value_closures' para {stock_name} (EOD Historical Data):")
#print(all_value_closures) # Imprime el DataFrame resultante
# Definir el nombre del archivo basado en el nombre de la acción
filename = f'{stock_name.lower()}.csv'
filepath = os.path.join(OUTPUT_DIRECTORY, filename)
# Guardar el DataFrame filtrado
all_value_closures.to_csv(filepath)
print(f"Datos de {stock_name} guardados en '{filepath}'")
else:
print(f"No se encontraron datos para {stock_name} ({symbol_eodhd}) en el rango especificado.")
elif isinstance(raw_data, dict) and 'Message' in raw_data:
print(f"Error al descargar los datos para {stock_name} ({symbol_eodhd}) desde EOD Historical Data: {raw_data['Message']}")
else:
print(f"Respuesta inesperada de la API para {stock_name} ({symbol_eodhd}) desde EOD Historical Data.")
# Ser respetuoso con la tasa de llamadas de la API (EODHD tiene sus propios límites)
time.sleep(15)
print("\nProceso de descarga y guardado completado (EOD Historical Data).")
# La variable all_value_closures_list contiene ahora los DataFrames de cada acción
2.5.- Leer cualquier fichero csv
Crea tu diccionario con las rutas de tus archivos. Ejemplo:
directorios_a_buscar = [
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_AlphaVantage',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Marketstack',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_YFinance',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_EODHD',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Finnhub',
''/content',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_R4_csv' # Directorio para archivos R4
# Añade aquí cualquier otra carpeta donde tengas tus archivos CSV
]
El directorio '/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_R4_csv' contiene archivos CSV con las siguientes características:
- Las fechas están en formato 'dd/mm/yy'.
- Utilizan tabulaciones como separador de campos (sep='\t').
- Utilizan comas como separador decimal (decimal=',').
Los demás directorios contienen archivos CSV con el formato por defecto de pandas.
- Separador de campos: Coma (,)
- Separador decimal: Punto (.)
- Formato de fecha: El formato de fecha por defecto de pandas depende de la inferencia automática de la librería, pero generalmente se alinea con formatos comunes como YYYY-MM-DD o MM/DD/YYYY.
3.- Script para la lectura de archivos.
import pandas as pd
import os
def seleccionar_directorio(lista_directorios):
"""Permite al usuario seleccionar un directorio de una lista."""
while True:
print("\nDirectorios disponibles:")
for i, directorio in enumerate(lista_directorios):
print(f"{i + 1}. {directorio}")
print(f"{len(lista_directorios) + 1}. Salir")
try:
seleccion = int(input("Seleccione el número del directorio donde se encuentran los archivos CSV: "))
if 1 <= seleccion <= len(lista_directorios):
return lista_directorios[seleccion - 1]
elif seleccion == len(lista_directorios) + 1:
return None
else:
print("Selección inválida. Por favor, ingrese un número de la lista o el número para salir.")
except ValueError:
print("Entrada inválida. Por favor, ingrese un número.")
def seleccionar_y_mostrar_csv(directorio):
"""
Lista los archivos CSV en el directorio seleccionado, permite al usuario seleccionar uno,
intenta inferir el formato de la fecha y muestra el DataFrame,
manejando formatos específicos como tabulaciones y comas decimales,
y asegura que la primera columna se use como índice de tipo datetime con formato 'YYYY-MM-DD'.
Args:
directorio (str): La ruta al directorio que contiene los archivos CSV.
Returns:
None, "volver_a_seleccionar_directorio", or DataFrame: Indica el resultado de la operación.
"""
archivos_csv = [f for f in os.listdir(directorio) if f.endswith('.csv')]
if not archivos_csv:
print(f"No se encontraron archivos CSV en el directorio: {directorio}")
return None
while True:
print(f"\nArchivos CSV disponibles en {directorio}:")
for i, nombre_archivo in enumerate(archivos_csv):
print(f"{i + 1}. {nombre_archivo}")
print(f"{len(archivos_csv) + 1}. Volver a seleccionar directorio")
print(f"{len(archivos_csv) + 2}. Salir")
try:
seleccion = int(input("Seleccione el número del archivo que desea abrir o la opción: "))
if 1 <= seleccion <= len(archivos_csv):
nombre_archivo_seleccionado = archivos_csv[seleccion - 1]
ruta_archivo_seleccionado = os.path.join(directorio, nombre_archivo_seleccionado)
try:
# Intentar leer el CSV con los parámetros específicos
if directorio.endswith('Ficheros_R4_csv'):
df = pd.read_csv(ruta_archivo_seleccionado, sep='\t', decimal=',')
else:
df = pd.read_csv(ruta_archivo_seleccionado)
print(f"\nArchivo {'R4 detectado con tabulaciones. Usando separador \'\\t\' y decimal \',\'\n' if directorio.endswith('Ficheros_R4_csv') else ''}Primeras filas del archivo '{nombre_archivo_seleccionado}':")
# Verificar si la primera columna tiene nombre
if df.columns[0] is None or df.columns[0] == 'Unnamed: 0':
df.columns = ['Date'] + list(df.columns[1:]) # Asignar 'Date' a la primera columna
# Si la primera columna no es 'Date', renombrarla a 'Date'
if df.columns[0] != 'Date':
df.rename(columns={df.columns[0]: 'Date'}, inplace=True)
try:
# Convertir la columna 'Date' a datetime y establecerla como índice
df['Date'] = pd.to_datetime(df['Date'], errors='coerce')
df.dropna(subset=['Date'], inplace=True)
df = df.set_index('Date')
df = df.sort_index()
df.index = df.index.strftime('%Y-%m-%d') # Formatear el índice
print(df.head())
print("\nColumnas disponibles:")
print(df.columns)
print(f"\nContenido del archivo '{nombre_archivo_seleccionado}' con 'Date' como índice (formato 'YYYY-MM-DD'):")
print(df)
return df
except ValueError as e:
print(f"Error al convertir a datetime o al establecer el índice: {e}")
print("Por favor, inspeccione el formato de la fecha en el archivo.")
return None
except FileNotFoundError:
print(f"Error: El archivo '{ruta_archivo_seleccionado}' no se encontró.")
except pd.errors.EmptyDataError:
print(f"Error: El archivo '{ruta_archivo_seleccionado}' está vacío.")
except pd.errors.ParserError as e:
print(f"Error al analizar el archivo '{ruta_archivo_seleccionado}'. Asegúrese de que el formato (separador, decimal) sea correcto. Error: {e}")
elif seleccion == len(archivos_csv) + 1:
return "volver_a_seleccionar_directorio"
elif seleccion == len(archivos_csv) + 2:
print("Saliendo del script.")
return None
else:
print("Selección inválida. Por favor, ingrese un número de la lista o la opción.")
except ValueError:
print("Entrada inválida. Por favor, ingrese un número.")
# Esto asegura que el bucle continúe si no se ha seleccionado "Salir"
print("\nOperación completada. Seleccione otro archivo o directorio, o elija 'Salir'.")
if __name__ == '__main__':
directorios_a_buscar = [
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_AlphaVantage',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Marketstack',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_YFinance',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_EODHD',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Finnhub',
'/content',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_R4_csv' # Directorio para archivos R4
# Añade aquí cualquier otra carpeta donde tengas tus archivos CSV
]
while True:
directorio_seleccionado = seleccionar_directorio(directorios_a_buscar)
if directorio_seleccionado is None:
break
resultado = seleccionar_y_mostrar_csv(directorio_seleccionado)
# Aquí está la corrección principal - comprobación explícita del tipo de resultado
if resultado is None:
continue # Volver al inicio del bucle para seleccionar otro directorio
elif isinstance(resultado, str) and resultado == "volver_a_seleccionar_directorio":
continue
elif isinstance(resultado, pd.DataFrame):
print("\nArchivo CSV mostrado correctamente.")
# Aquí puedes agregar código para trabajar con el DataFrame si es necesario
# No es necesario un break aquí, el bucle while externo continuará
print("\nOperación completada.")
Al ejecutra el código esta es la secuencia de pasos que va solicitando.
Directorios disponibles:
1. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_AlphaVantage
2. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Marketstack
3. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_YFinance
4. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_EODHD
5. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Finnhub
6. '/content'
7. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_R4_csv
8. Salir
Seleccione el número del directorio donde se encuentran los archivos CSV: 1
Archivos CSV disponibles en /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_AlphaVantage:
1. jpmorgan chase & co..csv
2. tesla.csv
3. microsoft.csv
4. meta platforms.csv
5. amazon.csv
6. johnson & johnson.csv
7. google.csv
8. apple.csv
9. berkshire hathaway.csv
10. Volver a seleccionar directorio
11. Salir
Seleccione el número del archivo que desea abrir o la opción: 1
Archivo Primeras filas del archivo 'jpmorgan chase & co..csv':
Open High Low Close Volume
Date
2010-01-04 41.79 42.99 41.67 42.85 35460500
2010-01-05 42.79 43.84 42.78 43.68 41208300
2010-01-06 43.45 44.09 43.31 43.92 27729000
2010-01-07 43.79 45.12 43.61 44.79 44864700
2010-01-08 44.37 44.70 44.08 44.68 33110100
Columnas disponibles:
Index(['Open', 'High', 'Low', 'Close', 'Volume'], dtype='object')
Contenido del archivo 'jpmorgan chase & co..csv' con 'Date' como índice (formato 'YYYY-MM-DD'):
Open High Low Close Volume
Date
2010-01-04 41.79 42.99 41.6700 42.85 35460500
2010-01-05 42.79 43.84 42.7800 43.68 41208300
2010-01-06 43.45 44.09 43.3100 43.92 27729000
2010-01-07 43.79 45.12 43.6100 44.79 44864700
2010-01-08 44.37 44.70 44.0800 44.68 33110100
... ... ... ... ... ...
2025-05-05 251.18 255.16 250.5901 252.56 5450744
2025-05-06 250.00 252.65 249.0000 249.25 6369934
2025-05-07 249.85 252.45 248.8300 249.39 8724267
2025-05-08 251.57 255.88 251.5500 253.47 8320118
2025-05-09 254.50 255.51 252.3400 253.08 5087639
[3862 rows x 5 columns]
Archivo CSV mostrado correctamente.
Directorios disponibles:
1. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_AlphaVantage
2. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Marketstack
3. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_YFinance
4. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_EODHD
5. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Finnhub
6. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Investing
7. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_R4_csv
8. Salir
Seleccione el número del directorio donde se encuentran los archivos CSV: 2
...
Características principales:
Amplia cobertura: Explora datos de más de 70 bolsas de valores en todo el mundo.
Datos históricos: Accede a información histórica de hasta 1 año, ideal para análisis y estrategias a largo plazo.
Datos de fin de día: Obtén datos esenciales de cierre de jornada para tus análisis.
Seguridad: La conexión HTTPS garantiza la protección de tus datos.
Puedes probar la API de Marketstack de forma gratuita y realizar hasta 100 solicitudes al mes.
Para empezar.
Obtén tu clave de API: [API KEY]
Encuentra los tickers que necesitas: [ marketstack ]
Integración en Python: Explora la librería en Market Stack API - Python [Market Stack API - Python] .
Con Marketstack, tendrás las herramientas necesarias para potenciar tus análisis bursátiles y tomar decisiones informadas.
Script.
import requests
import pandas as pd
import time
import os # Importar la librería para trabajar con directorios
# Reemplaza 'TU_CLAVE_DE_API_MARKETSTACK' con tu clave de API real de Marketstack
#API_KEY_MARKETSTACK = 'TU_CLAVE_DE_API_MARKETSTACK'
OUTPUT_DIRECTORY = '/content'
Ficheros_Marketstack' # Directorio de destino
DATE_START = '2024-01-04'
DATE_END = pd.to_datetime('today').strftime('%Y-%m-%d')
# Diccionario de símbolos y nombres de archivo
stocks_to_download = {
'Apple': 'AAPL',
'Microsoft': 'MSFT',
'Google': 'GOOGL',
'S&P 500': '^GSPC'
}
# Función para descargar datos históricos diarios desde Marketstack
def get_marketstack_daily_data(symbol, api_key, start_date, end_date):
base_url = 'http://api.marketstack.com/v1/eod'
params = {
'access_key': api_key,
'symbols': symbol,
'date_from': start_date,
'date_to': end_date,
'limit': 1000 # Puedes ajustar el límite si es necesario
}
response = requests.get(base_url, params=params)
data = response.json()
return data
if __name__ == '__main__':
# Crear el directorio si no existe
if not os.path.exists(OUTPUT_DIRECTORY):
os.makedirs(OUTPUT_DIRECTORY)
all_value_closures_list = [] # Lista para almacenar los DataFrames
for stock_name, symbol in stocks_to_download.items():
#print(f"\nDescargando datos para: {stock_name} ({symbol}) desde Marketstack")
raw_data = get_marketstack_daily_data(symbol, API_KEY_MARKETSTACK, DATE_START, DATE_END)
#print("Respuesta JSON sin procesar de la API (Marketstack):")
#print(pd.Series(raw_data)) # Imprime la respuesta JSON como una Serie de Pandas
if 'data' in raw_data:
stock_data = raw_data['data']
if stock_data:
df = pd.DataFrame(stock_data)
df['Date'] = pd.to_datetime(df['date']).dt.date
df = df.set_index('Date')
df = df.sort_index(ascending=True)
# Renombrar las columnas para mayor claridad (adaptado a Marketstack)
df = df.rename(columns={
'open': 'Open',
'high': 'High',
'low': 'Low',
'close': 'Close',
'volume': 'Volume'
})
all_value_closures = df
all_value_closures_list.append(all_value_closures) # Añadir a la lista
#print(f"\nDataFrame 'all_value_closures' para {stock_name} (Marketstack):")
#print(all_value_closures) # Imprime el DataFrame resultante
# Definir el nombre del archivo basado en el nombre de la acción
filename = f'{stock_name.lower()}.csv'
filepath = os.path.join(OUTPUT_DIRECTORY, filename)
# Guardar el DataFrame filtrado
all_value_closures.to_csv(filepath)
print(f"Datos de {stock_name} guardados en '{filepath}'")
else:
print(f"No se encontraron datos para {stock_name} ({symbol}) en el rango especificado.")
elif 'error' in raw_data:
print(f"Error al descargar los datos para {stock_name} ({symbol}) desde Marketstack: {raw_data['error']['message']}")
else:
print(f"Respuesta inesperada de la API para {stock_name} ({symbol}) desde Marketstack.")
# Ser respetuoso con la tasa de llamadas de la API (Marketstack tiene sus propios límites)
time.sleep(15)
print("\nProceso de descarga y guardado completado (Marketstack).")
# La variable all_value_closures_list contiene ahora los DataFrames de cada acción
2.4.- EOD Historical Data Utilizando la API.
EOD Historical Data: Ofrecen una API RESTful con varios planes, incluyendo uno gratuito con limitaciones. Puedes acceder a datos históricos de acciones, ETFs, divisas y más. La documentación de su API es bastante completa.
Sign Up for EOD Historical Data: If you haven't already, create an account on the EOD Historical Data website
Obtain Your API Token: Once you have an account, navigate to your account settings or API documentation section to find your API token. This token is a unique string of characters that identifies your account.
get API-token: API TOKEN = "api_token=" xxxxxxxxx"
python-eodhistoricaldata
El plan gratuito de EOD Historical Data a menudo solo da acceso a 1 año de datos históricos EOD.
Script:
import requests
import pandas as pd
import time
import os # Importar la librería para trabajar con directorios
# Reemplaza 'TU_CLAVE_DE_API_EODHD' con tu clave de API real de EOD Historical Data
#API_KEY_EODHD = 'TU_CLAVE_DE_API_EODHD'
OUTPUT_DIRECTORY = '/content'
# Directorio de destino
DATE_START = '2010-01-04'
DATE_END = pd.to_datetime('today').strftime('%Y-%m-%d')
# Diccionario de símbolos y nombres de archivo
stocks_to_download = {
'Apple': 'AAPL.US', # EODHD requiere el símbolo con el código de mercado (ej: .US para acciones de EE.UU.)
'Microsoft': 'MSFT.US',
'Google': 'GOOGL.US' # Ajusta los símbolos según el mercado
}
# Función para descargar datos históricos diarios desde EOD Historical Data
def get_eodhd_daily_data(symbol, api_key, start_date, end_date):
base_url = f'https://eodhistoricaldata.com/api/eod/{symbol}'
params = {
'api_token': api_key,
'from': start_date,
'to': end_date,
'fmt': 'json'
}
response = requests.get(base_url, params=params)
data = response.json()
return data
if __name__ == '__main__':
# Crear el directorio si no existe
if not os.path.exists(OUTPUT_DIRECTORY):
os.makedirs(OUTPUT_DIRECTORY)
all_value_closures_list = [] # Lista para almacenar los DataFrames
for stock_name, symbol_eodhd in stocks_to_download.items():
#(f"\nDescargando datos para: {stock_name} ({symbol_eodhd}) desde EOD Historical Data")
raw_data = get_eodhd_daily_data(symbol_eodhd, API_KEY_EODHD, DATE_START, DATE_END)
#print("Respuesta JSON sin procesar de la API (EOD Historical Data):")
#print(pd.Series(raw_data)) # Imprime la respuesta JSON como una Serie de Pandas
if isinstance(raw_data, list): # Los datos se devuelven como una lista de diccionarios
if raw_data:
df = pd.DataFrame(raw_data)
df['Date'] = pd.to_datetime(df['date']).dt.date
df = df.set_index('Date')
df = df.sort_index(ascending=True)
df = df.drop(columns=['date'])
# Renombrar las columnas para mayor claridad (adaptado a EODHD)
df = df.rename(columns={
'open': 'Open',
'high': 'High',
'low': 'Low',
'close': 'Close',
'volume': 'Volume'
})
all_value_closures = df
all_value_closures_list.append(all_value_closures) # Añadir a la lista
#print(f"\nDataFrame 'all_value_closures' para {stock_name} (EOD Historical Data):")
#print(all_value_closures) # Imprime el DataFrame resultante
# Definir el nombre del archivo basado en el nombre de la acción
filename = f'{stock_name.lower()}.csv'
filepath = os.path.join(OUTPUT_DIRECTORY, filename)
# Guardar el DataFrame filtrado
all_value_closures.to_csv(filepath)
print(f"Datos de {stock_name} guardados en '{filepath}'")
else:
print(f"No se encontraron datos para {stock_name} ({symbol_eodhd}) en el rango especificado.")
elif isinstance(raw_data, dict) and 'Message' in raw_data:
print(f"Error al descargar los datos para {stock_name} ({symbol_eodhd}) desde EOD Historical Data: {raw_data['Message']}")
else:
print(f"Respuesta inesperada de la API para {stock_name} ({symbol_eodhd}) desde EOD Historical Data.")
# Ser respetuoso con la tasa de llamadas de la API (EODHD tiene sus propios límites)
time.sleep(15)
print("\nProceso de descarga y guardado completado (EOD Historical Data).")
# La variable all_value_closures_list contiene ahora los DataFrames de cada acción
2.5.- Leer cualquier fichero csv
Crea tu diccionario con las rutas de tus archivos. Ejemplo:
directorios_a_buscar = [
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_AlphaVantage',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Marketstack',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_YFinance',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_EODHD',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Finnhub',
''/content',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_R4_csv' # Directorio para archivos R4
# Añade aquí cualquier otra carpeta donde tengas tus archivos CSV
]
El directorio '/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_R4_csv' contiene archivos CSV con las siguientes características:
- Las fechas están en formato 'dd/mm/yy'.
- Utilizan tabulaciones como separador de campos (sep='\t').
- Utilizan comas como separador decimal (decimal=',').
Los demás directorios contienen archivos CSV con el formato por defecto de pandas.
- Separador de campos: Coma (,)
- Separador decimal: Punto (.)
- Formato de fecha: El formato de fecha por defecto de pandas depende de la inferencia automática de la librería, pero generalmente se alinea con formatos comunes como YYYY-MM-DD o MM/DD/YYYY.
3.- Script para la lectura de archivos.
import pandas as pd
import os
def seleccionar_directorio(lista_directorios):
"""Permite al usuario seleccionar un directorio de una lista."""
while True:
print("\nDirectorios disponibles:")
for i, directorio in enumerate(lista_directorios):
print(f"{i + 1}. {directorio}")
print(f"{len(lista_directorios) + 1}. Salir")
try:
seleccion = int(input("Seleccione el número del directorio donde se encuentran los archivos CSV: "))
if 1 <= seleccion <= len(lista_directorios):
return lista_directorios[seleccion - 1]
elif seleccion == len(lista_directorios) + 1:
return None
else:
print("Selección inválida. Por favor, ingrese un número de la lista o el número para salir.")
except ValueError:
print("Entrada inválida. Por favor, ingrese un número.")
def seleccionar_y_mostrar_csv(directorio):
"""
Lista los archivos CSV en el directorio seleccionado, permite al usuario seleccionar uno,
intenta inferir el formato de la fecha y muestra el DataFrame,
manejando formatos específicos como tabulaciones y comas decimales,
y asegura que la primera columna se use como índice de tipo datetime con formato 'YYYY-MM-DD'.
Args:
directorio (str): La ruta al directorio que contiene los archivos CSV.
Returns:
None, "volver_a_seleccionar_directorio", or DataFrame: Indica el resultado de la operación.
"""
archivos_csv = [f for f in os.listdir(directorio) if f.endswith('.csv')]
if not archivos_csv:
print(f"No se encontraron archivos CSV en el directorio: {directorio}")
return None
while True:
print(f"\nArchivos CSV disponibles en {directorio}:")
for i, nombre_archivo in enumerate(archivos_csv):
print(f"{i + 1}. {nombre_archivo}")
print(f"{len(archivos_csv) + 1}. Volver a seleccionar directorio")
print(f"{len(archivos_csv) + 2}. Salir")
try:
seleccion = int(input("Seleccione el número del archivo que desea abrir o la opción: "))
if 1 <= seleccion <= len(archivos_csv):
nombre_archivo_seleccionado = archivos_csv[seleccion - 1]
ruta_archivo_seleccionado = os.path.join(directorio, nombre_archivo_seleccionado)
try:
# Intentar leer el CSV con los parámetros específicos
if directorio.endswith('Ficheros_R4_csv'):
df = pd.read_csv(ruta_archivo_seleccionado, sep='\t', decimal=',')
else:
df = pd.read_csv(ruta_archivo_seleccionado)
print(f"\nArchivo {'R4 detectado con tabulaciones. Usando separador \'\\t\' y decimal \',\'\n' if directorio.endswith('Ficheros_R4_csv') else ''}Primeras filas del archivo '{nombre_archivo_seleccionado}':")
# Verificar si la primera columna tiene nombre
if df.columns[0] is None or df.columns[0] == 'Unnamed: 0':
df.columns = ['Date'] + list(df.columns[1:]) # Asignar 'Date' a la primera columna
# Si la primera columna no es 'Date', renombrarla a 'Date'
if df.columns[0] != 'Date':
df.rename(columns={df.columns[0]: 'Date'}, inplace=True)
try:
# Convertir la columna 'Date' a datetime y establecerla como índice
df['Date'] = pd.to_datetime(df['Date'], errors='coerce')
df.dropna(subset=['Date'], inplace=True)
df = df.set_index('Date')
df = df.sort_index()
df.index = df.index.strftime('%Y-%m-%d') # Formatear el índice
print(df.head())
print("\nColumnas disponibles:")
print(df.columns)
print(f"\nContenido del archivo '{nombre_archivo_seleccionado}' con 'Date' como índice (formato 'YYYY-MM-DD'):")
print(df)
return df
except ValueError as e:
print(f"Error al convertir a datetime o al establecer el índice: {e}")
print("Por favor, inspeccione el formato de la fecha en el archivo.")
return None
except FileNotFoundError:
print(f"Error: El archivo '{ruta_archivo_seleccionado}' no se encontró.")
except pd.errors.EmptyDataError:
print(f"Error: El archivo '{ruta_archivo_seleccionado}' está vacío.")
except pd.errors.ParserError as e:
print(f"Error al analizar el archivo '{ruta_archivo_seleccionado}'. Asegúrese de que el formato (separador, decimal) sea correcto. Error: {e}")
elif seleccion == len(archivos_csv) + 1:
return "volver_a_seleccionar_directorio"
elif seleccion == len(archivos_csv) + 2:
print("Saliendo del script.")
return None
else:
print("Selección inválida. Por favor, ingrese un número de la lista o la opción.")
except ValueError:
print("Entrada inválida. Por favor, ingrese un número.")
# Esto asegura que el bucle continúe si no se ha seleccionado "Salir"
print("\nOperación completada. Seleccione otro archivo o directorio, o elija 'Salir'.")
if __name__ == '__main__':
directorios_a_buscar = [
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_AlphaVantage',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Marketstack',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_YFinance',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_EODHD',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Finnhub',
'/content',
'/home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_R4_csv' # Directorio para archivos R4
# Añade aquí cualquier otra carpeta donde tengas tus archivos CSV
]
while True:
directorio_seleccionado = seleccionar_directorio(directorios_a_buscar)
if directorio_seleccionado is None:
break
resultado = seleccionar_y_mostrar_csv(directorio_seleccionado)
# Aquí está la corrección principal - comprobación explícita del tipo de resultado
if resultado is None:
continue # Volver al inicio del bucle para seleccionar otro directorio
elif isinstance(resultado, str) and resultado == "volver_a_seleccionar_directorio":
continue
elif isinstance(resultado, pd.DataFrame):
print("\nArchivo CSV mostrado correctamente.")
# Aquí puedes agregar código para trabajar con el DataFrame si es necesario
# No es necesario un break aquí, el bucle while externo continuará
print("\nOperación completada.")
Al ejecutra el código esta es la secuencia de pasos que va solicitando.
Directorios disponibles:
1. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_AlphaVantage
2. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Marketstack
3. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_YFinance
4. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_EODHD
5. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Finnhub
6. '/content'
7. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_R4_csv
8. Salir
Seleccione el número del directorio donde se encuentran los archivos CSV: 1
Archivos CSV disponibles en /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_AlphaVantage:
1. jpmorgan chase & co..csv
2. tesla.csv
3. microsoft.csv
4. meta platforms.csv
5. amazon.csv
6. johnson & johnson.csv
7. google.csv
8. apple.csv
9. berkshire hathaway.csv
10. Volver a seleccionar directorio
11. Salir
Seleccione el número del archivo que desea abrir o la opción: 1
Archivo Primeras filas del archivo 'jpmorgan chase & co..csv':
Open High Low Close Volume
Date
2010-01-04 41.79 42.99 41.67 42.85 35460500
2010-01-05 42.79 43.84 42.78 43.68 41208300
2010-01-06 43.45 44.09 43.31 43.92 27729000
2010-01-07 43.79 45.12 43.61 44.79 44864700
2010-01-08 44.37 44.70 44.08 44.68 33110100
Columnas disponibles:
Index(['Open', 'High', 'Low', 'Close', 'Volume'], dtype='object')
Contenido del archivo 'jpmorgan chase & co..csv' con 'Date' como índice (formato 'YYYY-MM-DD'):
Open High Low Close Volume
Date
2010-01-04 41.79 42.99 41.6700 42.85 35460500
2010-01-05 42.79 43.84 42.7800 43.68 41208300
2010-01-06 43.45 44.09 43.3100 43.92 27729000
2010-01-07 43.79 45.12 43.6100 44.79 44864700
2010-01-08 44.37 44.70 44.0800 44.68 33110100
... ... ... ... ... ...
2025-05-05 251.18 255.16 250.5901 252.56 5450744
2025-05-06 250.00 252.65 249.0000 249.25 6369934
2025-05-07 249.85 252.45 248.8300 249.39 8724267
2025-05-08 251.57 255.88 251.5500 253.47 8320118
2025-05-09 254.50 255.51 252.3400 253.08 5087639
[3862 rows x 5 columns]
Archivo CSV mostrado correctamente.
Directorios disponibles:
1. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_AlphaVantage
2. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Marketstack
3. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_YFinance
4. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_EODHD
5. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Finnhub
6. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_Investing
7. /home/enri/Python_blog_gestion_conservadora/Datos/Ficheros_R4_csv
8. Salir
Seleccione el número del directorio donde se encuentran los archivos CSV: 2
...