Tests arrière basés sur des événements avec Python - Partie VI

Auteur:La bonté, Créé: 2019-03-26 09:13:08, mis à jour:

Cet article poursuit la discussion des backtesters basés sur des événements en Python. Dans l'article précédent, nous avons considéré une hiérarchie de classe de portefeuille qui gérait les positions actuelles, générait des ordres de négociation et suivait les profits et pertes (PnL).

Dans cet article, nous étudierons l'exécution de ces ordres, en créant une hiérarchie de classe qui représentera un mécanisme de traitement des ordres simulé et finalement lié à un courtage ou à d'autres moyens de connectivité du marché.

L'ExecutionHandler décrit ici est extrêmement simple, car il remplit tous les ordres au prix du marché actuel.

Comme pour les précédentes hiérarchies de classes de base abstraites, nous devons importer les propriétés et les décorateurs nécessaires de la bibliothèque abc.

# execution.py

import datetime
import Queue

de l'abc à l'import ABCMeta, méthode abstraite

depuis l'importation d'événement FillEvent, OrderEvent L'ExecutionHandler est similaire aux classes de base abstraites précédentes et a simplement une méthode virtuelle pure, 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()")

Pour tester les stratégies en arrière-plan, nous devons simuler comment une transaction sera effectuée. La mise en œuvre la plus simple possible est de supposer que tous les ordres sont remplis au prix du marché actuel pour toutes les quantités.

Notez que le FillEvent est donné une valeur de None pour le fill_cost (voir la ligne avant-dernière dans execute_order) car nous avons déjà pris soin du coût de remplissage de l'objet NaivePortfolio décrit dans l'article précédent.

Dans un environnement d'exécution en direct, cette dépendance du lieu serait beaucoup plus importante:

# 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)

Cela conclut les hiérarchies de classes nécessaires pour produire un backtester axé sur les événements.


Plus de