@@ -32,7 +32,7 @@ from app.markets import (
CryptoCompareWrapper ,
CryptoCompareWrapper ,
BinanceWrapper ,
BinanceWrapper ,
YFinanceWrapper ,
YFinanceWrapper ,
Base Wrapper
Market Wrapper
)
)
# Carica variabili d'ambiente
# Carica variabili d'ambiente
@@ -40,21 +40,21 @@ load_dotenv()
class DemoFormatter :
class DemoFormatter :
""" Classe per formattare l ' output del demo in modo strutturato. """
""" Classe per formattare l ' output del demo in modo strutturato. """
@staticmethod
@staticmethod
def print_header ( title : str , char : str = " = " , width : int = 80 ) :
def print_header ( title : str , char : str = " = " , width : int = 80 ) :
""" Stampa un ' intestazione formattata. """
""" Stampa un ' intestazione formattata. """
print ( f " \n { char * width } " )
print ( f " \n { char * width } " )
print ( f " { title : ^ { width } } " )
print ( f " { title : ^ { width } } " )
print ( f " { char * width } " )
print ( f " { char * width } " )
@staticmethod
@staticmethod
def print_subheader ( title : str , char : str = " - " , width : int = 60 ) :
def print_subheader ( title : str , char : str = " - " , width : int = 60 ) :
""" Stampa una sotto-intestazione formattata. """
""" Stampa una sotto-intestazione formattata. """
print ( f " \n { char * width } " )
print ( f " \n { char * width } " )
print ( f " { title } " )
print ( f " { title } " )
print ( f " { char * width } " )
print ( f " { char * width } " )
@staticmethod
@staticmethod
def print_request_info ( provider_name : str , method : str , timestamp : datetime ,
def print_request_info ( provider_name : str , method : str , timestamp : datetime ,
status : str , error : Optional [ str ] = None ) :
status : str , error : Optional [ str ] = None ) :
@@ -66,83 +66,83 @@ class DemoFormatter:
if error :
if error :
print ( f " ❌ Error: { error } " )
print ( f " ❌ Error: { error } " )
print ( )
print ( )
@staticmethod
@staticmethod
def print_product_table ( products : List [ Any ] , title : str = " Products " ) :
def print_product_table ( products : List [ Any ] , title : str = " Products " ) :
""" Stampa una tabella di prodotti. """
""" Stampa una tabella di prodotti. """
if not products :
if not products :
print ( f " 📋 { title } : Nessun prodotto trovato " )
print ( f " 📋 { title } : Nessun prodotto trovato " )
return
return
print ( f " 📋 { title } ( { len ( products ) } items): " )
print ( f " 📋 { title } ( { len ( products ) } items): " )
print ( f " { ' Symbol ' : <15 } { ' ID ' : <20 } { ' Price ' : <12 } { ' Quote ' : <10 } { ' Status ' : <10 } " )
print ( f " { ' Symbol ' : <15 } { ' ID ' : <20 } { ' Price ' : <12 } { ' Quote ' : <10 } { ' Status ' : <10 } " )
print ( " - " * 67 )
print ( " - " * 67 )
for product in products [ : 10 ] : # Mostra solo i primi 10
for product in products [ : 10 ] : # Mostra solo i primi 10
symbol = getattr ( product , ' symbol ' , ' N/A ' )
symbol = getattr ( product , ' symbol ' , ' N/A ' )
product_id = getattr ( product , ' id ' , ' N/A ' )
product_id = getattr ( product , ' id ' , ' N/A ' )
price = getattr ( product , ' price ' , 0.0 )
price = getattr ( product , ' price ' , 0.0 )
quote = getattr ( product , ' quote_currency ' , ' N/A ' )
quote = getattr ( product , ' quote_currency ' , ' N/A ' )
status = getattr ( product , ' status ' , ' N/A ' )
status = getattr ( product , ' status ' , ' N/A ' )
# Tronca l'ID se troppo lungo
# Tronca l'ID se troppo lungo
if len ( product_id ) > 18 :
if len ( product_id ) > 18 :
product_id = product_id [ : 15 ] + " ... "
product_id = product_id [ : 15 ] + " ... "
price_str = f " $ { price : .2f } " if price > 0 else " N/A "
price_str = f " $ { price : .2f } " if price > 0 else " N/A "
print ( f " { symbol : <15 } { product_id : <20 } { price_str : <12 } { quote : <10 } { status : <10 } " )
print ( f " { symbol : <15 } { product_id : <20 } { price_str : <12 } { quote : <10 } { status : <10 } " )
if len ( products ) > 10 :
if len ( products ) > 10 :
print ( f " ... e altri { len ( products ) - 10 } prodotti " )
print ( f " ... e altri { len ( products ) - 10 } prodotti " )
print ( )
print ( )
@staticmethod
@staticmethod
def print_prices_table ( prices : List [ Any ] , title : str = " Historical Prices " ) :
def print_prices_table ( prices : List [ Any ] , title : str = " Historical Prices " ) :
""" Stampa una tabella di prezzi storici. """
""" Stampa una tabella di prezzi storici. """
if not prices :
if not prices :
print ( f " 💰 { title } : Nessun prezzo trovato " )
print ( f " 💰 { title } : Nessun prezzo trovato " )
return
return
print ( f " 💰 { title } ( { len ( prices ) } entries): " )
print ( f " 💰 { title } ( { len ( prices ) } entries): " )
print ( f " { ' Time ' : <12 } { ' Open ' : <12 } { ' High ' : <12 } { ' Low ' : <12 } { ' Close ' : <12 } { ' Volume ' : <15 } " )
print ( f " { ' Time ' : <12 } { ' Open ' : <12 } { ' High ' : <12 } { ' Low ' : <12 } { ' Close ' : <12 } { ' Volume ' : <15 } " )
print ( " - " * 75 )
print ( " - " * 75 )
for price in prices [ : 5 ] : # Mostra solo i primi 5
for price in prices [ : 5 ] : # Mostra solo i primi 5
time_str = getattr ( price , ' time ' , ' N/A ' )
time_str = getattr ( price , ' time ' , ' N/A ' )
# Il time è già una stringa, non serve strftime
# Il time è già una stringa, non serve strftime
if len ( time_str ) > 10 :
if len ( time_str ) > 10 :
time_str = time_str [ : 10 ] # Tronca se troppo lungo
time_str = time_str [ : 10 ] # Tronca se troppo lungo
open_price = f " $ { getattr ( price , ' open ' , 0 ) : .2f } "
open_price = f " $ { getattr ( price , ' open ' , 0 ) : .2f } "
high_price = f " $ { getattr ( price , ' high ' , 0 ) : .2f } "
high_price = f " $ { getattr ( price , ' high ' , 0 ) : .2f } "
low_price = f " $ { getattr ( price , ' low ' , 0 ) : .2f } "
low_price = f " $ { getattr ( price , ' low ' , 0 ) : .2f } "
close_price = f " $ { getattr ( price , ' close ' , 0 ) : .2f } "
close_price = f " $ { getattr ( price , ' close ' , 0 ) : .2f } "
volume = f " { getattr ( price , ' volume ' , 0 ) : ,.0f } "
volume = f " { getattr ( price , ' volume ' , 0 ) : ,.0f } "
print ( f " { time_str : <12 } { open_price : <12 } { high_price : <12 } { low_price : <12 } { close_price : <12 } { volume : <15 } " )
print ( f " { time_str : <12 } { open_price : <12 } { high_price : <12 } { low_price : <12 } { close_price : <12 } { volume : <15 } " )
if len ( prices ) > 5 :
if len ( prices ) > 5 :
print ( f " ... e altri { len ( prices ) - 5 } prezzi " )
print ( f " ... e altri { len ( prices ) - 5 } prezzi " )
print ( )
print ( )
class ProviderTester :
class ProviderTester :
""" Classe per testare i provider di market data. """
""" Classe per testare i provider di market data. """
def __init__ ( self ) :
def __init__ ( self ) :
self . formatter = DemoFormatter ( )
self . formatter = DemoFormatter ( )
self . test_symbols = [ " BTC " , " ETH " , " ADA " ]
self . test_symbols = [ " BTC " , " ETH " , " ADA " ]
def test_provider ( self , wrapper : Base Wrapper, provider_name : str ) - > Dict [ str , Any ] :
def test_provider ( self , wrapper : Market Wrapper, provider_name : str ) - > Dict [ str , Any ] :
""" Testa un provider specifico con tutti i metodi disponibili. """
""" Testa un provider specifico con tutti i metodi disponibili. """
results = {
results : Dict [ str , Any ] = {
" provider_name " : provider_name ,
" provider_name " : provider_name ,
" tests " : { } ,
" tests " : { } ,
" overall_status " : " SUCCESS "
" overall_status " : " SUCCESS "
}
}
self . formatter . print_subheader ( f " 🔍 Testing { provider_name } " )
self . formatter . print_subheader ( f " 🔍 Testing { provider_name } " )
# Test get_product
# Test get_product
for symbol in self . test_symbols :
for symbol in self . test_symbols :
timestamp = datetime . now ( )
timestamp = datetime . now ( )
@@ -153,13 +153,13 @@ class ProviderTester:
)
)
if product :
if product :
print ( f " 📦 Product: { product . symbol } (ID: { product . id } ) " )
print ( f " 📦 Product: { product . symbol } (ID: { product . id } ) " )
print ( f " Price: $ { product . price : .2f } , Quote: { product . quote_ currency} " )
print ( f " Price: $ { product . price : .2f } , Quote: { product . currency } " )
print ( f " Volume 24h: { product . volume_24h : ,.2f } " )
print ( f " Volume 24h: { product . volume_24h : ,.2f } " )
else :
else :
print ( f " 📦 Product: Nessun prodotto trovato per { symbol } " )
print ( f " 📦 Product: Nessun prodotto trovato per { symbol } " )
results [ " tests " ] [ f " get_product_ { symbol } " ] = " SUCCESS "
results [ " tests " ] [ f " get_product_ { symbol } " ] = " SUCCESS "
except Exception as e :
except Exception as e :
error_msg = str ( e )
error_msg = str ( e )
self . formatter . print_request_info (
self . formatter . print_request_info (
@@ -167,7 +167,7 @@ class ProviderTester:
)
)
results [ " tests " ] [ f " get_product_ { symbol } " ] = f " ERROR: { error_msg } "
results [ " tests " ] [ f " get_product_ { symbol } " ] = f " ERROR: { error_msg } "
results [ " overall_status " ] = " PARTIAL "
results [ " overall_status " ] = " PARTIAL "
# Test get_products
# Test get_products
timestamp = datetime . now ( )
timestamp = datetime . now ( )
try :
try :
@@ -177,7 +177,7 @@ class ProviderTester:
)
)
self . formatter . print_product_table ( products , f " { provider_name } Products " )
self . formatter . print_product_table ( products , f " { provider_name } Products " )
results [ " tests " ] [ " get_products " ] = " SUCCESS "
results [ " tests " ] [ " get_products " ] = " SUCCESS "
except Exception as e :
except Exception as e :
error_msg = str ( e )
error_msg = str ( e )
self . formatter . print_request_info (
self . formatter . print_request_info (
@@ -185,7 +185,7 @@ class ProviderTester:
)
)
results [ " tests " ] [ " get_products " ] = f " ERROR: { error_msg } "
results [ " tests " ] [ " get_products " ] = f " ERROR: { error_msg } "
results [ " overall_status " ] = " PARTIAL "
results [ " overall_status " ] = " PARTIAL "
# Test get_historical_prices
# Test get_historical_prices
timestamp = datetime . now ( )
timestamp = datetime . now ( )
try :
try :
@@ -195,7 +195,7 @@ class ProviderTester:
)
)
self . formatter . print_prices_table ( prices , f " { provider_name } BTC Historical Prices " )
self . formatter . print_prices_table ( prices , f " { provider_name } BTC Historical Prices " )
results [ " tests " ] [ " get_historical_prices " ] = " SUCCESS "
results [ " tests " ] [ " get_historical_prices " ] = " SUCCESS "
except Exception as e :
except Exception as e :
error_msg = str ( e )
error_msg = str ( e )
self . formatter . print_request_info (
self . formatter . print_request_info (
@@ -203,7 +203,7 @@ class ProviderTester:
)
)
results [ " tests " ] [ " get_historical_prices " ] = f " ERROR: { error_msg } "
results [ " tests " ] [ " get_historical_prices " ] = f " ERROR: { error_msg } "
results [ " overall_status " ] = " PARTIAL "
results [ " overall_status " ] = " PARTIAL "
return results
return results
def check_environment_variables ( ) - > Dict [ str , bool ] :
def check_environment_variables ( ) - > Dict [ str , bool ] :
@@ -217,11 +217,11 @@ def check_environment_variables() -> Dict[str, bool]:
}
}
return env_vars
return env_vars
def initialize_providers ( ) - > Dict [ str , Base Wrapper] :
def initialize_providers ( ) - > Dict [ str , Market Wrapper] :
""" Inizializza tutti i provider disponibili. """
""" Inizializza tutti i provider disponibili. """
providers = { }
providers : Dict [ str , MarketWrapper ] = { }
env_vars = check_environment_variables ( )
env_vars = check_environment_variables ( )
# CryptoCompareWrapper
# CryptoCompareWrapper
if env_vars [ " CRYPTOCOMPARE_API_KEY " ] :
if env_vars [ " CRYPTOCOMPARE_API_KEY " ] :
try :
try :
@@ -231,7 +231,7 @@ def initialize_providers() -> Dict[str, BaseWrapper]:
print ( f " ❌ Errore nell ' inizializzazione di CryptoCompareWrapper: { e } " )
print ( f " ❌ Errore nell ' inizializzazione di CryptoCompareWrapper: { e } " )
else :
else :
print ( " ⚠️ CryptoCompareWrapper saltato: CRYPTOCOMPARE_API_KEY non trovata " )
print ( " ⚠️ CryptoCompareWrapper saltato: CRYPTOCOMPARE_API_KEY non trovata " )
# CoinBaseWrapper
# CoinBaseWrapper
if env_vars [ " COINBASE_API_KEY " ] and env_vars [ " COINBASE_API_SECRET " ] :
if env_vars [ " COINBASE_API_KEY " ] and env_vars [ " COINBASE_API_SECRET " ] :
try :
try :
@@ -241,14 +241,14 @@ def initialize_providers() -> Dict[str, BaseWrapper]:
print ( f " ❌ Errore nell ' inizializzazione di CoinBaseWrapper: { e } " )
print ( f " ❌ Errore nell ' inizializzazione di CoinBaseWrapper: { e } " )
else :
else :
print ( " ⚠️ CoinBaseWrapper saltato: credenziali Coinbase non complete " )
print ( " ⚠️ CoinBaseWrapper saltato: credenziali Coinbase non complete " )
# BinanceWrapper
# BinanceWrapper
try :
try :
providers [ " Binance " ] = BinanceWrapper ( )
providers [ " Binance " ] = BinanceWrapper ( )
print ( " ✅ BinanceWrapper inizializzato con successo " )
print ( " ✅ BinanceWrapper inizializzato con successo " )
except Exception as e :
except Exception as e :
print ( f " ❌ Errore nell ' inizializzazione di BinanceWrapper: { e } " )
print ( f " ❌ Errore nell ' inizializzazione di BinanceWrapper: { e } " )
# YFinanceWrapper (sempre disponibile - dati azionari e crypto gratuiti)
# YFinanceWrapper (sempre disponibile - dati azionari e crypto gratuiti)
try :
try :
providers [ " YFinance " ] = YFinanceWrapper ( )
providers [ " YFinance " ] = YFinanceWrapper ( )
@@ -261,22 +261,22 @@ def print_summary(results: List[Dict[str, Any]]):
""" Stampa un riassunto finale dei risultati. """
""" Stampa un riassunto finale dei risultati. """
formatter = DemoFormatter ( )
formatter = DemoFormatter ( )
formatter . print_header ( " 📊 RIASSUNTO FINALE " , " = " , 80 )
formatter . print_header ( " 📊 RIASSUNTO FINALE " , " = " , 80 )
total_providers = len ( results )
total_providers = len ( results )
successful_providers = sum ( 1 for r in results if r [ " overall_status " ] == " SUCCESS " )
successful_providers = sum ( 1 for r in results if r [ " overall_status " ] == " SUCCESS " )
partial_providers = sum ( 1 for r in results if r [ " overall_status " ] == " PARTIAL " )
partial_providers = sum ( 1 for r in results if r [ " overall_status " ] == " PARTIAL " )
print ( f " 🔢 Provider testati: { total_providers } " )
print ( f " 🔢 Provider testati: { total_providers } " )
print ( f " ✅ Provider completamente funzionanti: { successful_providers } " )
print ( f " ✅ Provider completamente funzionanti: { successful_providers } " )
print ( f " ⚠️ Provider parzialmente funzionanti: { partial_providers } " )
print ( f " ⚠️ Provider parzialmente funzionanti: { partial_providers } " )
print ( f " ❌ Provider non funzionanti: { total_providers - successful_providers - partial_providers } " )
print ( f " ❌ Provider non funzionanti: { total_providers - successful_providers - partial_providers } " )
print ( " \n 📋 Dettaglio per provider: " )
print ( " \n 📋 Dettaglio per provider: " )
for result in results :
for result in results :
provider_name = result [ " provider_name " ]
provider_name = result [ " provider_name " ]
status = result [ " overall_status " ]
status = result [ " overall_status " ]
status_icon = " ✅ " if status == " SUCCESS " else " ⚠️ " if status == " PARTIAL " else " ❌ "
status_icon = " ✅ " if status == " SUCCESS " else " ⚠️ " if status == " PARTIAL " else " ❌ "
print ( f " \n { status_icon } { provider_name } : " )
print ( f " \n { status_icon } { provider_name } : " )
for test_name , test_result in result [ " tests " ] . items ( ) :
for test_name , test_result in result [ " tests " ] . items ( ) :
test_icon = " ✅ " if test_result == " SUCCESS " else " ❌ "
test_icon = " ✅ " if test_result == " SUCCESS " else " ❌ "
@@ -285,39 +285,39 @@ def print_summary(results: List[Dict[str, Any]]):
def main ( ) :
def main ( ) :
""" Funzione principale del demo. """
""" Funzione principale del demo. """
formatter = DemoFormatter ( )
formatter = DemoFormatter ( )
# Intestazione principale
# Intestazione principale
formatter . print_header ( " 🚀 DEMO COMPLETO MARKET DATA PROVIDERS " , " = " , 80 )
formatter . print_header ( " 🚀 DEMO COMPLETO MARKET DATA PROVIDERS " , " = " , 80 )
print ( f " 🕒 Avvio demo: { datetime . now ( ) . strftime ( ' % Y- % m- %d % H: % M: % S ' ) } " )
print ( f " 🕒 Avvio demo: { datetime . now ( ) . strftime ( ' % Y- % m- %d % H: % M: % S ' ) } " )
print ( " 📝 Questo demo testa tutti i wrapper BaseWrapper disponibili " )
print ( " 📝 Questo demo testa tutti i wrapper BaseWrapper disponibili " )
print ( " 🔍 Ogni test include timestamp, stato della richiesta e dati formattati " )
print ( " 🔍 Ogni test include timestamp, stato della richiesta e dati formattati " )
# Verifica variabili d'ambiente
# Verifica variabili d'ambiente
formatter . print_subheader ( " 🔐 Verifica Configurazione " )
formatter . print_subheader ( " 🔐 Verifica Configurazione " )
env_vars = check_environment_variables ( )
env_vars = check_environment_variables ( )
print ( " Variabili d ' ambiente: " )
print ( " Variabili d ' ambiente: " )
for var_name , is_present in env_vars . items ( ) :
for var_name , is_present in env_vars . items ( ) :
status = " ✅ Presente " if is_present else " ❌ Mancante "
status = " ✅ Presente " if is_present else " ❌ Mancante "
print ( f " { var_name } : { status } " )
print ( f " { var_name } : { status } " )
# Inizializza provider
# Inizializza provider
formatter . print_subheader ( " 🏗️ Inizializzazione Provider " )
formatter . print_subheader ( " 🏗️ Inizializzazione Provider " )
providers = initialize_providers ( )
providers = initialize_providers ( )
if not providers :
if not providers :
print ( " ❌ Nessun provider disponibile. Verifica la configurazione. " )
print ( " ❌ Nessun provider disponibile. Verifica la configurazione. " )
return
return
print ( f " \n 🎯 Provider disponibili per il test: { list ( providers . keys ( ) ) } " )
print ( f " \n 🎯 Provider disponibili per il test: { list ( providers . keys ( ) ) } " )
# Testa ogni provider
# Testa ogni provider
formatter . print_header ( " 🧪 ESECUZIONE TEST PROVIDER " , " = " , 80 )
formatter . print_header ( " 🧪 ESECUZIONE TEST PROVIDER " , " = " , 80 )
tester = ProviderTester ( )
tester = ProviderTester ( )
all_results = [ ]
all_results : List [ Dict [ str , Any ] ] = [ ]
for provider_name , wrapper in providers . items ( ) :
for provider_name , wrapper in providers . items ( ) :
try :
try :
result = tester . test_provider ( wrapper , provider_name )
result = tester . test_provider ( wrapper , provider_name )
@@ -331,22 +331,22 @@ def main():
" overall_status " : " CRITICAL_ERROR " ,
" overall_status " : " CRITICAL_ERROR " ,
" error " : str ( e )
" error " : str ( e )
} )
} )
# Stampa riassunto finale
# Stampa riassunto finale
print_summary ( all_results )
print_summary ( all_results )
# Informazioni aggiuntive
# Informazioni aggiuntive
formatter . print_header ( " ℹ ️ INFORMAZIONI AGGIUNTIVE" , " = " , 80 )
formatter . print_header ( " ℹ ️ INFORMAZIONI AGGIUNTIVE" , " = " , 80 )
print ( " 📚 Documentazione: " )
print ( " 📚 Documentazione: " )
print ( " - BaseWrapper: src/app/markets/base.py " )
print ( " - BaseWrapper: src/app/markets/base.py " )
print ( " - Test completi: tests/agents/test_market.py " )
print ( " - Test completi: tests/agents/test_market.py " )
print ( " - Configurazione: .env " )
print ( " - Configurazione: .env " )
print ( " \n 🔧 Per abilitare tutti i provider: " )
print ( " \n 🔧 Per abilitare tutti i provider: " )
print ( " 1. Configura le credenziali nel file .env " )
print ( " 1. Configura le credenziali nel file .env " )
print ( " 2. Segui la documentazione di ogni provider " )
print ( " 2. Segui la documentazione di ogni provider " )
print ( " 3. Riavvia il demo " )
print ( " 3. Riavvia il demo " )
print ( f " \n 🏁 Demo completato: { datetime . now ( ) . strftime ( ' % Y- % m- %d % H: % M: % S ' ) } " )
print ( f " \n 🏁 Demo completato: { datetime . now ( ) . strftime ( ' % Y- % m- %d % H: % M: % S ' ) } " )
if __name__ == " __main__ " :
if __name__ == " __main__ " :