DD-DATA-CONNECTORS.md
Versione: 1.0 Data: 2025-10-15 Scopo: Descrivere l’architettura del sottosistema di gestione dei dati in FIRE, inclusa la logica di orchestrazione e il pattern per l’aggiunta di nuovi provider di dati (connettori). Documento Principale: FIRE 25.07 - ARCHITECTURE-OVERVIEW
1. Filosofia Architetturale
Il sottosistema di gestione dei dati è progettato per essere modulare, estensibile e disaccoppiato. L’obiettivo primario è isolare il resto dell’applicazione dalla complessità e dalle specificità di come e da dove vengono recuperati i dati di mercato. Questo si basa su tre pilastri:
-
Interfaccia Unificata (
AbstractDataConnector): Definisce un “contratto” standard che ogni provider di dati deve rispettare. Qualsiasi componente che necessita di dati interagisce con questa interfaccia astratta, non con un’implementazione concreta. -
Orchestrazione Centrale (
DataManager): Agisce come unico punto di contatto (facade) per il resto dell’applicazione. Gestisce la priorità dei connettori, il failover (se un provider fallisce, prova con il successivo) e l’accesso alle loro capacità. Nessun componente UI deve mai istanziare o comunicare direttamente con un connettore. -
Discovery Automatico: I nuovi connettori aggiunti alla directory
fire/connectors/vengono scoperti e registrati automaticamente all’avvio dell’applicazione, senza necessità di registrazione manuale.
2. Il Pattern del “Connettore Auto-Descrittivo” (get_capabilities)
Un problema comune nelle applicazioni che si basano su API esterne è la gestione dei limiti imposti da tali API (es. limiti di rate, profondità dei dati storici). Inserire questa logica di limitazione nel codice della UI è un errore architetturale che crea forte accoppiamento e rende il codice fragile.
Per risolvere questo problema, FIRE adotta il pattern del “Connettore Auto-Descrittivo”.
2.1. La Soluzione
L’interfaccia AbstractDataConnector obbliga ogni connettore a implementare il metodo:
def get_capabilities(self) -> Dict[str, int]:Questo metodo restituisce un dizionario che descrive i limiti di lookback (profondità storica) del provider per ogni timeframe.
- Chiave (str): Il
timeframe(es. “1h”, “5m”). - Valore (int): Il numero massimo di giorni di dati storici che il provider può fornire per quel timeframe.
- Convenzione: Un valore di
-1indica che non ci sono limiti noti. Un dizionario vuoto indica che il provider non ha limiti predefiniti (come nel caso diLocalCSVConnector).
2.2. Il Flusso di Lavoro
Quando un componente UI (come il grafico di backtest) deve richiedere dati, il flusso è il seguente:
- La UI chiede al
DataManagerquali sono le capacità del provider attivo:caps = data_manager.get_active_provider_capabilities(). - La UI ottiene il limite per il
timeframeselezionato:limit = caps.get(selected_timeframe). - Se esiste un limite, la UI adatta i parametri della richiesta (in particolare, la
start_date) per rispettarlo. - Solo a questo punto la UI invia al
DataManagerla richiesta di dati, già validata e conforme ai limiti del provider.
Questo approccio sposta la responsabilità della conoscenza dei limiti dove deve essere: nel connettore stesso.
3. Guida Pratica: Come Aggiungere un Nuovo Connettore
Grazie al discovery automatico, aggiungere un nuovo provider di dati è un processo strutturato.
-
Creare il File: Crea un nuovo file Python nella directory
fire/connectors/, ad esempiomio_nuovo_connector.py. -
Implementare l’Interfaccia: La tua nuova classe deve ereditare da
AbstractDataConnectore implementare tutti i suoi metodi astratti. -
Scrivere il Codice: Utilizza il seguente template come punto di partenza.
# fire/connectors/mio_nuovo_connector.py from typing import Optional, Dict import pandas as pd from ..core.data.abstract_data_connector import AbstractDataConnector class MioNuovoConnector(AbstractDataConnector): @property def name(self) -> str: # Nome univoco che apparirà nelle impostazioni return "MioNuovoProvider" def get_capabilities(self) -> Dict[str, int]: # Definisci i limiti del tuo provider return { "1m": 30, "1h": 365, "1d": -1 } def get_historical_data(self, ticker, start_date, end_date, timeframe) -> Optional[pd.DataFrame]: # ... Qui va la logica per chiamare la nuova API ... # ... e per formattare i dati in un DataFrame pandas ... # con le colonne [Open, High, Low, Close, Volume] e un DatetimeIndex. pass def check_availability(self) -> (bool, str): # (Opzionale) Aggiungi un controllo, es. per una API key. # Se non serve, puoi ometterlo e userà l'implementazione base. api_key = "..." if not api_key: return False, "API Key non configurata" return True, "Available" -
Configurare nelle Impostazioni: Avvia
FIRE. Il tuo nuovo connettore apparirà automaticamente nella sezione “Data Providers” delle impostazioni. Abilitalo e impostane la priorità per iniziare a usarlo.
4. Riepilogo dei Connettori Esistenti
| Nome Connettore | Descrizione | Capacità Chiave (Limiti Intraday) |
|---|---|---|
YahooFinance | Provider principale. Non richiede API key. | 1h: 365 giorni, 30m/15m/5m: 30 giorni, 1m: 7 giorni. |
AlphaVantage | Provider alternativo. Richiede API key. | Tutti i timeframe intraday sono limitati a circa 60 giorni (assumendo un piano gratuito). |
LocalCSV | Carica dati da file .csv locali. Non ha limiti intrinseci. | Nessun limite predefinito (get_capabilities restituisce {}). |