diff --git a/zipline/algorithm.py b/zipline/algorithm.py index 434aba44..4a89df59 100644 --- a/zipline/algorithm.py +++ b/zipline/algorithm.py @@ -40,7 +40,7 @@ from zipline.finance.slippage import ( ) from zipline.finance.commission import PerShare, PerTrade from zipline.finance.blotter import Blotter -from zipline.finance.constants import ANNUALIZER, FILL_DELAYS +from zipline.finance.constants import ANNUALIZER import zipline.finance.trading as trading import zipline.protocol from zipline.protocol import Event @@ -87,8 +87,6 @@ class TradingAlgorithm(object): annualizer : int Which constant to use for annualizing risk metrics. If not provided, will extract from data_frequency. - fill_delay : datetime.timedelta - Delay between placing an order and filling an order. capital_base : float How much capital to start with. """ @@ -109,13 +107,14 @@ class TradingAlgorithm(object): self.slippage = VolumeShareSlippage() self.commission = PerShare() - self.set_data_frequency(kwargs.pop('data_frequency', 'daily')) + if 'data_frequency' in kwargs: + self.set_data_frequency(kwargs.pop('data_frequency')) + else: + self.data_frequency = None # Override annualizer if set if 'annualizer' in kwargs: self.annualizer = kwargs['annualizer'] - if 'fill_delay' in kwargs: - self.fill_delay = kwargs['fill_delay'] # set the capital base self.capital_base = kwargs.pop('capital_base', DEFAULT_CAPITAL_BASE) @@ -126,7 +125,7 @@ class TradingAlgorithm(object): self.blotter = kwargs.pop('blotter', None) if not self.blotter: - self.blotter = Blotter(fill_delay=self.fill_delay) + self.blotter = Blotter() # an algorithm subclass needs to set initialized to True when # it is fully initialized. @@ -432,4 +431,3 @@ class TradingAlgorithm(object): assert data_frequency in ('daily', 'minute') self.data_frequency = data_frequency self.annualizer = ANNUALIZER[self.data_frequency] - self.fill_delay = FILL_DELAYS[self.data_frequency] diff --git a/zipline/finance/blotter.py b/zipline/finance/blotter.py index fe9112bd..29ac0094 100644 --- a/zipline/finance/blotter.py +++ b/zipline/finance/blotter.py @@ -18,7 +18,6 @@ import uuid from copy import copy from logbook import Logger from collections import defaultdict -from datetime import timedelta import zipline.errors import zipline.protocol as zp @@ -44,7 +43,7 @@ ORDER_STATUS = Enum( class Blotter(object): - def __init__(self, fill_delay=timedelta(minutes=1)): + def __init__(self): self.transact = transact_partial(VolumeShareSlippage(), PerShare()) # these orders are aggregated by sid self.open_orders = defaultdict(list) @@ -56,8 +55,6 @@ class Blotter(object): self.current_dt = None self.max_shares = int(1e+11) - self.fill_delay = fill_delay - def __repr__(self): return """ {class_name}( @@ -158,10 +155,8 @@ class Blotter(object): orders = self.open_orders[trade_event.sid] orders = sorted(orders, key=lambda o: o.dt) # Only use orders for the current day or before - # Since orders generally do not get filled immediately, - # we allow for a delay here. current_orders = filter( - lambda o: o.dt + self.fill_delay <= trade_event.dt, + lambda o: o.dt <= trade_event.dt, orders) else: return diff --git a/zipline/finance/constants.py b/zipline/finance/constants.py index e58e8229..ce7ec8f6 100644 --- a/zipline/finance/constants.py +++ b/zipline/finance/constants.py @@ -13,8 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from datetime import timedelta - TRADING_DAYS_IN_YEAR = 250 TRADING_HOURS_IN_DAY = 6 MINUTES_IN_HOUR = 60 @@ -23,6 +21,3 @@ ANNUALIZER = {'daily': TRADING_DAYS_IN_YEAR, 'hourly': TRADING_DAYS_IN_YEAR * TRADING_HOURS_IN_DAY, 'minute': TRADING_DAYS_IN_YEAR * TRADING_HOURS_IN_DAY * MINUTES_IN_HOUR} - -FILL_DELAYS = {'daily': timedelta(days=1), - 'minute': timedelta(minutes=1)} diff --git a/zipline/gens/tradesimulation.py b/zipline/gens/tradesimulation.py index 2d9266fe..167e73c3 100644 --- a/zipline/gens/tradesimulation.py +++ b/zipline/gens/tradesimulation.py @@ -110,7 +110,7 @@ class AlgorithmSimulator(object): self.algo.perf_tracker.process_event(event) else: - events = [] + for event in snapshot: if event.type in (DATASOURCE_TYPE.TRADE, DATASOURCE_TYPE.CUSTOM): @@ -120,8 +120,11 @@ class AlgorithmSimulator(object): self.algo.set_datetime(event.dt) bm_updated = True - # Save events to stream through blotter below. - events.append(event) + process_trade = self.algo.blotter.process_trade + for txn, order in process_trade(event): + self.algo.perf_tracker.process_event(txn) + self.algo.perf_tracker.process_event(order) + self.algo.perf_tracker.process_event(event) # Update our portfolio. self.algo.set_portfolio( @@ -142,16 +145,6 @@ class AlgorithmSimulator(object): self.algo.perf_tracker.process_event(order) self.algo.blotter.new_orders = [] - # Fill orders - for event in events: - process_trade = self.algo.blotter.process_trade - for txn, order in process_trade(event): - - self.algo.perf_tracker.process_event(txn) - self.algo.perf_tracker.process_event(order) - - self.algo.perf_tracker.process_event(event) - # The benchmark is our internal clock. When it # updates, we need to emit a performance message. if bm_updated: