File size: 6,110 Bytes
4b54e83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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)