1. Filosofia: “Dichiara le Intenzioni, non Disegnare”
Per replicare la flessibilità di Pine Script, abbiamo esteso BaseStrategy con un’API che permette di “dichiarare” le proprie esigenze di visualizzazione. L’architettura è progettata per disaccoppiare la logica della strategia dal rendering finale.
Il tuo ruolo come sviluppatore di strategie è usare i metodi plot(), plot_shape() e set_bar_color() per descrivere COSA vuoi vedere. Il framework si occuperà di COME disegnarlo.
Questa guida illustra il riferimento completo dell’API e le best practice.
2. Disegnare Linee e Indicatori (self.plot)
Il metodo self.plot è l’equivalente della funzione plot() di Pine Script e serve per disegnare serie di dati continue, come Medie Mobili, RSI, o bande.
Sintassi
self.plot(series, name, color, style, width, overlay)series(pd.Series): Obbligatorio. La serie di dati da disegnare.name(str): Obbligatorio. Il nome da mostrare nella legenda del grafico.color(str): Colore della linea (es.'orange','#FFD700'). Default:'blue'.width(int): Spessore della linea. Default:1.style(str): Stile della linea ('line','dotted','dashed'). Supporto futuro per'histogram'. Default:'line'.overlay(bool): SeTrue, la linea viene disegnata sul grafico principale dei prezzi. SeFalse, verrà disegnata in un pannello separato sotto il grafico (non ancora implementato, ma previsto). Default:True.
Dove usarlo?
Il metodo self.plot va chiamato esclusivamente all’interno del metodo init() della tua strategia, subito dopo aver calcolato la serie dell’indicatore.
Esempio: Disegnare una EMA
# In fire/strategies/my_strategy.py
class MyEmaStrategy(BaseStrategy):
def __init__(self):
super().__init__()
self.add_parameter("ema_period", 20, type="int")
def init(self):
ema_period = self.params["ema_period"]
# 1. Calcola l'indicatore
self.my_ema = self.data['Close'].ewm(span=ema_period, adjust=False).mean()
# 2. Dichiara l'intenzione di disegnarlo
self.plot(self.my_ema, name=f"EMA({ema_period})", color="cyan", width=2)3. Disegnare Marker di Segnale (self.plot_shape)
Il metodo self.plot_shape è l’equivalente di plotshape() e serve a disegnare icone (marker) su specifiche barre per evidenziare un evento (es. un segnale di setup, un incrocio).
Sintassi
self.plot_shape(style, color, location, text)style(str): La forma dell’icona ('circle','square','arrow_up','arrow_down').color(str): Il colore dell’icona.location(str): La posizione rispetto alla barra ('above','below').text(str): Un breve testo opzionale da mostrare vicino al marker.
Dove usarlo?
Il metodo self.plot_shape va chiamato all’interno del metodo next(), solo sulla barra in cui la condizione è vera.
Esempio: Marcare un Setup “SlingShot”
# In fire/strategies/slingshot_strategy.py
def next(self):
# ... (logica di calcolo) ...
is_slingshot = (c > ema) and (c_1 < ema_1) # ...
if not self.position:
if is_slingshot:
self.buy()
# Disegna un marker blu sotto la barra del segnale
if self.params["show_slingshot"]:
self.plot_shape(style="circle", color="blue", location="below", text="Sling")4. Colorare le Barre (self.set_bar_color)
Il metodo self.set_bar_color è l’equivalente di barcolor() e serve a cambiare il colore di una specifica candela per evidenziarla.
Sintassi
self.set_bar_color(color)color(str): Il colore da applicare alla candela corrente (es.'yellow','#FFD700').
Dove usarlo?
Come plot_shape, va chiamato all’interno del metodo next(), condizionalmente.
Esempio: Colorare la Candela del Segnale SlingShot
# In fire/strategies/slingshot_strategy.py
def next(self):
# ... (logica di calcolo) ...
is_slingshot = (c > ema) and (c_1 < ema_1) # ...
if not self.position:
if is_slingshot:
self.buy()
# Colora la candela corrente di giallo/oro
if self.params["paint_bar"]:
self.set_bar_color(self.params["bar_color"])5. Il Flusso Dati Dietro le Quinte (Architettura)
- Raccolta: La tua strategia, eseguita dal
BacktestEngine, popola i dizionari interni (_plot_lines,_plot_shapes,_bar_colors). - Trasporto: Al termine del backtest, il
BacktestEngineimpacchetta questi dati in un dizionariocustom_plotse lo restituisce alBacktestWorker. - Inoltro: Il
BacktestWorkeraggiungecustom_plotsall’oggetto dei risultati che viene inviato alla UI tramite un segnale Qt. - Preparazione: Il
BacktestPlottingHandlerriceve i risultati e passacustom_plotsalLWCOverlayManager. - Rendering: Il
LWCOverlayManageritera sulle istruzioni e chiama i metodi JavaScript (add_line_series,set_markers, etc.) per disegnare gli elementi sul grafico.