Ereignisgesteuertes Backtesting mit Python - Teil VI

Schriftsteller:Gutes, Erstellt: 2019-03-26 09:13:08, aktualisiert:

In diesem Artikel wird die Diskussion über ereignisgesteuerte Backtester in Python fortgesetzt.

In diesem Artikel werden wir die Ausführung dieser Aufträge untersuchen, indem wir eine Klassenhierarchie erstellen, die einen simulierten Auftragsbearbeitungsmechanismus darstellt und letztendlich an eine Maklergesellschaft oder andere Mittel der Marktverbindung gebunden ist.

Der hier beschriebene ExecutionHandler ist äußerst einfach, da er alle Aufträge zum aktuellen Marktpreis ausfüllt.

Wie bei den vorherigen abstrakten Basisklassenhierarchien müssen wir die notwendigen Eigenschaften und Dekoratoren aus der abc-Bibliothek importieren.

# execution.py

import datetime
import Queue

von abc import ABCMeta, abstrakte Methode

von Ereignisimport FillEvent, OrderEvent Der ExecutionHandler ist ähnlich wie frühere abstrakte Basisklassen und hat einfach eine reine virtuelle Methode, execute_order:

# execution.py

class ExecutionHandler(object):
    """
    The ExecutionHandler abstract class handles the interaction
    between a set of order objects generated by a Portfolio and
    the ultimate set of Fill objects that actually occur in the
    market. 

    The handlers can be used to subclass simulated brokerages
    or live brokerages, with identical interfaces. This allows
    strategies to be backtested in a very similar manner to the
    live trading engine.
    """

    __metaclass__ = ABCMeta

    @abstractmethod
    def execute_order(self, event):
        """
        Takes an Order event and executes it, producing
        a Fill event that gets placed onto the Events queue.

        Parameters:
        event - Contains an Event object with order information.
        """
        raise NotImplementedError("Should implement execute_order()")

Um Backtest-Strategien zu entwickeln, müssen wir simulieren, wie ein Handel abgewickelt wird. Die einfachste mögliche Implementierung ist, dass alle Aufträge zum aktuellen Marktpreis für alle Mengen ausgeführt werden. Dies ist eindeutig extrem unrealistisch und ein großer Teil der Verbesserung des Backtest-Realismus wird von der Gestaltung von ausgeklügelteren Modellen für Rutsch und Marktwirkung kommen.

Beachten Sie, dass das FillEvent einen Wert von None für die fill_cost (siehe vorletzte Zeile in execute_order) hat, da wir uns bereits um die Kosten der Füllung des im vorherigen Artikel beschriebenen NaivePortfolio-Objekts gekümmert haben.

Ich habe einfach ARCA als Austausch verwendet, obwohl dies für Backtesting-Zwecke nur ein Platzhalter ist.

# execution.py

class SimulatedExecutionHandler(ExecutionHandler):
    """
    The simulated execution handler simply converts all order
    objects into their equivalent fill objects automatically
    without latency, slippage or fill-ratio issues.

    This allows a straightforward "first go" test of any strategy,
    before implementation with a more sophisticated execution
    handler.
    """
    
    def __init__(self, events):
        """
        Initialises the handler, setting the event queues
        up internally.

        Parameters:
        events - The Queue of Event objects.
        """
        self.events = events

    def execute_order(self, event):
        """
        Simply converts Order objects into Fill objects naively,
        i.e. without any latency, slippage or fill ratio problems.

        Parameters:
        event - Contains an Event object with order information.
        """
        if event.type == 'ORDER':
            fill_event = FillEvent(datetime.datetime.utcnow(), event.symbol,
                                   'ARCA', event.quantity, event.direction, None)
            self.events.put(fill_event)

Dies schließt die Klassenhierarchien ab, die notwendig sind, um einen ereignisgesteuerten Backtester zu erzeugen.


Mehr