Bài viết này tiếp tục thảo luận về các backtester dựa trên sự kiện trong Python. Trong bài viết trước, chúng tôi đã xem xét một hệ thống phân cấp lớp danh mục đầu tư xử lý các vị trí hiện tại, tạo ra lệnh giao dịch và theo dõi lợi nhuận và lỗ (PnL).
Trong bài viết này, chúng tôi sẽ nghiên cứu việc thực hiện các lệnh này, bằng cách tạo ra một hệ thống phân cấp lớp sẽ đại diện cho một cơ chế xử lý lệnh mô phỏng và cuối cùng gắn vào môi giới hoặc các phương tiện kết nối thị trường khác.
Các ExecutionHandler mô tả ở đây là cực kỳ đơn giản, vì nó hoàn thành tất cả các đơn đặt hàng tại giá thị trường hiện tại.
Như với các phân cấp lớp cơ bản trừu tượng trước đây, chúng ta phải nhập các thuộc tính và trang trí cần thiết từ thư viện abc. Ngoài ra chúng ta cần nhập FillEvent và OrderEvent:
# execution.py
import datetime
import Queue
từ abc nhập khẩu ABCMeta, abstractmethod
từ nhập sự kiện FillEvent, OrderEvent ExecutionHandler tương tự như các lớp cơ sở trừu tượng trước đây và chỉ đơn giản là có một phương thức ảo thuần túy, 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()")
Để kiểm tra lại các chiến lược, chúng ta cần mô phỏng cách giao dịch sẽ được thực hiện. Việc thực hiện đơn giản nhất có thể là giả định tất cả các đơn đặt hàng được thực hiện ở mức giá thị trường hiện tại cho tất cả các số lượng. Điều này rõ ràng là cực kỳ không thực tế và một phần lớn cải thiện tính thực tế của kiểm tra lại sẽ đến từ việc thiết kế các mô hình tinh vi hơn về trượt và tác động thị trường.
Lưu ý rằng FillEvent được đưa ra một giá trị của None cho fill_cost (xem dòng trước cuối trong execute_order) như chúng ta đã chăm sóc chi phí của việc điền vào đối tượng NaivePortfolio được mô tả trong bài viết trước.
Tôi chỉ đơn giản là sử dụng ARCA như là trao đổi mặc dù cho mục đích backtesting đây chỉ là một vị trí giữ.
# 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)
Điều này kết luận các phân cấp lớp cần thiết để tạo ra một backtester dựa trên sự kiện.