События, обусловленные обратным тестированием с Python - Часть VI

Автор:Доброта, Создано: 2019-03-26 09:13:08, Обновлено:

В предыдущей статье мы рассмотрели иерархию класса портфеля, которая обрабатывала текущие позиции, генерировала торговые ордера и отслеживала прибыль и убытки (PnL).

В этой статье мы будем изучать исполнение этих ордеров, создавая иерархию классов, которая будет представлять собой симулированный механизм обработки ордеров и в конечном итоге связана с брокерским или другими средствами связи рынка.

Описанный здесь ExecutionHandler чрезвычайно прост, поскольку он выполняет все заказы по текущей рыночной цене.

Как и с предыдущими абстрактными иерархиями базовых классов, мы должны импортировать необходимые свойства и декораторы из библиотеки abc.

# execution.py

import datetime
import Queue

из abc import ABCMeta, абстрактный метод

из импорта события FillEvent, OrderEvent ExecutionHandler похож на предыдущие абстрактные базовые классы и просто имеет один чистый виртуальный метод, 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()")

Для того, чтобы проверить стратегии, мы должны смоделировать, как будет осуществляться торговля. Самая простая возможная реализация предполагает, что все заказы выполняются по текущей рыночной цене для всех количеств. Это явно крайне нереалистично, и большая часть улучшения реализма обратного теста будет исходить из разработки более сложных моделей скольжения и влияния на рынок.

Обратите внимание, что FillEvent получает значение None для fill_cost (см. предпоследнюю строку в execute_order), так как мы уже позаботились о стоимости заполнения объекта NaivePortfolio, описанного в предыдущей статье.

Я просто использовал ARCA в качестве обмена, хотя для целей обратного тестирования это чисто местонахождение.

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

В следующей статье мы рассмотрим, как рассчитать набор показателей производительности для проверенной стратегии.


Больше