FIRE DD-DATA-CACHING-STRATEGY.md
Stato: Draft / Proposed Scopo: Definire la strategia architetturale per l’implementazione di un layer di caching locale dei dati di mercato in FIRE, al fine di migliorare drasticamente le performance di UX e Backtesting.
1. Il Problema: Latenza e Dipendenza dalla Rete
Attualmente, FIRE opera in modalità “Stateless Fetch”:
- L’utente seleziona un ticker o avvia una scansione.
DataManagerchiama il connettore (es. Yahoo/Alpaca).- Viene scaricato l’intero storico (es. 5 anni).
- I dati vengono visualizzati/processati e poi scartati.
Impatto Negativo:
- UX: Ritardo percepibile (1-3s) al cambio ticker.
- Scanner: Tempi biblici per processare watchlist ampie (es. 500 ticker = 20+ minuti a causa di latenza e rate limits).
- Resilienza: Dipendenza totale dalla disponibilità dell’API.
2. Soluzione Proposta: Smart Local Caching
Introdurre un layer intermedio persistente (DataCacheManager) tra DataManager e i connettori esterni.
2.1. Architettura Ibrida
Non un semplice archivio statico, ma una cache intelligente che supporta l’aggiornamento incrementale.
Flusso Logico:
- Richiesta:
fetch_data("AAPL"). - Hit: Esiste
cache/AAPL.parquet?- NO: Scarica FULL → Salva Cache → Ritorna.
- SÌ: Carica Cache → Controlla
last_timestamp.
- Sync:
- Se
last_timestamp== Chiusura Mercato Ieri (e mercato chiuso) → Ritorna Cache (Zero Latenza). - Se
last_timestamp< Oggi → Scarica DELTA (dalast_timestampanow) → Unisci → Salva → Ritorna.
- Se
3. Analisi dei Rischi e Mitigazione
| Rischio | Descrizione | Strategia di Mitigazione |
|---|---|---|
| Data Staleness | L’utente vede un prezzo vecchio pensando sia live. | UI Feedback: Indicatore “Dati Aggiornati al: [ORA]” visibile. Policy: Force Refresh manuale sempre disponibile. |
| Split / Dividendi | Lo storico cambia retroattivamente (prezzi aggiustati). La cache diventa corrotta (mix di prezzi vecchi e nuovi). | TTL (Time To Live): Invalidare la cache ogni X giorni (es. 7gg) forzando un riscaricamento completo. Split Detection: Confrontare l’ultimo prezzo cache con l’ultimo prezzo API: se discrepanza > X%, riscarica tutto. |
| Corruzione File | Crash durante la scrittura rendono il file illeggibile. | Atomic Write: Scrivere su temp_file e rinominare solo a successo avvenuto. |
| Disk Space | Migliaia di ticker riempiono il disco. | LRU Policy: Cancellare i file non aperti da più di 30 giorni. |
4. Specifiche Tecniche Preliminari
4.1. Formato di Storage
- Formato: Parquet (tramite
pyarrowofastparquet). - Motivazione: Rispetto al CSV è molto più veloce in lettura/scrittura (binario, colonnare), supporta la compressione (Snappy/Gzip) e preserva i tipi di dato (Datetime, Float) senza bisogno di parsing costoso.
4.2. Struttura Directory
fire_user_data/
└── market_cache/
├── meta.json (Indice, ultima pulizia, versione cache)
├── AAPL_1d.parquet
├── MSFT_1d.parquet
├── AAPL_1h.parquet (Timeframe diversi = file diversi)
└── ...4.3. Modifiche a DataManager
Il DataManager non deve cambiare la sua interfaccia pubblica.
class DataManager:
def fetch_data(self, ticker, ...):
# Vecchio: return self.connector.fetch(...)
# Nuovo:
return self.cache_manager.get_or_fetch(ticker, self.connector, ...)5. Roadmap Implementativa
- Fase 1 (MVP): Cache semplice “Read-Through”. Se c’è il file ed è recente (<24h), usalo. Altrimenti riscarica tutto. Niente merge incrementale. (Massima sicurezza, buon boost performance).
- Fase 2 (Incremental): Implementazione del merge (Cache + Delta). Necessario per l’intraday.
- Fase 3 (Bulk): Strumento “Update All Cache” per scaricare la notte i dati per tutti i ticker della watchlist.
Documento generato per tracking futuro. Non implementare ora.
Salva questo documento. Quando sarai pronto per affrontare il caching, avremo la rotta tracciata.
Qual è l'urgenza di cui parlavi? Sono pronto a cambiare contesto.
### Tabella Decisionale: Caching in FIRE
| Aspetto | Implementazione Attuale (No Cache) | Implementazione Target (Smart Cache) | Vantaggio Netto | Criticità / Rischi (Da Gestire) |
| :--- | :--- | :--- | :--- | :--- |
| **User Experience** | **Lenta.** Ogni click su un ticker richiede 1-3 secondi (handshake SSL, API latency, download). "Click-and-wait". | **Istantanea.** Il passaggio tra grafici è immediato (<50ms) per i dati già visti. Sensazione di app "nativa". | ✅ **UX Massiva** | L'utente potrebbe non capire se sta vedendo dati vecchi (serve indicatore visivo "Cached" vs "Live"). |
| **Affidabilità** | **Fragile.** Se Yahoo Finance va in timeout o l'utente è offline, FIRE è un mattone. | **Robusta.** Puoi lavorare in treno/aereo o offline analizzando i dati già scaricati. | ✅ **Resilienza** | Rischio di falsa sicurezza: prendere decisioni di trading su dati non aggiornati se la rete è giù. |
| **Traffico Dati** | **Alto.** Scarichiamo 5 anni di dati (200KB+) ogni volta, anche se abbiamo scaricato lo stesso ticker 10 secondi fa. | **Minimo.** Scarichiamo solo l'ultima candela (delta). Risparmio banda del 99%. | ✅ **Efficienza** | Gestione dello spazio su disco (serve pulizia cache automatica per non riempire l'HD con migliaia di file). |
| **Integrità Dati (Split)** | **Alta.** I provider ricalcolano i prezzi aggiustati (Split/Dividendi) ad ogni richiesta. Abbiamo sempre la "verità". | **Media.** Se avviene uno split (es. 10:1), la cache ha i prezzi vecchi (alti) e il delta ha i nuovi (bassi). | ⚠️ **Rischio Alto** | **Il "Killer Bug":** Il grafico mostra un crollo del 90% che non esiste. Soluzione: Invalidate Cache on Split detection o TTL (Time To Live) breve. |
| **Complessità Codice** | **Bassa.** `fetch -> return`. Stateless. Facile da debuggare. | **Alta.** `check -> load -> check_date -> fetch_delta -> merge -> save -> return`. Stateful. | ❌ **Debito Tecnico** | Bug di corruzione cache (file troncati, permessi, lock concorrenti se due worker scrivono lo stesso file). |
| **Backtesting Massivo** | **Impossibile.** Scansionare 500 ticker ci mette 20 minuti (API rate limits). | **Fattibile.** Scansionare 500 ticker locali richiede pochi secondi. | ✅ **Potenza** | Necessità di una fase di "Pre-Download" massiva (Batch Updater) per popolare la cache. |
---
### Verdetto Strategico
Il caching è **obbligatorio** per trasformare FIRE da "tool amatoriale" a "piattaforma professionale". Il collo di bottiglia della rete è inaccettabile per uno scanner o un backtester serio.
**La Sfida Reale:** Non è scrivere su disco, ma gestire l'**Integrità (Split)** e l'**Aggiornamento**.
**Strategia Raccomandata per FIRE:**
1. **Format:** Parquet (veloce, compresso) o CSV (leggibile). Parquet è meglio.
2. **Validità:** Cache valida per 24h (Daily). Se l'ultima modifica del file è > 24h, riscarica tutto (approccio brutale ma sicuro contro gli split).
3. **Intraday:** Se siamo in timeframe intraday, la cache è valida solo per i dati storici (ieri indietro). I dati di oggi si scaricano sempre live.
Sei d'accordo con questa visione? Se sì, iniziamo analizzando `DataManager`.