diff --git a/tests/test_finance.py b/tests/test_finance.py index 9b7c8f74..2f8cd7f0 100644 --- a/tests/test_finance.py +++ b/tests/test_finance.py @@ -366,7 +366,7 @@ class FinanceTestCase(TestCase): for event in events: if event.type == DATASOURCE_TYPE.TRADE: - txns = blotter.process_trade(event) + txns, _ = blotter.process_trade(event) for txn in txns: transactions.append(txn) diff --git a/zipline/finance/slippage.py b/zipline/finance/slippage.py index c3ccb2d5..4887ef27 100644 --- a/zipline/finance/slippage.py +++ b/zipline/finance/slippage.py @@ -144,6 +144,7 @@ class VolumeShareSlippage(object): if zp_math.tolerant_equals(open_amount, 0): continue + order.check_triggers(event) if not order.triggered: continue @@ -172,7 +173,7 @@ class VolumeShareSlippage(object): simulated_impact = (volume_share) ** 2 \ * self.price_impact * order.direction * event.price - if cur_amount > 0: + if order.direction * cur_amount > 0: txn = create_transaction( event.sid, cur_amount, @@ -206,6 +207,7 @@ class FixedSlippage(object): # and one for 100 shares short # such as in a hedging scenario? + order.check_triggers(event) if not order.triggered: continue diff --git a/zipline/gens/tradesimulation.py b/zipline/gens/tradesimulation.py index 3327f543..b71707b4 100644 --- a/zipline/gens/tradesimulation.py +++ b/zipline/gens/tradesimulation.py @@ -17,6 +17,7 @@ import math import uuid from copy import copy +from itertools import chain from logbook import Logger, Processor from collections import defaultdict @@ -78,22 +79,8 @@ class Blotter(object): results.append(event) # We only fill transactions on trade events. if event.type == DATASOURCE_TYPE.TRADE: - txns = self.process_trade(event) - results.extend(txns) - - modified_orders = [order for order - in self.open_orders[event.sid] - if order.last_modified_dt == date] - results.extend(modified_orders) - - # update the open orders for the trade_event's sid - self.open_orders[event.sid] = [order for order - in self.open_orders[event.sid] - if order.open] - - for order in modified_orders: - if not order.open: - del self.orders[order.id] + txns, modified_orders = self.process_trade(event) + results.extend(chain(txns, modified_orders)) yield date, results @@ -101,7 +88,7 @@ class Blotter(object): if zp_math.tolerant_equals(trade_event.volume, 0): # there are zero volume trade_events bc some stocks trade # less frequently than once per minute. - return [] + return [], [] if trade_event.sid in self.open_orders: orders = self.open_orders[trade_event.sid] @@ -111,19 +98,28 @@ class Blotter(object): lambda o: o.dt <= trade_event.dt, orders) else: - return [] + return [], [] - for order in current_orders: - # check price limits, continue if the - # order isn't triggered yet - order.check_triggers(trade_event) txns = self.transact(trade_event, current_orders) for txn in txns: self.orders[txn.order_id].filled += txn.amount # mark the last_modified date of the order to match self.orders[txn.order_id].last_modified_dt = txn.dt - return txns + modified_orders = [order for order + in self.open_orders[trade_event.sid] + if order.last_modified_dt == trade_event.dt] + for order in modified_orders: + if not order.open: + del self.orders[order.id] + + # update the open orders for the trade_event's sid + self.open_orders[trade_event.sid] = \ + [order for order + in self.open_orders[trade_event.sid] + if order.open] + + return txns, modified_orders class Order(object):