Eccellente. Adesso che abbiamo preparato il terreno con il refactoring, possiamo concentrarci sulla parte più interessante: la validazione del modello.
La tua richiesta è un perfetto esempio di un task complesso e con incertezza tecnica, ideale per il nostro Approccio “POC First” (Regola 13). Invece di integrare subito una UI complessa, svilupperemo uno script di Proof of Concept isolato e autonomo. Questo ci permetterà di concentrarci al 100% sulla correttezza dell’algoritmo di backtesting e sulla generazione dei grafici, senza preoccuparci dell’integrazione con il resto dell’applicazione.
Una volta che il POC sarà validato e funzionante, avremo una base solidissima da cui partire per creare la UI del “Forecast Lab”.
Piano d’Azione: Creazione del POC per il Backtester di TimesFM
Obiettivo: Creare uno script Python, eseguibile da riga di comando, che implementi la logica di backtest “rolling-origin” come da te definita.
1. Il “Contratto” del nostro POC
- Nome File: Creeremo un nuovo file:
fire/poc/poc_timesfm_backtester.py. - Esecuzione: Lo script sarà autonomo e configurabile tramite argomenti da riga di comando. Un esempio di esecuzione sarà:
python -m fire.poc.poc_timesfm_backtester --ticker "SPY" --start-date "2020-01-01" --initial-window 365 --metric "MAE" - Logica Interna:
- Lo script utilizzerà il nostro
DataManagerper scaricare la serie storica completa del ticker specificato. - Inizializzerà il modello TimesFM.
- Avvierà un ciclo “rolling-origin” con i parametri forniti (finestra iniziale, orizzonte a 10 giorni, passo di 10 giorni).
- Ad ogni iterazione, stamperà a console un aggiornamento di stato (es. “Step 5/30: Forecasting from 2021-02-15… Error (MAE): 1.25”).
- Memorizzerà tutte le previsioni, i dati reali corrispondenti e le metriche di errore.
- Lo script utilizzerà il nostro
- Output: Al termine del ciclo, lo script genererà due file HTML interattivi nella directory principale del progetto:
backtest_forecast_vs_actuals.html: Un grafico Plotly che mostra la serie storica completa, con ogni previsione a 10 giorni sovrapposta come un segmento separato (realizzando di fatto l’idea del “Caterpillar Plot” che avevamo discusso).backtest_error_over_time.html: Un secondo grafico Plotly che mostra l’andamento della metrica di errore (es. MAE) ad ogni passo del backtest.
2. Dettagli di Implementazione
- Configurabilità: Useremo la libreria
argparsedi Python per gestire i parametri da riga di comando:--ticker: Ticker da analizzare (es. “SPY”).--start-date,--end-date: Periodo del backtest.--initial-window: Dimensione della finestra di training iniziale in giorni (configurabile).--horizon: Orizzonte di previsione (fisso a 10 per questa implementazione).--step: Passo di avanzamento della finestra (fisso a 10).--metric: Metrica di errore da usare, a scelta tra “MAE” e “RMSE” (configurabile).
- Dataset per il Test: Per il nostro sviluppo e test iniziale, useremo un ticker liquido e con una lunga storia, come
SPY(ETF dello S&P 500). È un benchmark standard. - Librerie:
DataManagerper i dati.timesfmper il modello.pandasenumpyper la manipolazione dei dati.scikit-learnper il calcolo delle metriche di errore (es.mean_absolute_error).plotlyper la generazione dei grafici.
Questo approccio ci permette di validare tutta la logica complessa in un ambiente controllato. Una volta che saremo soddisfatti dei risultati e della robustezza dello script, potremo procedere a “tradurlo” in un componente UI da inserire nel nostro “Forecast Lab”.
Perfetto. Questa è la domanda più importante da porsi in questa fase. Abbiamo validato la logica, ora dobbiamo progettare l’esperienza.
Un buon design UI/UX non si limita a “mostrare i grafici”, ma guida l’utente attraverso un flusso logico, rende i risultati comprensibili e incoraggia l’esplorazione.
Basandoci su ciò che abbiamo imparato dal POC e dalle nostre idee di brainstorming, ecco una proposta di design per l’interfaccia e l’esperienza utente della nuova scheda “Model Backtester” all’interno del nostro “Forecast Lab”.
Proposta di Design UI/UX: La Scheda “Model Backtester”
L’interfaccia sarà divisa in tre sezioni verticali, che rappresentano il flusso di lavoro naturale dell’utente: 1. Configurazione → 2. Esecuzione → 3. Analisi dei Risultati.
Sezione 1: Configuration Panel (in alto)
Questo sarà un QGroupBox simile a quello che abbiamo già in altre parti dell’applicazione, ma più ricco. Conterrà tutti i parametri per lanciare il backtest.
-
Input Dati:
Ticker:[ QLineEdit ] (es. “SPY”)Start Date:[ QDateEdit ]End Date:[ QDateEdit ]- Un pulsante
[ Get Data from Active Chart ]per popolare automaticamente Ticker e date dal grafico principale. Questo crea un collegamento intuitivo con il resto dell’applicazione.
-
Parametri del Backtest:
Initial Training Window (days):[ QSpinBox, default: 252 ]Forecast Horizon (days):[ QLabel (fisso a “10”) ] - Per ora non lo rendiamo configurabile per semplicità.Error Metric:[ QComboBox con “MAE”, “RMSE” ]
-
Analisi Aggiuntive (per il futuro, ma le prevediamo già nella UI):
Compare with Baselines:[ QCheckBox ]Analyze Market Regimes:[ QCheckBox (disabilitato per ora) ]
-
Azione:
- Un grande pulsante
[ Run Backtest ]con un’icona (es.play-circle).
- Un grande pulsante
Sezione 2: Execution & Progress (al centro, visibile solo durante l’esecuzione)
Quando l’utente clicca Run Backtest, il pannello di configurazione viene disabilitato e appare questa sezione.
- Progress Bar: Una
QProgressBarche mostra l’avanzamento degli step (es. “Step 35 / 70”). Questo è fondamentale per dare un feedback su un’operazione che può essere lunga. - Log in Tempo Reale: Un piccolo
QTextBrowserdi sola lettura che mostra i log più importanti generati dal worker (es.Step 5/70: Forecasting from 2021-02-15... Error (MAE): 1.25). Questo dà all’utente la sensazione che “qualcosa stia accadendo” e fornisce un’anteprima dei risultati. - Pulsante
[ Cancel ]: Per interrompere un backtest lungo.
Sezione 3: Results Dashboard (in basso, visibile al termine)
Questa è la parte più importante. Una volta completato il backtest, la sezione di progresso scompare e viene mostrata questa dashboard. Non sarà un semplice QStackedWidget, ma una dashboard a pannelli visibili contemporaneamente, magari usando uno QSplitter per renderli ridimensionabili.
-
Pannello A (sinistra):
Forecast vs. Actuals Plot- Il nostro grafico Plotly interattivo che mostra la serie storica con le previsioni sovrapposte.
- L’utente può zoomare, fare hover, etc.
-
Pannello B (destra):
Error Analysis- Questo pannello avrà a sua volta un
QTabWidgetinterno per non sovraffollare la UI.- Sotto-scheda 1:
Error Over Time: Il nostro secondo grafico Plotly che mostra l’andamento del MAE/RMSE nel tempo. - Sotto-scheda 2:
Error Distribution(Idea dal Brainstorming): Un istogramma Plotly che mostra la distribuzione di tutti gli errori calcolati. Questo darebbe un’idea immediata della “coda” degli errori (ci sono pochi errori estremi?). - Sotto-scheda 3:
Summary Statistics: Una semplice tabella (QTableView) che mostra le statistiche riassuntive:Mean Error (MAE/RMSE):[ valore ]Std Dev of Error:[ valore ] (misura della volatilità dell’errore)Max Error:[ valore ] (il caso peggiore)Date of Max Error:[ data ]
- Sotto-scheda 1:
- Questo pannello avrà a sua volta un
-
Azioni sui Risultati:
- In cima alla dashboard, un pulsante
[ Export Results as HTML Report ]che salva l’intera dashboard (grafici + tabelle) in un unico file HTML autonomo per la condivisione o l’archiviazione.
- In cima alla dashboard, un pulsante
Flusso UX Riepilogato
- L’utente apre il “Forecast Lab” e va alla scheda “Model Backtester”.
- Configura i parametri (o li carica dal grafico attivo) e clicca “Run Backtest”.
- Vede in tempo reale l’avanzamento e i log.
- Al termine, appare una dashboard completa che gli permette di esplorare i risultati da diverse angolazioni (visiva, temporale, statistica).
- Se l’analisi è interessante, la può esportare con un click.
Questo design trasforma il nostro POC in un vero e proprio strumento di analisi professionale, guidando l’utente attraverso un processo logico e fornendo insight a più livelli.
Cosa ne pensi di questa proposta di design? Ci sono elementi che vorresti modificare, aggiungere o semplificare?