Contesto e Problema

Durante lo sviluppo della visualizzazione dei segnali di backtest sul grafico, è stato riscontrato un bug critico: i segnali di Buy (frecce verdi) non venivano renderizzati correttamente, mentre i segnali di Sell (frecce rosse) apparivano. Un’analisi approfondita ha rivelato che tutti i dati venivano trasmessi correttamente dal backend Python al JavaScript.

Il problema si manifestava nella chiamata finale series.setMarkers(markers) di Lightweight Charts v4.1.0. La causa radice identificata è una limitazione (o un bug di rendering) della libreria: non gestisce correttamente la visualizzazione di più marker che condividono lo stesso identico timestamp, specialmente se passati in un unico array. L’ultimo marker disegnato tende a sovrascrivere o a nascondere gli altri.

Decisione Presa

È stata implementata una soluzione denominata “Smart Markers” per affrontare il problema a livello di preparazione dei dati prima di invocare la libreria grafica. Questo garantisce la correttezza dei dati e una visualizzazione chiara.

La logica implementata è la seguente:

  1. Mappatura per Timestamp: Il codice itera su tutti i segnali (Buy e Sell) e costruisce una mappa (un dizionario) dove ogni chiave è un timestamp unico. Il valore associato a ogni chiave indica quali tipi di segnali (buy, sell) esistono per quel timestamp.
  2. Generazione Condizionale con Posizionamento: Per ogni timestamp nella mappa, vengono generati i marker necessari usando posizioni diverse per evitare conflitti visivi:
    • I segnali di Buy vengono creati con position: 'belowBar'.
    • I segnali di Sell vengono creati con position: 'aboveBar'.
  3. Ordinamento: L’array finale di marker viene ordinato cronologicamente prima di essere passato alla libreria per rispettare le sue aspettative e prevenire potenziali avvisi o errori.

Questo approccio garantisce che, anche se un Buy e un Sell avvengono sulla stessa candela, entrambi siano visibili e posizionati correttamente.

Conseguenze

Positive

  • Il bug è risolto in modo definitivo e robusto.
  • L’integrità dei dati è preservata: i timestamp dei marker corrispondono esattamente ai timestamp dei segnali, senza alcuna alterazione.
  • L’esperienza utente è migliorata, con una visualizzazione chiara e non ambigua dei segnali.
  • Il codice è ora resiliente a strategie che potrebbero generare segnali di Buy e Sell sulla stessa candela.

Negative

  • La logica di generazione dei marker in lightweight_chart_widget.py è leggermente più complessa rispetto a un’iterazione lineare. Tuttavia, questa complessità è giustificata dalla robustezza ottenuta.

Alternative Considerate

Soluzione: “Offset Temporale” (Scartata)

  • Descrizione: Questa soluzione proponeva di aggiungere un piccolo offset temporale (es. 1 secondo per i dati intraday) ai timestamp di uno dei due tipi di segnali (es. i Buy). Questo avrebbe garantito fisicamente che non ci fossero mai due marker con lo stesso identico timestamp.
  • Pro: Implementazione semplice e diretta, efficace nell’evitare il bug di rendering della libreria.
  • Contro (Motivi della Scelta di Scartarla):
    • Integrità dei Dati Compromessa: La ragione principale per scartare questa soluzione è che altera i dati. Un segnale che è avvenuto al tempo T verrebbe visualizzato al tempo T+1. Questo viola il principio di correttezza dei dati, fondamentale per una piattaforma di analisi finanziaria.
    • Non Gestisce Correttamente i Casi Limite: Non rappresenta correttamente il caso in cui Buy e Sell avvengono sulla stessa candela, ma li sfalsa visivamente.