1. Filosofia: “Dichiara i Parametri, Lascia che FIRE Costruisca la UI”
Per trasformare uno script di backtesting in uno strumento flessibile, i parametri hardcoded devono essere eliminati. FIRE adotta un approccio dichiarativo: la strategia definisce quali sono i suoi parametri, e il framework si occupa di generare automaticamente una finestra di dialogo per permettere all’utente di modificarli.
Questo disaccoppia la logica della strategia dalla sua interfaccia di configurazione, rendendo il sistema modulare e facilmente estensibile.
2. Definire i Parametri (self.add_parameter)
Per rendere un valore configurabile, devi “dichiararlo” usando il metodo self.add_parameter all’interno del costruttore (__init__) della tua strategia.
Sintassi
self.add_parameter(name, default, type, label, **kwargs)name(str): Obbligatorio. Il nome della variabile interna. Sarà la chiave per accedere al valore inself.params. Es:'ema_length'.default(any): Obbligatorio. Il valore di default del parametro.type(str): Obbligatorio. Il tipo di input da mostrare nella UI. Valori supportati:'int': Campo numerico intero (QSpinBox).'float': Campo numerico con decimali (QDoubleSpinBox).'bool': Casella di controllo (QCheckBox).'color': Selettore di colore (ColorPickerLabel).'select': Menu a tendina (QComboBox).'str': Campo di testo (QLineEdit).
label(str): Etichetta leggibile da mostrare nella UI. Se omesso, viene generato dalname(es.ema_length→Ema Length).**kwargs: Argomenti opzionali specifici per tipo.- Per
intefloat:min,max,step. - Per
float:decimals. - Per
select:options=['EURUSD', 'GBPUSD'].
- Per
3. Usare i Parametri nella Strategia
Una volta dichiarati, i valori correnti dei parametri sono sempre disponibili nel dizionario self.params.
Dove usarli?
Accedi a self.params all’interno dei metodi init() e next() per influenzare la logica e la visualizzazione della tua strategia.
Esempio Completo: SlingShotStrategy
# In fire/strategies/slingshot_strategy.py
class SlingShotStrategy(BaseStrategy):
def __init__(self):
super().__init__()
self.name = "TAPLOT SlingShot"
# --- Dichiarazione dei parametri ---
self.add_parameter("ema_length", 4, type="int", min=1, label="EMA Length")
self.add_parameter("show_ema", True, type="bool", label="Show EMA Line?")
self.add_parameter("paint_bar", True, type="bool", label="Paint Bar?")
self.add_parameter("bar_color", "#FFD700", type="color", label="Bar Color")
def init(self):
# --- Uso dei parametri ---
ema_len = self.params["ema_length"]
show_ema = self.params["show_ema"]
self.ema_high_series = self.data['high'].ewm(span=ema_len, adjust=False).mean()
if show_ema:
self.plot(self.ema_high_series, name=f"EMA High ({ema_len})", ...)
def next(self):
# ...
if is_slingshot:
# --- Uso dei parametri ---
if self.params["paint_bar"]:
self.set_bar_color(self.params["bar_color"])4. Il Flusso Dati Dietro le Quinte (Architettura)
- Apertura Dialogo: L’utente clicca il pulsante “⚙️” nel
BacktestTabWidget. - Lettura Configurazione: Il widget chiama
strategy.get_parameters_config()per ottenere le definizioni dei parametri. Legge anche eventuali valori salvati in precedenza daSettingsManager. - Costruzione UI: Il
StrategySettingsDialogriceve queste definizioni e costruisce dinamicamente il form con i widget appropriati (QSpinBox,QCheckBox, etc.). - Conferma Utente: L’utente modifica i valori e preme “OK”.
- Salvataggio: Il
BacktestTabWidgetrecupera i nuovi valori dal dialogo e li salva inSettingsManagerin un file JSON, garantendo la persistenza tra le sessioni. - Rilancio: Il
BacktestTabWidgetemette un segnale per rieseguire il backtest. - Iniezione Parametri: Il
BacktestOrchestratorintercetta la richiesta, carica l’istanza della strategia, legge i parametri salvati daSettingsManagere li “inietta” nella strategia chiamandostrategy.update_parameters(saved_params). - Esecuzione: La strategia viene eseguita dal
BacktestEnginecon i nuovi valori.