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.
This commit is contained in:
Eddie Hebert
2013-06-19 13:13:35 -04:00
parent c36fe01637
commit d6abe172a2
2 changed files with 39 additions and 0 deletions
+29
View File
@@ -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()
+10
View File
@@ -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.