Esecuzione degli Ordini – Creare un Trading System Parte 6

Esecuzione degli Ordini di un Trading System

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.”

Torna in alto