Backtesting baseado em eventos com Python - Parte VI

Autora:Bem-estar, Criado: 2019-03-26 09:13:08, Atualizado:

Este artigo continua a discussão de backtesters orientados por eventos em Python. No artigo anterior, consideramos uma hierarquia de classe de carteira que lidava com posições atuais, gerou ordens de negociação e manteve o controle de lucro e perda (PnL).

Neste artigo, vamos estudar a execução dessas ordens, criando uma hierarquia de classes que representará um mecanismo de processamento de ordens simulado e, finalmente, vinculado a uma corretoria ou outros meios de conectividade do mercado.

O ExecutionHandler descrito aqui é extremamente simples, uma vez que preenche todas as ordens ao preço de mercado atual.

Como com as hierarquias de classes básicas abstratas anteriores, devemos importar as propriedades e decoradores necessários da biblioteca abc. Além disso, precisamos importar o FillEvent e OrderEvent:

# execution.py

import datetime
import Queue

de abc import ABCMeta, abstractmethod

da importação de eventos FillEvent, OrderEvent O ExecutionHandler é semelhante às classes básicas abstratas anteriores e simplesmente tem um método virtual puro, 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()")

A implementação mais simples possível é assumir que todas as ordens são preenchidas no preço de mercado atual para todas as quantidades. Isso é claramente extremamente irrealista e uma grande parte da melhoria do realismo do backtest virá do projeto de modelos mais sofisticados de deslizamento e impacto no mercado.

Observe que o FillEvent recebe um valor de Nenhum para o fill_cost (veja a penúltima linha em execute_order) como já tomamos conta do custo de preenchimento no objeto NaivePortfolio descrito no artigo anterior.

Em um ambiente de execução ao vivo, esta dependência de local seria muito mais 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)

Isto conclui as hierarquias de classes necessárias para produzir um backtester orientado por eventos.


Mais.