In questo articolo
Dopo questo articolo saprai…
- Controllare ID fra segnali e prezzi prima di togliere l’indice.
- Distinguere disponibilità dei dati, segnale e prezzo eseguito.
- Riconciliare stato, oneri e risultati con un registro riproducibile.
I concetti senza lasciare l’articolo
Backtesting Esecuzione di un ordine Commissione di trading Drawdown Stop loss Take profit, livello di uscitaUn backtest Python richiede una catena controllabile: dati, informazione disponibile in quell’istante, richieste, eseguiti e registro riconciliato. Conserva identificativi oltre ai timestamp. Un grafico veloce dell’equity non dimostra che il segnale ignorasse pubblicazioni successive o che il prezzo fosse eseguibile nel modello.
Scegli l’ambiente per la domanda di ricerca
Il tester MT5 supporta EA multivaluta, test e ottimizzazione: Python non è necessariamente la fuga da un limite di un solo cambio. Offre un altro modo di organizzare dati, calcoli personalizzati e ricerca. Confronta prodotto, contratto e modello di Esecuzione di un ordine; per indagare differenze fra implementazioni congela stessi dati e regole.
Conserva i dati e il loro significato
Registra strumento e prodotto, fornitore, lato della quotazione, fuso, campionamento e intervallo scaricato. Controlla duplicati, ordine e periodi mancanti. Una chiusura di mercato non è automaticamente un file corrotto; riempire un vuoto può inventare osservazioni. Salva originale e trasformazioni separati. Vedi Backtest: controllare lacune, duplicati e conflitti CSV.
copy_rates_range di MetaTrader5 restituisce time, OHLC, tick_volume, spread e real_volume, non una tariffa completa storica di commissioni e swap. Le barre dipendono da storia disponibile nel terminale e impostazioni; richiedere un intervallo non prova completezza. Argomenti temporali e dati restituiti usano UTC. Converti sessioni con fusi espliciti, senza assumere che Europe/Rome coincida sempre con un offset costante.
pandas e NumPy consentono calcoli; Backtrader offre un flusso a eventi. Anche vectorbt aggiorna stato monetario e delle attività, con modalità ordini, segnali e funzioni personalizzate. «Vettoriale» non significa esecuzioni indipendenti dallo stato precedente. Nessuna etichetta garantisce realismo o un tempo fisso. Scegli dipendenze necessarie, annota versioni, licenze, diritti sui dati e ambiente supportato: dati e distribuzione possono avere costi separati.
Togliere l’indice può spostare il segnale
Tre record fittizi completati, ordinati A = 100, B = 102, C = 104. Una Series di flag ha invece ordine C: 1, A: 0, B: 0. Uno indica soltanto un candidato da modellare, non un ordine o un prezzo eseguito.
Identificativo e posizione non sono la stessa chiave
Scorri orizzontalmente o ingrandisci il diagramma per leggere i dettagli.
pandas allinea Series per etichetta: prices * flags dà A: 0, B: 0, C: 104. Convertire entrambe in array e moltiplicare per posizione produce 100, 0, 0. Riassegnarlo ad A, B, C rende A il candidato. Verifica ID prima di to_numpy(), non soltanto le lunghezze. Il corretto allineamento non risolve ancora la disponibilità temporale del segnale.
Quando il record diventa utilizzabile?
Una barra H1 etichettata con apertura 10:00 non ha OHLC definitivo alle 10:00: serve la fine del periodo. Nel resampling pandas closed decide appartenenza ai bordi e label il bordo visualizzato. Cambiare etichetta non anticipa la disponibilità dell’aggregato.
Unisci osservazioni macro per pubblicazione della versione allora disponibile, non solo per mese di riferimento. merge_asof richiede chiavi ordinate: backward cerca prima o allo stesso istante, nearest può trovare un record successivo. Nessuno conosce da solo le revisioni. Definisci tolleranza e ordine per eventi con lo stesso timestamp.
Test inventato: decisione 10:04 UTC; record 10:00 valore 50 e 10:05 valore 60. Senza tolleranza, backward seleziona 50, quattro minuti prima; nearest 60, uno dopo ma futuro. Tolleranza backward inclusiva di due minuti: nessuna corrispondenza. Non sostituire il dato assente col futuro soltanto perché più vicino.
Ricetta separata: prime venti barre con High da 100 a 119, Open = High −0.5, Low = High −2, Close = High −1. Barra 21 O120/H121/L118/C120.5; barra 22 O120.6/H122/L119/C121. Prezzi arbitrari, non serie forex reale.
previous_high = bars["high"].shift(1).rolling(20).max()
signal = bars["close"] > previous_high
next_bar_signal = signal.shift(1, fill_value=False)
Alla 21 il massimo delle venti barre precedenti è 119: 120.5> 119 vero. Includere High corrente rende soglia 121 e confronto falso. L’ultima riga colloca il segnale osservato nella 22: non determina fill, accettazione, uscita o quantità. Usa input completati e specifica eventi ed esecuzione separatamente. Il codice mantiene sintassi e punti decimali Python, anche nel testo italiano.
Segnale, fill e oneri separati
Nel modello standard documentato Backtrader, un Market richiesto dopo elaborazione della barra usa l’Open della prossima disponibile. Impostazioni o modelli diversi possono cambiare tempi. Se stop e target ricadono nello stesso intervallo OHLC, non conosci necessariamente quale sia stato osservato prima.
Modello originale: acquisto 10000 EUR su EUR/USD all’Ask 1.1002 con Bid 1.1000. Vendita successiva di tutto al Bid 1.1012 con Ask 1.1014. Pip 0.0001 USD per EUR: differenza dieci pip = 10 USD. Commissione 1 USD per lato → netto 8 USD; finanziamento e ulteriore slippage zero per ipotesi. Sottrarre altri due pip d’ingresso darebbe 6 USD, contando due volte uno scarto già presente nei fill.
Nuovo modello separato in EUR: quattro unità di un prodotto ipotetico quotato in EUR, acquisto eseguito 250 EUR ciascuna e vendita 252, senza cambio o finanziamento. Lordo 4 × 2 = 8 EUR, commissione 1,50 EUR per lato, netto 5 EUR. Gli eseguiti includono già i prezzi effettivi: sottrarre un altro spread fittizio di 1 EUR produce 4 EUR errati. Non è un preventivo o una specifica di un broker.
Per il prodotto reale definisci finanziamento, conversioni, contratto, margine e rifiuti. Con più strumenti modellizza cassa condivisa, margine e ordine di richieste simultanee: sommare curve indipendenti può includere ordini non finanziabili insieme. Uno slippage casuale richiede distribuzione, seed e versione.
Il registro rende verificabili le metriche
Altro modello con R monetario identico: quaranta +2 R e sessanta −1 R danno guadagni 80 R, perdite 60 R, netto 20 R, PF 80/60≈1,33, media 0,2 R. Costo 0,1 R su ogni trade: quaranta +1,9 R e sessanta −1,1 R → guadagni 76 R, perdite 66 R, netto 10 R, PF 76/66≈1,15, media 0,1 R. Non è un risultato osservato di backtest.
Controesempio di stato: su cinque barre condizioni vero, vero, vero, falso, vero. Entrambi i protocolli entrano nella 1; uno stop chiude nella 2 prima di valutare l’ingresso. Nessuna uscita successiva. Entrare ogni volta che sei flat e vero dà ingressi 1 e 2. Richiedere prima un nuovo falso per riarmare aspetta 2 e 3, si riarma nella 4 ed entra nella 5. Due ingressi ciascuno, tempi diversi. È un nostro protocollo, non una pretesa sui default delle librerie.
Conserva equity delle posizioni aperte e risultati chiusi. Per il Drawdown includi capitale iniziale e separa flussi. Non aggiungere rendimento o Sharpe non ricostruibili da registro e serie datati.
Netto 5 EUR: non sottrarre un altro spread già contenuto nei fill.
- Prezzi eseguiti
- 4 × (252−250) = 8 EUR – Nessun cambio o finanziamento per ipotesi.
- Commissioni
- 1,50 + 1,50 = 3 EUR – Esplicite e separate.
- Risultato netto
- 5 EUR – Sottrarre ancora 1 EUR darebbe 4, doppio conteggio.
Selezione e dati intatti
Fissa finestre cronologiche di sviluppo e test prima di scegliere regole. Registra ogni strumento, filtro, combinazione e split tentati, anche scartati. Pochi parametri non significano poche ipotesi esplorate. La ricerca di Bailey e coautori studia sovraottimizzazione da selezione ripetuta; qui non stimiamo una probabilità PBO dai modelli fittizi.
Altro campione inventato: 75 vincite +0,2 R e 25 perdite −1 R danno 15 R contro 25 R, netto −10 R prima dei costi e PF 0,6, pur con 75% di successi. Una percentuale alta non diagnostica da sola bias; verifica causalità, contabilità, dipendenza, esecuzione e sensibilità dei parametri.
Prima prova offline
- Crea progetto isolato e conserva dati originali, identificativi, UTC, lato quotazione e versioni. Non servono credenziali live né ordini.
- Riproduci pochi record specificati: disponibilità del segnale, evento eseguibile, dato assente e revisione.
- Definisci stato: aggiunte, inversioni, rientro dopo stop o riarmo. Confronta gli identificativi attesi d’ingresso.
- Riconcilia fill e oneri, deriva risultati dal registro e ripeti con alternative d’esecuzione dichiarate.
- Salva tentativi, finestre intatte, limiti e versioni. Un calo fisso di performance non identifica da solo la causa. Prosegui con Walk-forward: finestre, gap e limiti della valutazione.
Verifica ciò che hai imparato
Circa 2 minuti di esercizio.
Mostra risposta e spiegazione
L’unico flag 1 appartiene a C, il cui prezzo è 104.
Altre domande
Quanto Python serve per iniziare?
Saper ispezionare record, funzioni e differenza fra indice e posizione. Riproduci un modello piccolo prima di aumentare dati. L’allineamento non è una strategia completa: tempi, stato, quantità e uscite richiedono definizioni. Trenta righe o una durata fissa non provano preparazione.
Backtrader o vectorbt?
Confronta modalità documentata e requisiti. Backtrader è a eventi; nel suo modello standard Market usa il prossimo Open. vectorbt ha ordini, segnali e funzioni personalizzate con stato aggiornato. Nessuno garantisce velocità indipendente dai dati o realismo automatico.
Da dove ottenere uno storico affidabile?
Definisci prodotto, fornitore, lato, fuso e storia disponibile. copy_rates_range usa UTC e limiti del terminale, senza tariffa storica completa o prova dei fill. yfinance è uno strumento indipendente con avvisi d’uso dei dati Yahoo; CCXT riguarda exchange. Il nome non sostituisce completezza e idoneità. Conserva file originale e riparazioni.
Come riconoscere un test troppo bello?
Ricostruisci informazioni disponibili, segnali, fill e costi; conserva tentativi e dati intatti. 75 vincite da 0,2 R contro 25 perdite da 1 R perdono 10 R prima degli oneri. Win rate e PF insoliti motivano un’indagine, non diagnosticano da soli un bug.
Perché nearest può usare il futuro?
Alle 10:04 un record 10:05 è distante un minuto, meno dei quattro fino alle 10:00. Essere vicino non significa disponibile. Backward con tolleranza di due minuti non trova nulla nel modello: non sostituirlo col futuro.
Perché due ingressi non provano gli stessi trade?
Con vero, vero, vero, falso, vero e stop nella 2 prima dell’ingresso, una politica rientra nella 2; quella che attende un nuovo falso entra nella 5. Totale uguale, tempi e prezzi potenziali diversi.
Fonti e verifica
- pandas — Series label alignment
Le Series pandas possono allinearsi per etichetta dell’indice: l’allineamento non coincide necessariamente con la posizione della riga.
- pandas — merge_asof
merge_asof richiede dati ordinati e scelte esplicite su direzione, tolleranza e corrispondenze esatte. L’orario dell’esempio è ipotetico.
- pandas — DataFrame.resample
In pandas resample, closed determina l’appartenenza agli intervalli e label la loro etichetta. L’etichetta non dimostra quando il dato era disponibile.
- MetaQuotes — copy_rates_range
copy_rates_range di MetaTrader 5: orari UTC, campi restituiti e limiti della cronologia. La funzione non ricostruisce da sola tutte le commissioni storiche.
- Backtrader — Order creation/execution
Nel modello Backtrader un ordine Market può essere eseguito all’apertura della barra successiva. È una convenzione del simulatore, non un’esecuzione reale garantita.
- vectorbt — Portfolio workflow
Documentazione vectorbt sulla simulazione sequenziale di portafogli, ordini e segnali. Non viene presentata come prova di un’esecuzione effettuata dall’autore.
I calcoli usano ipotesi esplicite. Non sostituiscono i dati attuali di mercato o le condizioni dell’intermediario.
