ENH: Add option of instantly filling orders.

This commit is contained in:
Thomas Wiecki
2013-10-01 20:30:01 -04:00
committed by Eddie Hebert
parent 31b85239f3
commit 65637b9430
4 changed files with 49 additions and 6 deletions
+8
View File
@@ -22,6 +22,7 @@ import zipline.utils.factory as factory
from zipline.test_algorithms import (TestRegisterTransformAlgorithm,
RecordAlgorithm,
TestOrderAlgorithm,
TestOrderInstantAlgorithm,
TestOrderValueAlgorithm,
TestTargetAlgorithm,
TestOrderPercentAlgorithm,
@@ -186,3 +187,10 @@ class TestTransformAlgorithm(TestCase):
data_frequency='daily'
)
algo.run(self.df)
def test_order_instant(self):
algo = TestOrderInstantAlgorithm(sim_params=self.sim_params,
data_frequency='daily',
instant_fill=True)
algo.run(self.df)
+2
View File
@@ -112,6 +112,8 @@ class TradingAlgorithm(object):
else:
self.data_frequency = None
self.instant_fill = kwargs.pop('instant_fill', False)
# Override annualizer if set
if 'annualizer' in kwargs:
self.annualizer = kwargs['annualizer']
+21 -6
View File
@@ -85,6 +85,13 @@ class AlgorithmSimulator(object):
return self.EMISSION_TO_PERF_KEY_MAP[
self.algo.perf_tracker.emission_rate]
def process_event(self, 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)
def transform(self, stream_in):
"""
Main generator work loop.
@@ -117,6 +124,8 @@ class AlgorithmSimulator(object):
self.algo.perf_tracker.process_event(event)
else:
if self.algo.instant_fill:
events = []
for event in snapshot:
if event.type == DATASOURCE_TYPE.SPLIT:
@@ -129,12 +138,12 @@ class AlgorithmSimulator(object):
if event.type == DATASOURCE_TYPE.BENCHMARK:
self.algo.set_datetime(event.dt)
bm_updated = True
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)
# If we are instantly filling orders we process
# them after handle_data().
if not self.algo.instant_fill:
self.process_event(event)
else:
events.append(event)
# Update our portfolio.
self.algo.set_portfolio(
@@ -155,6 +164,12 @@ class AlgorithmSimulator(object):
self.algo.perf_tracker.process_event(order)
self.algo.blotter.new_orders = []
# If we are instantly filling we execute orders
# in this iteration rather than the next.
if self.algo.instant_fill:
for event in events:
self.process_event(event)
# The benchmark is our internal clock. When it
# updates, we need to emit a performance message.
if bm_updated:
+18
View File
@@ -234,6 +234,24 @@ class TestOrderAlgorithm(TradingAlgorithm):
self.order(0, 1)
class TestOrderInstantAlgorithm(TradingAlgorithm):
def initialize(self):
self.incr = 0
self.last_price = None
def handle_data(self, data):
if self.incr == 0:
assert 0 not in self.portfolio.positions
else:
assert self.portfolio.positions[0]['amount'] == \
self.incr, "Orders not filled immediately."
assert self.portfolio.positions[0]['last_sale_price'] == \
self.last_price, "Orders was not filled at last price."
self.incr += 2
self.order_value(0, data[0].price * 2.)
self.last_price = data[0].price
class TestOrderValueAlgorithm(TradingAlgorithm):
def initialize(self):
self.incr = 0