Update app.py
Browse files
app.py
CHANGED
|
@@ -493,8 +493,48 @@ def get_iframe_holdings(ticker):
|
|
| 493 |
except KeyError:
|
| 494 |
return f"No hay datos de holding de Bitcoin para {ticker}."
|
| 495 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 496 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 497 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 498 |
|
| 499 |
### CONFIGURACION DE GRADIO:
|
| 500 |
|
|
@@ -561,6 +601,35 @@ with gr.Blocks(title="Análisis de Correlación") as demo:
|
|
| 561 |
outputs=[output_iframe_holdings]
|
| 562 |
)
|
| 563 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 564 |
with gr.Tab("Resumen Holding"):
|
| 565 |
gr.Markdown("### Descargar resumen de holdings a Excel")
|
| 566 |
gr.Markdown("Esto descargará los datos de holding de BTC de la web, los procesará y creará un archivo Excel a partir de una plantilla.")
|
|
@@ -583,7 +652,7 @@ with gr.Blocks(title="Análisis de Correlación") as demo:
|
|
| 583 |
outputs=[output_resumen_file, output_resumen_msg]
|
| 584 |
)
|
| 585 |
|
| 586 |
-
|
| 587 |
|
| 588 |
|
| 589 |
#Inicia la aplicación
|
|
|
|
| 493 |
except KeyError:
|
| 494 |
return f"No hay datos de holding de Bitcoin para {ticker}."
|
| 495 |
|
| 496 |
+
def generar_resumen_holding():
|
| 497 |
+
"""
|
| 498 |
+
Descarga los datos de holding de BTC para stocks y ETFs y devuelve
|
| 499 |
+
los 15 principales de cada categoría en dos DataFrames.
|
| 500 |
+
"""
|
| 501 |
+
url_stocks = "https://bitcointreasuries.net/"
|
| 502 |
+
url_etfs = "https://bitcointreasuries.net/etfs-and-exchanges"
|
| 503 |
|
| 504 |
+
df_stocks = descargar_tabla_web(url_stocks, indice_tabla=3)
|
| 505 |
+
df_etfs = descargar_tabla_web(url_etfs, indice_tabla=3)
|
| 506 |
+
|
| 507 |
+
# Procesar Stocks
|
| 508 |
+
if df_stocks is not None and not df_stocks.empty:
|
| 509 |
+
df_stocks.columns = [
|
| 510 |
+
'Rank', 'Name', 'Bitcoin', 'BTC in USD',
|
| 511 |
+
'Marketcap', 'Sector', '% Total BTC 21M',
|
| 512 |
+
'Marketcap vs Bitcoin Holding', 'Date of Entry',
|
| 513 |
+
'Source', 'Website', 'Notes', 'Ticker'
|
| 514 |
+
]
|
| 515 |
+
df_stocks['Bitcoin'] = df_stocks['Bitcoin'].apply(limpiar_texto).apply(expand_money)
|
| 516 |
+
# Limpiamos y ordenamos por la columna de Bitcoin
|
| 517 |
+
df_stocks = df_stocks.sort_values(by='Bitcoin', ascending=False, ignore_index=True)
|
| 518 |
+
top_stocks = df_stocks[['Name', 'Bitcoin']].head(15).copy()
|
| 519 |
+
top_stocks.columns = ['Nombre', 'Bitcoin Holdings']
|
| 520 |
+
else:
|
| 521 |
+
top_stocks = pd.DataFrame(columns=['Nombre', 'Bitcoin Holdings'])
|
| 522 |
|
| 523 |
+
# Procesar ETFs
|
| 524 |
+
if df_etfs is not None and not df_etfs.empty:
|
| 525 |
+
df_etfs.columns = [
|
| 526 |
+
'Rank', 'Name', 'Bitcoin', 'BTC in USD',
|
| 527 |
+
'% Total BTC 21M', 'Date of Entry', 'Source'
|
| 528 |
+
]
|
| 529 |
+
df_etfs['Bitcoin'] = df_etfs['Bitcoin'].apply(limpiar_texto).apply(expand_money)
|
| 530 |
+
# Limpiamos y ordenamos por la columna de Bitcoin
|
| 531 |
+
df_etfs = df_etfs.sort_values(by='Bitcoin', ascending=False, ignore_index=True)
|
| 532 |
+
top_etfs = df_etfs[['Name', 'Bitcoin']].head(15).copy()
|
| 533 |
+
top_etfs.columns = ['Nombre', 'Bitcoin Holdings']
|
| 534 |
+
else:
|
| 535 |
+
top_etfs = pd.DataFrame(columns=['Nombre', 'Bitcoin Holdings'])
|
| 536 |
+
|
| 537 |
+
return top_stocks, top_etfs
|
| 538 |
|
| 539 |
### CONFIGURACION DE GRADIO:
|
| 540 |
|
|
|
|
| 601 |
outputs=[output_iframe_holdings]
|
| 602 |
)
|
| 603 |
|
| 604 |
+
|
| 605 |
+
|
| 606 |
+
# === Pestaña de Resumen Holding (NUEVA) ===
|
| 607 |
+
with gr.Tab("Resumen Holding"):
|
| 608 |
+
gr.Markdown("### Top 15 Holdings de Bitcoin")
|
| 609 |
+
gr.Markdown("Pulsa el botón para generar las tablas con las 15 empresas y ETFs con más BTC.")
|
| 610 |
+
|
| 611 |
+
btn_resumen = gr.Button("Generar Resumen")
|
| 612 |
+
|
| 613 |
+
gr.Markdown("#### Top 15 Stocks con más Bitcoin")
|
| 614 |
+
output_top_stocks = gr.DataFrame(
|
| 615 |
+
label="Stocks",
|
| 616 |
+
headers=['Nombre', 'Bitcoin Holdings'],
|
| 617 |
+
interactive=False
|
| 618 |
+
)
|
| 619 |
+
|
| 620 |
+
gr.Markdown("#### Top 15 ETFs con más Bitcoin")
|
| 621 |
+
output_top_etfs = gr.DataFrame(
|
| 622 |
+
label="ETFs",
|
| 623 |
+
headers=['Nombre', 'Bitcoin Holdings'],
|
| 624 |
+
interactive=False
|
| 625 |
+
)
|
| 626 |
+
|
| 627 |
+
btn_resumen.click(
|
| 628 |
+
fn=generar_resumen_holding,
|
| 629 |
+
inputs=[],
|
| 630 |
+
outputs=[output_top_stocks, output_top_etfs]
|
| 631 |
+
)
|
| 632 |
+
'''
|
| 633 |
with gr.Tab("Resumen Holding"):
|
| 634 |
gr.Markdown("### Descargar resumen de holdings a Excel")
|
| 635 |
gr.Markdown("Esto descargará los datos de holding de BTC de la web, los procesará y creará un archivo Excel a partir de una plantilla.")
|
|
|
|
| 652 |
outputs=[output_resumen_file, output_resumen_msg]
|
| 653 |
)
|
| 654 |
|
| 655 |
+
'''
|
| 656 |
|
| 657 |
|
| 658 |
#Inicia la aplicación
|