From b1234adee612db362e00369498d8e28ccea662e3 Mon Sep 17 00:00:00 2001 From: Eddie Hebert Date: Tue, 18 Jun 2013 11:14:52 -0400 Subject: [PATCH] BUG: Protect against transactions with an amount less than 1. If the amount is less than 1, then many more transactions than are needed are created and then ignored by both the slippage and blotter code. --- zipline/finance/slippage.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/zipline/finance/slippage.py b/zipline/finance/slippage.py index f26390d3..5352f8bb 100644 --- a/zipline/finance/slippage.py +++ b/zipline/finance/slippage.py @@ -103,6 +103,14 @@ class Transaction(object): def create_transaction(event, order, price, amount): + # floor the amount to protect against non-whole number orders + # TODO: Investigate whether we can add a robust check in blotter + # and/or tradesimulation, as well. + amount_magnitude = int(math.copysign(amount, 1)) + + if amount_magnitude < 1: + raise Exception("Transaction magnitude must be at least 1.") + txn = { 'sid': event.sid, 'amount': int(amount), @@ -180,17 +188,17 @@ class VolumeShareSlippage(SlippageModel): # price impact accounts for the total volume of transactions # created against the current minute bar remaining_volume = max_volume - self.volume_for_bar - if ( - remaining_volume <= 0 - or - zp_math.tolerant_equals(remaining_volume, 0) - ): + if remaining_volume < 1: # we can't fill any more transactions return # the current order amount will be the min of the # volume available in the bar or the open amount. - cur_volume = min(remaining_volume, abs(order.open_amount)) + cur_volume = int(min(remaining_volume, abs(order.open_amount))) + + if cur_volume < 1: + return + # tally the current amount into our total amount ordered. # total amount will be used to calculate price impact total_volume = self.volume_for_bar + cur_volume