DD-WATCHLIST-MANAGER.md

Versione: 1.0 Data: 2025-10-10 Scopo: Descrivere l’architettura e l’interfaccia pubblica del sottosistema Watchlist Manager. Documento Principale: FIRE 25.07 - ARCHITECTURE-OVERVIEW


1. Panoramica e Responsabilità

Il Watchlist Manager (precedentemente noto come “FavoriteTickersTab”) è stato trasformato da un semplice gestore di preferiti a un componente di servizio disaccoppiato fondamentale per l’architettura di FIRE.

La sua responsabilità è agire come unica “fonte di verità” per qualsiasi universo di ticker definito dall’utente. Invece di avere ogni sinapsi (come lo Scanner) che gestisce la propria lista, centralizziamo questa logica in un unico componente riutilizzabile e autorevole.

Le sue funzioni principali sono:

  • Permettere all’utente di creare, salvare e caricare watchlist multiple da file di testo.
  • Gestire la watchlist “attiva” (aggiungendo o rimuovendo ticker).
  • Notificare in modo proattivo il resto dell’applicazione ogni volta che la watchlist attiva cambia.

2. Architettura e Pattern di Design

Il design del Watchlist Manager si basa sul pattern Publish-Subscribe (Pub/Sub), implementato tramite i segnali e gli slot di Qt. Il Watchlist Manager è il “Publisher”, mentre le altre sinapsi (come il Signal Scanner) sono i “Subscribers”.

Questo design garantisce un basso accoppiamento: i sottosistemi che consumano la watchlist non hanno bisogno di conoscere i dettagli implementativi del Watchlist Manager (es. se i dati provengono da un file, da un database o da un’API). Si limitano a reagire alle notifiche.

  • FavoriteTickersTab (Widget di Implementazione):
    • Responsabilità: Fornisce l’interfaccia utente per la gestione delle watchlist. Contiene la logica per leggere/scrivere file e per modificare la lista interna dei ticker. Implementa l’interfaccia pubblica.

3. Interfaccia Pubblica (API)

L’interazione con il Watchlist Manager da parte di altri componenti deve avvenire esclusivamente tramite la sua interfaccia pubblica, composta da un metodo e due segnali.

3.1. Metodo: get_active_tickers() -> List[str]

  • Scopo: Permette a un componente di interrogare lo stato attuale della watchlist. È l’unico modo per ottenere la lista di ticker in un dato momento (es. all’avvio di un’altra sinapsi).
  • Utilizzo: tickers = self.watchlist_manager.get_active_tickers()

3.2. Segnale: watchlist_changed = Signal(list)

  • Scopo: È il cuore del pattern Pub/Sub. Viene emesso ogni volta che la lista di ticker attiva viene modificata (caricamento, aggiunta, rimozione).
  • Payload: La nuova lista completa di ticker.
  • Utilizzo: I componenti “subscriber” si connettono a questo segnale per aggiornare il loro stato interno in tempo reale.
    # In MainWindow.py
    self.watchlist_manager.watchlist_changed.connect(self.signal_scanner.on_watchlist_update)

#### 3.3. Segnale: ticker_selected = Signal(str)

- **Scopo:** Viene emesso quando l'utente fa doppio click su un singolo ticker nella lista. È usato per azioni immediate e contestuali.
    
- **Payload:** Il ticker selezionato (stringa).
    
- **Utilizzo:** Tipicamente connesso a un'azione come "mostra il grafico di questo ticker".
    
    codePython
    
    ```
    # In MainWindow.py
    self.watchlist_manager.ticker_selected.connect(self.charting_widget.load_ticker)
    ```
    

---

### 4. Guide Pratiche

#### 4.1. Come Interagire con il Watchlist Manager da un Nuovo Modulo

Se stai sviluppando una nuova sinapsi che deve operare su una lista di ticker definita dall'utente, segui questo pattern disaccoppiato.

1. **NON Accedere Direttamente:** Il tuo modulo **non deve mai** tentare di leggere file di watchlist o di accedere a variabili interne del Watchlist Manager.
    
2. **Stabilisci la Connessione (MainWindow):** Il punto di coordinamento per le interazioni tra sinapsi è MainWindow. Qui devi stabilire le connessioni tra il Watchlist Manager e il tuo nuovo modulo.
    
3. **Ottieni lo Stato Iniziale:** Quando il tuo modulo viene inizializzato, chiama il metodo get_active_tickers() per popolare il suo stato iniziale.
    
    codePython
    
    ```
    # In MainWindow.py, dopo aver creato il tuo nuovo_modulo
    initial_tickers = self.watchlist_manager.get_active_tickers()
    self.nuovo_modulo.set_initial_watchlist(initial_tickers)
    ```
    
4. **Ascolta i Cambiamenti:** Connetti il segnale watchlist_changed a uno slot pubblico del tuo nuovo modulo. Questo garantirà che il tuo modulo sia sempre sincronizzato con la watchlist attiva, senza bisogno di polling o interrogazioni continue.
    
    codePython
    
    ```
    # In MainWindow.py
    self.watchlist_manager.watchlist_changed.connect(self.nuovo_modulo.on_watchlist_update)
    
    # Nel tuo nuovo_modulo.py
    def on_watchlist_update(self, new_tickers: list):
        # Logica per aggiornare la UI o lo stato interno del tuo modulo
        print(f"Watchlist aggiornata: {new_tickers}")
    ```