Quant0 commited on
Commit
02b7d96
·
verified ·
1 Parent(s): 91e1b87

Create processes.py

Browse files
Files changed (1) hide show
  1. processes.py +289 -0
processes.py ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import yfinance as yf
3
+ from datetime import datetime, timedelta
4
+ from data import all_historical_data, df_descargado_ETFs, df_descargado_stocks
5
+ from config import tickers_to_ids
6
+ import plotly.graph_objects as go
7
+
8
+ # -----------------------------------------------
9
+ # Función de Correlación
10
+ # -----------------------------------------------
11
+
12
+ def evolucion_correlacion(ticker_company, step, ticker_btc="BTC-USD", window_months=12):
13
+ """
14
+ Calcula la evolución de la correlación entre el precio de las acciones de una empresa y Bitcoin.
15
+ Args:
16
+ ticker_company (str): El símbolo de cotización de la empresa.
17
+ step (int): El número de días para el desplazamiento de la correlación.
18
+ ticker_btc (str): El símbolo de cotización de Bitcoin (por defecto: "BTC-USD").
19
+ window_months (int): El tamaño de la ventana móvil en meses.
20
+ outputs:
21
+ pandas.Series: Una serie con la evolución de la correlación, o None si faltan datos.
22
+ """
23
+ end_date = datetime.now()
24
+ start_date = end_date - timedelta(days=10*365)
25
+
26
+ if ticker_company not in all_historical_data:
27
+ print(f"Descargando datos para {ticker_company}...")
28
+ data = yf.download(ticker_company, start=start_date, end=end_date)
29
+ if not data.empty:
30
+ all_historical_data[ticker_company] = data
31
+ print(f"Datos de {ticker_company} descargados con éxito.")
32
+ else:
33
+ print(f"Error al descargar datos para {ticker_company}.")
34
+ return None
35
+
36
+ if ticker_btc not in all_historical_data:
37
+ print(f"Descargando datos para {ticker_btc}...")
38
+ data = yf.download(ticker_btc, start=start_date, end=end_date)
39
+ if not data.empty:
40
+ all_historical_data[ticker_btc] = data
41
+ print(f"Datos de {ticker_btc} descargados con éxito.")
42
+ else:
43
+ print(f"Error al descargar datos para {ticker_btc}.")
44
+ return None
45
+
46
+ company_data = all_historical_data.get(ticker_company)
47
+ btc_data = all_historical_data.get(ticker_btc)
48
+
49
+ if company_data.empty or btc_data.empty:
50
+ print(f"No podemos calcular la correlación dinámica: No hay datos disponibles para {ticker_company} o {ticker_btc}.")
51
+ return None
52
+
53
+ company_prices = company_data['Close']
54
+ btc_prices = btc_data['Close']
55
+
56
+ combined_prices = pd.concat([company_prices, btc_prices], axis=1).dropna()
57
+ combined_prices.columns = [ticker_company, ticker_btc]
58
+
59
+ if combined_prices.empty:
60
+ print(f"No hay datos históricos en común entre {ticker_company} y {ticker_btc}.")
61
+ return None
62
+
63
+ company_returns = combined_prices[ticker_company].pct_change().dropna()
64
+ btc_returns = combined_prices[ticker_btc].pct_change().dropna()
65
+
66
+ window_days = window_months * 30
67
+ if step == 0:
68
+ dynamic_corr = company_returns.rolling(window=f"{window_days}D").corr(btc_returns).iloc[-1]
69
+ return pd.Series([dynamic_corr], index=[end_date])
70
+ else:
71
+ dynamic_corr = company_returns.rolling(window=f"{window_days}D").corr(btc_returns).dropna()
72
+ return dynamic_corr.iloc[9::step]
73
+
74
+
75
+
76
+
77
+ # -----------------------------------------------
78
+ # PLOT DE LA CORRELACIÓN
79
+ # -----------------------------------------------
80
+
81
+
82
+
83
+ def plot_evolucion_correlacion_gradio(ticker_company, step, window_months):
84
+
85
+ """
86
+ Genera el gráfico de la evolución de la correlación.
87
+ """
88
+ ticker_company = ticker_company.upper()
89
+ serie = evolucion_correlacion(ticker_company, step, window_months=12)
90
+
91
+ if serie is None or serie.empty:
92
+ return None, f"No hay datos de correlación disponibles para {ticker_company}."
93
+
94
+ # --- Create the Plotly graph ---
95
+ fig = go.Figure()
96
+
97
+ # Add the correlation series
98
+ fig.add_trace(go.Scatter(
99
+ x=serie.index,
100
+ y=serie.values,
101
+ mode='lines',
102
+ name='Correlación',
103
+ line=dict(color='#2263eb', width=2), # electric blue color for the line
104
+ fill='tozeroy', # Fill the area down to Y=0 axis
105
+ fillcolor='rgba(34,99,235,0.1)', # Very faint elctric blue shadow (10% opacity)
106
+ hovertemplate='Fecha: %{x|%Y-%m-%d}<br>Correlación: %{y:.4f}<extra></extra>'
107
+ ))
108
+
109
+ # --- Configure axes and range selector ---
110
+ fig.update_layout(
111
+ title_text=f'<b>Evolución de la correlación entre {ticker_company} y BTC-USD<b>',
112
+ title_x=0, # Align title to the left
113
+ height=500, # Graph height
114
+ template="plotly_white", # Graph theme (clean and modern)
115
+ margin=dict(l=20, r=20, t=60, b=20), # Graph margins
116
+ showlegend=False, # No legend needed if only one main series
117
+
118
+ xaxis=go.layout.XAxis(
119
+ rangeslider=dict(
120
+ visible=True,
121
+ thickness=0.08, # Rangeslider thickness
122
+ bgcolor="rgba(50, 0, 128, 0.1)", # Very transparent purple for rangeslider
123
+ bordercolor="rgba(50, 0, 128, 0.2)", # Slightly more visible border
124
+ borderwidth=1,
125
+ range=[serie.index.min(), serie.index.max()] # Initial slider range
126
+ ),
127
+ rangeselector=dict(
128
+ buttons=list([
129
+ dict(count=1, label="1m", step="month", stepmode="backward"),
130
+ dict(count=3, label="3m", step="month", stepmode="backward"),
131
+ dict(count=6, label="6m", step="month", stepmode="backward"),
132
+ dict(step="year", count=1, label="YTD", stepmode="todate"), # YTD
133
+ dict(count=1, label="1y", step="year", stepmode="backward"),
134
+ dict(step="all", label="All")
135
+ ]),
136
+ bgcolor="rgba(247,247,247,255)", # Transparent background for buttons
137
+ bordercolor="rgba(0,0,0,0)", # Transparent border
138
+ borderwidth=0,
139
+ activecolor="rgba(230,233,255,255)", # Active button color (slightly darker purple)
140
+ font=dict(color="#000000", size=10), # Button font style
141
+ x=0.9, y=1.1, xanchor='right', yanchor='top' # Button position
142
+ ),
143
+ type="date",
144
+ domain=[0, 1], # Occupy full graph width
145
+ rangeslider_yaxis_rangemode="auto", # Rangeslider Y-axis range adjusts automatically
146
+ showgrid=False,
147
+ gridcolor='#e0e0e0',
148
+ zeroline=False
149
+ ),
150
+ yaxis=go.layout.YAxis(
151
+ title_text='Correlación',
152
+ side='left',
153
+ showgrid=True,
154
+ gridcolor='#e0e0e0',
155
+ zeroline=False,
156
+ tickformat=".2f", # 2 decimal places format
157
+ range=[-1.0, 1.0] # Fixed range for correlation
158
+ ),
159
+ hovermode="x unified", # Unify hover to show data for the series
160
+ paper_bgcolor='rgba(255,255,255,1)', # Transparent background for notebook integration
161
+ plot_bgcolor='rgba(255,255,255,1)'
162
+ )
163
+
164
+ # --- Add annotation for max value (similar to Matplotlib) ---
165
+ max_value = serie.max()
166
+ max_index = serie.idxmax()
167
+ fig.add_annotation(
168
+ x=max_index,
169
+ y=max_value,
170
+ text=f'Corr_max: {max_value:.4f}<br>Fecha: {max_index.date()}',
171
+ showarrow=True,
172
+ arrowhead=2,
173
+ ax=0,
174
+ ay=-40, # Adjust vertical position of the annotation
175
+ bgcolor="rgba(255, 255, 255, 0.8)", # Semi-transparent white background
176
+ bordercolor="#c7c7c7",
177
+ borderwidth=1,
178
+ borderpad=4,
179
+ font=dict(size=10, color="#333"),
180
+ # You can adjust text position with xanchor/yanchor if needed
181
+ )
182
+
183
+ return fig, "Gráfico de correlación generado."
184
+
185
+
186
+
187
+ # -----------------------------------------------
188
+ # EXPORTACIÓN DE LA CORRELACIÓN
189
+ # -----------------------------------------------
190
+
191
+
192
+ def exportar_correlacion(ticker_company, step, window_months):
193
+
194
+ """
195
+ Exporta la serie de correlación a un archivo Excel.
196
+ """
197
+ try:
198
+ serie = evolucion_correlacion(ticker_company, step, window_months=window_months)
199
+ if serie is not None and not serie.empty:
200
+ nombre_archivo = f'{ticker_company}_evolucion_correlacion.xlsx'
201
+ serie.to_excel(nombre_archivo)
202
+ return nombre_archivo, "Archivo Excel generado con éxito."
203
+ else:
204
+ return None, "No se pudieron generar los datos para exportar."
205
+ except Exception as e:
206
+ return None, f"Error al exportar: {e}"
207
+
208
+
209
+ # -----------------------------------------------
210
+ # EMBED PLOT STOCK VS BTC DE BTC TREASURY
211
+ # -----------------------------------------------
212
+
213
+
214
+ def get_iframe_stock_vs_btc(ticker):
215
+ """
216
+ Genera el código HTML para el iframe de Stock vs Bitcoin.
217
+ """
218
+ try:
219
+ entity_id = tickers_to_ids[ticker]
220
+ iframe_code = f"""
221
+ <iframe src="https://bitcointreasuries.net/embed?component=StockVsBitcoinChart&entityId={entity_id}"
222
+ title="Bitcoin Treasuries" credentialless style="width: 100%; height: 660px; border: none;"></iframe>
223
+ """
224
+ return iframe_code
225
+ except KeyError:
226
+ return f"No hay datos de holding de Bitcoin para {ticker}."
227
+
228
+
229
+
230
+ # -----------------------------------------------
231
+ # EMBED PLOT HOLDING BTC DE BTC TREASURY
232
+ # -----------------------------------------------
233
+
234
+
235
+ def get_iframe_holdings(ticker):
236
+ """
237
+ Genera el código HTML para el iframe de Bitcoin Holdings.
238
+ """
239
+ try:
240
+ entity_id = tickers_to_ids[ticker]
241
+ iframe_code = f"""
242
+ <iframe src="https://bitcointreasuries.net/embed?component=BitcoinHoldingsChart&entityId={entity_id}"
243
+ title="Bitcoin Holdings Chart" credentialless style="width: 100%; height: 660px; border: none;"></iframe>
244
+ """
245
+ return iframe_code
246
+ except KeyError:
247
+ return f"No hay datos de holding de Bitcoin para {ticker}."
248
+
249
+
250
+
251
+
252
+ # -----------------------------------------------
253
+ # TABLAS TOP HOLDING RESUMEN
254
+ # -----------------------------------------------
255
+
256
+
257
+
258
+ df_descargado_ETFs, df_descargado_stocks = top_holding()
259
+ df_descargado_ETFs = df_descargado_ETFs.reset_index()
260
+
261
+ # Crear un DataFrame de ejemplo
262
+ top5_ETFs = df_descargado_ETFs.copy().iloc[:,[1,2,3]].head()
263
+ top5_ETFs = pd.DataFrame(top5_ETFs)
264
+
265
+ top5_stocks = df_descargado_stocks.copy().iloc[:,[0,1,2]].head()
266
+ top5_stocks = pd.DataFrame(top5_stocks)
267
+
268
+ # Aplicar estilo con color de marca y bordes redondeados
269
+ styled_stocks = top5_stocks.style.set_table_attributes(
270
+ 'style="border-collapse: separate; border-spacing: 0; border-radius: 12px; overflow: hidden;"'
271
+ ).set_table_styles([
272
+ {'selector': 'thead th',
273
+ 'props': [('background-color', '#0085CA'), ('color', 'white'), ('padding', '10px'), ('border', '1px solid #0085CA')]},
274
+ {'selector': 'td',
275
+ 'props': [('background-color', 'white'), ('color', 'black'), ('padding', '10px'), ('border', '1px solid #0085CA')]},
276
+ {'selector': 'table',
277
+ 'props': [('border', '2px solid #0085CA'), ('border-radius', '12px'), ('overflow', 'hidden')]}
278
+ ])
279
+
280
+ styled_ETFs = top5_ETFs.style.set_table_attributes(
281
+ 'style="border-collapse: separate; border-spacing: 0; border-radius: 12px; overflow: hidden;"'
282
+ ).set_table_styles([
283
+ {'selector': 'thead th',
284
+ 'props': [('background-color', '#0085CA'), ('color', 'white'), ('padding', '10px'), ('border', '1px solid #0085CA')]},
285
+ {'selector': 'td',
286
+ 'props': [('background-color', 'white'), ('color', 'black'), ('padding', '10px'), ('border', '1px solid #0085CA')]},
287
+ {'selector': 'table',
288
+ 'props': [('border', '2px solid #0085CA'), ('border-radius', '12px'), ('overflow', 'hidden')]}
289
+ ])