Artikel ini meneruskan perbincangan tentang backtesters yang didorong oleh peristiwa di Python. Dalam artikel sebelumnya, kami mempertimbangkan hierarki kelas portfolio yang mengendalikan kedudukan semasa, menjana pesanan dagangan dan menjejaki keuntungan dan kerugian (PnL).
Dalam artikel ini kita akan mengkaji pelaksanaan pesanan ini, dengan mewujudkan hierarki kelas yang akan mewakili mekanisme pengendalian pesanan yang disimulasikan dan akhirnya mengikat ke dalam broker atau cara lain penyambungan pasaran.
ExecutionHandler yang diterangkan di sini sangat mudah, kerana ia memenuhi semua pesanan pada harga pasaran semasa.
Seperti dengan hierarki kelas asas abstrak sebelumnya, kita mesti mengimport sifat dan dekorator yang diperlukan dari perpustakaan abc.
# execution.py
import datetime
import Queue
daripada abc import ABCMeta, abstrakmetod
daripada import peristiwa FillEvent, OrderEvent ExecutionHandler serupa dengan kelas asas abstrak sebelumnya dan hanya mempunyai satu kaedah maya murni, 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()")
Untuk menguji strategi backtest, kita perlu mensimulasikan bagaimana perdagangan akan ditransfer. Pelaksanaan yang paling mudah adalah menganggap semua pesanan dipenuhi pada harga pasaran semasa untuk semua kuantiti. Ini jelas sangat tidak realistik dan sebahagian besar peningkatan realisme backtest akan datang dari merancang model yang lebih canggih seluncur dan kesan pasaran.
Perhatikan bahawa FillEvent diberi nilai None untuk fill_cost (lihat baris penutup dalam execute_order) kerana kita telah menguruskan kos mengisi objek NaivePortfolio yang diterangkan dalam artikel sebelumnya.
Saya hanya menggunakan ARCA sebagai pertukaran walaupun untuk tujuan backtesting ini semata-mata tempat penahan.
# 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)
Ini menyimpulkan hierarki kelas yang diperlukan untuk menghasilkan backtester yang didorong oleh peristiwa.