import pandas as pd import gradio as gr import ccxt import numpy as np import matplotlib.pyplot as plt import requests import pandas as pd import time from datetime import datetime, timedelta # Configuración de la API API_KEY = "TU_API_KEY_DE_CRYPTOCOMPARE" # Opcional para límites más altos, pero altamente recomendado BASE_URL = "https://min-api.cryptocompare.com/data/v2/histohour" SYMBOL = "BTC" CURRENCY = "USD" LIMIT_PER_CALL = 2000 # Máximo que permite CryptoCompare por llamada # Define el inicio hace 10 años (aproximadamente) # Ajusta la fecha final a la actual end_time = datetime.now() start_time = end_time - timedelta(days=10*365) # 10 años atrás aproximadamente # Convertir a timestamp de Unix (segundos) to_timestamp = int(end_time.timestamp()) all_data = [] print(f"Fetching BTC/{CURRENCY} hourly data from {start_time.strftime('%Y-%m-%d')} to {end_time.strftime('%Y-%m-%d')}") while True: params = { "fsym": SYMBOL, "tsym": CURRENCY, "limit": LIMIT_PER_CALL, "toTs": to_timestamp, "api_key": API_KEY # Si tienes una clave } try: response = requests.get(BASE_URL, params=params) data = response.json() if data['Response'] == 'Error': print(f"API Error: {data['Message']}") break ohlcv_data = data['Data']['Data'] if not ohlcv_data: break # No more data to fetch all_data.extend(ohlcv_data) # El siguiente `toTs` es el timestamp del primer punto de datos obtenido menos 1 hora (o 1 segundo) # para asegurarnos de no duplicar y retroceder en el tiempo. # Asegúrate de que los datos estén ordenados por tiempo ascendente desde la API. # CryptoCompare devuelve datos desde 'fromTs' hasta 'toTs' en orden ascendente, # pero cuando usamos `toTs`, devuelve los datos *anteriores* a `toTs`. # Por lo tanto, el nuevo `toTs` debe ser el 'time' del primer elemento de la llamada actual. to_timestamp = ohlcv_data[0]['time'] - 1 # Retrocede 1 segundo para la siguiente llamada # Convertir el timestamp del último dato para referencia oldest_data_time = datetime.fromtimestamp(ohlcv_data[0]['time']) print(f"Fetched data up to {oldest_data_time.strftime('%Y-%m-%d %H:%M:%S')}. Total records: {len(all_data)}") if oldest_data_time <= start_time: print(f"Reached desired start time ({start_time.strftime('%Y-%m-%d')}). Stopping.") break time.sleep(1) # Respetar límites de rate de la API except requests.exceptions.RequestException as e: print(f"Network error: {e}") time.sleep(5) # Esperar y reintentar except Exception as e: print(f"An unexpected error occurred: {e}") break # Convertir la lista de diccionarios a un DataFrame de Pandas btc_hour_10y = pd.DataFrame(all_data) btc_hour_10y['time'] = pd.to_datetime(btc_hour_10y['time'], unit='s') btc_hour_10y.set_index('time', inplace=True) btc_hour_10y.sort_index(inplace=True) # Asegurarse de que esté ordenado cronológicamente # Eliminar duplicados si los hubiera (puede pasar si las llamadas se solapan) btc_hour_10y = btc_hour_10y[~btc_hour_10y.index.duplicated(keep='first')] print("\nDataFrame Head:") print(btc_hour_10y.head()) print("\nDataFrame Tail:") print(btc_hour_10y.tail()) print(f"\nTotal records fetched: {len(btc_hour_10y)}") # Guardar a CSV btc_hour_10y.to_csv('btc_hourly_cryptocompare_10_years.csv') print("Data saved to btc_hourly_cryptocompare_10_years.csv") # Ajuste del formato: btc_hour_10y.index = btc_hour_10y.index.tz_localize('UTC') btc_hour_10y.index = btc_hour_10y.index.tz_convert('America/New_York') #Convertir el dataframe de UTC a 'America NY' btc_hour_10y = btc_hour_10y[btc_hour_10y.index.hour == 16] # Filtrar el dataframe para quedarnos la hora de cierre 4:00 PM EST btc_hour_10y.index = btc_hour_10y.index.date #Limpiamos el índice para que sólo muestre las fechas de los días btc_hour_10y.columns = btc_hour_10y.columns.str.title() #Ponemos los headers con la primera letra en Mayuscula btc_hour_10y.index = pd.to_datetime(btc_hour_10y.index) # Para coincidir con el formato de yahoofinance debemos convertir los indices a fechas en formato: dtype='datetime64[ns]' all_historical_data = { 'BTC-USD': btc_hour_10y } # @title función de datos: import yfinance as yf import pandas as pd import numpy as np from datetime import datetime, date def data_option(ticker, date, option_type,size_of_the_window=4): ''' El ticker es un string la fecha es un string en formato 'yyyy-mm-dd' el tipo de opción es un string 'call' o 'put' por defecto se mostrará el de call ''' ## la función está bien, sólo queda comprobar que el formato sea correcto, por ejemplo fecha es sting price = yf.Ticker(ticker).info['regularMarketPrice'] data = yf.Ticker(ticker).option_chain(date).puts.iloc[:, [0, 2, 3, 8, 10, 11, 13]] if option_type == 'put' else yf.Ticker(ticker).option_chain(date).calls.iloc[:, [0, 2, 3, 8, 10, 11, 13]] data['impliedVolatility'] = data['impliedVolatility'].apply(lambda x: f"{x*100:.2f}%") ## now, we wanto to keep the 20 closest to spot options in the list data = data.sort_values(by='strike', key=lambda x: abs(x - price)) price_row = pd.DataFrame([['░░░░░░░ Spot Price ░░░░░░░', price,'░░░░░░░░░░░░░░','░░░░░░░░░░','░░░░░░░░░░░░░░░░░░','░░░░░░░░░░░','░░░░░░░░░░']], columns= data.columns) date_row = pd.DataFrame([[f"▓▓▓▓▓▓▓ {date} ▓▓▓▓▓▓▓",'▓▓▓▓▓▓▓','▓▓▓▓▓▓▓▓▓▓▓▓▓▓','▓▓▓▓▓▓▓▓▓▓', '▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓', '▓▓▓▓▓▓▓▓▓▓▓','▓▓▓▓▓▓▓▓▓▓']],columns = data.columns) data = pd.concat( [data.head(size_of_the_window), price_row]).sort_values(by='strike') data = pd.concat([date_row, data]) return pd.DataFrame(data)