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”:

  1. L’utente seleziona un ticker o avvia una scansione.
  2. DataManager chiama il connettore (es. Yahoo/Alpaca).
  3. Viene scaricato l’intero storico (es. 5 anni).
  4. 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:

  1. Richiesta: fetch_data("AAPL").
  2. Hit: Esiste cache/AAPL.parquet?
    • NO: Scarica FULL Salva Cache Ritorna.
    • SÌ: Carica Cache Controlla last_timestamp.
  3. Sync:
    • Se last_timestamp == Chiusura Mercato Ieri (e mercato chiuso) Ritorna Cache (Zero Latenza).
    • Se last_timestamp < Oggi Scarica DELTA (da last_timestamp a now) Unisci Salva Ritorna.

3. Analisi dei Rischi e Mitigazione

RischioDescrizioneStrategia di Mitigazione
Data StalenessL’utente vede un prezzo vecchio pensando sia live.UI Feedback: Indicatore “Dati Aggiornati al: [ORA]” visibile. Policy: Force Refresh manuale sempre disponibile.
Split / DividendiLo 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 FileCrash durante la scrittura rendono il file illeggibile.Atomic Write: Scrivere su temp_file e rinominare solo a successo avvenuto.
Disk SpaceMigliaia 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 pyarrow o fastparquet).
  • 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

  1. 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).
  2. Fase 2 (Incremental): Implementazione del merge (Cache + Delta). Necessario per l’intraday.
  3. 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`.