From d6abe172a2112829a16319d722e0957a02fdc006 Mon Sep 17 00:00:00 2001 From: Eddie Hebert Date: Wed, 19 Jun 2013 13:13:35 -0400 Subject: [PATCH] ENH: Add check to ensure transactions and orders are aligned. Raise exceptions when the slippage model returns transactions that are non-sensical, i.e. those with zero volume, buy transactions when the order is a sell (and vice-versa), and transactions that are for a larger amount than the corresponding order. TODO: After adding a unit test suite that covers just the blotter, add tests that exercise this logic to that suite. --- zipline/errors.py | 29 +++++++++++++++++++++++++++++ zipline/finance/blotter.py | 10 ++++++++++ 2 files changed, 39 insertions(+) diff --git a/zipline/errors.py b/zipline/errors.py index 4095552c..c7859b49 100644 --- a/zipline/errors.py +++ b/zipline/errors.py @@ -82,3 +82,32 @@ You attempted to override commission after the simulation has \ started. You may only call override_commission in your initialize \ method. """.strip() + + +class TransactionWithNoVolume(ZiplineError): + """ + Raised if a transact call returns a transaction with zero volume. + """ + msg = """ +Transaction {txn} has a volume of zero. +""".strip() + + +class TransactionWithWrongDirection(ZiplineError): + """ + Raised if a transact call returns a transaction with a direction that + does not match the order. + """ + msg = """ +Transaction {txn} not in same direction as corresponding order {order}. +""".strip() + + +class TransactionWithNoAmount(ZiplineError): + """ + Raised if a transact call returns a transaction with a volume greater than +the corresponding order. + """ + msg = """ +Transaction volume of {txn} exceeds the order volume of {order}. +""".strip() diff --git a/zipline/finance/blotter.py b/zipline/finance/blotter.py index 88ec8a0a..6c9a37ad 100644 --- a/zipline/finance/blotter.py +++ b/zipline/finance/blotter.py @@ -19,6 +19,7 @@ from copy import copy from logbook import Logger from collections import defaultdict +import zipline.errors import zipline.protocol as zp from zipline.finance.slippage import ( @@ -161,6 +162,15 @@ class Blotter(object): return for order, txn in self.transact(trade_event, current_orders): + if txn.amount == 0: + raise zipline.errors.TransactionWithNoAmount(txn=txn) + if math.copysign(1, txn.amount) != order.direction: + raise zipline.errors.TransactionWithWrongDirection( + txn=txn, order=order) + if abs(txn.amount) > abs(self.orders[txn.order_id].amount): + raise zipline.errors.TransactionVolumeExceedsOrder( + txn=txn, order=order) + order.filled += txn.amount # mark the date of the order to match the transaction # that is filling it.