In questa lezione continua lo sviluppo di un trading system basato sugli eventi con Python. Descriviamo come implementare l’esecuzione degli ordini, creando una gerarchia di classi che rappresenta un meccanismo per la simulazione della gestione degli ordini e, infine, collegarsi ad un broker o ad altri intermediari di mercato.
Esecuzione degli Ordini
L’ExecutionHandler
descritto in questa lezione è estremamente semplice. Prevede di eseguire tutti gli ordini al prezzo corrente di mercato. Questo è altamente irrealistico, ma serve come base di partenza da perfezionare successivamente.
Come per le precedenti gerarchie di classi astratte di base, per la classe di esecuzione degli ordini dobbiamo importare le proprietà e i decoratori dalla libreria abc
. Inoltre, dobbiamo importare FillEvent
e OrderEvent
:
# execution.py
import datetime
import queue
from abc import ABCMeta, abstractmethod
from event.event import FillEvent, OrderEvent
La classe ExecutionHandler
è simile alle precedenti classi astratte di base e ha solamente un metodo virtuale, execute_order
:
# execution.py
class ExecutionHandler(object):
"""
La classe astratta ExecutionHandler gestisce l'interazione
tra un insieme di oggetti "ordini" generati da un portafoglio e
l'ultimo set di oggetti Fill che effettivamente si verificano
nel mercato.
Gli handles possono essere utilizzati per creare sottoclassi
con interfacce identiche per broker simulati o broker live.
Questo permette di sottoporre strategie a backtesting in modo
molto simile al motore di live trading.
"""
__metaclass__ = ABCMeta
@abstractmethod
def execute_order(self, event):
"""
Accetta un evento Order e lo esegue, producendo
un evento Fill che viene inserito nella coda degli eventi.
Parametri:
event - Contiene un oggetto Event con informazioni sull'ordine.
"""
raise NotImplementedError("Should implement execute_order()")
Per testare le strategie di trading, simuliamo l’esecuzione degli ordini. La forma più semplice prevede che tutti gli ordini vengano eseguiti al prezzo di mercato corrente, indipendentemente dalla quantità. Tuttavia, questa ipotesi risulta irrealistica. Gran parte del lavoro necessario per rendere più realistico il backtesting consiste nel progettare modelli avanzati che simulino lo slippage e l’impacto del mercato.
Nel metodo FillEvent
, il valore None
viene passato all’attributo fill_cost
(vedi la penultima riga in execute_order
), come abbiamo spiegato per il costo di esecuzione nell’oggetto NaivePortfolio
, descritto nella precedente lezione. In un’implementazione più realistica, si usano i dati di mercato “attuali” per ottenere un costo di esecuzione più preciso.
Per il backtesting, abbiamo utilizzato ARCA come exchange, ma questo è solo un segnaposto. In un ambiente di esecuzione dal vivo, questo attributo assume un’importanza maggiore.
# execution.py
class SimulatedExecutionHandler(ExecutionHandler):
"""
Il gestore di esecuzione simulato converte semplicemente tutti gli
oggetti Ordine automaticamente negli equivalenti oggetti Fill
senza considerare i problemi di latenza, slittamento e rapporto di
esecuzione (fill-ratio).
Ciò consente un semplice test "first go" di qualsiasi strategia,
prima dell'implementazione con un gestiore di esecuzione più sofisticato.
"""
def __init__(self, events):
"""
Inizializza il gestore, impostando internamente le code degli eventi.
Parametri
events - L'oggetto di coda degli eventi.
"""
self.events = events
def execute_order(self, event):
"""
Converte semplicemente gli oggetti Order in oggetti Fill base,
cioè senza considerare latenza, slittamento o rapporto di esecuzione.
Parametri:
event - Contiene un oggetto Event con informazioni sull'ordine.
"""
if event.type == 'ORDER':
fill_event = FillEvent(datetime.datetime.utcnow(), event.symbol,
'ARCA', event.quantity, event.direction, None)
self.events.put(fill_event)
Conclusione
Questa classe conclude le gerarchie di classi necessarie per implementare un ambiente di backtesting basato sugli eventi.
Nella prossima lezione descriviamo come calcolare un insieme di metriche sul rendimento per la strategia oggetto del backtesting.
Il codice completo presentato in questa lezione, basato sul sistema di trading event-driven TQTradingSystem, è disponibile nel seguente repository GitHub: https://github.com/tradingquant-it/TQTradingSystem.”